diff --git a/.gitignore b/.gitignore index 8823d8abe..24806f0c7 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ openDMP/dmp-backend/uploads/ openDMP/dmp-backend/tmp/ storage/ logs/ +dmp-backend/web/src/main/resources/certificates/ diff --git a/dmp-backend/core/pom.xml b/dmp-backend/core/pom.xml index fd9d90930..3f5dff069 100644 --- a/dmp-backend/core/pom.xml +++ b/dmp-backend/core/pom.xml @@ -39,6 +39,11 @@ gr.cite.opendmp repositorydepositbase 1.0.4 + + + gr.cite + elastic + 2.1.2 org.eclipse.angus @@ -52,8 +57,8 @@ org.apache.maven.plugins maven-compiler-plugin - 17 - 17 + 21 + 21 diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticConfiguration.java new file mode 100644 index 000000000..cb1785a28 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticConfiguration.java @@ -0,0 +1,20 @@ +package eu.eudat.configurations.elastic; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(AppElasticProperties.class) +public class AppElasticConfiguration { + private final AppElasticProperties properties; + + @Autowired + public AppElasticConfiguration(AppElasticProperties properties) { + this.properties = properties; + } + + public AppElasticProperties getProperties() { + return properties; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticProperties.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticProperties.java new file mode 100644 index 000000000..3d69932ae --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/elastic/AppElasticProperties.java @@ -0,0 +1,43 @@ +package eu.eudat.configurations.elastic; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "app-elastic") +public class AppElasticProperties { + private boolean enabled; + private String dmpIndexName; + private String descriptionIndexName; + private boolean enableIcuAnalysisPlugin; + + public String getDmpIndexName() { + return dmpIndexName; + } + + public void setDmpIndexName(String dmpIndexName) { + this.dmpIndexName = dmpIndexName; + } + + public boolean isEnableIcuAnalysisPlugin() { + return enableIcuAnalysisPlugin; + } + + public void setEnableIcuAnalysisPlugin(boolean enableIcuAnalysisPlugin) { + this.enableIcuAnalysisPlugin = enableIcuAnalysisPlugin; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getDescriptionIndexName() { + return descriptionIndexName; + } + + public void setDescriptionIndexName(String descriptionIndexName) { + this.descriptionIndexName = descriptionIndexName; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/ElasticConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/ElasticConfiguration.java new file mode 100644 index 000000000..e0df8dfcb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/ElasticConfiguration.java @@ -0,0 +1,38 @@ +package eu.eudat.elastic; + + +import eu.eudat.elastic.converter.*; +import gr.cite.tools.elastic.configuration.AbstractElasticConfiguration; +import gr.cite.tools.elastic.configuration.ElasticCertificateProvider; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions; + +import java.util.List; + +@Configuration +@EnableConfigurationProperties(ElasticProperties.class) +@ConditionalOnProperty(prefix = "elastic", name = "enabled", matchIfMissing = false) +public class ElasticConfiguration extends AbstractElasticConfiguration { + + public ElasticConfiguration(ApplicationContext applicationContext, ElasticProperties elasticProperties, ElasticCertificateProvider elasticCertificateProvider) { + super(elasticProperties, elasticCertificateProvider); + } + + @Bean + @Override + public ElasticsearchCustomConversions elasticsearchCustomConversions() { + return new ElasticsearchCustomConversions( + List.of( + new DmpUserRoleToShortConverter(), + new DescriptionStatusToShortConverter(), + new DmpStatusToShortConverter(), + new IsActiveToShortConverter(), + new DmpAccessTypeToShortConverter() + )); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DescriptionStatusToShortConverter.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DescriptionStatusToShortConverter.java new file mode 100644 index 000000000..83be88784 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DescriptionStatusToShortConverter.java @@ -0,0 +1,13 @@ +package eu.eudat.elastic.converter; + +import eu.eudat.commons.enums.DescriptionStatus; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.WritingConverter; + +@WritingConverter +public class DescriptionStatusToShortConverter implements Converter { + @Override + public Short convert(DescriptionStatus source) { + return source.getValue(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpAccessTypeToShortConverter.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpAccessTypeToShortConverter.java new file mode 100644 index 000000000..efb5eb50f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpAccessTypeToShortConverter.java @@ -0,0 +1,13 @@ +package eu.eudat.elastic.converter; + +import eu.eudat.commons.enums.DmpAccessType; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.WritingConverter; + +@WritingConverter +public class DmpAccessTypeToShortConverter implements Converter { + @Override + public Short convert(DmpAccessType source) { + return source.getValue(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpStatusToShortConverter.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpStatusToShortConverter.java new file mode 100644 index 000000000..fd3dbee43 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpStatusToShortConverter.java @@ -0,0 +1,14 @@ +package eu.eudat.elastic.converter; + +import eu.eudat.commons.enums.DescriptionStatus; +import eu.eudat.commons.enums.DmpStatus; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.WritingConverter; + +@WritingConverter +public class DmpStatusToShortConverter implements Converter { + @Override + public Short convert(DmpStatus source) { + return source.getValue(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpUserRoleToShortConverter.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpUserRoleToShortConverter.java new file mode 100644 index 000000000..7a61e7f21 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/DmpUserRoleToShortConverter.java @@ -0,0 +1,13 @@ +package eu.eudat.elastic.converter; + +import eu.eudat.commons.enums.DmpUserRole; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.WritingConverter; + +@WritingConverter +public class DmpUserRoleToShortConverter implements Converter { + @Override + public Short convert(DmpUserRole source) { + return source.getValue(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/IsActiveToShortConverter.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/IsActiveToShortConverter.java new file mode 100644 index 000000000..8f54da448 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/converter/IsActiveToShortConverter.java @@ -0,0 +1,13 @@ +package eu.eudat.elastic.converter; + +import eu.eudat.commons.enums.DmpStatus; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.WritingConverter; + +@WritingConverter +public class IsActiveToShortConverter implements Converter { + @Override + public Short convert(DmpStatus source) { + return source.getValue(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DescriptionElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DescriptionElasticEntity.java new file mode 100644 index 000000000..bad305c08 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DescriptionElasticEntity.java @@ -0,0 +1,126 @@ +package eu.eudat.elastic.data; + +import eu.eudat.commons.enums.DescriptionStatus; +import eu.eudat.elastic.data.nested.*; +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@Document(indexName = "description") +public class DescriptionElasticEntity { + + @Id + @Field(value = DescriptionElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = DescriptionElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + @Field(value = DescriptionElasticEntity._description, type = FieldType.Text) + private String description; + public final static String _description = "description"; + + @Field(value = DescriptionElasticEntity._status, type = FieldType.Short) + private DescriptionStatus status; + public final static String _status = "status"; + + @Field(value = DescriptionElasticEntity._finalizedAt, type = FieldType.Date) + private Date finalizedAt; + public final static String _finalizedAt = "finalizedAt"; + + @Field(value = DescriptionElasticEntity._tags, type = FieldType.Nested) + private List tags; + public final static String _tags = "tags"; + + @Field(value = DescriptionElasticEntity._descriptionTemplate, type = FieldType.Object) + private NestedDescriptionTemplateElasticEntity descriptionTemplate; + public final static String _descriptionTemplate = "descriptionTemplate"; + + @Field(value = DescriptionElasticEntity._dmp, type = FieldType.Object) + private NestedDmpElasticEntity dmp; + public final static String _dmp = "dmp"; + + @Field(value = DescriptionElasticEntity._references, type = FieldType.Nested) + private List references; + public final static String _references = "references"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public DescriptionStatus getStatus() { + return status; + } + + public void setStatus(DescriptionStatus status) { + this.status = status; + } + + public Date getFinalizedAt() { + return finalizedAt; + } + + public void setFinalizedAt(Date finalizedAt) { + this.finalizedAt = finalizedAt; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public NestedDescriptionTemplateElasticEntity getDescriptionTemplate() { + return descriptionTemplate; + } + + public void setDescriptionTemplate(NestedDescriptionTemplateElasticEntity descriptionTemplate) { + this.descriptionTemplate = descriptionTemplate; + } + + public NestedDmpElasticEntity getDmp() { + return dmp; + } + + public void setDmp(NestedDmpElasticEntity dmp) { + this.dmp = dmp; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DmpElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DmpElasticEntity.java new file mode 100644 index 000000000..05b0e66c8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/DmpElasticEntity.java @@ -0,0 +1,198 @@ +package eu.eudat.elastic.data; + +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.elastic.data.nested.*; +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@Document(indexName = "dmp") +public class DmpElasticEntity { + @Id + @Field(value = DmpElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = DmpElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + @Field(value = DmpElasticEntity._description, type = FieldType.Text) + private String description; + public final static String _description = "description"; + + @Field(value = DmpElasticEntity._version, type = FieldType.Keyword) + private Short version; + public final static String _version = "version"; + + @Field(value = DmpElasticEntity._status, type = FieldType.Short) + private DmpStatus status; + public final static String _status = "status"; + + @Field(value = DmpElasticEntity._accessType, type = FieldType.Short) + private DmpAccessType accessType; + public final static String _accessType = "accessType"; + + @Field(value = DmpElasticEntity._language, type = FieldType.Keyword) + private String language; + public final static String _language = "language"; + + @Field(value = DmpElasticEntity._blueprintId, type = FieldType.Keyword) + private UUID blueprintId; + public final static String _blueprintId = "blueprintId"; + + @Field(value = DmpElasticEntity._groupId, type = FieldType.Keyword) + private UUID groupId; + public final static String _groupId = "groupId"; + + @Field(value = DmpElasticEntity._finalizedAt, type = FieldType.Date) + private Date finalizedAt; + public final static String _finalizedAt = "finalizedAt"; + + @Field(value = DmpElasticEntity._references, type = FieldType.Nested) + private List references; + public final static String _references = "references"; + + @Field(value = DmpElasticEntity._collaborators, type = FieldType.Nested) + private List collaborators; + public final static String _collaborators = "collaborators"; + + @Field(value = DmpElasticEntity._descriptionTemplates, type = FieldType.Nested) + private List descriptionTemplates; + public final static String _descriptionTemplates = "descriptionTemplates"; + + @Field(value = DmpElasticEntity._descriptions, type = FieldType.Nested) + private List descriptions; + public final static String _descriptions = "descriptions"; + + @Field(value = DmpElasticEntity._dois, type = FieldType.Nested) + private List dois; + public final static String _dois = "dois"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Short getVersion() { + return version; + } + + public void setVersion(Short version) { + this.version = version; + } + + public DmpStatus getStatus() { + return status; + } + + public void setStatus(DmpStatus status) { + this.status = status; + } + + public DmpAccessType getAccessType() { + return accessType; + } + + public void setAccessType(DmpAccessType accessType) { + this.accessType = accessType; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public UUID getBlueprintId() { + return blueprintId; + } + + public void setBlueprintId(UUID blueprintId) { + this.blueprintId = blueprintId; + } + + public UUID getGroupId() { + return groupId; + } + + public void setGroupId(UUID groupId) { + this.groupId = groupId; + } + + public Date getFinalizedAt() { + return finalizedAt; + } + + public void setFinalizedAt(Date finalizedAt) { + this.finalizedAt = finalizedAt; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + + public List getCollaborators() { + return collaborators; + } + + public void setCollaborators(List collaborators) { + this.collaborators = collaborators; + } + + public List getDescriptionTemplates() { + return descriptionTemplates; + } + + public void setDescriptionTemplates(List descriptionTemplates) { + this.descriptionTemplates = descriptionTemplates; + } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getDois() { + return dois; + } + + public void setDois(List dois) { + this.dois = dois; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedCollaboratorElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedCollaboratorElasticEntity.java new file mode 100644 index 000000000..c8c6326c9 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedCollaboratorElasticEntity.java @@ -0,0 +1,49 @@ +package eu.eudat.elastic.data.nested; + +import eu.eudat.commons.enums.DmpUserRole; +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.UUID; + +public class NestedCollaboratorElasticEntity { + @Id + @Field(value = NestedCollaboratorElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = NestedCollaboratorElasticEntity._name, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String name; + public final static String _name = "name"; + + @Field(value = NestedCollaboratorElasticEntity._role, type = FieldType.Short) + private DmpUserRole role; + public final static String _role = "role"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public DmpUserRole getRole() { + return role; + } + + public void setRole(DmpUserRole role) { + this.role = role; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionElasticEntity.java new file mode 100644 index 000000000..a08d0e34c --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionElasticEntity.java @@ -0,0 +1,112 @@ +package eu.eudat.elastic.data.nested; + +import eu.eudat.commons.enums.DescriptionStatus; +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class NestedDescriptionElasticEntity { + + @Id + @Field(value = NestedDescriptionElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @Field(value = NestedDescriptionElasticEntity._dmpId, type = FieldType.Keyword) + private UUID dmpId; + public final static String _dmpId = "dmpId"; + + @MultiField(mainField = @Field(value = NestedDescriptionElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + @Field(value = NestedDescriptionElasticEntity._description, type = FieldType.Text) + private String description; + public final static String _description = "description"; + + @Field(value = NestedDescriptionElasticEntity._status, type = FieldType.Short) + private DescriptionStatus status; + public final static String _status = "status"; + + @Field(value = NestedDescriptionElasticEntity._finalizedAt, type = FieldType.Date) + private Date finalizedAt; + public final static String _finalizedAt = "finalizedAt"; + + @Field(value = NestedDescriptionElasticEntity._tags, type = FieldType.Nested) + private List tags; + public final static String _tags = "tags"; + + @Field(value = NestedDescriptionElasticEntity._references, type = FieldType.Nested) + private List references; + public final static String _references = "references"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getDmpId() { + return dmpId; + } + + public void setDmpId(UUID dmpId) { + this.dmpId = dmpId; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public DescriptionStatus getStatus() { + return status; + } + + public void setStatus(DescriptionStatus status) { + this.status = status; + } + + public Date getFinalizedAt() { + return finalizedAt; + } + + public void setFinalizedAt(Date finalizedAt) { + this.finalizedAt = finalizedAt; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionTemplateElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionTemplateElasticEntity.java new file mode 100644 index 000000000..fb0075081 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDescriptionTemplateElasticEntity.java @@ -0,0 +1,37 @@ +package eu.eudat.elastic.data.nested; + +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.UUID; + +public class NestedDescriptionTemplateElasticEntity { + + @Id + @Field(value = NestedDescriptionTemplateElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = NestedDescriptionTemplateElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDmpElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDmpElasticEntity.java new file mode 100644 index 000000000..86c9bb7db --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDmpElasticEntity.java @@ -0,0 +1,172 @@ +package eu.eudat.elastic.data.nested; + +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class NestedDmpElasticEntity { + @Id + @Field(value = NestedDmpElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = NestedDmpElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + @Field(value = NestedDmpElasticEntity._description, type = FieldType.Text) + private String description; + public final static String _description = "description"; + + @Field(value = NestedDmpElasticEntity._version, type = FieldType.Keyword) + private Short version; + public final static String _version = "version"; + + @Field(value = NestedDmpElasticEntity._status, type = FieldType.Short) + private DmpStatus status; + public final static String _status = "status"; + + @Field(value = NestedDmpElasticEntity._accessType, type = FieldType.Short) + private DmpAccessType accessType; + public final static String _accessType = "accessType"; + + @Field(value = NestedDmpElasticEntity._language, type = FieldType.Keyword) + private String language; + public final static String _language = "language"; + + @Field(value = NestedDmpElasticEntity._blueprintId, type = FieldType.Keyword) + private UUID blueprintId; + public final static String _blueprintId = "blueprintId"; + + @Field(value = NestedDmpElasticEntity._groupId, type = FieldType.Keyword) + private UUID groupId; + public final static String _groupId = "groupId"; + + @Field(value = NestedDmpElasticEntity._finalizedAt, type = FieldType.Date) + private Date finalizedAt; + public final static String _finalizedAt = "finalizedAt"; + + @Field(value = NestedDmpElasticEntity._references, type = FieldType.Nested) + private List references; + public final static String _references = "references"; + + @Field(value = NestedDmpElasticEntity._collaborators, type = FieldType.Nested) + private List collaborators; + public final static String _collaborators = "collaborators"; + + @Field(value = NestedDmpElasticEntity._dois, type = FieldType.Nested) + private List dois; + public final static String _dois = "dois"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Short getVersion() { + return version; + } + + public void setVersion(Short version) { + this.version = version; + } + + public DmpStatus getStatus() { + return status; + } + + public void setStatus(DmpStatus status) { + this.status = status; + } + + public DmpAccessType getAccessType() { + return accessType; + } + + public void setAccessType(DmpAccessType accessType) { + this.accessType = accessType; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public UUID getBlueprintId() { + return blueprintId; + } + + public void setBlueprintId(UUID blueprintId) { + this.blueprintId = blueprintId; + } + + public UUID getGroupId() { + return groupId; + } + + public void setGroupId(UUID groupId) { + this.groupId = groupId; + } + + public Date getFinalizedAt() { + return finalizedAt; + } + + public void setFinalizedAt(Date finalizedAt) { + this.finalizedAt = finalizedAt; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + + public List getCollaborators() { + return collaborators; + } + + public void setCollaborators(List collaborators) { + this.collaborators = collaborators; + } + + public List getDois() { + return dois; + } + + public void setDois(List dois) { + this.dois = dois; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDoiElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDoiElasticEntity.java new file mode 100644 index 000000000..73f258d6a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedDoiElasticEntity.java @@ -0,0 +1,46 @@ +package eu.eudat.elastic.data.nested; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.UUID; + +public class NestedDoiElasticEntity { + + @Id + @Field(value = NestedDoiElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @Field(value = NestedDoiElasticEntity._repositoryId, type = FieldType.Keyword) + private String repositoryId; + public final static String _repositoryId = "repositoryId"; + + @Field(value = NestedDoiElasticEntity._doi, type = FieldType.Keyword) + private String doi; + public final static String _doi = "doi"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getRepositoryId() { + return repositoryId; + } + + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDoi() { + return doi; + } + + public void setDoi(String doi) { + this.doi = doi; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedReferenceElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedReferenceElasticEntity.java new file mode 100644 index 000000000..afe582927 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedReferenceElasticEntity.java @@ -0,0 +1,36 @@ +package eu.eudat.elastic.data.nested; + +import gr.cite.tools.elastic.ElasticConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; + +import java.util.UUID; + +public class NestedReferenceElasticEntity { + @Id + @Field(value = NestedReferenceElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = NestedReferenceElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedTagElasticEntity.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedTagElasticEntity.java new file mode 100644 index 000000000..707b45005 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/data/nested/NestedTagElasticEntity.java @@ -0,0 +1,36 @@ +package eu.eudat.elastic.data.nested; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.*; +import gr.cite.tools.elastic.ElasticConstants; + +import java.util.UUID; + +public class NestedTagElasticEntity { + @Id + @Field(value = NestedTagElasticEntity._id, type = FieldType.Keyword) + private UUID id; + public final static String _id = "id"; + + @MultiField(mainField = @Field(value = NestedTagElasticEntity._label, type = FieldType.Text), otherFields = { + @InnerField(suffix = ElasticConstants.SubFields.keyword, type = FieldType.Keyword) + }) + private String label; + public final static String _label = "label"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/BaseElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/BaseElasticBuilder.java new file mode 100644 index 000000000..d06896183 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/BaseElasticBuilder.java @@ -0,0 +1,93 @@ +package eu.eudat.elastic.elasticbuilder; + +import eu.eudat.convention.ConventionService; +import gr.cite.tools.data.builder.Builder; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; + +import java.time.Instant; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +public abstract class BaseElasticBuilder implements Builder { + protected final LoggerService logger; + protected final ConventionService conventionService; + + public BaseElasticBuilder( + ConventionService conventionService, + LoggerService logger + ) { + this.conventionService = conventionService; + this.logger = logger; + } + + public M build(D data) throws MyApplicationException { + if (data == null) { + M model = null; + return null; //TODO + } + List models = this.build(Arrays.asList(data)); + return models.stream().findFirst().orElse(null); //TODO + } + + public abstract List build(List datas) throws MyApplicationException; + + public Map asForeignKey(QueryBase query, Function keySelector) throws MyApplicationException { + this.logger.trace("Building references from query"); + List datas = query.collect(); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + return this.asForeignKey(datas, keySelector); + } + + public Map asForeignKey(List datas, Function keySelector) throws MyApplicationException { + this.logger.trace("building references"); + List models = this.build(datas); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(e -> e.size()).orElse(0), Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + Map map = models.stream().collect(Collectors.toMap(o -> keySelector.apply(o), o -> o)); + return map; + } + + public Map> asMasterKey(QueryBase query, Function keySelector) throws MyApplicationException { + this.logger.trace("Building details from query"); + List datas = query.collect(); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + return this.asMasterKey(datas, keySelector); + } + + public Map> asMasterKey(List datas, Function keySelector) throws MyApplicationException { + this.logger.trace("building details"); + List models = this.build(datas); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(e -> e.size()).orElse(0), Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + Map> map = new HashMap<>(); + for (M model : models) { + K key = keySelector.apply(model); + if (!map.containsKey(key)) map.put(key, new ArrayList()); + map.get(key).add(model); + } + return map; + } + + public Map asEmpty(List keys, Function mapper, Function keySelector) { + this.logger.trace("building static references"); + List models = keys.stream().map(x -> mapper.apply(x)).collect(Collectors.toList()); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(x -> x.size()).orElse(0), Optional.ofNullable(keys).map(x -> x.size())); + Map map = models.stream().collect(Collectors.toMap(o -> keySelector.apply(o), o -> o)); + return map; + } + + protected String hashValue(Instant value) throws MyApplicationException { + return this.conventionService.hashValue(value); + } + + protected String asPrefix(String name) { + return this.conventionService.asPrefix(name); + } + + protected String asIndexer(String... names) { + return this.conventionService.asIndexer(names); + } + +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DescriptionElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DescriptionElasticBuilder.java new file mode 100644 index 000000000..327549108 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DescriptionElasticBuilder.java @@ -0,0 +1,148 @@ +package eu.eudat.elastic.elasticbuilder; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DescriptionReferenceEntity; +import eu.eudat.data.DescriptionTagEntity; +import eu.eudat.data.DmpDescriptionTemplateEntity; +import eu.eudat.elastic.data.DescriptionElasticEntity; +import eu.eudat.elastic.data.nested.*; +import eu.eudat.elastic.elasticbuilder.nested.NestedDescriptionTemplateElasticBuilder; +import eu.eudat.elastic.elasticbuilder.nested.NestedDmpElasticBuilder; +import eu.eudat.elastic.elasticbuilder.nested.NestedReferenceElasticBuilder; +import eu.eudat.elastic.elasticbuilder.nested.NestedTagElasticBuilder; +import eu.eudat.model.*; +import eu.eudat.model.builder.DescriptionBuilder; +import eu.eudat.model.builder.ReferenceBuilder; +import eu.eudat.query.*; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DescriptionElasticBuilder extends BaseElasticBuilder { + + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + + @Autowired + public DescriptionElasticBuilder( + ConventionService conventionService, QueryFactory queryFactory, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DescriptionElasticBuilder.class))); + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + Map> referenceElasticEntityMap = this.collectDescriptionReferences(data); + Map> tagElasticEntityMap = this.collectDescriptionTags(data); + Map dmpElasticEntityMap = this.collectDmps(data); + Map descriptionTemplateElasticEntityMap = this.collectDescriptionTemplates(data); + + List models = new ArrayList<>(); + for (DescriptionEntity d : data) { + DescriptionElasticEntity m = new DescriptionElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + m.setDescription(d.getDescription()); + m.setStatus(d.getStatus()); + m.setFinalizedAt(Date.from(d.getFinalizedAt())); + if (referenceElasticEntityMap != null) m.setReferences(referenceElasticEntityMap.getOrDefault(d.getId(), null)); + if (tagElasticEntityMap != null) m.setTags(tagElasticEntityMap.getOrDefault(d.getId(), null)); + if (dmpElasticEntityMap != null) m.setDmp(dmpElasticEntityMap.getOrDefault(d.getDmpId(), null)); + if (descriptionTemplateElasticEntityMap != null) m.setDescriptionTemplate(descriptionTemplateElasticEntityMap.getOrDefault(d.getDmpId(), null)); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + private Map> collectDescriptionReferences(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DescriptionReference.class.getSimpleName()); + + DescriptionReferenceQuery associationQuery = this.queryFactory.query(DescriptionReferenceQuery.class).descriptionIds(data.stream().map(DescriptionEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + ReferenceQuery query = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DescriptionReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedReferenceElasticBuilder.class).asForeignKey(query, NestedReferenceElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DescriptionReferenceEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDescriptionId())) itemMap.put(associationEntity.getDescriptionId(), new ArrayList<>()); + NestedReferenceElasticEntity item = itemMapById.getOrDefault(associationEntity.getReferenceId(), null); + if (item != null) itemMap.get(associationEntity.getDescriptionId()).add(item); + } + + return itemMap; + } + + private Map> collectDescriptionTags(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DescriptionTag.class.getSimpleName()); + + DescriptionTagQuery associationQuery = this.queryFactory.query(DescriptionTagQuery.class).descriptionIds(data.stream().map(DescriptionEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + TagQuery query = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DescriptionTagEntity::getTagId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedTagElasticBuilder.class).asForeignKey(query, NestedTagElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DescriptionTagEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDescriptionId())) itemMap.put(associationEntity.getDescriptionId(), new ArrayList<>()); + NestedTagElasticEntity item = itemMapById.getOrDefault(associationEntity.getTagId(), null); + if (item != null) itemMap.get(associationEntity.getDescriptionId()).add(item); + } + + return itemMap; + } + + private Map collectDmps(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", Dmp.class.getSimpleName()); + + Map itemMap; + DmpQuery q = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).ids(data.stream().map(DescriptionEntity::getDmpId).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(NestedDmpElasticBuilder.class).asForeignKey(q, NestedDmpElasticEntity::getId); + + return itemMap; + } + + + + private Map collectDescriptionTemplates(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", DescriptionTemplate.class.getSimpleName()); + + DmpDescriptionTemplateQuery associationQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(data.stream().map(DescriptionEntity::getDmpDescriptionTemplateId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + DescriptionTemplateQuery query = this.queryFactory.query(DescriptionTemplateQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DmpDescriptionTemplateEntity::getDescriptionTemplateId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedDescriptionTemplateElasticBuilder.class).asForeignKey(query, NestedDescriptionTemplateElasticEntity::getId); + + Map itemMap = new HashMap<>(); + for (DmpDescriptionTemplateEntity associationEntity : associationEntities){ + itemMap.put(associationEntity.getId(), itemMapById.getOrDefault(associationEntity.getDescriptionTemplateId(), null)); + } + return itemMap; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java new file mode 100644 index 000000000..af1356648 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java @@ -0,0 +1,163 @@ +package eu.eudat.elastic.elasticbuilder; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.*; +import eu.eudat.elastic.data.DmpElasticEntity; +import eu.eudat.elastic.data.nested.*; +import eu.eudat.elastic.elasticbuilder.nested.*; +import eu.eudat.model.DmpReference; +import eu.eudat.query.*; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpElasticBuilder extends BaseElasticBuilder { + + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + + @Autowired + public DmpElasticBuilder( + ConventionService conventionService, QueryFactory queryFactory, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpElasticBuilder.class))); + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + Map> referenceElasticEntityMap = this.collectDmpReferences(data); + Map> dmpElasticEntityMap = this.collectDescriptions(data); + Map> collaboratorElasticEntityMap = this.collectCollaborators(data); + Map> doiElasticEntityMap = this.collectDois(data); + Map> descriptionTemplateElasticEntityMap = this.collectDescriptionTemplates(data); + + List models = new ArrayList<>(); + for (DmpEntity d : data) { + DmpElasticEntity m = new DmpElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + m.setDescription(d.getDescription()); + m.setVersion(d.getVersion()); + m.setStatus(d.getStatus()); + m.setAccessType(d.getAccessType()); + m.setLanguage(d.getLanguage()); + m.setBlueprintId(d.getBlueprint()); + m.setGroupId(d.getGroupId()); + m.setFinalizedAt(Date.from(d.getFinalizedAt())); + if (referenceElasticEntityMap != null) m.setReferences(referenceElasticEntityMap.getOrDefault(d.getId(), null)); + if (dmpElasticEntityMap != null) m.setDescriptions(dmpElasticEntityMap.getOrDefault(d.getId(), null)); + if (collaboratorElasticEntityMap != null) m.setCollaborators(collaboratorElasticEntityMap.getOrDefault(d.getId(), null)); + if (doiElasticEntityMap != null) m.setDois(doiElasticEntityMap.getOrDefault(d.getId(), null)); + if (descriptionTemplateElasticEntityMap != null) m.setDescriptionTemplates(descriptionTemplateElasticEntityMap.getOrDefault(d.getId(), null)); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + private Map> collectDmpReferences(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DmpReference.class.getSimpleName()); + + DmpReferenceQuery associationQuery = this.queryFactory.query(DmpReferenceQuery.class).dmpIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActives(IsActive.Active); + List associationEntities = associationQuery.collect(); + + ReferenceQuery query = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DmpReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedReferenceElasticBuilder.class).asForeignKey(query, NestedReferenceElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DmpReferenceEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDmpId())) itemMap.put(associationEntity.getDmpId(), new ArrayList<>()); + NestedReferenceElasticEntity item = itemMapById.getOrDefault(associationEntity.getReferenceId(), null); + if (item != null) itemMap.get(associationEntity.getDmpId()).add(item); + } + + return itemMap; + } + + private Map> collectDescriptionTemplates(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DmpReference.class.getSimpleName()); + + DmpDescriptionTemplateQuery associationQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class).dmpIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + DescriptionTemplateQuery query = this.queryFactory.query(DescriptionTemplateQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DmpDescriptionTemplateEntity::getDescriptionTemplateId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedDescriptionTemplateElasticBuilder.class).asForeignKey(query, NestedDescriptionTemplateElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DmpDescriptionTemplateEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDmpId())) itemMap.put(associationEntity.getDmpId(), new ArrayList<>()); + NestedDescriptionTemplateElasticEntity item = itemMapById.getOrDefault(associationEntity.getDescriptionTemplateId(), null); + if (item != null) itemMap.get(associationEntity.getDmpId()).add(item); + } + + return itemMap; + } + + private Map> collectDescriptions(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", DescriptionEntity.class.getSimpleName()); + + Map> itemMap; + DescriptionQuery q = this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(this.queryFactory.query(DmpQuery.class).ids(data.stream().map(DmpEntity::getId).distinct().collect(Collectors.toList()))); + itemMap = this.builderFactory.builder(NestedDescriptionElasticBuilder.class).asMasterKey(q, NestedDescriptionElasticEntity::getDmpId); + + return itemMap; + } + + private Map> collectCollaborators(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", DmpUserEntity.class.getSimpleName()); + + DmpUserQuery associationQuery = this.queryFactory.query(DmpUserQuery.class).dmpIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActives(IsActive.Active); + List associationEntities = associationQuery.collect(); + + Map itemMapById = this.builderFactory.builder(NestedCollaboratorElasticBuilder.class).asForeignKey(associationEntities, NestedCollaboratorElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DmpUserEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmp(), new ArrayList<>()); + NestedCollaboratorElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); + if (item != null) itemMap.get(associationEntity.getDmp()).add(item); + } + return itemMap; + } + + private Map> collectDois(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", EntityDoiEntity.class.getSimpleName()); + + EntityDoiQuery associationQuery = this.queryFactory.query(EntityDoiQuery.class).entityIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + Map itemMapById = this.builderFactory.builder(NestedDoiElasticBuilder.class).asForeignKey(associationEntities, NestedDoiElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (EntityDoiEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getEntityId(), new ArrayList<>()); + NestedDoiElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); + if (item != null) itemMap.get(associationEntity.getEntityId()).add(item); + } + return itemMap; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedCollaboratorElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedCollaboratorElasticBuilder.java new file mode 100644 index 000000000..63ac8c863 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedCollaboratorElasticBuilder.java @@ -0,0 +1,45 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.elastic.data.nested.NestedCollaboratorElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedCollaboratorElasticBuilder extends BaseElasticBuilder { + + @Autowired + public NestedCollaboratorElasticBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedCollaboratorElasticBuilder.class))); + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (DmpUserEntity d : data) { + NestedCollaboratorElasticEntity m = new NestedCollaboratorElasticEntity(); + m.setId(d.getId()); + m.setRole(d.getRole()); + m.setName(d.getUser().toString()); //TODO: Get UserName + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionElasticBuilder.java new file mode 100644 index 000000000..ac9e4d4d1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionElasticBuilder.java @@ -0,0 +1,110 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DescriptionReferenceEntity; +import eu.eudat.data.DescriptionTagEntity; +import eu.eudat.elastic.data.nested.NestedDescriptionElasticEntity; +import eu.eudat.elastic.data.nested.NestedReferenceElasticEntity; +import eu.eudat.elastic.data.nested.NestedTagElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import eu.eudat.model.DescriptionReference; +import eu.eudat.model.DescriptionTag; +import eu.eudat.query.DescriptionReferenceQuery; +import eu.eudat.query.DescriptionTagQuery; +import eu.eudat.query.ReferenceQuery; +import eu.eudat.query.TagQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDescriptionElasticBuilder extends BaseElasticBuilder { + + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + + @Autowired + public NestedDescriptionElasticBuilder( + ConventionService conventionService, QueryFactory queryFactory, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedDescriptionElasticBuilder.class))); + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + Map> referenceElasticEntityMap = this.collectDescriptionReferences(data); + Map> tagElasticEntityMap = this.collectDescriptionTags(data); + + List models = new ArrayList<>(); + for (DescriptionEntity d : data) { + NestedDescriptionElasticEntity m = new NestedDescriptionElasticEntity(); + m.setId(d.getId()); + m.setDmpId(d.getDmpId()); + m.setLabel(d.getLabel()); + m.setDescription(d.getDescription()); + m.setStatus(d.getStatus()); + m.setFinalizedAt(Date.from(d.getFinalizedAt())); + if (referenceElasticEntityMap != null) m.setReferences(referenceElasticEntityMap.getOrDefault(d.getId(), null)); + if (tagElasticEntityMap != null) m.setTags(tagElasticEntityMap.getOrDefault(d.getId(), null)); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + private Map> collectDescriptionReferences(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DescriptionReference.class.getSimpleName()); + + DescriptionReferenceQuery associationQuery = this.queryFactory.query(DescriptionReferenceQuery.class).descriptionIds(data.stream().map(DescriptionEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + ReferenceQuery query = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DescriptionReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedReferenceElasticBuilder.class).asForeignKey(query, NestedReferenceElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DescriptionReferenceEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDescriptionId())) itemMap.put(associationEntity.getDescriptionId(), new ArrayList<>()); + NestedReferenceElasticEntity item = itemMapById.getOrDefault(associationEntity.getReferenceId(), null); + if (item != null) itemMap.get(associationEntity.getDescriptionId()).add(item); + } + + return itemMap; + } + + private Map> collectDescriptionTags(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DescriptionTag.class.getSimpleName()); + + DescriptionTagQuery associationQuery = this.queryFactory.query(DescriptionTagQuery.class).descriptionIds(data.stream().map(DescriptionEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + TagQuery query = this.queryFactory.query(TagQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DescriptionTagEntity::getTagId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedTagElasticBuilder.class).asForeignKey(query, NestedTagElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DescriptionTagEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDescriptionId())) itemMap.put(associationEntity.getDescriptionId(), new ArrayList<>()); + NestedTagElasticEntity item = itemMapById.getOrDefault(associationEntity.getTagId(), null); + if (item != null) itemMap.get(associationEntity.getDescriptionId()).add(item); + } + + return itemMap; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionTemplateElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionTemplateElasticBuilder.java new file mode 100644 index 000000000..7d862463a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDescriptionTemplateElasticBuilder.java @@ -0,0 +1,44 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionTemplateEntity; +import eu.eudat.elastic.data.nested.NestedDescriptionTemplateElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDescriptionTemplateElasticBuilder extends BaseElasticBuilder { + + @Autowired + public NestedDescriptionTemplateElasticBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedDescriptionTemplateElasticBuilder.class))); + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (DescriptionTemplateEntity d : data) { + NestedDescriptionTemplateElasticEntity m = new NestedDescriptionTemplateElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java new file mode 100644 index 000000000..91a7d8f6d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java @@ -0,0 +1,134 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DmpEntity; +import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.data.EntityDoiEntity; +import eu.eudat.elastic.data.nested.*; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import eu.eudat.model.DmpReference; +import eu.eudat.query.DmpReferenceQuery; +import eu.eudat.query.DmpUserQuery; +import eu.eudat.query.EntityDoiQuery; +import eu.eudat.query.ReferenceQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDmpElasticBuilder extends BaseElasticBuilder { + + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + + @Autowired + public NestedDmpElasticBuilder( + ConventionService conventionService, QueryFactory queryFactory, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedDmpElasticBuilder.class))); + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + Map> referenceElasticEntityMap = this.collectDmpReferences(data); + Map> collaboratorElasticEntityMap = this.collectCollaborators(data); + Map> doiElasticEntityMap = this.collectDois(data); + + List models = new ArrayList<>(); + for (DmpEntity d : data) { + NestedDmpElasticEntity m = new NestedDmpElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + m.setDescription(d.getDescription()); + m.setVersion(d.getVersion()); + m.setStatus(d.getStatus()); + m.setAccessType(d.getAccessType()); + m.setLanguage(d.getLanguage()); + m.setBlueprintId(d.getBlueprint()); + m.setGroupId(d.getGroupId()); + m.setGroupId(d.getGroupId()); + m.setFinalizedAt(Date.from(d.getFinalizedAt())); + if (referenceElasticEntityMap != null) m.setReferences(referenceElasticEntityMap.getOrDefault(d.getId(), null)); + if (collaboratorElasticEntityMap != null) m.setCollaborators(collaboratorElasticEntityMap.getOrDefault(d.getId(), null)); + if (doiElasticEntityMap != null) m.setDois(doiElasticEntityMap.getOrDefault(d.getId(), null)); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + private Map> collectDmpReferences(List data) throws MyApplicationException { + if (data.isEmpty()) return null; + this.logger.debug("checking related - {}", DmpReference.class.getSimpleName()); + + DmpReferenceQuery associationQuery = this.queryFactory.query(DmpReferenceQuery.class).dmpIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActives(IsActive.Active); + List associationEntities = associationQuery.collect(); + + ReferenceQuery query = this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).ids(associationEntities.stream().map(DmpReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); + Map itemMapById = this.builderFactory.builder(NestedReferenceElasticBuilder.class).asForeignKey(query, NestedReferenceElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DmpReferenceEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getDmpId())) itemMap.put(associationEntity.getDmpId(), new ArrayList<>()); + NestedReferenceElasticEntity item = itemMapById.getOrDefault(associationEntity.getReferenceId(), null); + if (item != null) itemMap.get(associationEntity.getDmpId()).add(item); + } + + return itemMap; + } + + private Map> collectCollaborators(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", DmpUserEntity.class.getSimpleName()); + + DmpUserQuery associationQuery = this.queryFactory.query(DmpUserQuery.class).dmpIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActives(IsActive.Active); + List associationEntities = associationQuery.collect(); + + Map itemMapById = this.builderFactory.builder(NestedCollaboratorElasticBuilder.class).asForeignKey(associationEntities, NestedCollaboratorElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (DmpUserEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmp(), new ArrayList<>()); + NestedCollaboratorElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); + if (item != null) itemMap.get(associationEntity.getDmp()).add(item); + } + return itemMap; + } + + private Map> collectDois(List data) throws MyApplicationException { + if (data.isEmpty()) + return null; + this.logger.debug("checking related - {}", EntityDoiEntity.class.getSimpleName()); + + EntityDoiQuery associationQuery = this.queryFactory.query(EntityDoiQuery.class).entityIds(data.stream().map(DmpEntity::getId).collect(Collectors.toList())).isActive(IsActive.Active); + List associationEntities = associationQuery.collect(); + + Map itemMapById = this.builderFactory.builder(NestedDoiElasticBuilder.class).asForeignKey(associationEntities, NestedDoiElasticEntity::getId); + + Map> itemMap = new HashMap<>(); + for (EntityDoiEntity associationEntity : associationEntities){ + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getEntityId(), new ArrayList<>()); + NestedDoiElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); + if (item != null) itemMap.get(associationEntity.getEntityId()).add(item); + } + return itemMap; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDoiElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDoiElasticBuilder.java new file mode 100644 index 000000000..788d8bf97 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDoiElasticBuilder.java @@ -0,0 +1,45 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.convention.ConventionService; +import eu.eudat.data.EntityDoiEntity; +import eu.eudat.elastic.data.nested.NestedDoiElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDoiElasticBuilder extends BaseElasticBuilder { + + @Autowired + public NestedDoiElasticBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedDoiElasticBuilder.class))); + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (EntityDoiEntity d : data) { + NestedDoiElasticEntity m = new NestedDoiElasticEntity(); + m.setId(d.getId()); + m.setDoi(d.getDoi()); + m.setRepositoryId(d.getRepositoryId()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedReferenceElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedReferenceElasticBuilder.java new file mode 100644 index 000000000..4a018aeb4 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedReferenceElasticBuilder.java @@ -0,0 +1,42 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.convention.ConventionService; +import eu.eudat.data.ReferenceEntity; +import eu.eudat.elastic.data.nested.NestedReferenceElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedReferenceElasticBuilder extends BaseElasticBuilder { + + @Autowired + public NestedReferenceElasticBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedReferenceElasticBuilder.class))); + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (ReferenceEntity d : data) { + NestedReferenceElasticEntity m = new NestedReferenceElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedTagElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedTagElasticBuilder.java new file mode 100644 index 000000000..9dd4d614a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedTagElasticBuilder.java @@ -0,0 +1,44 @@ +package eu.eudat.elastic.elasticbuilder.nested; + +import eu.eudat.convention.ConventionService; +import eu.eudat.data.TagEntity; +import eu.eudat.elastic.data.nested.NestedTagElasticEntity; +import eu.eudat.elastic.elasticbuilder.BaseElasticBuilder; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedTagElasticBuilder extends BaseElasticBuilder { + + @Autowired + public NestedTagElasticBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(NestedTagElasticBuilder.class))); + } + + @Override + public List build(List data) throws MyApplicationException { + if (data == null) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (TagEntity d : data) { + NestedTagElasticEntity m = new NestedTagElasticEntity(); + m.setId(d.getId()); + m.setLabel(d.getLabel()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java new file mode 100644 index 000000000..b65bc99d5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java @@ -0,0 +1,164 @@ +package eu.eudat.elastic.query; +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DescriptionStatus; +import eu.eudat.configurations.elastic.AppElasticProperties; +import eu.eudat.elastic.data.DescriptionElasticEntity; +import eu.eudat.service.elastic.ElasticService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import gr.cite.tools.elastic.query.ElasticQuery; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +@Component +//Like in C# make it Transient +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class DescriptionElasticQuery extends ElasticQuery { + + private Collection ids; + private Collection statuses; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + public DescriptionElasticQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public DescriptionElasticQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public DescriptionElasticQuery ids(Collection values) { + this.ids = values; + return this; + } + + public DescriptionElasticQuery statuses(DescriptionStatus value) { + this.statuses = List.of(value); + return this; + } + + public DescriptionElasticQuery statuses(DescriptionStatus... value) { + this.statuses = Arrays.asList(value); + return this; + } + + public DescriptionElasticQuery statuses(Collection values) { + this.statuses = values; + return this; + } + + public DescriptionElasticQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final QueryFactory queryFactory; + private final AppElasticProperties appElasticProperties; + private final ElasticService elasticService; + @Autowired() + public DescriptionElasticQuery(ElasticsearchTemplate elasticsearchTemplate, ElasticProperties elasticProperties, QueryFactory queryFactory, AppElasticProperties appElasticProperties, ElasticService elasticService) { + super(elasticsearchTemplate, elasticProperties); + this.queryFactory = queryFactory; + this.appElasticProperties = appElasticProperties; + this.elasticService = elasticService; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.statuses); + } + + @Override + protected Class entityClass() { + return DescriptionElasticEntity.class; + } + + @Override + protected Query applyFilters() { + List predicates = new ArrayList<>(); + if (ids != null) { + predicates.add(this.containsUUID(this.elasticFieldOf(DescriptionElasticEntity._id), ids)._toQuery()); + } + if (statuses != null) { + predicates.add(this.contains(this.elasticFieldOf(DescriptionElasticEntity._status), statuses.stream().map(x-> x.getValue()).collect(Collectors.toList()).toArray(new Short[statuses.size()]))._toQuery()); + } + + if (!predicates.isEmpty()) { + return this.and(predicates); + } else { + return null; + } + } + + @Override + public DescriptionElasticEntity convert(Map rawData, Set columns) { + DescriptionElasticEntity mocDoc = new DescriptionElasticEntity(); + if (columns.contains(DescriptionElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(DescriptionElasticEntity._id), UUID.class)); + if (columns.contains(DescriptionElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(DescriptionElasticEntity._label), String.class)); + if (columns.contains(DescriptionElasticEntity._description)) mocDoc.setDescription(FieldBasedMapper.shallowSafeConversion(rawData.get(DescriptionElasticEntity._description), String.class)); + if (columns.contains(DescriptionElasticEntity._status)) mocDoc.setStatus(FieldBasedMapper.shallowSafeConversion(rawData.get(DescriptionElasticEntity._status), DescriptionStatus.class)); + if (columns.contains(DescriptionElasticEntity._finalizedAt)) mocDoc.setFinalizedAt(FieldBasedMapper.shallowSafeConversion(rawData.get(DescriptionElasticEntity._finalizedAt), Date.class)); + mocDoc.setTags(this.convertNested(rawData, columns, this.queryFactory.query(NestedTagElasticQuery.class), DescriptionElasticEntity._tags, null)); + mocDoc.setReferences(this.convertNested(rawData, columns, this.queryFactory.query(NestedReferenceElasticQuery.class), DescriptionElasticEntity._references, null)); + mocDoc.setDescriptionTemplate(this.convertInnerObject(rawData, columns, this.queryFactory.query(InnerObjectDescriptionTemplateElasticQuery.class), DescriptionElasticEntity._descriptionTemplate, null)); + mocDoc.setDmp(this.convertInnerObject(rawData, columns, this.queryFactory.query(InnerObjectDmpElasticQuery.class), DescriptionElasticEntity._dmp, null)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(DescriptionElasticEntity._id)) return this.elasticFieldOf(DescriptionElasticEntity._id); + else if (item.match(DescriptionElasticEntity._label)) return this.elasticFieldOf(DescriptionElasticEntity._label); + else if (item.match(DescriptionElasticEntity._description)) return this.elasticFieldOf(DescriptionElasticEntity._description); + else if (item.match(DescriptionElasticEntity._status)) return this.elasticFieldOf(DescriptionElasticEntity._status); + else if (item.match(DescriptionElasticEntity._finalizedAt)) return this.elasticFieldOf(DescriptionElasticEntity._finalizedAt); + else if (item.prefix(DescriptionElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(DescriptionElasticEntity._references).fieldNameOf(this.extractPrefixed(item, DescriptionElasticEntity._references)); + else if (item.prefix(DescriptionElasticEntity._tags)) return this.queryFactory.query(NestedTagElasticQuery.class).nestedPath(DescriptionElasticEntity._tags).fieldNameOf(this.extractPrefixed(item, DescriptionElasticEntity._tags)); + else if (item.prefix(DescriptionElasticEntity._descriptionTemplate)) return this.queryFactory.query(InnerObjectDescriptionTemplateElasticQuery.class).innerPath(DescriptionElasticEntity._descriptionTemplate).fieldNameOf(this.extractPrefixed(item, DescriptionElasticEntity._description)); + else if (item.prefix(DescriptionElasticEntity._dmp)) return this.queryFactory.query(InnerObjectDmpElasticQuery.class).innerPath(DescriptionElasticEntity._dmp).fieldNameOf(this.extractPrefixed(item, DescriptionElasticEntity._dmp)); + else return null; + } + + @Override + protected String[] getIndex() { + List indexNames = new ArrayList<>(); + indexNames.add(this.appElasticProperties.getDescriptionIndexName()); + try { + this.elasticService.ensureDescriptionIndex(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return indexNames.toArray(new String[indexNames.size()]); + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(DescriptionElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + if (item.prefix(DescriptionElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(DescriptionElasticEntity._references); + else if (item.prefix(DescriptionElasticEntity._tags)) return this.queryFactory.query(NestedTagElasticQuery.class).nestedPath(DescriptionElasticEntity._tags); + else return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DmpElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DmpElasticQuery.java new file mode 100644 index 000000000..f57fbddc4 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DmpElasticQuery.java @@ -0,0 +1,171 @@ +package eu.eudat.elastic.query; +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.configurations.elastic.AppElasticProperties; +import eu.eudat.elastic.data.DmpElasticEntity; +import eu.eudat.service.elastic.ElasticService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import gr.cite.tools.elastic.query.ElasticQuery; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +@Component +//Like in C# make it Transient +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class DmpElasticQuery extends ElasticQuery { + + private Collection ids; + private Collection statuses; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + public DmpElasticQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public DmpElasticQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public DmpElasticQuery ids(Collection values) { + this.ids = values; + return this; + } + + public DmpElasticQuery statuses(DmpStatus value) { + this.statuses = List.of(value); + return this; + } + + public DmpElasticQuery statuses(DmpStatus... value) { + this.statuses = Arrays.asList(value); + return this; + } + + public DmpElasticQuery statuses(Collection values) { + this.statuses = values; + return this; + } + + public DmpElasticQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final QueryFactory queryFactory; + private final AppElasticProperties appElasticProperties; + private final ElasticService elasticService; + @Autowired() + public DmpElasticQuery(ElasticsearchTemplate elasticsearchTemplate, ElasticProperties elasticProperties, QueryFactory queryFactory, AppElasticProperties appElasticProperties, ElasticService elasticService) { + super(elasticsearchTemplate, elasticProperties); + this.queryFactory = queryFactory; + this.appElasticProperties = appElasticProperties; + this.elasticService = elasticService; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.statuses); + } + + @Override + protected Class entityClass() { + return DmpElasticEntity.class; + } + + @Override + protected Query applyFilters() { + List predicates = new ArrayList<>(); + if (ids != null) { + predicates.add(this.containsUUID(this.elasticFieldOf(DmpElasticEntity._id), ids)._toQuery()); + } + if (statuses != null) { + predicates.add(this.contains(this.elasticFieldOf(DmpElasticEntity._status), statuses.stream().map(x-> x.getValue()).collect(Collectors.toList()).toArray(new Short[statuses.size()]))._toQuery()); + } + + if (!predicates.isEmpty()) { + return this.and(predicates); + } else { + return null; + } + } + + @Override + public DmpElasticEntity convert(Map rawData, Set columns) { + DmpElasticEntity mocDoc = new DmpElasticEntity(); + if (columns.contains(DmpElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._id), UUID.class)); + if (columns.contains(DmpElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._label), String.class)); + if (columns.contains(DmpElasticEntity._description)) mocDoc.setDescription(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._description), String.class)); + if (columns.contains(DmpElasticEntity._status)) mocDoc.setStatus(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._status), DmpStatus.class)); + if (columns.contains(DmpElasticEntity._groupId)) mocDoc.setGroupId(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._groupId), UUID.class)); + if (columns.contains(DmpElasticEntity._accessType)) mocDoc.setAccessType(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._accessType), DmpAccessType.class)); + if (columns.contains(DmpElasticEntity._finalizedAt)) mocDoc.setFinalizedAt(FieldBasedMapper.shallowSafeConversion(rawData.get(DmpElasticEntity._finalizedAt), Date.class)); + mocDoc.setCollaborators(this.convertNested(rawData, columns, this.queryFactory.query(NestedCollaboratorElasticQuery.class), DmpElasticEntity._collaborators, null)); + mocDoc.setReferences(this.convertNested(rawData, columns, this.queryFactory.query(NestedReferenceElasticQuery.class), DmpElasticEntity._references, null)); + mocDoc.setDescriptionTemplates(this.convertNested(rawData, columns, this.queryFactory.query(NestedDescriptionTemplateElasticQuery.class), DmpElasticEntity._descriptionTemplates, null)); + mocDoc.setDescriptions(this.convertNested(rawData, columns, this.queryFactory.query(NestedDescriptionElasticQuery.class), DmpElasticEntity._descriptions, null)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(DmpElasticEntity._id)) return this.elasticFieldOf(DmpElasticEntity._id); + else if (item.match(DmpElasticEntity._label)) return this.elasticFieldOf(DmpElasticEntity._label); + else if (item.match(DmpElasticEntity._description)) return this.elasticFieldOf(DmpElasticEntity._description); + else if (item.match(DmpElasticEntity._status)) return this.elasticFieldOf(DmpElasticEntity._status); + else if (item.match(DmpElasticEntity._groupId)) return this.elasticFieldOf(DmpElasticEntity._groupId); + else if (item.match(DmpElasticEntity._finalizedAt)) return this.elasticFieldOf(DmpElasticEntity._finalizedAt); + else if (item.match(DmpElasticEntity._accessType)) return this.elasticFieldOf(DmpElasticEntity._accessType); + else if (item.prefix(DmpElasticEntity._collaborators)) return this.queryFactory.query(NestedCollaboratorElasticQuery.class).nestedPath(DmpElasticEntity._collaborators).fieldNameOf(this.extractPrefixed(item, DmpElasticEntity._collaborators)); + else if (item.prefix(DmpElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(DmpElasticEntity._references).fieldNameOf(this.extractPrefixed(item, DmpElasticEntity._references)); + else if (item.prefix(DmpElasticEntity._descriptionTemplates)) return this.queryFactory.query(NestedDescriptionTemplateElasticQuery.class).nestedPath(DmpElasticEntity._descriptionTemplates).fieldNameOf(this.extractPrefixed(item, DmpElasticEntity._descriptionTemplates)); + else if (item.prefix(DmpElasticEntity._descriptions)) return this.queryFactory.query(NestedDescriptionElasticQuery.class).nestedPath(DmpElasticEntity._descriptions).fieldNameOf(this.extractPrefixed(item, DmpElasticEntity._descriptions)); + else return null; + } + + @Override + protected String[] getIndex() { + List indexNames = new ArrayList<>(); + indexNames.add(this.appElasticProperties.getDmpIndexName()); + try { + this.elasticService.ensureDescriptionIndex(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return indexNames.toArray(new String[indexNames.size()]); + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(DmpElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + if (item.prefix(DmpElasticEntity._collaborators)) return this.queryFactory.query(NestedCollaboratorElasticQuery.class).nestedPath(DmpElasticEntity._collaborators); + else if (item.prefix(DmpElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(DmpElasticEntity._references); + else if (item.prefix(DmpElasticEntity._descriptionTemplates)) return this.queryFactory.query(NestedDescriptionTemplateElasticQuery.class).nestedPath(DmpElasticEntity._descriptionTemplates); + else if (item.prefix(DmpElasticEntity._descriptions)) return this.queryFactory.query(NestedDescriptionElasticQuery.class).nestedPath(DmpElasticEntity._descriptions); + else return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDescriptionTemplateElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDescriptionTemplateElasticQuery.java new file mode 100644 index 000000000..d2bc1c589 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDescriptionTemplateElasticQuery.java @@ -0,0 +1,94 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.elastic.data.nested.NestedDescriptionTemplateElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticInnerObjectQuery; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class InnerObjectDescriptionTemplateElasticQuery extends ElasticInnerObjectQuery { + + private String innerPath; + + @Override + public InnerObjectDescriptionTemplateElasticQuery innerPath(String value) { + this.innerPath = value; + return this; + } + + + public InnerObjectDescriptionTemplateElasticQuery( + ElasticsearchTemplate elasticsearchRestTemplate, + ElasticProperties elasticProperties + ) { + super(elasticsearchRestTemplate, elasticProperties); + } + + @Override + protected Class entityClass() { + return NestedDescriptionTemplateElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedDescriptionTemplateElasticEntity convert(Map rawData, Set columns) { + NestedDescriptionTemplateElasticEntity mocDoc = new NestedDescriptionTemplateElasticEntity(); + if (columns.contains(NestedDescriptionTemplateElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionTemplateElasticEntity._id), UUID.class)); + if (columns.contains(NestedDescriptionTemplateElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionTemplateElasticEntity._label), String.class)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedDescriptionTemplateElasticEntity._id)) return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._id).disableInfer(true); + else if (item.match(NestedDescriptionTemplateElasticEntity._label)) return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._label).disableInfer(true); + else return null; + } + + @Override + protected String getInnerPath() { + return this.innerPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDmpElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDmpElasticQuery.java new file mode 100644 index 000000000..567c9e0e3 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/InnerObjectDmpElasticQuery.java @@ -0,0 +1,107 @@ +package eu.eudat.elastic.query; +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.elastic.data.nested.NestedDmpElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticInnerObjectQuery; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +//Like in C# make it Transient +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class InnerObjectDmpElasticQuery extends ElasticInnerObjectQuery { + + private String innerPath; + + @Override + public InnerObjectDmpElasticQuery innerPath(String value) { + this.innerPath = value; + return this; + } + + + private final QueryFactory queryFactory; + @Autowired() + public InnerObjectDmpElasticQuery(ElasticsearchTemplate elasticsearchTemplate, ElasticProperties elasticProperties, QueryFactory queryFactory) { + super(elasticsearchTemplate, elasticProperties); + this.queryFactory = queryFactory; + } + + @Override + protected Class entityClass() { + return NestedDmpElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedDmpElasticEntity convert(Map rawData, Set columns) { + NestedDmpElasticEntity mocDoc = new NestedDmpElasticEntity(); + if (columns.contains(NestedDmpElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._id), UUID.class)); + if (columns.contains(NestedDmpElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._label), String.class)); + if (columns.contains(NestedDmpElasticEntity._description)) mocDoc.setDescription(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._description), String.class)); + if (columns.contains(NestedDmpElasticEntity._status)) mocDoc.setStatus(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._status), DmpStatus.class)); + if (columns.contains(NestedDmpElasticEntity._groupId)) mocDoc.setGroupId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._groupId), UUID.class)); + if (columns.contains(NestedDmpElasticEntity._accessType)) mocDoc.setAccessType(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._accessType), DmpAccessType.class)); + if (columns.contains(NestedDmpElasticEntity._finalizedAt)) mocDoc.setFinalizedAt(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDmpElasticEntity._finalizedAt), Date.class)); + mocDoc.setCollaborators(this.convertNested(rawData, columns, this.queryFactory.query(NestedCollaboratorElasticQuery.class), NestedDmpElasticEntity._collaborators, null)); + mocDoc.setReferences(this.convertNested(rawData, columns, this.queryFactory.query(NestedReferenceElasticQuery.class), NestedDmpElasticEntity._references, null)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedDmpElasticEntity._id)) return this.elasticFieldOf(NestedDmpElasticEntity._id); + else if (item.match(NestedDmpElasticEntity._label)) return this.elasticFieldOf(NestedDmpElasticEntity._label); + else if (item.match(NestedDmpElasticEntity._description)) return this.elasticFieldOf(NestedDmpElasticEntity._description); + else if (item.match(NestedDmpElasticEntity._status)) return this.elasticFieldOf(NestedDmpElasticEntity._status); + else if (item.match(NestedDmpElasticEntity._groupId)) return this.elasticFieldOf(NestedDmpElasticEntity._groupId); + else if (item.match(NestedDmpElasticEntity._finalizedAt)) return this.elasticFieldOf(NestedDmpElasticEntity._finalizedAt); + else if (item.match(NestedDmpElasticEntity._accessType)) return this.elasticFieldOf(NestedDmpElasticEntity._accessType); + else if (item.prefix(NestedDmpElasticEntity._collaborators)) return this.queryFactory.query(NestedCollaboratorElasticQuery.class).nestedPath(NestedDmpElasticEntity._collaborators).fieldNameOf(this.extractPrefixed(item, NestedDmpElasticEntity._collaborators)); + else if (item.prefix(NestedDmpElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(NestedDmpElasticEntity._references).fieldNameOf(this.extractPrefixed(item, NestedDmpElasticEntity._references)); + else return null; + } + + @Override + protected String getInnerPath() { + return this.innerPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedDmpElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + if (item.prefix(NestedDmpElasticEntity._collaborators)) return this.queryFactory.query(NestedCollaboratorElasticQuery.class).nestedPath(NestedDmpElasticEntity._collaborators); + else if (item.prefix(NestedDmpElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(NestedDmpElasticEntity._references); + else return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java new file mode 100644 index 000000000..ddc586f24 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java @@ -0,0 +1,94 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.commons.enums.DmpUserRole; +import eu.eudat.elastic.data.nested.NestedCollaboratorElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedCollaboratorElasticQuery extends ElasticNestedQuery { + + private String nestedPath; + + @Override + public NestedCollaboratorElasticQuery nestedPath(String value) { + this.nestedPath = value; + return this; + } + + + public NestedCollaboratorElasticQuery( + ElasticsearchTemplate elasticsearchRestTemplate, + ElasticProperties elasticProperties + ) { + super(elasticsearchRestTemplate, elasticProperties); + } + + @Override + protected Class entityClass() { + return NestedCollaboratorElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedCollaboratorElasticEntity convert(Map rawData, Set columns) { + NestedCollaboratorElasticEntity mocDoc = new NestedCollaboratorElasticEntity(); + if (columns.contains(NestedCollaboratorElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedCollaboratorElasticEntity._id), UUID.class)); + if (columns.contains(NestedCollaboratorElasticEntity._name)) mocDoc.setName(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedCollaboratorElasticEntity._name), String.class)); + if (columns.contains(NestedCollaboratorElasticEntity._role)) mocDoc.setRole(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedCollaboratorElasticEntity._role), DmpUserRole.class)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedCollaboratorElasticEntity._id)) return this.elasticFieldOf(NestedCollaboratorElasticEntity._id).disableInfer(true); + else if (item.match(NestedCollaboratorElasticEntity._name)) return this.elasticFieldOf(NestedCollaboratorElasticEntity._name).disableInfer(true); + else if (item.match(NestedCollaboratorElasticEntity._role)) return this.elasticFieldOf(NestedCollaboratorElasticEntity._role).disableInfer(true); + else return null; + } + + @Override + protected String getNestedPath() { + return this.nestedPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedCollaboratorElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionElasticQuery.java new file mode 100644 index 000000000..efdf580c9 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionElasticQuery.java @@ -0,0 +1,114 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.commons.enums.DescriptionStatus; +import eu.eudat.convention.ConventionService; +import eu.eudat.elastic.data.nested.NestedDescriptionElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDescriptionElasticQuery extends ElasticNestedQuery { + + private String nestedPath; + + @Override + public NestedDescriptionElasticQuery nestedPath(String value) { + this.nestedPath = value; + return this; + } + + private final QueryFactory queryFactory; + private final ConventionService conventionService; + public NestedDescriptionElasticQuery( + ElasticsearchTemplate elasticsearchRestTemplate, + ElasticProperties elasticProperties, + QueryFactory queryFactory, ConventionService conventionService) { + super(elasticsearchRestTemplate, elasticProperties); + this.queryFactory = queryFactory; + this.conventionService = conventionService; + } + + @Override + protected Class entityClass() { + return NestedDescriptionElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedDescriptionElasticEntity convert(Map rawData, Set columns) { + NestedDescriptionElasticEntity mocDoc = new NestedDescriptionElasticEntity(); + if (columns.contains(NestedDescriptionElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._id), UUID.class)); + if (columns.contains(NestedDescriptionElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._label), String.class)); + if (columns.contains(NestedDescriptionElasticEntity._dmpId)) mocDoc.setDmpId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._dmpId), UUID.class)); + if (columns.contains(NestedDescriptionElasticEntity._description)) mocDoc.setDescription(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._description), String.class)); + if (columns.contains(NestedDescriptionElasticEntity._status)) mocDoc.setStatus(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._status), DescriptionStatus.class)); + if (columns.contains(NestedDescriptionElasticEntity._finalizedAt)) mocDoc.setFinalizedAt(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionElasticEntity._finalizedAt), Date.class)); + mocDoc.setReferences(this.convertNested(rawData, columns, this.queryFactory.query(NestedReferenceElasticQuery.class), NestedDescriptionElasticEntity._references, this.getNestedPath())); + mocDoc.setTags(this.convertNested(rawData, columns, this.queryFactory.query(NestedTagElasticQuery.class), NestedDescriptionElasticEntity._tags, this.getNestedPath())); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedDescriptionElasticEntity._id)) return this.elasticFieldOf(NestedDescriptionElasticEntity._id); + else if (item.match(NestedDescriptionElasticEntity._label)) return this.elasticFieldOf(NestedDescriptionElasticEntity._label); + else if (item.match(NestedDescriptionElasticEntity._dmpId)) return this.elasticFieldOf(NestedDescriptionElasticEntity._dmpId); + else if (item.match(NestedDescriptionElasticEntity._description)) return this.elasticFieldOf(NestedDescriptionElasticEntity._description); + else if (item.match(NestedDescriptionElasticEntity._status)) return this.elasticFieldOf(NestedDescriptionElasticEntity._status); + else if (item.match(NestedDescriptionElasticEntity._finalizedAt)) return this.elasticFieldOf(NestedDescriptionElasticEntity._finalizedAt); + else if (item.prefix(NestedDescriptionElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(this.conventionService.asIndexer(this.getNestedPath(), NestedDescriptionElasticEntity._references)).fieldNameOf(this.extractPrefixed(item, NestedDescriptionElasticEntity._references)); + else if (item.prefix(NestedDescriptionElasticEntity._tags)) return this.queryFactory.query(NestedTagElasticQuery.class).nestedPath(this.conventionService.asIndexer(this.getNestedPath(), NestedDescriptionElasticEntity._tags)).fieldNameOf(this.extractPrefixed(item, NestedDescriptionElasticEntity._tags)); + else return null; + } + + @Override + protected String getNestedPath() { + return this.nestedPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedDescriptionElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + if (item.prefix(NestedDescriptionElasticEntity._references)) return this.queryFactory.query(NestedReferenceElasticQuery.class).nestedPath(this.conventionService.asIndexer(this.getNestedPath(), NestedDescriptionElasticEntity._references)); + else if (item.prefix(NestedDescriptionElasticEntity._tags)) return this.queryFactory.query(NestedTagElasticQuery.class).nestedPath(this.conventionService.asIndexer(this.getNestedPath(), NestedDescriptionElasticEntity._tags)); + else return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionTemplateElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionTemplateElasticQuery.java new file mode 100644 index 000000000..09b80fc63 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedDescriptionTemplateElasticQuery.java @@ -0,0 +1,93 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.elastic.data.nested.NestedDescriptionTemplateElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedDescriptionTemplateElasticQuery extends ElasticNestedQuery { + + private String nestedPath; + + @Override + public NestedDescriptionTemplateElasticQuery nestedPath(String value) { + this.nestedPath = value; + return this; + } + + + public NestedDescriptionTemplateElasticQuery( + ElasticsearchTemplate elasticsearchRestTemplate, + ElasticProperties elasticProperties + ) { + super(elasticsearchRestTemplate, elasticProperties); + } + + @Override + protected Class entityClass() { + return NestedDescriptionTemplateElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedDescriptionTemplateElasticEntity convert(Map rawData, Set columns) { + NestedDescriptionTemplateElasticEntity mocDoc = new NestedDescriptionTemplateElasticEntity(); + if (columns.contains(NestedDescriptionTemplateElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionTemplateElasticEntity._id), UUID.class)); + if (columns.contains(NestedDescriptionTemplateElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedDescriptionTemplateElasticEntity._label), String.class)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedDescriptionTemplateElasticEntity._id)) return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._id).disableInfer(true); + else if (item.match(NestedDescriptionTemplateElasticEntity._label)) return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._label).disableInfer(true); + else return null; + } + + @Override + protected String getNestedPath() { + return this.nestedPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedDescriptionTemplateElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedReferenceElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedReferenceElasticQuery.java new file mode 100644 index 000000000..95e25667a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedReferenceElasticQuery.java @@ -0,0 +1,90 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.elastic.data.nested.NestedReferenceElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedReferenceElasticQuery extends ElasticNestedQuery { + + private String nestedPath; + + @Override + public NestedReferenceElasticQuery nestedPath(String value) { + this.nestedPath = value; + return this; + } + + public NestedReferenceElasticQuery( + ElasticsearchTemplate elasticsearchTemplate, + ElasticProperties elasticProperties + ) { + super(elasticsearchTemplate, elasticProperties); + } + + @Override + protected Class entityClass() { + return NestedReferenceElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedReferenceElasticEntity convert(Map rawData, Set columns) { + NestedReferenceElasticEntity mocDoc = new NestedReferenceElasticEntity(); + if (columns.contains(NestedReferenceElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedReferenceElasticEntity._id), UUID.class)); + if (columns.contains(NestedReferenceElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedReferenceElasticEntity._label), String.class)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedReferenceElasticEntity._id)) return this.elasticFieldOf(NestedReferenceElasticEntity._id).disableInfer(true); + else if (item.match(NestedReferenceElasticEntity._label)) return this.elasticFieldOf(NestedReferenceElasticEntity._label).disableInfer(true); + else return null; + } + + @Override + protected String getNestedPath() { + return this.nestedPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedReferenceElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedTagElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedTagElasticQuery.java new file mode 100644 index 000000000..aaaf6832a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedTagElasticQuery.java @@ -0,0 +1,91 @@ +package eu.eudat.elastic.query; + +import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.elastic.data.nested.NestedTagElasticEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.elastic.configuration.ElasticProperties; +import gr.cite.tools.elastic.mapper.FieldBasedMapper; +import gr.cite.tools.elastic.query.ElasticField; +import gr.cite.tools.elastic.query.ElasticNestedQuery; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class NestedTagElasticQuery extends ElasticNestedQuery { + + private String nestedPath; + + @Override + public NestedTagElasticQuery nestedPath(String value) { + this.nestedPath = value; + return this; + } + + + public NestedTagElasticQuery( + ElasticsearchTemplate elasticsearchTemplate, + ElasticProperties elasticProperties + ) { + super(elasticsearchTemplate, elasticProperties); + } + + @Override + protected Class entityClass() { + return NestedTagElasticEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return false; + } + + @Override + protected Query applyAuthZ() { + return null; + } + + @Override + protected Query applyFilters() { + return null; + } + + @Override + public NestedTagElasticEntity convert(Map rawData, Set columns) { + NestedTagElasticEntity mocDoc = new NestedTagElasticEntity(); + if (columns.contains(NestedTagElasticEntity._id)) mocDoc.setId(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedTagElasticEntity._id), UUID.class)); + if (columns.contains(NestedTagElasticEntity._label)) mocDoc.setLabel(FieldBasedMapper.shallowSafeConversion(rawData.get(NestedTagElasticEntity._label), String.class)); + return mocDoc; + } + + @Override + protected ElasticField fieldNameOf(FieldResolver item) { + if (item.match(NestedTagElasticEntity._id)) return this.elasticFieldOf(NestedTagElasticEntity._id).disableInfer(true); + else if (item.match(NestedTagElasticEntity._label)) return this.elasticFieldOf(NestedTagElasticEntity._label).disableInfer(true); + else return null; + } + + @Override + protected String getNestedPath() { + return this.nestedPath; + } + + @Override + protected UUID toKey(String key) { + return UUID.fromString(key); + } + + @Override + protected ElasticField getKeyField() { + return this.elasticFieldOf(NestedTagElasticEntity._id); + } + + @Override + protected ElasticNestedQuery nestedQueryOf(FieldResolver item) { + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java index 29a8afaf3..5dd185db4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java @@ -176,7 +176,11 @@ public class DmpQuery extends QueryBase { List predicates = new ArrayList<>(); if (userId != null || usePublic ) { predicates.add(queryContext.CriteriaBuilder.or( - usePublic ? queryContext.CriteriaBuilder.equal(queryContext.Root.get(DmpEntity._accessType), DmpAccessType.Public) : queryContext.CriteriaBuilder.or(), //Creates a false query + usePublic ? queryContext.CriteriaBuilder.and( + queryContext.CriteriaBuilder.equal(queryContext.Root.get(DmpEntity._status), DmpStatus.FINALISED), + queryContext.CriteriaBuilder.equal(queryContext.Root.get(DmpEntity._accessType), DmpAccessType.Public) + ) + : queryContext.CriteriaBuilder.or(), //Creates a false query userId != null ? queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)).value(this.queryUtilsService.buildDmpUserAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, userId)) : queryContext.CriteriaBuilder.or() //Creates a false query )); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java index 67d1af970..6cffef11e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java @@ -1,6 +1,7 @@ package eu.eudat.query.utils; import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpUserEntity; @@ -30,6 +31,7 @@ public class QueryUtilsServiceImpl implements QueryUtilsService { .filterFunc((subQueryRoot, cb) -> cb.or( usePublic ? cb.and( cb.equal(subQueryRoot.get(DmpEntity._accessType), DmpAccessType.Public), + cb.equal(subQueryRoot.get(DmpEntity._status), DmpStatus.FINALISED), cb.equal(subQueryRoot.get(DmpEntity._isActive), IsActive.Active) ): cb.or(), //Creates a false query userId != null ? cb.in(subQueryRoot.get(DmpEntity._id)).value(this.buildDmpUserAuthZSubQuery(query, criteriaBuilder, userId)) : cb.or() //Creates a false query @@ -49,6 +51,7 @@ public class QueryUtilsServiceImpl implements QueryUtilsService { .filterFunc((subQueryRoot, cb) -> usePublic ? cb.and( cb.equal(subQueryRoot.get(DmpEntity._accessType), DmpAccessType.Public), + cb.equal(subQueryRoot.get(DmpEntity._status), DmpStatus.FINALISED), cb.equal(subQueryRoot.get(DmpEntity._isActive), IsActive.Active) ): cb.or() //Creates a false query ) diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticService.java b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticService.java new file mode 100644 index 000000000..fabacb500 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticService.java @@ -0,0 +1,27 @@ +package eu.eudat.service.elastic; + +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DmpEntity; + +import java.io.IOException; + +public interface ElasticService { + boolean enabled(); + boolean existsDmpIndex() throws IOException; + + boolean existsDescriptionIndex() throws IOException; + + void ensureDmpIndex() throws IOException; + + void ensureDescriptionIndex() throws IOException; + + void ensureIndexes() throws IOException; + + void persistDmp(DmpEntity dmp) throws IOException; + + void deleteDmp(DmpEntity dmp) throws IOException; + + void persistDescription(DescriptionEntity description) throws IOException; + + void deleteDescription(DescriptionEntity description) throws IOException; +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticServiceImpl.java new file mode 100644 index 000000000..c90dac6b5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticServiceImpl.java @@ -0,0 +1,306 @@ +package eu.eudat.service.elastic; + +import co.elastic.clients.elasticsearch.ElasticsearchClient; +import co.elastic.clients.elasticsearch._types.mapping.Property; +import co.elastic.clients.elasticsearch._types.mapping.TypeMapping; +import co.elastic.clients.elasticsearch.indices.*; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.configurations.elastic.AppElasticProperties; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DmpEntity; +import eu.eudat.elastic.data.DescriptionElasticEntity; +import eu.eudat.elastic.data.DmpElasticEntity; +import eu.eudat.elastic.data.nested.*; +import eu.eudat.elastic.elasticbuilder.DescriptionElasticBuilder; +import eu.eudat.elastic.elasticbuilder.DmpElasticBuilder; +import eu.eudat.model.Description; +import eu.eudat.model.Dmp; +import eu.eudat.query.DescriptionQuery; +import eu.eudat.query.DmpQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.elastic.ElasticConstants; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.BaseFieldSet; +import jakarta.persistence.EntityManager; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.data.elasticsearch.annotations.FieldType; + +import java.io.IOException; +import java.util.*; + +import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.stereotype.Service; +import org.springframework.web.context.annotation.RequestScope; + +@Service +public class ElasticServiceImpl implements ElasticService { + public final AppElasticProperties appElasticProperties; + private final ElasticsearchClient restHighLevelClient; + private final ElasticsearchTemplate elasticsearchTemplate; + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + private final EntityManager entityManager; + private final MessageSource messageSource; + + public ElasticServiceImpl(AppElasticProperties appElasticProperties, ElasticsearchClient restHighLevelClient, ElasticsearchTemplate elasticsearchTemplate, QueryFactory queryFactory, BuilderFactory builderFactory, EntityManager entityManager, MessageSource messageSource) { + this.appElasticProperties = appElasticProperties; + this.restHighLevelClient = restHighLevelClient; + this.elasticsearchTemplate = elasticsearchTemplate; + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + this.entityManager = entityManager; + this.messageSource = messageSource; + } + + @Override + public boolean enabled() { + return appElasticProperties.isEnabled(); + } + + @Override + public boolean existsDmpIndex() throws IOException { + if (!this.enabled()) return false; + return restHighLevelClient.indices().exists(new ExistsRequest.Builder().index(this.appElasticProperties.getDmpIndexName()).includeDefaults(true).build()).value(); + } + + + @Override + public boolean existsDescriptionIndex() throws IOException { + if (!this.enabled()) return false; + return restHighLevelClient.indices().exists(new ExistsRequest.Builder().index(this.appElasticProperties.getDmpIndexName()).includeDefaults(true).build()).value(); + } + + //region ensure index + + @Override + public void ensureDmpIndex() throws IOException { + if (!this.enabled()) return ; + boolean exists = this.existsDmpIndex(); + if (exists) return ; + + this.ensureIndex(this.appElasticProperties.getDmpIndexName(), this.createDmpTemplatePropertyMap()); + } + + @Override + public void ensureDescriptionIndex() throws IOException { + if (!this.enabled()) return ; + boolean exists = this.existsDescriptionIndex(); + if (exists) return ; + this.ensureIndex(this.appElasticProperties.getDescriptionIndexName(), this.createDescriptionTemplatePropertyMap()); + } + + @Override + public void ensureIndexes() throws IOException { + if (!this.enabled()) return ; + + this.ensureDmpIndex(); + this.ensureDescriptionIndex(); + } + + private void ensureIndex(String indexName, Map propertyMap) throws IOException { + TypeMapping.Builder typeMapping = new TypeMapping.Builder(); + typeMapping.properties(propertyMap); + + IndexSettings.Builder indexSettings = new IndexSettings.Builder(); + IndexSettingsAnalysis.Builder indexSettingsAnalysis = new IndexSettingsAnalysis.Builder(); + indexSettingsAnalysis.filter("english_stemmer", ((tf) -> tf.definition(tfdb -> tfdb.stemmer(stemmerBuilder -> stemmerBuilder.language("english"))))) + .filter("english_stop", tf -> tf.definition(tfdb -> tfdb.stop(stopTokenBuilder -> stopTokenBuilder))); + + if (this.appElasticProperties.isEnableIcuAnalysisPlugin()){ + indexSettingsAnalysis.analyzer("icu_analyzer_text", ab -> ab.custom(x-> x.filter("icu_folding", "english_stop", "english_stemmer").tokenizer("icu_tokenizer"))); + } else { + indexSettingsAnalysis.analyzer("icu_analyzer_text", ab -> ab.custom(x-> x.filter("icu_folding", "english_stop", "english_stemmer").tokenizer("standard"))); + } + indexSettings.analysis(indexSettingsAnalysis.build()); + CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(new CreateIndexRequest.Builder().index(indexName).mappings(typeMapping.build()).settings(indexSettings.build()).build()); + + } + + private Map createDescriptionTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(DescriptionElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DescriptionElasticEntity._label, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DescriptionElasticEntity._description, this.createElastic(FieldType.Text, true)); + propertyMap.put(DescriptionElasticEntity._status, this.createElastic(FieldType.Short, false)); + propertyMap.put(DescriptionElasticEntity._finalizedAt, this.createElastic(FieldType.Date, false)); + + propertyMap.put(DescriptionElasticEntity._tags, new Property.Builder().nested(x -> x.properties(this.createNestedTagsTemplatePropertyMap())).build()); + propertyMap.put(DescriptionElasticEntity._references, new Property.Builder().nested(x -> x.properties(this.createNestedReferencesTemplatePropertyMap())).build()); + propertyMap.put(DescriptionElasticEntity._descriptionTemplate, new Property.Builder().object(x -> x.properties(this.createNestedDescriptionTemplateTemplatePropertyMap())).build()); + propertyMap.put(DescriptionElasticEntity._dmp, new Property.Builder().object(x -> x.properties(this.createNetsedDmpTemplatePropertyMap())).build()); + return propertyMap; + } + + private Map createDmpTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(DmpElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DmpElasticEntity._label, this.createElastic(FieldType.Text, true)); + propertyMap.put(DmpElasticEntity._description, this.createElastic(FieldType.Text, false)); + propertyMap.put(DmpElasticEntity._status, this.createElastic(FieldType.Short, false)); + propertyMap.put(DmpElasticEntity._version, this.createElastic(FieldType.Short, false)); + propertyMap.put(DmpElasticEntity._language, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DmpElasticEntity._blueprintId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DmpElasticEntity._accessType, this.createElastic(FieldType.Short, false)); + propertyMap.put(DmpElasticEntity._groupId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(DmpElasticEntity._finalizedAt, this.createElastic(FieldType.Date, false)); + + propertyMap.put(DmpElasticEntity._descriptions, new Property.Builder().nested(x -> x.properties(this.createNestedDescriptionTemplatePropertyMap())).build()); + propertyMap.put(DmpElasticEntity._references, new Property.Builder().nested(x -> x.properties(this.createNestedReferencesTemplatePropertyMap())).build()); + propertyMap.put(DmpElasticEntity._collaborators, new Property.Builder().nested(x -> x.properties(this.createNestedCollaboratorTemplatePropertyMap())).build()); + propertyMap.put(DmpElasticEntity._dois, new Property.Builder().nested(x -> x.properties(this.createNestedDoisTemplatePropertyMap())).build()); + return propertyMap; + } + + private Map createNestedDescriptionTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedDescriptionElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDescriptionElasticEntity._label, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDescriptionElasticEntity._dmpId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDescriptionElasticEntity._description, this.createElastic(FieldType.Text, true)); + propertyMap.put(NestedDescriptionElasticEntity._status, this.createElastic(FieldType.Short, false)); + propertyMap.put(NestedDescriptionElasticEntity._finalizedAt, this.createElastic(FieldType.Date, false)); + + propertyMap.put(NestedDescriptionElasticEntity._tags, new Property.Builder().nested(x -> x.properties(this.createNestedTagsTemplatePropertyMap())).build()); + propertyMap.put(NestedDescriptionElasticEntity._references, new Property.Builder().nested(x -> x.properties(this.createNestedReferencesTemplatePropertyMap())).build()); + + return propertyMap; + } + + private Map createNestedTagsTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedTagElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedTagElasticEntity._label, this.createElastic(FieldType.Text, true)); + + return propertyMap; + } + + private Map createNestedReferencesTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedReferenceElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedReferenceElasticEntity._label, this.createElastic(FieldType.Text, true)); + + return propertyMap; + } + + private Map createNestedDescriptionTemplateTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedDescriptionTemplateElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDescriptionTemplateElasticEntity._label, this.createElastic(FieldType.Text, true)); + + return propertyMap; + } + + private Map createNetsedDmpTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedDmpElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDmpElasticEntity._label, this.createElastic(FieldType.Text, true)); + propertyMap.put(NestedDmpElasticEntity._description, this.createElastic(FieldType.Text, false)); + propertyMap.put(NestedDmpElasticEntity._status, this.createElastic(FieldType.Short, false)); + propertyMap.put(NestedDmpElasticEntity._version, this.createElastic(FieldType.Short, false)); + propertyMap.put(NestedDmpElasticEntity._language, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDmpElasticEntity._blueprintId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDmpElasticEntity._accessType, this.createElastic(FieldType.Short, false)); + propertyMap.put(NestedDmpElasticEntity._groupId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDmpElasticEntity._finalizedAt, this.createElastic(FieldType.Date, false)); + + propertyMap.put(NestedDmpElasticEntity._references, new Property.Builder().nested(x -> x.properties(this.createNestedReferencesTemplatePropertyMap())).build()); + propertyMap.put(NestedDmpElasticEntity._collaborators, new Property.Builder().nested(x -> x.properties(this.createNestedCollaboratorTemplatePropertyMap())).build()); + propertyMap.put(NestedDmpElasticEntity._dois, new Property.Builder().nested(x -> x.properties(this.createNestedDoisTemplatePropertyMap())).build()); + return propertyMap; + } + + private Map createNestedCollaboratorTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedCollaboratorElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedCollaboratorElasticEntity._name, this.createElastic(FieldType.Text, true)); + propertyMap.put(NestedCollaboratorElasticEntity._role, this.createElastic(FieldType.Short, false)); + + return propertyMap; + } + + private Map createNestedDoisTemplatePropertyMap(){ + Map propertyMap = new HashMap<>(); + propertyMap.put(NestedDoiElasticEntity._id, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDoiElasticEntity._repositoryId, this.createElastic(FieldType.Keyword, false)); + propertyMap.put(NestedDoiElasticEntity._doi, this.createElastic(FieldType.Keyword, false)); + return propertyMap; + } + + private Property createElastic(FieldType fieldType, boolean hasKeywordSubField){ + switch (fieldType){ + case Keyword -> { + return new Property.Builder().keyword(x -> x).build(); + } + case Text -> { + return hasKeywordSubField ? new Property.Builder().text(x -> x.analyzer("icu_analyzer_text").fields(ElasticConstants.SubFields.keyword, y -> y.keyword(z-> z))).build() : new Property.Builder().text(x -> x).build(); + } + case Date -> { + return new Property.Builder().date(x -> x).build(); + } + case Short -> { + return new Property.Builder().short_(x -> x).build(); + } + case Boolean -> { + return new Property.Builder().boolean_(x -> x).build(); + } + default -> throw new RuntimeException(); + } + } + + //endregion + + @Override + public void persistDmp(DmpEntity dmp) throws IOException { + if (!this.enabled()) return; + this.ensureIndexes(); + + DmpElasticEntity dmpElasticEntity = this.builderFactory.builder(DmpElasticBuilder.class).build(dmp); + this.elasticsearchTemplate.save(dmpElasticEntity, IndexCoordinates.of(this.appElasticProperties.getDmpIndexName())); + List descriptions = this.builderFactory.builder(DescriptionElasticBuilder.class).build(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(this.queryFactory.query(DmpQuery.class).ids(dmp.getId())).collect()); + this.elasticsearchTemplate.save(descriptions, IndexCoordinates.of(this.appElasticProperties.getDescriptionIndexName())); + } + + @Override + public void deleteDmp(DmpEntity dmp) throws IOException { + if (!this.enabled()) return; + this.ensureIndexes(); + + this.elasticsearchTemplate.delete(dmp.getId(), IndexCoordinates.of(this.appElasticProperties.getDmpIndexName())); + List descriptions = this.queryFactory.query(DescriptionQuery.class).dmpSubQuery(this.queryFactory.query(DmpQuery.class).ids(dmp.getId())).collectAs(new BaseFieldSet().ensure(Description._id)); + for (DescriptionEntity description: descriptions) { + this.elasticsearchTemplate.delete(description.getId(), IndexCoordinates.of(this.appElasticProperties.getDescriptionIndexName())); + } + } + + @Override + public void persistDescription(DescriptionEntity description) throws IOException { + if (!this.enabled()) return; + this.ensureIndexes(); + + DescriptionElasticEntity descriptionElasticEntity = this.builderFactory.builder(DescriptionElasticBuilder.class).build(description); + this.elasticsearchTemplate.save(descriptionElasticEntity, IndexCoordinates.of(this.appElasticProperties.getDescriptionIndexName())); + DmpEntity dmpEntity = this.entityManager.find(DmpEntity.class, description.getDmpId()); + if (dmpEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{description.getDmpId(), Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (dmpEntity.getIsActive().equals(IsActive.Active)) { + DmpElasticEntity dmpElasticEntity = this.builderFactory.builder(DmpElasticBuilder.class).build(dmpEntity); + this.elasticsearchTemplate.save(dmpElasticEntity, IndexCoordinates.of(this.appElasticProperties.getDmpIndexName())); + } + } + + @Override + public void deleteDescription(DescriptionEntity description) throws IOException { + if (!this.enabled()) return; + this.ensureIndexes(); + + this.elasticsearchTemplate.delete(description.getId(), IndexCoordinates.of(this.appElasticProperties.getDescriptionIndexName())); + DmpEntity dmpEntity = this.entityManager.find(DmpEntity.class, description.getDmpId()); + if (dmpEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{description.getDmpId(), Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (dmpEntity.getIsActive().equals(IsActive.Active)) { + DmpElasticEntity dmpElasticEntity = this.builderFactory.builder(DmpElasticBuilder.class).build(dmpEntity); + this.elasticsearchTemplate.save(dmpElasticEntity, IndexCoordinates.of(this.appElasticProperties.getDmpIndexName())); + } + } +} diff --git a/dmp-backend/core/target/maven-archiver/pom.properties b/dmp-backend/core/target/maven-archiver/pom.properties new file mode 100644 index 000000000..bc6d378ce --- /dev/null +++ b/dmp-backend/core/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=core +groupId=eu.eudat +version=1.0.0-SNAPSHOT diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java index 5c50ac732..54c674e01 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java @@ -1,5 +1,6 @@ package eu.eudat.elastic.repository; +import co.elastic.clients.elasticsearch.ElasticsearchClient; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.entities.Dataset; import eu.eudat.elastic.entities.Dmp; @@ -42,7 +43,7 @@ public class DatasetRepository extends ElasticRepository()); - } - dmp.getDatasets().add(entity); - } - IndexRequest request = new IndexRequest(this.environment.getProperty("elasticsearch.index")).id(dmp.getId().toString()).source(dmp.toElasticEntity(builder));//new IndexRequest("datasets", "doc", entity.getId()).source(entity.toElasticEntity(builder)); - this.getClient().index(request, RequestOptions.DEFAULT); - } - return entity; - } +// if (this.getClient() != null) { +// XContentBuilder builder = XContentFactory.jsonBuilder(); +// Dmp dmp = this.dmpRepository.findDocument(entity.getDmp().toString()); +// if (dmp != null) { +// boolean found = false; +// if (dmp.getDatasets() != null && !dmp.getDatasets().isEmpty()) { +// for (int i = 0; i < dmp.getDatasets().size(); i++) { +// if (dmp.getDatasets().get(i).getId().equals(entity.getId())) { +// dmp.getDatasets().set(i, entity); +// found = true; +// break; +// } +// } +// } +// if (!found) { +// if (dmp.getDatasets() == null) { +// dmp.setDatasets(new ArrayList<>()); +// } +// dmp.getDatasets().add(entity); +// } +// IndexRequest request = new IndexRequest(this.environment.getProperty("elasticsearch.index")).id(dmp.getId().toString()).source(dmp.toElasticEntity(builder));//new IndexRequest("datasets", "doc", entity.getId()).source(entity.toElasticEntity(builder)); +// this.getClient().index(request, RequestOptions.DEFAULT).index(); +// } +// return entity; +// } return null; } @Override public Dataset findDocument(String id) throws IOException { - if (this.getClient() != null) { - SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().should(QueryBuilders.termQuery("datasets.id.keyword", id)); - NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery( "datasets", boolQuery, ScoreMode.Avg).innerHit(new InnerHitBuilder()); - searchSourceBuilder.query(nestedQueryBuilder); - searchRequest.source(searchSourceBuilder); - SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); - return ((Stream)Arrays.stream(response.getHits().getHits()) - .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) - .map(SearchHits::getHits).flatMap(Arrays::stream) - .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).findFirst().orElse(null); -// GetRequest request = new GetRequest("datasets", id); -// GetResponse response = this.getClient().get(request, RequestOptions.DEFAULT); -// return new Dataset().fromElasticEntity(response.getSourceAsMap()); - } +// if (this.getClient() != null) { +// SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); +// BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().should(QueryBuilders.termQuery("datasets.id.keyword", id)); +// NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery( "datasets", boolQuery, ScoreMode.Avg).innerHit(new InnerHitBuilder()); +// searchSourceBuilder.query(nestedQueryBuilder); +// searchRequest.source(searchSourceBuilder); +// SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); +// return ((Stream)Arrays.stream(response.getHits().getHits()) +// .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) +// .map(SearchHits::getHits).flatMap(Arrays::stream) +// .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).findFirst().orElse(null); +//// GetRequest request = new GetRequest("datasets", id); +//// GetResponse response = this.getClient().get(request, RequestOptions.DEFAULT); +//// return new Dataset().fromElasticEntity(response.getSourceAsMap()); +// } return null; } @Override public List query(DatasetCriteria criteria) throws IOException { - if (this.getClient() != null) { - SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - - /*CountRequest countRequest = new CountRequest("dmps").routing("datasets").routing("id"); - countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); - CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); - Long count = countResponse.getCount();*/ - - SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); - FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); - nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); - SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); - countSourceBuilder.aggregation(nestedAggregationBuilder); - countRequest.source(countSourceBuilder); - SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); - Long count = ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); - - - searchSourceBuilder.size(count.intValue()); - - List sortBuilders = new ArrayList<>(); - BoolQueryBuilder boolQuery = createBoolQuery(criteria); - - - if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { - criteria.getSortCriteria().forEach(sortCriteria -> { - switch(sortCriteria.getColumnType()) { - case COLUMN: - sortBuilders.add(SortBuilders.fieldSort("datasets." + sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - break; - case JOIN_COLUMN: - List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); - fields.stream().filter(name -> !name.startsWith("dmp")).forEach(field -> { - sortBuilders.add(SortBuilders.fieldSort(field).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - }); - break; - } - }); - - } - - NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(true, new String[]{"datasets.tags"}, null)).setSize(this.environment.getProperty("elasticsearch.innerHitsSize", Integer.class))); - searchSourceBuilder.query(nestedQueryBuilder)/*.from(criteria.getOffset())*/.fetchSource("datasets.tags", null); - /*if (criteria.getSize() > 0) { - searchSourceBuilder.size(criteria.getSize()); - }*/ - sortBuilders.forEach(searchSourceBuilder::sort); - searchRequest.source(searchSourceBuilder); - SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); - return ((Stream)Arrays.stream(response.getHits().getHits()) - .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) - .map(SearchHits::getHits).flatMap(Arrays::stream) - .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).collect(Collectors.toList()); - } +// if (this.getClient() != null) { +// SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); +// +// /*CountRequest countRequest = new CountRequest("dmps").routing("datasets").routing("id"); +// countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); +// CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); +// Long count = countResponse.getCount();*/ +// +// SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); +// FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); +// nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); +// SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); +// countSourceBuilder.aggregation(nestedAggregationBuilder); +// countRequest.source(countSourceBuilder); +// SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); +// Long count = ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); +// +// +// searchSourceBuilder.size(count.intValue()); +// +// List sortBuilders = new ArrayList<>(); +// BoolQueryBuilder boolQuery = createBoolQuery(criteria); +// +// +// if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { +// criteria.getSortCriteria().forEach(sortCriteria -> { +// switch(sortCriteria.getColumnType()) { +// case COLUMN: +// sortBuilders.add(SortBuilders.fieldSort("datasets." + sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// break; +// case JOIN_COLUMN: +// List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); +// fields.stream().filter(name -> !name.startsWith("dmp")).forEach(field -> { +// sortBuilders.add(SortBuilders.fieldSort(field).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// }); +// break; +// } +// }); +// +// } +// +// NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(true, new String[]{"datasets.tags"}, null)).setSize(this.environment.getProperty("elasticsearch.innerHitsSize", Integer.class))); +// searchSourceBuilder.query(nestedQueryBuilder)/*.from(criteria.getOffset())*/.fetchSource("datasets.tags", null); +// /*if (criteria.getSize() > 0) { +// searchSourceBuilder.size(criteria.getSize()); +// }*/ +// sortBuilders.forEach(searchSourceBuilder::sort); +// searchRequest.source(searchSourceBuilder); +// SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); +// return ((Stream)Arrays.stream(response.getHits().getHits()) +// .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) +// .map(SearchHits::getHits).flatMap(Arrays::stream) +// .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).collect(Collectors.toList()); +// } return null; } public List queryIds(DatasetCriteria criteria) throws IOException { - if (this.getClient() != null) { - SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - - /*CountRequest countRequest = new CountRequest("dmps").routing("datasets").routing("id"); - countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); - CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); - Long count = countResponse.getCount();*/ - - SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); - FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); - nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); - SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); - countSourceBuilder.aggregation(nestedAggregationBuilder); - countRequest.source(countSourceBuilder); - SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); - Long count = ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); - - - searchSourceBuilder.size(count.intValue()); - - List sortBuilders = new ArrayList<>(); - BoolQueryBuilder boolQuery = createBoolQuery(criteria); - - - if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { - criteria.getSortCriteria().forEach(sortCriteria -> { - switch(sortCriteria.getColumnType()) { - case COLUMN: - sortBuilders.add(SortBuilders.fieldSort("datasets." + sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - break; - case JOIN_COLUMN: - List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); - fields.stream().filter(name -> !name.startsWith("dmp")).forEach(field -> { - sortBuilders.add(SortBuilders.fieldSort(field).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - }); - break; - } - }); - - } - - NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.None).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(true, new String[]{"datasets.id"}, null)).setSize(this.environment.getProperty("elasticsearch.innerHitsSize", Integer.class))); - searchSourceBuilder.query(nestedQueryBuilder)/*.from(criteria.getOffset()).size(criteria.getSize())*/.fetchSource("datasets.id", null); - sortBuilders.forEach(searchSourceBuilder::sort); - searchRequest.source(searchSourceBuilder); - SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); - return ((Stream)Arrays.stream(response.getHits().getHits()) - .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) - .map(SearchHits::getHits).flatMap(Arrays::stream) - .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).collect(Collectors.toList()); - } +// if (this.getClient() != null) { +// SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); +// +// /*CountRequest countRequest = new CountRequest("dmps").routing("datasets").routing("id"); +// countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); +// CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); +// Long count = countResponse.getCount();*/ +// +// SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); +// FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status.keyword", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())))); +// nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); +// SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); +// countSourceBuilder.aggregation(nestedAggregationBuilder); +// countRequest.source(countSourceBuilder); +// SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); +// Long count = ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); +// +// +// searchSourceBuilder.size(count.intValue()); +// +// List sortBuilders = new ArrayList<>(); +// BoolQueryBuilder boolQuery = createBoolQuery(criteria); +// +// +// if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { +// criteria.getSortCriteria().forEach(sortCriteria -> { +// switch(sortCriteria.getColumnType()) { +// case COLUMN: +// sortBuilders.add(SortBuilders.fieldSort("datasets." + sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// break; +// case JOIN_COLUMN: +// List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); +// fields.stream().filter(name -> !name.startsWith("dmp")).forEach(field -> { +// sortBuilders.add(SortBuilders.fieldSort(field).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// }); +// break; +// } +// }); +// +// } +// +// NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.None).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(true, new String[]{"datasets.id"}, null)).setSize(this.environment.getProperty("elasticsearch.innerHitsSize", Integer.class))); +// searchSourceBuilder.query(nestedQueryBuilder)/*.from(criteria.getOffset()).size(criteria.getSize())*/.fetchSource("datasets.id", null); +// sortBuilders.forEach(searchSourceBuilder::sort); +// searchRequest.source(searchSourceBuilder); +// SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); +// return ((Stream)Arrays.stream(response.getHits().getHits()) +// .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) +// .map(SearchHits::getHits).flatMap(Arrays::stream) +// .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class)))).collect(Collectors.toList()); +// } return null; } @Override public Long count(DatasetCriteria criteria) throws IOException { - if (this.getClient() != null) { - //CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); - - SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - BoolQueryBuilder boolQuery = createBoolQuery(criteria); - NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); - FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", boolQuery); - nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); - SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); - countSourceBuilder.aggregation(nestedAggregationBuilder); - countRequest.source(countSourceBuilder); - SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); - return ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); - - - - /*NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.None).innerHit(new InnerHitBuilder()); - countRequest.query(nestedQueryBuilder); - CountResponse response = this.getClient().count(countRequest, RequestOptions.DEFAULT); - return response.getCount();*/ - } +// if (this.getClient() != null) { +// //CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); +// +// SearchRequest countRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// BoolQueryBuilder boolQuery = createBoolQuery(criteria); +// NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("by_dataset", "datasets"); +// FiltersAggregationBuilder filtersAggregationBuilder = AggregationBuilders.filters("dataset_query", boolQuery); +// nestedAggregationBuilder.subAggregation(filtersAggregationBuilder); +// SearchSourceBuilder countSourceBuilder = new SearchSourceBuilder(); +// countSourceBuilder.aggregation(nestedAggregationBuilder); +// countRequest.source(countSourceBuilder); +// SearchResponse countResponse = getClient().search(countRequest, RequestOptions.DEFAULT); +// return ((ParsedFilters)((ParsedNested)countResponse.getAggregations().asMap().get("by_dataset")).getAggregations().get("dataset_query")).getBuckets().get(0).getDocCount(); +// +// +// +// /*NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("datasets", boolQuery, ScoreMode.None).innerHit(new InnerHitBuilder()); +// countRequest.query(nestedQueryBuilder); +// CountResponse response = this.getClient().count(countRequest, RequestOptions.DEFAULT); +// return response.getCount();*/ +// } return null; } @@ -324,11 +325,11 @@ public class DatasetRepository extends ElasticRepository { private final Environment environment; @Autowired - public DmpRepository(RestHighLevelClient client, Environment environment) { + public DmpRepository(ElasticsearchClient client, Environment environment) { super(client, environment); this.environment = environment; } private void generateMapping() throws IOException { - if (this.getClient() != null) { - XContentBuilder builder = XContentFactory.jsonBuilder(); - builder.startObject(); - builder.startObject("properties"); - builder.startObject("datasets"); - builder.field("type", "nested"); - builder.endObject(); - builder.endObject(); - builder.endObject(); - PutMappingRequest putMappingRequest = new PutMappingRequest(this.environment.getProperty("elasticsearch.index")); - putMappingRequest.source(builder); - this.getClient().indices().putMapping(putMappingRequest, RequestOptions.DEFAULT); - } +// if (this.getClient() != null) { +// XContentBuilder builder = XContentFactory.jsonBuilder(); +// builder.startObject(); +// builder.startObject("properties"); +// builder.startObject("datasets"); +// builder.field("type", "nested"); +// builder.endObject(); +// builder.endObject(); +// builder.endObject(); +// PutMappingRequest putMappingRequest = new PutMappingRequest(this.environment.getProperty("elasticsearch.index")); +// putMappingRequest.source(builder); +// this.getClient().indices().putMapping(putMappingRequest, RequestOptions.DEFAULT); +// } } @Override public Dmp createOrUpdate(Dmp entity) throws IOException { - if (this.getClient() != null) { - XContentBuilder builder = XContentFactory.jsonBuilder(); - IndexRequest request = new IndexRequest(this.environment.getProperty("elasticsearch.index")).id(entity.getId().toString()).source(entity.toElasticEntity(builder)); - IndexResponse response = this.getClient().index(request, RequestOptions.DEFAULT); - return entity; - } +// if (this.getClient() != null) { +// XContentBuilder builder = XContentFactory.jsonBuilder(); +// IndexRequest request = new IndexRequest(this.environment.getProperty("elasticsearch.index")).id(entity.getId().toString()).source(entity.toElasticEntity(builder)); +// IndexResponse response = this.getClient().index(request, RequestOptions.DEFAULT); +// return entity; +// } return null; } @Override public Dmp findDocument(String id) throws IOException { - if (this.getClient() != null) { - GetRequest request = new GetRequest(this.environment.getProperty("elasticsearch.index"), id); - GetResponse response = this.getClient().get(request, RequestOptions.DEFAULT); - return new Dmp().fromElasticEntity(response.getSourceAsMap()); - } +// if (this.getClient() != null) { +// GetRequest request = new GetRequest(this.environment.getProperty("elasticsearch.index"), id); +// GetResponse response = this.getClient().get(request, RequestOptions.DEFAULT); +// return new Dmp().fromElasticEntity(response.getSourceAsMap()); +// } return null; } @Override public List query(DmpCriteria criteria) throws IOException { - if (this.getClient() != null) { - SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - - CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); - countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(Dmp.MapKey.STATUS.getName(), Collections.singletonList(Dmp.DMPStatus.DELETED.getValue())))); - CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); - Long count = countResponse.getCount(); - - searchSourceBuilder.size(count.intValue()); - - List sortBuilders = new ArrayList<>(); - BoolQueryBuilder boolQuery = createBoolQuery(criteria); - - if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { - criteria.getSortCriteria().forEach(sortCriteria -> { - switch(sortCriteria.getColumnType()) { - case COLUMN: - sortBuilders.add(SortBuilders.fieldSort(sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - break; - case JOIN_COLUMN: - List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); - fields.forEach(field -> { - sortBuilders.add(SortBuilders.fieldSort(sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); - }); - break; - } - }); - - } - searchSourceBuilder.query(boolQuery).from(criteria.getOffset()).fetchSource("id", null); - if (criteria.getSize() != null && criteria.getSize() > 0) { - searchSourceBuilder.size(criteria.getSize()); - } - sortBuilders.forEach(searchSourceBuilder::sort); - searchRequest.source(searchSourceBuilder); - SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); - return Arrays.stream(response.getHits().getHits()).map(x -> new Dmp().fromElasticEntity((Map) this.transformFromString(x.getSourceAsString(), Map.class))).collect(Collectors.toList()); - } +// if (this.getClient() != null) { +// SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); +// SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); +// +// CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); +// countRequest.query(QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(Dmp.MapKey.STATUS.getName(), Collections.singletonList(Dmp.DMPStatus.DELETED.getValue())))); +// CountResponse countResponse = getClient().count(countRequest, RequestOptions.DEFAULT); +// Long count = countResponse.getCount(); +// +// searchSourceBuilder.size(count.intValue()); +// +// List sortBuilders = new ArrayList<>(); +// BoolQueryBuilder boolQuery = createBoolQuery(criteria); +// +// if (criteria.getSortCriteria() != null && !criteria.getSortCriteria().isEmpty()) { +// criteria.getSortCriteria().forEach(sortCriteria -> { +// switch(sortCriteria.getColumnType()) { +// case COLUMN: +// sortBuilders.add(SortBuilders.fieldSort(sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// break; +// case JOIN_COLUMN: +// List fields = Arrays.asList(sortCriteria.getFieldName().split(":")); +// fields.forEach(field -> { +// sortBuilders.add(SortBuilders.fieldSort(sortCriteria.getFieldName()).order(SortOrder.fromString(sortCriteria.getOrderByType().name()))); +// }); +// break; +// } +// }); +// +// } +// searchSourceBuilder.query(boolQuery).from(criteria.getOffset()).fetchSource("id", null); +// if (criteria.getSize() != null && criteria.getSize() > 0) { +// searchSourceBuilder.size(criteria.getSize()); +// } +// sortBuilders.forEach(searchSourceBuilder::sort); +// searchRequest.source(searchSourceBuilder); +// SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); +// return Arrays.stream(response.getHits().getHits()).map(x -> new Dmp().fromElasticEntity((Map) this.transformFromString(x.getSourceAsString(), Map.class))).collect(Collectors.toList()); +// } return null; } @Override public Long count(DmpCriteria criteria) throws IOException { - if (this.getClient() != null) { - CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); - - BoolQueryBuilder boolQuery = createBoolQuery(criteria); - - countRequest.query(boolQuery); - CountResponse response = this.getClient().count(countRequest, RequestOptions.DEFAULT); - return response.getCount(); - } +// if (this.getClient() != null) { +// CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index")); +// +// BoolQueryBuilder boolQuery = createBoolQuery(criteria); +// +// countRequest.query(boolQuery); +// CountResponse response = this.getClient().count(countRequest, RequestOptions.DEFAULT); +// return response.getCount(); +// } return null; } @@ -198,11 +199,11 @@ public class DmpRepository extends ElasticRepository { public boolean createIndex() { try { - if (!this.exists()) { - CreateIndexRequest createIndexRequest = new CreateIndexRequest(this.environment.getProperty("elasticsearch.index")); - this.getClient().indices().create(createIndexRequest, RequestOptions.DEFAULT); - this.generateMapping(); - } +// if (!this.exists()) { +// CreateIndexRequest createIndexRequest = new CreateIndexRequest(this.environment.getProperty("elasticsearch.index")); +// this.getClient().indices().create(createIndexRequest, RequestOptions.DEFAULT); +// this.generateMapping(); +// } return true; } catch (Exception e) { logger.error(e.getMessage(), e); @@ -212,21 +213,21 @@ public class DmpRepository extends ElasticRepository { @Override public boolean exists() throws IOException { - if (this.getClient() != null) { - GetIndexRequest request = new GetIndexRequest(this.environment.getProperty("elasticsearch.index")); - return this.getClient().indices().exists(request, RequestOptions.DEFAULT); - } +// if (this.getClient() != null) { +// GetIndexRequest request = new GetIndexRequest(this.environment.getProperty("elasticsearch.index")); +// return this.getClient().indices().exists(request, RequestOptions.DEFAULT); +// } return false; } @Override public void clear() throws IOException { - if (exists()) { - DeleteByQueryRequest delete = new DeleteByQueryRequest(this.environment.getProperty("elasticsearch.index")); - delete.setQuery(QueryBuilders.matchAllQuery()); - this.getClient().deleteByQuery(delete, RequestOptions.DEFAULT); - DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(this.environment.getProperty("elasticsearch.index")); - this.getClient().indices().delete(deleteIndexRequest, RequestOptions.DEFAULT); - } +// if (exists()) { +// DeleteByQueryRequest delete = new DeleteByQueryRequest(this.environment.getProperty("elasticsearch.index")); +// delete.setQuery(QueryBuilders.matchAllQuery()); +// this.getClient().deleteByQuery(delete, RequestOptions.DEFAULT); +// DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(this.environment.getProperty("elasticsearch.index")); +// this.getClient().indices().delete(deleteIndexRequest, RequestOptions.DEFAULT); +// } } } diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java index 6f1ba9da8..9476138f5 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java @@ -1,5 +1,6 @@ package eu.eudat.elastic.repository; +import co.elastic.clients.elasticsearch.ElasticsearchClient; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.elastic.criteria.Criteria; import eu.eudat.elastic.entities.ElasticEntity; @@ -16,19 +17,19 @@ import java.io.IOException; */ public abstract class ElasticRepository implements Repository { private static final Logger logger = LoggerFactory.getLogger(ElasticRepository.class); - private RestHighLevelClient client; + private ElasticsearchClient client; - public RestHighLevelClient getClient() { + public ElasticsearchClient getClient() { return client; } - public ElasticRepository(RestHighLevelClient client, Environment environment) { + public ElasticRepository(ElasticsearchClient client, Environment environment) { try { - if (Boolean.FALSE.equals(environment.getProperty("elasticsearch.enabled", boolean.class))){ + if (!Boolean.TRUE.equals(environment.getProperty("elastic.enabled", boolean.class))){ logger.warn("Unable to connect to Elastic Services"); this.client = null; return; } - if (client.ping(RequestOptions.DEFAULT)) { + if (client.ping().value()) { this.client = client; } } catch (IOException e) { diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml index b02a37cf4..51ede467e 100644 --- a/dmp-backend/pom.xml +++ b/dmp-backend/pom.xml @@ -25,7 +25,7 @@ 1.19.0 1.19.0 0.2.0 - 17 + 21 0.0.1-SNAPSHOT @@ -34,8 +34,9 @@ 1.2.17 2.15.0 - 17 - 17 + 21 + 21 + 21 @@ -343,6 +344,11 @@ oidc-authz 2.1.0 + + gr.cite + elastic + 2.1.2 + diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index e09628fa6..ae7ec5673 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -229,8 +229,8 @@ maven-compiler-plugin 3.8.1 - 17 - 17 + 21 + 21 @@ -276,7 +276,8 @@ eu.eudat.EuDatApplication 4.0.1 - 17 - 17 + 21 + 21 + 21 \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java deleted file mode 100644 index 70690ff62..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java +++ /dev/null @@ -1,118 +0,0 @@ -package eu.eudat.configurations; - -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; -import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; -import org.apache.http.nio.reactor.IOReactorException; -import org.apache.http.nio.reactor.IOReactorExceptionHandler; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestHighLevelClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; - -/** - * Created by ikalyvas on 7/5/2018. - */ -@Configuration -public class ElasticSearchConfiguration { - private static final Logger logger = LoggerFactory.getLogger(ElasticSearchConfiguration.class); - - private Environment environment; - - @Autowired - public ElasticSearchConfiguration(Environment environment) { - this.environment = environment; - } - - @Bean(destroyMethod = "close") - public RestHighLevelClient client() throws Exception { - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, - new UsernamePasswordCredentials(this.environment.getProperty("elasticsearch.username"), this.environment.getProperty("elasticsearch.password"))); - - try { - DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(); - ioReactor.setExceptionHandler(new IOReactorExceptionHandler() { - @Override - public boolean handle(IOException e) { - logger.warn("System may be unstable: IOReactor encountered a checked exception : " + e.getMessage(), e); - return true; // Return true to note this exception as handled, it will not be re-thrown - } - - @Override - public boolean handle(RuntimeException e) { - logger.warn("System may be unstable: IOReactor encountered a runtime exception : " + e.getMessage(), e); - return true; // Return true to note this exception as handled, it will not be re-thrown - } - }); - - RestHighLevelClient client; - if(this.environment.getProperty("elasticsearch.usingssl", Boolean.class)){ - -// Path caCertificatePath = Paths.get(this.environment.getProperty("elasticsearch.certPath")); -// CertificateFactory factory = -// CertificateFactory.getInstance("X.509"); -// Certificate trustedCa; -// try (InputStream is = Files.newInputStream(caCertificatePath)) { -// trustedCa = factory.generateCertificate(is); -// } -// KeyStore trustStore = KeyStore.getInstance("pkcs12"); -// trustStore.load(null, null); -// trustStore.setCertificateEntry("ca", trustedCa); -// -// TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); -// tmf.init(trustStore); -// -// SSLContext sslContext = SSLContext.getInstance("TLS"); -// sslContext.init(null, tmf.getTrustManagers(), null); - - SSLContextBuilder sslBuilder = SSLContexts.custom() - .loadTrustMaterial(null, (x509Certificates, s) -> true); - final SSLContext sslContext = sslBuilder.build(); - client = new RestHighLevelClient( - RestClient.builder( - new HttpHost(this.environment.getProperty("elasticsearch.host"), - Integer.parseInt(this.environment.getProperty("elasticsearch.port")), "https")) - .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder - .setDefaultCredentialsProvider(credentialsProvider).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext)) - .setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(5000).setSocketTimeout(120000)) - ); - } - else { - client = new RestHighLevelClient( - RestClient.builder( - new HttpHost(this.environment.getProperty("elasticsearch.host"), - Integer.parseInt(this.environment.getProperty("elasticsearch.port")), "http")) - .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder - .setDefaultCredentialsProvider(credentialsProvider).setConnectionManager(new PoolingNHttpClientConnectionManager(ioReactor)))); - } - return client; - }catch (IOReactorException ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpBlueprintController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpBlueprintController.java index 912fb84c3..795f80426 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpBlueprintController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpBlueprintController.java @@ -12,6 +12,7 @@ import eu.eudat.model.result.QueryResult; import eu.eudat.query.*; import eu.eudat.query.lookup.DmpBlueprintLookup; import eu.eudat.service.dmpblueprint.DmpBlueprintService; +import eu.eudat.service.elastic.ElasticService; import gr.cite.tools.auditing.AuditService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.censor.CensorFactory; @@ -59,6 +60,8 @@ public class DmpBlueprintController { private final QueryFactory queryFactory; private final MessageSource messageSource; + + private final ElasticService elasticService; public DmpBlueprintController( BuilderFactory builderFactory, @@ -66,19 +69,29 @@ public class DmpBlueprintController { DmpBlueprintService dmpBlueprintService, CensorFactory censorFactory, QueryFactory queryFactory, - MessageSource messageSource) { + MessageSource messageSource, ElasticService elasticService) { this.builderFactory = builderFactory; this.auditService = auditService; this.dmpBlueprintService = dmpBlueprintService; this.censorFactory = censorFactory; this.queryFactory = queryFactory; this.messageSource = messageSource; + this.elasticService = elasticService; } @PostMapping("query") public QueryResult query(@RequestBody DmpBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException { logger.debug("querying {}", DmpBlueprint.class.getSimpleName()); + var a = elasticService.enabled(); + try { + var a1 = elasticService.existsDmpIndex(); + elasticService.ensureDmpIndex(); + elasticService.ensureDescriptionIndex(); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.censorFactory.censor(DmpBlueprintCensor.class).censor(lookup.getProject(), null); DmpBlueprintQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermissionOrMemberOrPublic); diff --git a/dmp-backend/web/src/main/resources/config/elasticsearch.yml b/dmp-backend/web/src/main/resources/config/elasticsearch.yml index 43312d25b..3b1f80b9f 100644 --- a/dmp-backend/web/src/main/resources/config/elasticsearch.yml +++ b/dmp-backend/web/src/main/resources/config/elasticsearch.yml @@ -1,10 +1,20 @@ -elasticsearch: - host: localhost - port: 9200 - username: elastic +elastic: + enabled: ${ELASTIC_ENABLED:} + hosts: + - ${ELASTIC_HOST:} + username: ${ELASTIC_USER:} password: ${ELASTIC_PASS:} - index: ${ELASTIC_INDEX:} - usingssl: false - certPath: ${ELASTIC_CERT_PATH:} - certKey: ${ELASTIC_CERT_KEY:} - innerHitsSize: 100 \ No newline at end of file + useSSL: ${ELASTIC_USE_SSL:} + socketTimeoutMillis: 30000 + connectTimeoutMillis: 30000 + defaultResultSize: 100 + defaultCollectAllResultSize: 1000 + defaultScrollSize: 100 + defaultScrollSeconds: 120 + defaultCompositeAggregationResultSize: 200000 + disableHostnameVerifier: false +app-elastic: + enabled: ${ELASTIC_ENABLED:} + dmpIndexName: ${ELASTIC_DMP_INDEX:} + descriptionIndexName: ${ELASTIC_DESCRIPTION_INDEX:} + enableIcuAnalysisPlugin: false \ No newline at end of file