diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index fd4fa77dc..98b3b7b3d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -29,7 +29,19 @@ public class AuditableAction { public static final EventId DmpBlueprint_Delete = new EventId(3003, "DmpBlueprint_Delete"); public static final EventId User_Settings_Query = new EventId(4000, "User_Settings_Query"); + public static final EventId User_Settings_Lookup = new EventId(4001, "User_Settings_Lookup"); + public static final EventId User_Settings_Persist = new EventId(4002, "User_Settings_Persist"); + public static final EventId User_Settings_Delete = new EventId(4003, "User_Settings_Delete"); + + public static final EventId Dmp_Query = new EventId(5000, "Dmp_Query"); + + public static final EventId Dmp_Lookup = new EventId(5001, "Dmp_Lookup"); + + public static final EventId Dmp_Persist = new EventId(5002, "Dmp_Persist"); + + public static final EventId Dmp_Delete = new EventId(5003, "Dmp_Delete"); + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/Dmp.java b/dmp-backend/core/src/main/java/eu/eudat/model/Dmp.java index ffbd11a0c..b06e7ad92 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/Dmp.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/Dmp.java @@ -84,10 +84,10 @@ public class Dmp { public static final String _project = "project"; - public final static String _hash = "hash"; - private String hash; + public static final String _hash = "hash"; + public UUID getId() { return id; } 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 415d9d58e..1ed09a96d 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 @@ -28,11 +28,13 @@ public class DmpQuery extends QueryBase { private Collection ids; + private Collection excludedIds; + private Collection isActives; private Collection statuses; - private Collection excludedIds; + private Collection versions; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @@ -65,6 +67,21 @@ public class DmpQuery extends QueryBase { return this; } + public DmpQuery excludedIds(Collection values) { + this.excludedIds = values; + return this; + } + + public DmpQuery excludedIds(UUID value) { + this.excludedIds = List.of(value); + return this; + } + + public DmpQuery excludedIds(UUID... value) { + this.excludedIds = Arrays.asList(value); + return this; + } + public DmpQuery isActive(IsActive value) { this.isActives = List.of(value); return this; @@ -95,18 +112,18 @@ public class DmpQuery extends QueryBase { return this; } - public DmpQuery excludedIds(Collection values) { - this.excludedIds = values; + public DmpQuery versions(Integer value) { + this.versions = List.of(value); return this; } - public DmpQuery excludedIds(UUID value) { - this.excludedIds = List.of(value); + public DmpQuery versions(Integer... value) { + this.versions = Arrays.asList(value); return this; } - public DmpQuery excludedIds(UUID... value) { - this.excludedIds = Arrays.asList(value); + public DmpQuery versions(Collection values) { + this.versions = values; return this; } @@ -128,14 +145,19 @@ public class DmpQuery extends QueryBase { @Override protected Predicate applyFilters(QueryContext queryContext) { List predicates = new ArrayList<>(); + if (this.like != null && !this.like.isEmpty()) { + predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(DmpEntity._label), this.like)); + } if (this.ids != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)); for (UUID item : this.ids) inClause.value(item); predicates.add(inClause); - } - if (this.like != null && !this.like.isEmpty()) { - predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(DmpEntity._label), this.like)); + }if (this.excludedIds != null) { + CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)); + for (UUID item : this.excludedIds) + notInClause.value(item); + predicates.add(notInClause.not()); } if (this.isActives != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._isActive)); @@ -143,18 +165,17 @@ public class DmpQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } - if (this.statuses != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._status)); for (DmpStatus item : this.statuses) inClause.value(item); predicates.add(inClause); } - if (this.excludedIds != null) { - CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)); - for (UUID item : this.excludedIds) - notInClause.value(item); - predicates.add(notInClause.not()); + if (this.versions != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._version)); + for (Integer item : this.versions) + inClause.value(item); + predicates.add(inClause); } if (!predicates.isEmpty()) { Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java index 1c7ac7e03..80207fb37 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java @@ -13,13 +13,15 @@ public class DmpLookup extends Lookup { private String like; + private List ids; + + private List excludedIds; + private List isActive; private List statuses; - private List ids; - - private List excludedIds; + private List versions; public String getLike() { return like; @@ -29,22 +31,6 @@ public class DmpLookup extends Lookup { this.like = like; } - public List getIsActive() { - return isActive; - } - - public void setIsActive(List isActive) { - this.isActive = isActive; - } - - public List getStatuses() { - return statuses; - } - - public void setStatuses(List statuses) { - this.statuses = statuses; - } - public List getIds() { return ids; } @@ -61,13 +47,38 @@ public class DmpLookup extends Lookup { this.excludedIds = excludedIds; } + public List getIsActive() { + return isActive; + } + + public void setIsActive(List isActive) { + this.isActive = isActive; + } + + public List getStatuses() { + return statuses; + } + + public void setStatuses(List statuses) { + this.statuses = statuses; + } + + public List getVersions() { + return versions; + } + + public void setVersions(List versions) { + this.versions = versions; + } + public DmpQuery enrich(QueryFactory queryFactory) { DmpQuery query = queryFactory.query(DmpQuery.class); if (this.like != null) query.like(this.like); - if (this.isActive != null) query.isActive(this.isActive); - if (this.statuses != null) query.statuses(this.statuses); if (this.ids != null) query.ids(this.ids); if (this.excludedIds != null) query.excludedIds(this.excludedIds); + if (this.isActive != null) query.isActive(this.isActive); + if (this.statuses != null) query.statuses(this.statuses); + if (this.versions != null) query.versions(this.versions); this.enrichCommon(query); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java index fbe85ba14..e87548d39 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java @@ -1,7 +1,6 @@ package eu.eudat.service.dmp; import eu.eudat.model.Dmp; -import eu.eudat.model.persist.DescriptionTemplateTypePersist; import eu.eudat.model.persist.DmpPersist; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java new file mode 100644 index 000000000..f2d323e53 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java @@ -0,0 +1,127 @@ +package eu.eudat.controllers.v2; + +import eu.eudat.audit.AuditableAction; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.data.DmpEntity; +import eu.eudat.model.Dmp; +import eu.eudat.model.builder.DmpBuilder; +import eu.eudat.model.censorship.DmpCensor; +import eu.eudat.model.persist.DmpPersist; +import eu.eudat.model.result.QueryResult; +import eu.eudat.query.DmpQuery; +import eu.eudat.query.lookup.DmpLookup; +import eu.eudat.service.dmp.DmpService; +import gr.cite.tools.auditing.AuditService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import gr.cite.tools.validation.MyValidate; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import javax.management.InvalidApplicationException; +import java.util.*; + +@RestController +@RequestMapping(path = "api/dmp") +public class DmpController { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpController.class)); + + private final BuilderFactory builderFactory; + + private final AuditService auditService; + + private final DmpService dmpService; + + private final CensorFactory censorFactory; + + private final QueryFactory queryFactory; + + private final MessageSource messageSource; + + public DmpController( + BuilderFactory builderFactory, + AuditService auditService, + DmpService dmpService, + CensorFactory censorFactory, + QueryFactory queryFactory, + MessageSource messageSource) { + this.builderFactory = builderFactory; + this.auditService = auditService; + this.dmpService = dmpService; + this.censorFactory = censorFactory; + this.queryFactory = queryFactory; + this.messageSource = messageSource; + } + + @PostMapping("query") + public QueryResult Query(@RequestBody DmpLookup lookup) throws MyApplicationException, MyForbiddenException { + logger.debug("querying {}", Dmp.class.getSimpleName()); + + this.censorFactory.censor(DmpCensor.class).censor(lookup.getProject(), null); + + DmpQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + + List data = query.collectAs(lookup.getProject()); + List models = this.builderFactory.builder(DmpBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); + long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); + + this.auditService.track(AuditableAction.Dmp_Query, "lookup", lookup); + + return new QueryResult<>(models, count); + } + + @GetMapping("{id}") + public Dmp Get(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving" + Dmp.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + + this.censorFactory.censor(DmpCensor.class).censor(fieldSet, null); + + DmpQuery query = this.queryFactory.query(DmpQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).ids(id); + Dmp model = this.builderFactory.builder(DmpBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet)); + if (model == null) + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + this.auditService.track(AuditableAction.Dmp_Lookup, Map.ofEntries( + new AbstractMap.SimpleEntry("id", id), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + + return model; + } + + @PostMapping("persist") + @Transactional + public Dmp Persist(@MyValidate @RequestBody DmpPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("persisting" + Dmp.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + Dmp persisted = this.dmpService.persist(model, fieldSet); + + this.auditService.track(AuditableAction.Dmp_Persist, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + + return persisted; + } + + @DeleteMapping("{id}") + @Transactional + public void Delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving" + Dmp.class.getSimpleName()).And("id", id)); + + this.dmpService.deleteAndSave(id); + + this.auditService.track(AuditableAction.Dmp_Delete, "id", id); + } + +}