From 30870c690f0057f489079467621aeb71a173ccdf Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Mon, 12 Feb 2024 18:00:50 +0200 Subject: [PATCH] Adding annotation entity on annotation service --- .../web/controllers/AnnotationController.java | 13 +++ .../src/main/resources/config/permissions.yml | 84 +------------- .../annotation/authorization/Permission.java | 25 +--- .../annotation/data/AnnotationEntity.java | 95 +++++++++++++++ .../gr/cite/annotation/model/Annotation.java | 82 +++++++++++++ .../model/builder/AnnotationBuilder.java | 59 ++++++++++ .../annotation/model/builder/BaseBuilder.java | 26 ++--- .../model/deleter/AnnotationDeleter.java | 76 ++++++++++++ .../model/persist/AnnotationPersist.java | 91 +++++++++++++++ .../UserTouchedIntegrationEventPersist.java | 2 +- .../annotation/query/AnnotationQuery.java | 109 ++++++++++++++++++ .../query/lookup/AnnotationLookup.java | 5 + .../service/annotation/AnnotationService.java | 20 ++++ .../annotation/AnnotationServiceImpl.java | 88 ++++++++++++++ 14 files changed, 661 insertions(+), 114 deletions(-) create mode 100644 annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/data/AnnotationEntity.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/model/Annotation.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/model/deleter/AnnotationDeleter.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/AnnotationPersist.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/query/lookup/AnnotationLookup.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java new file mode 100644 index 000000000..adbd3cdef --- /dev/null +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java @@ -0,0 +1,13 @@ +package gr.cite.annotation.web.controllers; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(path = "api/annotation", produces = MediaType.APPLICATION_JSON_VALUE) +public class AnnotationController { + + + +} diff --git a/annotation-service/annotation-web/src/main/resources/config/permissions.yml b/annotation-service/annotation-web/src/main/resources/config/permissions.yml index d7247f8d8..59115ee60 100644 --- a/annotation-service/annotation-web/src/main/resources/config/permissions.yml +++ b/annotation-service/annotation-web/src/main/resources/config/permissions.yml @@ -72,20 +72,20 @@ permissions: clients: [ ] allowAnonymous: false allowAuthenticated: false - #Notification - BrowseNotification: + #Annotation + BrowseAnnotation: roles: - Admin clients: [ ] allowAnonymous: true allowAuthenticated: false - EditNotification: + EditAnnotation: roles: - Admin clients: [ ] allowAnonymous: true allowAuthenticated: false - DeleteNotification: + DeleteAnnotation: roles: - Admin clients: [ ] @@ -104,79 +104,5 @@ permissions: clients: [ ] allowAnonymous: false allowAuthenticated: false - #User Notification Preference - BrowseUserNotificationPreference: - roles: - - ic-sti-superuser - clients: [ ] - allowAnonymous: true - allowAuthenticated: false - EditUserNotificationPreference: - roles: - - ic-sti-superuser - - user - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - # ViewPage Permissions - ViewNotificationPage: - roles: - - ic-sti-superuser - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - ViewNotificationEventRulePage: - roles: - - ic-sti-superuser - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - ViewInAppNotificationPage: - roles: - - ic-sti-superuser - - tenantadmin - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - ViewNotificationTemplatePage: - roles: - - ic-sti-superuser - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - - # Notification Template Permissions - BrowseNotificationTemplate: - roles: - - Admin - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - EditNotificationTemplate: - roles: - - Admin - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - DeleteNotificationTemplate: - roles: - - Admin - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - - # In App Notification Permissions - BrowseInAppNotification: - roles: - - Admin - - User - clients: [ ] - allowAnonymous: false - allowAuthenticated: false - DeleteInAppNotification: - roles: - - Admin - clients: [ ] - allowAnonymous: false - allowAuthenticated: false \ No newline at end of file + # ViewPage Permissions \ No newline at end of file diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/Permission.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/Permission.java index 00d6fec0e..b28aa042b 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/Permission.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/Permission.java @@ -17,32 +17,15 @@ public final class Permission { public static String DeleteTenant = "DeleteTenant"; public static String AllowNoTenant = "AllowNoTenant"; - //Notification - public static final String BrowseNotification = "BrowseNotification"; - public static String EditNotification = "EditNotification"; - public static String DeleteNotification = "DeleteNotification"; + //Annotation + public static final String BrowseAnnotation = "BrowseAnnotation"; + public static String EditAnnotation = "EditAnnotation"; + public static String DeleteAnnotation = "DeleteAnnotation"; public static final String BrowseTenantConfiguration = "BrowseTenantConfiguration"; public static final String EditTenantConfiguration = "EditTenantConfiguration"; - //Notification Preference - public static final String BrowseUserNotificationPreference = "BrowseUserNotificationPreference"; - public static final String EditUserNotificationPreference = "EditUserNotificationPreference"; - - //Notification Template - public static final String BrowseNotificationTemplate = "BrowseNotificationTemplate"; - public static String EditNotificationTemplate = "EditNotificationTemplate"; - public static String DeleteNotificationTemplate = "DeleteNotificationTemplate"; - - //InApp Notification - public static final String BrowseInAppNotification = "BrowseInAppNotification"; - public static String DeleteInAppNotification = "DeleteInAppNotification"; - // UI Pages public static String ViewTenantConfigurationPage = "ViewTenantConfigurationPage"; - public static String ViewNotificationPage = "ViewNotificationPage"; - public static String ViewNotificationEventRulePage = "ViewNotificationEventRulePage"; - public static String ViewInAppNotificationPage = "ViewInAppNotificationPage"; - public static String ViewNotificationTemplatePage = "ViewNotificationTemplatePage"; } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/AnnotationEntity.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/AnnotationEntity.java new file mode 100644 index 000000000..cfa45e409 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/AnnotationEntity.java @@ -0,0 +1,95 @@ +package gr.cite.annotation.data; + +import gr.cite.annotation.common.enums.IsActive; +import gr.cite.annotation.data.conventers.IsActiveConverter; +import jakarta.persistence.*; + +import java.time.Instant; +import java.util.UUID; + +@Entity +@Table(name = "\"Annotation\"") +public class AnnotationEntity { + + @Id + @Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false) + private UUID id; + + public static final String _id = "id"; + + @Id + @Column(name = "id", columnDefinition = "uuid", nullable = false) + private UUID entityId; + + public static final String _entityId = "entityId"; + + @Id + @Column(name = "payload", nullable = false) + private String payload; + + public static final String _payload = "payload"; + + @Column(name = "\"created_at\"", nullable = false) + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + @Column(name = "\"updated_at\"", nullable = false) + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getEntityId() { + return entityId; + } + + public void setEntityId(UUID entityId) { + this.entityId = entityId; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/Annotation.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/Annotation.java new file mode 100644 index 000000000..a440322b3 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/Annotation.java @@ -0,0 +1,82 @@ +package gr.cite.annotation.model; + +import gr.cite.annotation.common.enums.IsActive; + +import java.time.Instant; +import java.util.UUID; + +public class Annotation { + + private UUID id; + + public static final String _id = "id"; + + private UUID entityId; + + public static final String _entityId = "entityId"; + + private String payload; + + public static final String _payload = "payload"; + + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + private IsActive isActive; + + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getEntityId() { + return entityId; + } + + public void setEntityId(UUID entityId) { + this.entityId = entityId; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java new file mode 100644 index 000000000..e9de7df16 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java @@ -0,0 +1,59 @@ +package gr.cite.annotation.model.builder; + +import gr.cite.annotation.authorization.AuthorizationFlags; +import gr.cite.annotation.convention.ConventionService; +import gr.cite.annotation.data.AnnotationEntity; +import gr.cite.annotation.data.UserEntity; +import gr.cite.annotation.model.Annotation; +import gr.cite.annotation.model.User; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +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 AnnotationBuilder extends BaseBuilder{ + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + public AnnotationBuilder(ConventionService conventionService, LoggerService logger) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(AnnotationBuilder.class))); + } + + public AnnotationBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || fields.isEmpty()) return new ArrayList<>(); + + List models = new ArrayList<>(); + + if (data == null) + return models; + for (AnnotationEntity d : data) { + Annotation m = new Annotation(); + if (fields.hasField(this.asIndexer(Annotation._id))) m.setId(d.getId()); + if (fields.hasField(this.asIndexer(Annotation._entityId))) m.setEntityId(d.getEntityId()); + if (fields.hasField(this.asIndexer(Annotation._payload))) m.setPayload(d.getPayload()); + if (fields.hasField(this.asIndexer(Annotation._createdAt))) m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(Annotation._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); + if (fields.hasField(this.asIndexer(Annotation._isActive))) m.setIsActive(d.getIsActive()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java index 5987e6ca0..a4b24163c 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java @@ -35,34 +35,34 @@ public abstract class BaseBuilder implements Builder { return models.stream().findFirst().orElse(null); //TODO } - public abstract List build(FieldSet directives, List datas) throws MyApplicationException; + public abstract List build(FieldSet directives, List data) throws MyApplicationException; public Map asForeignKey(QueryBase query, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("Building references from query"); List datas = query.collectAs(directives); - this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(List::size).orElse(0)); return this.asForeignKey(datas, directives, keySelector); } - public Map asForeignKey(List datas, FieldSet directives, Function keySelector) throws MyApplicationException { + public Map asForeignKey(List data, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("building references"); - List models = this.build(directives, 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)); + List models = this.build(directives, data); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(List::size).orElse(0), Optional.ofNullable(data).map(List::size).orElse(0)); + Map map = models.stream().collect(Collectors.toMap(keySelector, o -> o)); return map; } public Map> asMasterKey(QueryBase query, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("Building details from query"); List datas = query.collectAs(directives); - this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(List::size).orElse(0)); return this.asMasterKey(datas, directives, keySelector); } - public Map> asMasterKey(List datas, FieldSet directives, Function keySelector) throws MyApplicationException { + public Map> asMasterKey(List data, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("building details"); - List models = this.build(directives, 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)); + List models = this.build(directives, data); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(List::size).orElse(0), Optional.ofNullable(data).map(List::size).orElse(0)); Map> map = new HashMap<>(); for (M model : models) { K key = keySelector.apply(model); @@ -74,9 +74,9 @@ public abstract class BaseBuilder implements Builder { 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)); + List models = keys.stream().map(mapper).collect(Collectors.toList()); + this.logger.debug("mapping {} build items from {} requested", Optional.of(models).map(List::size).orElse(0), Optional.of(keys).map(List::size)); + Map map = models.stream().collect(Collectors.toMap(keySelector, o -> o)); return map; } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/deleter/AnnotationDeleter.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/deleter/AnnotationDeleter.java new file mode 100644 index 000000000..b78014ab4 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/deleter/AnnotationDeleter.java @@ -0,0 +1,76 @@ +package gr.cite.annotation.model.deleter; + +import gr.cite.annotation.common.enums.IsActive; +import gr.cite.annotation.data.AnnotationEntity; +import gr.cite.annotation.data.TenantScopedEntityManager; +import gr.cite.annotation.data.UserCredentialEntity; +import gr.cite.annotation.query.AnnotationQuery; +import gr.cite.annotation.query.UserCredentialQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +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 javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class AnnotationDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserCredentialDeleter.class)); + + private final TenantScopedEntityManager entityManager; + + private final QueryFactory queryFactory; + + @Autowired + public AnnotationDeleter( + TenantScopedEntityManager entityManager, + QueryFactory queryFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(AnnotationQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + Instant now = Instant.now(); + + for (AnnotationEntity item : data) { + logger.trace("deleting item {}", item); + item.setIsActive(IsActive.Inactive); + item.setUpdatedAt(now); + logger.trace("updating item"); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/AnnotationPersist.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/AnnotationPersist.java new file mode 100644 index 000000000..38aec7930 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/AnnotationPersist.java @@ -0,0 +1,91 @@ +package gr.cite.annotation.model.persist; + +import gr.cite.annotation.common.validation.BaseValidator; +import gr.cite.annotation.convention.ConventionService; +import gr.cite.annotation.errorcode.ErrorThesaurusProperties; +import gr.cite.tools.validation.specification.Specification; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class AnnotationPersist { + + private UUID subjectId; + + public static final String _subjectId = "subjectId"; + + private UUID entityId; + + public static final String _entityId = "entityId"; + + private String payload; + + public static final String _payload = "payload"; + + public UUID getSubjectId() { + return subjectId; + } + + public void setSubjectId(UUID subjectId) { + this.subjectId = subjectId; + } + + public UUID getEntityId() { + return entityId; + } + + public void setEntityId(UUID entityId) { + this.entityId = entityId; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + @Component(AnnotationPersistValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class AnnotationPersistValidator extends BaseValidator { + + public static final String ValidatorName = "AnnotationIntegrationEventPersistValidator"; + + private final MessageSource messageSource; + + protected AnnotationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + super(conventionService, errors); + this.messageSource = messageSource; + } + + @Override + protected Class modelClass() { + return AnnotationPersist.class; + } + + @Override + protected List specifications(AnnotationPersist item) { + return Arrays.asList( + this.spec() + .iff(() -> !this.isNull(item.getSubjectId())) + .must(() -> this.isValidGuid(item.getSubjectId())) + .failOn(AnnotationPersist._subjectId).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationPersist._subjectId}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isNull(item.getEntityId())) + .must(() -> this.isValidGuid(item.getEntityId())) + .failOn(AnnotationPersist._entityId).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationPersist._entityId}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> this.isEmpty(item.getPayload())) + .failOn(AnnotationPersist._payload).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationPersist._payload}, LocaleContextHolder.getLocale())) + ); + } + } + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/UserTouchedIntegrationEventPersist.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/UserTouchedIntegrationEventPersist.java index 5a40c8329..da06b8cee 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/UserTouchedIntegrationEventPersist.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/persist/UserTouchedIntegrationEventPersist.java @@ -42,7 +42,7 @@ public class UserTouchedIntegrationEventPersist { this.name = name; } - @Component(UserTouchedIntegrationEventPersist.UserTouchedIntegrationEventPersistValidator.ValidatorName) + @Component(UserTouchedIntegrationEventPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class UserTouchedIntegrationEventPersistValidator extends BaseValidator { diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java new file mode 100644 index 000000000..37c29b2ce --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java @@ -0,0 +1,109 @@ +package gr.cite.annotation.query; + +import gr.cite.annotation.authorization.AuthorizationFlags; +import gr.cite.annotation.common.enums.IsActive; +import gr.cite.annotation.common.scope.user.UserScope; +import gr.cite.annotation.data.AnnotationEntity; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.Predicate; +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 AnnotationQuery extends QueryBase { + + private Collection ids; + + private Collection excludedIds; + + private Collection isActives; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + private final UserScope userScope; + + private final AuthorizationService authService; + + public AnnotationQuery(UserScope userScope, AuthorizationService authService) { + this.userScope = userScope; + this.authService = authService; + } + + public AnnotationQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public AnnotationQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public AnnotationQuery ids(Collection values) { + this.ids = values; + return this; + } + + public AnnotationQuery excludedIds(Collection values) { + this.excludedIds = values; + return this; + } + + public AnnotationQuery excludedIds(UUID value) { + this.excludedIds = List.of(value); + return this; + } + + public AnnotationQuery excludedIds(UUID... value) { + this.excludedIds = Arrays.asList(value); + return this; + } + + public AnnotationQuery isActive(IsActive value) { + this.isActives = List.of(value); + return this; + } + + public AnnotationQuery isActive(IsActive... value) { + this.isActives = Arrays.asList(value); + return this; + } + + public AnnotationQuery isActive(Collection values) { + this.isActives = values; + return this; + } + + @Override + protected Boolean isFalseQuery() { + return null; + } + + @Override + protected Class entityClass() { + return null; + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + return null; + } + + @Override + protected String fieldNameOf(FieldResolver item) { + return null; + } + + @Override + protected AnnotationEntity convert(Tuple tuple, Set columns) { + return null; + } +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/lookup/AnnotationLookup.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/lookup/AnnotationLookup.java new file mode 100644 index 000000000..cefb9611a --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/lookup/AnnotationLookup.java @@ -0,0 +1,5 @@ +package gr.cite.annotation.query.lookup; + +public class AnnotationLookup { + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java new file mode 100644 index 000000000..232d5f22e --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java @@ -0,0 +1,20 @@ +package gr.cite.annotation.service.annotation; + +import gr.cite.annotation.model.Annotation; +import gr.cite.annotation.model.persist.AnnotationPersist; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.FieldSet; + +import javax.management.InvalidApplicationException; +import java.util.UUID; + +public interface AnnotationService { + + Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException; + + void deleteAndSave(UUID id) throws InvalidApplicationException; + +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java new file mode 100644 index 000000000..9a2bcf6cc --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java @@ -0,0 +1,88 @@ +package gr.cite.annotation.service.annotation; + +import gr.cite.annotation.authorization.AuthorizationFlags; +import gr.cite.annotation.authorization.Permission; +import gr.cite.annotation.common.enums.IsActive; +import gr.cite.annotation.data.AnnotationEntity; +import gr.cite.annotation.model.Annotation; +import gr.cite.annotation.model.builder.AnnotationBuilder; +import gr.cite.annotation.model.deleter.AnnotationDeleter; +import gr.cite.annotation.model.persist.AnnotationPersist; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import jakarta.transaction.Transactional; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; + +@Service +public class AnnotationServiceImpl implements AnnotationService { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AnnotationServiceImpl.class)); + + private final AuthorizationService authorizationService; + + private final DeleterFactory deleterFactory; + + private final EntityManager entityManager; + + private final BuilderFactory builderFactory; + + public AnnotationServiceImpl( + AuthorizationService authorizationService, + DeleterFactory deleterFactory, + EntityManager entityManager, + BuilderFactory builderFactory) { + this.authorizationService = authorizationService; + this.deleterFactory = deleterFactory; + this.entityManager = entityManager; + this.builderFactory = builderFactory; + } + + @Override + @Transactional + public Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException { + logger.debug(new MapLogEntry("persisting user").And("model", model).And("fields", fields)); + + this.authorizationService.authorizeForce(Permission.EditAnnotation); + + AnnotationEntity data = new AnnotationEntity(); + data.setId(UUID.randomUUID()); + data.setEntityId(model.getEntityId()); + data.setPayload(model.getPayload()); + data.setCreatedAt(Instant.now()); + data.setUpdatedAt(Instant.now()); + data.setIsActive(IsActive.Active); + + this.entityManager.persist(data); + + this.entityManager.flush(); + + return this.builderFactory.builder(AnnotationBuilder.class).authorize(EnumSet.of(AuthorizationFlags.None)).build(BaseFieldSet.build(fields, Annotation._id), data); + } + + @Override + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug("deleting Annotation: {}", id); + + this.authorizationService.authorizeForce(Permission.DeleteAnnotation); + + this.deleterFactory.deleter(AnnotationDeleter.class).deleteAndSaveByIds(List.of(id)); + } + +}