Commit ad245dde authored by Diamantis Tziotzios's avatar Diamantis Tziotzios
Browse files

Merge branch 'Development' of...

Merge branch 'Development' of https://gitlab.eudat.eu/dmp/OpenAIRE-EUDAT-DMP-service-pilot into Development
parents b8b78f66 6e21ad12
......@@ -15,11 +15,11 @@ import java.util.stream.Collectors;
@NamedEntityGraphs({
@NamedEntityGraph(
name = "dataManagementPlanListingModel",
attributeNodes = {@NamedAttributeNode("organisations"), @NamedAttributeNode("researchers"), @NamedAttributeNode("associatedDmps"),
@NamedAttributeNode("grant"), @NamedAttributeNode(value = "users", subgraph = "users"), @NamedAttributeNode("creator"), @NamedAttributeNode("profile"), @NamedAttributeNode("dataset")},
subgraphs = {
attributeNodes = {
@NamedAttributeNode("grant"), @NamedAttributeNode("creator"), @NamedAttributeNode("profile")}/*,*/
/*subgraphs = {
@NamedSubgraph(name = "users", attributeNodes = {@NamedAttributeNode("user")}),
}
}*/
),
@NamedEntityGraph(
name = "fullyDetailed",
......
......@@ -34,6 +34,10 @@ public class ColumnOrderings {
ordering.fieldName(ordering.getFieldName().replace("|count|", "")).columnType(Ordering.ColumnType.COUNT);
else if (ordering.getFieldName().contains("|join|"))
ordering.fieldName(ordering.getFieldName().replace("|join|", "")).columnType(Ordering.ColumnType.JOIN_COLUMN);
else if (ordering.getFieldName().equals("asc"))
ordering.fieldName("label").orderByType(Ordering.OrderByType.ASC);
else if (ordering.getFieldName().equals("desc"))
ordering.fieldName("label").orderByType(Ordering.OrderByType.DESC);
return ordering;
}
}
......@@ -21,6 +21,9 @@ public class DatasetCriteria extends Criteria {
private List<Tag> tags;
private boolean isPublic;
private Short grantStatus;
private int offset;
private int size;
private List<SortCriteria> sortCriteria;
public String getLike() {
return like;
......@@ -117,4 +120,28 @@ public class DatasetCriteria extends Criteria {
public void setGrantStatus(Short grantStatus) {
this.grantStatus = grantStatus;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public List<SortCriteria> getSortCriteria() {
return sortCriteria;
}
public void setSortCriteria(List<SortCriteria> sortCriteria) {
this.sortCriteria = sortCriteria;
}
}
......@@ -9,11 +9,16 @@ public class DmpCriteria extends Criteria {
private List<UUID> templates;
private List<UUID> grants;
private List<UUID> collaborators;
private List<Integer> roles;
private List<UUID> organizations;
private boolean isPublic;
private List<UUID> groupIds;
private boolean allowAllVersions;
private Short grantStatus;
private int offset;
private Integer size;
private List<SortCriteria> sortCriteria;
public String getLike() {
return like;
......@@ -55,6 +60,14 @@ public class DmpCriteria extends Criteria {
this.collaborators = collaborators;
}
public List<Integer> getRoles() {
return roles;
}
public void setRoles(List<Integer> roles) {
this.roles = roles;
}
public List<UUID> getOrganizations() {
return organizations;
}
......@@ -94,4 +107,28 @@ public class DmpCriteria extends Criteria {
public void setGrantStatus(Short grantStatus) {
this.grantStatus = grantStatus;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public List<SortCriteria> getSortCriteria() {
return sortCriteria;
}
public void setSortCriteria(List<SortCriteria> sortCriteria) {
this.sortCriteria = sortCriteria;
}
}
package eu.eudat.elastic.criteria;
public class SortCriteria {
public enum OrderByType {
ASC, DESC
}
public enum ColumnType {
COUNT, COLUMN, JOIN_COLUMN
}
private String fieldName;
private OrderByType orderByType;
private ColumnType columnType;
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public OrderByType getOrderByType() {
return orderByType;
}
public void setOrderByType(OrderByType orderByType) {
this.orderByType = orderByType;
}
public ColumnType getColumnType() {
return columnType;
}
public void setColumnType(ColumnType columnType) {
this.columnType = columnType;
}
}
......@@ -4,11 +4,11 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
public class Collaborator implements ElasticEntity<Collaborator> {
private String id;
private String name;
private int role;
public String getId() {
return id;
......@@ -26,11 +26,20 @@ public class Collaborator implements ElasticEntity<Collaborator> {
this.name = name;
}
public int getRole() {
return role;
}
public void setRole(int role) {
this.role = role;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
builder.field("id", this.id);
builder.field("name", this.name);
builder.field("role", this.role);
builder.endObject();
return builder;
}
......@@ -39,6 +48,7 @@ public class Collaborator implements ElasticEntity<Collaborator> {
public Collaborator fromElasticEntity(Map fields) {
this.id = (String) fields.get("id");
this.name = (String) fields.get("name");
this.role = (int) fields.get("role");
return this;
}
}
......@@ -5,6 +5,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
......@@ -59,6 +60,9 @@ public class Dataset implements ElasticEntity<Dataset> {
private Boolean isPublic;
private Short grantStatus;
private String formData;
private Date created;
private Date modified;
private Date finalizedAt;
public String getId() {
return id;
......@@ -188,6 +192,30 @@ public class Dataset implements ElasticEntity<Dataset> {
this.formData = formData;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getFinalizedAt() {
return finalizedAt;
}
public void setFinalizedAt(Date finalizedAt) {
this.finalizedAt = finalizedAt;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
......@@ -197,6 +225,9 @@ public class Dataset implements ElasticEntity<Dataset> {
builder.field("template", this.template.toString());
builder.field("status", this.status.toString());
builder.field("dmp", this.dmp.toString());
builder.field("created", this.created);
builder.field("modified", this.modified);
builder.field("finalizedAt", this.finalizedAt);
if (this.group != null) {
builder.field("group", this.group.toString());
}
......@@ -263,6 +294,12 @@ public class Dataset implements ElasticEntity<Dataset> {
this.dmp = UUID.fromString((String) fields.get("dmp"));
this.group = UUID.fromString((String) fields.get("group"));
this.grant = UUID.fromString((String) fields.get("grant"));
if (fields.get("created") != null)
this.created = Date.from(Instant.parse((String) fields.get("created")));
if (fields.get("modified") != null)
this.modified = Date.from(Instant.parse((String) fields.get("modified")));
if (fields.get("finalizedAt") != null)
this.finalizedAt = Date.from(Instant.parse((String) fields.get("finalizedAt")));
if (fields.get("collaborators") != null) {
this.collaborators = ((List<HashMap>) fields.get("collaborators")).stream().map(hashMap -> new Collaborator().fromElasticEntity(hashMap)).collect(Collectors.toList());
}
......
......@@ -5,10 +5,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
public class Dmp implements ElasticEntity<Dmp> {
......@@ -55,6 +52,11 @@ public class Dmp implements ElasticEntity<Dmp> {
private List<Dataset> datasets;
private UUID grant;
private Short grantStatus;
private Date created;
private Date modified;
private Date finalizedAt;
private Date publishedAt;
private String doi;
public UUID getId() {
return id;
......@@ -168,6 +170,46 @@ public class Dmp implements ElasticEntity<Dmp> {
this.grantStatus = grantStatus;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getFinalizedAt() {
return finalizedAt;
}
public void setFinalizedAt(Date finalizedAt) {
this.finalizedAt = finalizedAt;
}
public Date getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(Date publishedAt) {
this.publishedAt = publishedAt;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
......@@ -233,6 +275,11 @@ public class Dmp implements ElasticEntity<Dmp> {
builder.field(MapKey.GRANT.getName(), this.grant.toString());
}
builder.field(MapKey.GRANTSTATUS.getName(), this.grantStatus);
builder.field(MapKey.CREATED.getName(), this.created);
builder.field(MapKey.MODIFIED.getName(), this.modified);
builder.field(MapKey.FINALIZEDAT.getName(), this.finalizedAt);
builder.field(MapKey.PUBLISHEDAT.getName(), this.publishedAt);
builder.field(MapKey.DOI.getName(), this.doi);
builder.endObject();
return builder;
}
......@@ -282,7 +329,12 @@ public class Dmp implements ElasticEntity<Dmp> {
ISPUBLIC ("isPublic"),
DATASETS ("datasets"),
GRANT ("grant"),
GRANTSTATUS ("grantStatus");
GRANTSTATUS ("grantStatus"),
CREATED ("created"),
MODIFIED ("modified"),
FINALIZEDAT ("finalizedAt"),
PUBLISHEDAT ("publishedAt"),
DOI ("doi");
private final String name;
......
......@@ -24,6 +24,9 @@ import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilters;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
......@@ -120,6 +123,7 @@ public class DatasetRepository extends ElasticRepository<Dataset, DatasetCriteri
searchSourceBuilder.size(count.intValue());
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery("datasets.status", Stream.of(Dataset.Status.DELETED.getValue(), Dataset.Status.CANCELED.getValue()).collect(Collectors.toList())));
List<SortBuilder> sortBuilders = new ArrayList<>();
if (criteria.isPublic()) {
boolQuery = boolQuery.should(QueryBuilders.termQuery("datasets.public", "true"));
boolQuery = boolQuery.should(QueryBuilders.termQuery("datasets.status", Dataset.Status.FINALISED.getValue()));
......@@ -181,8 +185,26 @@ public class DatasetRepository extends ElasticRepository<Dataset, DatasetCriteri
boolQuery.minimumShouldMatch(boolQuery.should().size());
}
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<String> 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());
searchSourceBuilder.query(nestedQueryBuilder);
searchSourceBuilder.query(nestedQueryBuilder).from(criteria.getOffset()).size(criteria.getSize());
sortBuilders.forEach(searchSourceBuilder::sort);
searchRequest.source(searchSourceBuilder);
SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT);
return ((Stream<Dataset>)Arrays.stream(response.getHits().getHits())
......
......@@ -23,6 +23,9 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -97,6 +100,7 @@ public class DmpRepository extends ElasticRepository<Dmp, DmpCriteria> {
searchSourceBuilder.size(count.intValue());
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(Dmp.MapKey.STATUS.getName(), Collections.singletonList(Dmp.DMPStatus.DELETED.getValue())));
List<SortBuilder> sortBuilders = new ArrayList<>();
if (criteria.isPublic()) {
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.ISPUBLIC.getName(), true));
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.STATUS.getName(), Dmp.DMPStatus.FINALISED.getValue()));
......@@ -125,7 +129,11 @@ public class DmpRepository extends ElasticRepository<Dmp, DmpCriteria> {
}
if (criteria.getCollaborators() != null && criteria.getCollaborators().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.COLLABORATORS.getName() + ".keyword", criteria.getCollaborators().stream().map(UUID::toString).collect(Collectors.toList())));
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.COLLABORATORS.getName() + ".id.keyword", criteria.getCollaborators().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (criteria.getRoles() != null && criteria.getRoles().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.COLLABORATORS.getName() + ".role.keyword", criteria.getRoles()));
}
if (!criteria.isAllowAllVersions()) {
......@@ -145,7 +153,28 @@ public class DmpRepository extends ElasticRepository<Dmp, DmpCriteria> {
} else {
boolQuery.minimumShouldMatch(boolQuery.should().size());
}
searchSourceBuilder.query(boolQuery);
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<String> 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());
if (criteria.getSize() != null) {
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<String, Object>) this.transformFromString(x.getSourceAsString(), Map.class))).collect(Collectors.toList());
......@@ -153,6 +182,67 @@ public class DmpRepository extends ElasticRepository<Dmp, DmpCriteria> {
return null;
}
public Long count(DmpCriteria criteria) throws IOException {
if (this.getClient() != null) {
CountRequest countRequest = new CountRequest(this.environment.getProperty("elasticsearch.index"));
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().mustNot(QueryBuilders.termsQuery(Dmp.MapKey.STATUS.getName(), Collections.singletonList(Dmp.DMPStatus.DELETED.getValue())));
if (criteria.isPublic()) {
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.ISPUBLIC.getName(), true));
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.STATUS.getName(), Dmp.DMPStatus.FINALISED.getValue()));
}
if (criteria.getLike() != null && !criteria.getLike().isEmpty()) {
boolQuery = boolQuery.should(QueryBuilders.queryStringQuery(criteria.getLike()).fields(Stream.of(new Object[][]{
{Dmp.MapKey.LABEL.getName(), 1.0f},
{Dmp.MapKey.DESCRIPTION.getName(), 1.0f}
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Float) data[1]))));
}
if (criteria.getTemplates() != null && criteria.getTemplates().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.TEMPLATES.getName() + ".id.keyword", criteria.getTemplates().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (criteria.getStatus() != null) {
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.STATUS.getName(), criteria.getStatus().intValue()));
}
if (criteria.getGroupIds() != null && criteria.getGroupIds().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.GROUPID.getName(), criteria.getGroupIds().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (criteria.getGrants() != null && criteria.getGrants().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.GRANT.getName() + ".keyword", criteria.getGrants().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (criteria.getCollaborators() != null && criteria.getCollaborators().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.COLLABORATORS.getName() + ".id.keyword", criteria.getCollaborators().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (!criteria.isAllowAllVersions()) {
boolQuery = boolQuery.should(QueryBuilders.termQuery(criteria.isPublic() ? Dmp.MapKey.LASTPUBLICVERSION.getName() : Dmp.MapKey.LASTVERSION.getName(), true));
}
if (criteria.getOrganizations() != null && criteria.getOrganizations().size() > 0) {
boolQuery = boolQuery.should(QueryBuilders.termsQuery(Dmp.MapKey.ORGANIZATIONS.getName() + ".id.keyword", criteria.getOrganizations().stream().map(UUID::toString).collect(Collectors.toList())));
}
if (criteria.getGrantStatus() != null) {
boolQuery = boolQuery.should(QueryBuilders.termQuery(Dmp.MapKey.GRANTSTATUS.getName(), criteria.getGrantStatus()));
}
if (boolQuery.should().isEmpty() && boolQuery.mustNot().isEmpty()) {
boolQuery = boolQuery.should(QueryBuilders.matchAllQuery());
} else {
boolQuery.minimumShouldMatch(boolQuery.should().size());
}
countRequest.query(boolQuery);
CountResponse response = this.getClient().count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
}
return null;
}
public boolean createIndex() {
try {
if (!this.exists()) {
......
......@@ -243,7 +243,6 @@ public class DMPs extends BaseController {
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UUID>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(cloneId));
}
@Transactional
@RequestMapping(method = RequestMethod.DELETE, value = {"{id}"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> delete(@PathVariable UUID id, Principal principal) {
......@@ -260,7 +259,7 @@ public class DMPs extends BaseController {
if (files[0].getContentType().equals(APPLICATION_JSON.toString())) {