From b58401525630e973e31c5f21ecae1cd937814939 Mon Sep 17 00:00:00 2001 From: "CITE\\amentis" Date: Wed, 11 Sep 2024 15:41:41 +0300 Subject: [PATCH] add indicator events for maintenance --- .../org/opencdmp/audit/AuditableAction.java | 3 + .../indicator/IndicatorFieldBaseType.java | 49 ++++ .../outbox/OutboxIntegrationEvent.java | 6 + .../outbox/OutboxProperties.java | 51 ++-- .../outbox/OutboxRepositoryImpl.java | 12 + .../indicator/IndicatorElasticEvent.java | 83 +++++++ .../IndicatorElasticEventHandler.java | 8 + .../IndicatorElasticEventHandlerImpl.java | 42 ++++ .../outbox/indicator/IndicatorField.java | 219 ++++++++++++++++++ .../outbox/indicator/IndicatorMetadata.java | 96 ++++++++ .../outbox/indicator/IndicatorSchema.java | 73 ++++++ .../indicatoraccess/IndicatorAccessEvent.java | 29 +++ .../IndicatorAccessEventHandler.java | 10 + .../IndicatorAccessEventHandlerImpl.java | 41 ++++ .../indicatorpoint/IndicatorPointEvent.java | 131 +++++++++++ .../IndicatorPointEventHandler.java | 7 + .../IndicatorPointEventHandlerImpl.java | 41 ++++ .../service/maintenance/KpiConfiguration.java | 20 ++ .../service/maintenance/KpiProperties.java | 68 ++++++ .../maintenance/MaintenanceService.java | 6 + .../maintenance/MaintenanceServiceImpl.java | 127 +++++++++- .../controllers/MaintenanceController.java | 30 +++ .../src/main/resources/config/application.yml | 3 +- backend/web/src/main/resources/config/kpi.yml | 8 + .../web/src/main/resources/config/queue.yml | 3 + .../maintenance/maintenance.service.ts | 21 ++ .../maintenance-tasks.component.html | 6 + .../maintenance-tasks.component.ts | 97 ++++++++ frontend/src/assets/i18n/baq.json | 1 + frontend/src/assets/i18n/de.json | 1 + frontend/src/assets/i18n/en.json | 1 + frontend/src/assets/i18n/es.json | 1 + frontend/src/assets/i18n/gr.json | 1 + frontend/src/assets/i18n/hr.json | 1 + frontend/src/assets/i18n/pl.json | 1 + frontend/src/assets/i18n/pt.json | 1 + frontend/src/assets/i18n/sk.json | 1 + frontend/src/assets/i18n/sr.json | 1 + frontend/src/assets/i18n/tr.json | 1 + 39 files changed, 1277 insertions(+), 24 deletions(-) create mode 100644 backend/core/src/main/java/org/opencdmp/commons/types/indicator/IndicatorFieldBaseType.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEvent.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandler.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandlerImpl.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorField.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorMetadata.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorSchema.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEvent.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandler.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandlerImpl.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEvent.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandler.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandlerImpl.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/maintenance/KpiConfiguration.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/maintenance/KpiProperties.java create mode 100644 backend/web/src/main/resources/config/kpi.yml diff --git a/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java index 1fe8e1c5d..ac8f18db5 100644 --- a/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java +++ b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java @@ -171,6 +171,9 @@ public class AuditableAction { public static final EventId Maintenance_SendPrefillingSourceAccountingEntriesEvents = new EventId(230010, "Maintenance_SendPrefillingSourceAccountingEntriesEvents"); public static final EventId Maintenance_SendReferenceTypeAccountingEntriesEvents = new EventId(230011, "Maintenance_SendReferenceTypeAccountingEntriesEvents"); public static final EventId Maintenance_SendUserAccountingEntriesEvents = new EventId(230012, "Maintenance_SendUserAccountingEntriesEvents"); + public static final EventId Maintenance_SendIndicatorCreateEntryEvents = new EventId(230013, "Maintenance_SendIndicatorCreateEntryEvents"); + public static final EventId Maintenance_SendIndicatorAccessEntryEvents = new EventId(230014, "Maintenance_SendIndicatorAccessEntryEvents"); + public static final EventId Maintenance_SendIndicatorPointEntryEvents = new EventId(230015, "Maintenance_SendIndicatorPointEntryEvents"); public static final EventId Principal_Lookup = new EventId(240000, "Principal_Lookup"); diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/indicator/IndicatorFieldBaseType.java b/backend/core/src/main/java/org/opencdmp/commons/types/indicator/IndicatorFieldBaseType.java new file mode 100644 index 000000000..509893b1d --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/commons/types/indicator/IndicatorFieldBaseType.java @@ -0,0 +1,49 @@ +package org.opencdmp.commons.types.indicator; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.HashMap; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +public enum IndicatorFieldBaseType { + String("string"), + Keyword("keyword"), + Integer("integer"), + Double("double"), + Date("date"), + IntegerMap("integerMap"), + DoubleMap("doubleMap"), + IntegerArray("integerArray"), + DoubleArray("doubleArray"), + KeywordArray("keywordArray"), + ; + private static final Map values = new HashMap<>(); + + private final String mappedName; + + //For jackson parsing (used by MVC) + @JsonValue + public java.lang.String getMappedName() { + return mappedName; + } + + static { + for (IndicatorFieldBaseType e : values()) { + values.put(e.asString(), e); + } + } + + private IndicatorFieldBaseType(String mappedName) { + this.mappedName = mappedName; + } + + public String asString() { + return this.mappedName; + } + + public static IndicatorFieldBaseType fromString(String value) { + return values.getOrDefault(value, String); + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxIntegrationEvent.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxIntegrationEvent.java index 9b2208064..b79624315 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxIntegrationEvent.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxIntegrationEvent.java @@ -34,6 +34,12 @@ public class OutboxIntegrationEvent extends IntegrationEvent { public static final String GENERATE_FILE = "GENERATE_FILE"; + public static final String INDICATOR_POINT_ENTRY = "INDICATOR_POINT_ENTRY"; + + public static final String INDICATOR_ACCESS_ENTRY = "INDICATOR_ACCESS_ENTRY"; + + public static final String INDICATOR_ENTRY = "INDICATOR_ENTRY"; + private TrackedEvent event; public TrackedEvent getEvent() { diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxProperties.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxProperties.java index 53cc081de..51ea9500f 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxProperties.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxProperties.java @@ -36,23 +36,29 @@ public class OutboxProperties { private final String accountingEntryCreatedTopic; + private final String indicatorPointTopic; + + private final String indicatorTopic; + + private final String indicatorAccessTopic; + private final String generateFileTopic; public OutboxProperties(String exchange, int handleAckRetries, int handleNackRetries, int handleAckWaitInMilliSeconds, int handleNackWaitInMilliSeconds, - String tenantDefaultLocaleRemovalTopic, - String tenantDefaultLocaleTouchedTopic, - String tenantTouchTopic, - String tenantRemovalTopic, - String tenantReactivationTopic, - String tenantUserInviteTopic, - String userRemovalTopic, - String userTouchTopic, - String annotationEntitiesTouchTopic, - String annotationEntitiesRemovalTopic, - String notifyTopic, - String forgetMeCompletedTopic, - String whatYouKnowAboutMeCompletedTopic, - String accountingEntryCreatedTopic, String generateFileTopic + String tenantDefaultLocaleRemovalTopic, + String tenantDefaultLocaleTouchedTopic, + String tenantTouchTopic, + String tenantRemovalTopic, + String tenantReactivationTopic, + String tenantUserInviteTopic, + String userRemovalTopic, + String userTouchTopic, + String annotationEntitiesTouchTopic, + String annotationEntitiesRemovalTopic, + String notifyTopic, + String forgetMeCompletedTopic, + String whatYouKnowAboutMeCompletedTopic, + String accountingEntryCreatedTopic, String indicatorPointTopic, String indicatorTopic, String indicatorAccessTopic, String generateFileTopic ) { this.exchange = exchange; this.handleAckRetries = handleAckRetries; @@ -73,7 +79,10 @@ public class OutboxProperties { this.forgetMeCompletedTopic = forgetMeCompletedTopic; this.whatYouKnowAboutMeCompletedTopic = whatYouKnowAboutMeCompletedTopic; this.accountingEntryCreatedTopic = accountingEntryCreatedTopic; - this.generateFileTopic = generateFileTopic; + this.indicatorPointTopic = indicatorPointTopic; + this.indicatorTopic = indicatorTopic; + this.indicatorAccessTopic = indicatorAccessTopic; + this.generateFileTopic = generateFileTopic; } public String getExchange() { @@ -155,4 +164,16 @@ public class OutboxProperties { public String getGenerateFileTopic() { return this.generateFileTopic; } + + public String getIndicatorPointTopic() { + return indicatorPointTopic; + } + + public String getIndicatorTopic() { + return indicatorTopic; + } + + public String getIndicatorAccessTopic() { + return indicatorAccessTopic; + } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java index 3b8827ab7..e156ecb05 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java @@ -446,6 +446,18 @@ public class OutboxRepositoryImpl implements OutboxRepository { routingKey = this.outboxProperties.getTenantTouchTopic(); break; } + case OutboxIntegrationEvent.INDICATOR_POINT_ENTRY: { + routingKey = this.outboxProperties.getIndicatorPointTopic(); + break; + } + case OutboxIntegrationEvent.INDICATOR_ENTRY: { + routingKey = this.outboxProperties.getIndicatorTopic(); + break; + } + case OutboxIntegrationEvent.INDICATOR_ACCESS_ENTRY: { + routingKey = this.outboxProperties.getIndicatorAccessTopic(); + break; + } case OutboxIntegrationEvent.TENANT_USER_INVITE: { routingKey = this.outboxProperties.getTenantUserInviteTopic(); break; diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEvent.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEvent.java new file mode 100644 index 000000000..880d6ea2e --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEvent.java @@ -0,0 +1,83 @@ +package org.opencdmp.integrationevent.outbox.indicator; + +import gr.cite.tools.validation.ValidatorFactory; +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.opencdmp.integrationevent.TrackedEvent; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class IndicatorElasticEvent extends TrackedEvent { + + private UUID id; + + private IndicatorMetadata metadata; + + private IndicatorSchema schema; + public static final String _schema = "schema"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public IndicatorMetadata getMetadata() { + return metadata; + } + + public void setMetadata(IndicatorMetadata metadata) { + this.metadata = metadata; + } + + public IndicatorSchema getSchema() { + return schema; + } + + public void setSchema(IndicatorSchema schema) { + this.schema = schema; + } + + @Component(IndicatorElasticEventValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class IndicatorElasticEventValidator extends BaseValidator { + + public static final String ValidatorName = "IndicatorElasticEventValidator"; + + private final MessageSource messageSource; + + private final ValidatorFactory validatorFactory; + + protected IndicatorElasticEventValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + super(conventionService, errors); + this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + @Override + protected Class modelClass() { + return IndicatorElasticEvent.class; + } + + @Override + protected List specifications(IndicatorElasticEvent item) { + return Arrays.asList( + this.refSpec() + .iff(() -> !this.isNull(item.getSchema())) + .on(IndicatorElasticEvent._schema) + .over(item.getSchema()) + .using(() -> this.validatorFactory.validator(IndicatorSchema.IndicatorSchemaValidator.class)) + ); + } + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandler.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandler.java new file mode 100644 index 000000000..759d3b53f --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandler.java @@ -0,0 +1,8 @@ +package org.opencdmp.integrationevent.outbox.indicator; + + +public interface IndicatorElasticEventHandler { + + void handle(IndicatorElasticEvent event); + +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandlerImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandlerImpl.java new file mode 100644 index 000000000..6b8519f93 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorElasticEventHandlerImpl.java @@ -0,0 +1,42 @@ +package org.opencdmp.integrationevent.outbox.indicator; + +import gr.cite.tools.logging.LoggerService; +import org.opencdmp.integrationevent.outbox.OutboxIntegrationEvent; +import org.opencdmp.integrationevent.outbox.OutboxService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class IndicatorElasticEventHandlerImpl implements IndicatorElasticEventHandler { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(IndicatorElasticEventHandlerImpl.class)); + + private final OutboxService outboxService; + + private final ApplicationContext applicationContext; + + @Autowired + public IndicatorElasticEventHandlerImpl(OutboxService outboxService, ApplicationContext applicationContext) { + this.outboxService = outboxService; + this.applicationContext = applicationContext; + } + + + @Override + public void handle(IndicatorElasticEvent event) { + OutboxIntegrationEvent message = new OutboxIntegrationEvent(); + message.setMessageId(UUID.randomUUID()); + message.setType(OutboxIntegrationEvent.INDICATOR_ENTRY); + message.setEvent(event); + message.setTenantId(null); + + this.outboxService.publish(message); + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorField.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorField.java new file mode 100644 index 000000000..d631b907c --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorField.java @@ -0,0 +1,219 @@ +package org.opencdmp.integrationevent.outbox.indicator; + +import com.fasterxml.jackson.annotation.JsonProperty; +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.types.indicator.IndicatorFieldBaseType; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +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 IndicatorField { + + private UUID id; + + private String code; + + private String name; + + private String label; + + private String description; + + @JsonProperty(value="basetype") + private IndicatorFieldBaseType basetype; + public static final String _baseType = "basetype"; + + @JsonProperty(value="typesemantics") + private String typeSemantics; + + @JsonProperty("typeid") + private String typeId; + +// @JsonProperty("alt_labels") +// private List altLabels; +// +// @JsonProperty("alt_descriptions") +// private List altDescriptions; +// +// @JsonProperty("valuerange") +// private ValueRangePersist valueRange; + + @JsonProperty("subfieldof") + private String subfieldOf; + + @JsonProperty("valuefield") + private String valueField; + + @JsonProperty("useas") + private String useAs; + +// private List operations; +// +// private List validation; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + 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 IndicatorFieldBaseType getBasetype() { + return basetype; + } + + public void setBasetype(IndicatorFieldBaseType basetype) { + this.basetype = basetype; + } + + public String getTypeSemantics() { + return typeSemantics; + } + + public void setTypeSemantics(String typeSemantics) { + this.typeSemantics = typeSemantics; + } + + public String getTypeId() { + return typeId; + } + + public void setTypeId(String typeId) { + this.typeId = typeId; + } + +// public List getAltLabels() { +// return altLabels; +// } +// +// public void setAltLabels(List altLabels) { +// this.altLabels = altLabels; +// } +// +// public List getAltDescriptions() { +// return altDescriptions; +// } +// +// public void setAltDescriptions(List altDescriptions) { +// this.altDescriptions = altDescriptions; +// } +// +// public ValueRangePersist getValueRange() { +// return valueRange; +// } +// +// public void setValueRange(ValueRangePersist valueRange) { +// this.valueRange = valueRange; +// } + + public String getSubfieldOf() { + return subfieldOf; + } + + public void setSubfieldOf(String subfieldOf) { + this.subfieldOf = subfieldOf; + } + + public String getValueField() { + return valueField; + } + + public void setValueField(String valueField) { + this.valueField = valueField; + } + + public String getUseAs() { + return useAs; + } + + public void setUseAs(String useAs) { + this.useAs = useAs; + } + +// public List getOperations() { +// return operations; +// } +// +// public void setOperations(List operations) { +// this.operations = operations; +// } +// +// public List getValidation() { +// return validation; +// } +// +// public void setValidation(List validation) { +// this.validation = validation; +// } + + @Component(IndicatorFieldValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class IndicatorFieldValidator extends BaseValidator { + + public static final String ValidatorName = "IndicatorFieldValidator"; + + private final MessageSource messageSource; + + + protected IndicatorFieldValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + super(conventionService, errors); + this.messageSource = messageSource; + } + + @Override + protected Class modelClass() { + return IndicatorField.class; + } + + @Override + protected List specifications(IndicatorField item) { + return Arrays.asList( + this.spec() + .must(() -> !this.isNull(item.getBasetype())) + .failOn(IndicatorField._baseType).failWith(messageSource.getMessage("Validation_Required", new Object[]{IndicatorField._baseType}, LocaleContextHolder.getLocale())) + ); + } + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorMetadata.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorMetadata.java new file mode 100644 index 000000000..567c6a5d3 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorMetadata.java @@ -0,0 +1,96 @@ +package org.opencdmp.integrationevent.outbox.indicator; + +import java.time.Instant; + +public class IndicatorMetadata { + + private String label; + + private String description; + + private String url; + + private String code; + +// private List semanticLabels; +// +// private List altLabels; +// +// private List altDescriptions; + + private Instant date; + +// private List coverage; + + 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 String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + +// public List getSemanticLabels() { +// return semanticLabels; +// } +// +// public void setSemanticLabels(List semanticLabels) { +// this.semanticLabels = semanticLabels; +// } +// +// public List getAltLabels() { +// return altLabels; +// } +// +// public void setAltLabels(List altLabels) { +// this.altLabels = altLabels; +// } +// +// public List getAltDescriptions() { +// return altDescriptions; +// } +// +// public void setAltDescriptions(List altDescriptions) { +// this.altDescriptions = altDescriptions; +// } + + public Instant getDate() { + return date; + } + + public void setDate(Instant date) { + this.date = date; + } + +// public List getCoverage() { +// return coverage; +// } +// +// public void setCoverage(List coverage) { +// this.coverage = coverage; +// } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorSchema.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorSchema.java new file mode 100644 index 000000000..b079f333c --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicator/IndicatorSchema.java @@ -0,0 +1,73 @@ +package org.opencdmp.integrationevent.outbox.indicator; + + +import gr.cite.tools.validation.ValidatorFactory; +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class IndicatorSchema { + + private UUID id; + + private List fields; + public static final String _fields = "fields"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + @Component(IndicatorSchemaValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class IndicatorSchemaValidator extends BaseValidator { + + public static final String ValidatorName = "IndicatorSchemaValidator"; + + private final MessageSource messageSource; + + private final ValidatorFactory validatorFactory; + + protected IndicatorSchemaValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + super(conventionService, errors); + this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + @Override + protected Class modelClass() { + return IndicatorSchema.class; + } + + @Override + protected List specifications(IndicatorSchema item) { + return Arrays.asList( + this.navSpec() + .iff(() -> !this.isNull(item.getFields())) + .on(IndicatorSchema._fields) + .over(item.getFields()) + .using((itm) -> this.validatorFactory.validator(IndicatorField.IndicatorFieldValidator.class)) + ); + } + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEvent.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEvent.java new file mode 100644 index 000000000..0642e57cd --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEvent.java @@ -0,0 +1,29 @@ +package org.opencdmp.integrationevent.outbox.indicatoraccess; + +import org.opencdmp.integrationevent.TrackedEvent; + +import java.util.*; + +public class IndicatorAccessEvent extends TrackedEvent { + + private UUID userId; + public static final String _indicatorId= "indicatorId"; + + private UUID indicatorId; + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public UUID getIndicatorId() { + return indicatorId; + } + + public void setIndicatorId(UUID indicatorId) { + this.indicatorId = indicatorId; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandler.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandler.java new file mode 100644 index 000000000..14def2380 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandler.java @@ -0,0 +1,10 @@ +package org.opencdmp.integrationevent.outbox.indicatoraccess; + + +import java.util.UUID; + +public interface IndicatorAccessEventHandler { + + void handle(IndicatorAccessEvent event, UUID tenant); + +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandlerImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandlerImpl.java new file mode 100644 index 000000000..da2f09037 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatoraccess/IndicatorAccessEventHandlerImpl.java @@ -0,0 +1,41 @@ +package org.opencdmp.integrationevent.outbox.indicatoraccess; + +import gr.cite.tools.logging.LoggerService; +import org.opencdmp.integrationevent.outbox.OutboxIntegrationEvent; +import org.opencdmp.integrationevent.outbox.OutboxService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class IndicatorAccessEventHandlerImpl implements IndicatorAccessEventHandler { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(IndicatorAccessEventHandlerImpl.class)); + + private final OutboxService outboxService; + + private final ApplicationContext applicationContext; + + @Autowired + public IndicatorAccessEventHandlerImpl(OutboxService outboxService, ApplicationContext applicationContext) { + this.outboxService = outboxService; + this.applicationContext = applicationContext; + } + + @Override + public void handle(IndicatorAccessEvent event, UUID tenant) { + OutboxIntegrationEvent message = new OutboxIntegrationEvent(); + message.setMessageId(UUID.randomUUID()); + message.setType(OutboxIntegrationEvent.INDICATOR_ACCESS_ENTRY); + message.setEvent(event); + message.setTenantId(tenant); + + this.outboxService.publish(message); + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEvent.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEvent.java new file mode 100644 index 000000000..efac2e193 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEvent.java @@ -0,0 +1,131 @@ +package org.opencdmp.integrationevent.outbox.indicatorpoint; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import gr.cite.tools.validation.ValidatorFactory; +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.opencdmp.integrationevent.TrackedEvent; +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.*; + +public class IndicatorPointEvent extends TrackedEvent { + public IndicatorPointEvent() { + properties = new HashMap<>(); + } + + private UUID indicatorId; + public static final String _indicatorId= "indicatorId"; + + private Date timestamp; + + private String batchId; + + private String groupHash; + +// private DataGroupInfoPersist groupInfo; +// public static final String _groupInfo= "groupInfo"; + + private Date batchTimestamp; + + private Map properties; + + public UUID getIndicatorId() { + return indicatorId; + } + + public void setIndicatorId(UUID indicatorId) { + this.indicatorId = indicatorId; + } + + public Date getBatchTimestamp() { + return batchTimestamp; + } + + public void setBatchTimestamp(Date batchTimestamp) { + this.batchTimestamp = batchTimestamp; + } + + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getGroupHash() { + return groupHash; + } + + public void setGroupHash(String groupHash) { + this.groupHash = groupHash; + } + +// public DataGroupInfoPersist getGroupInfo() { +// return groupInfo; +// } +// +// public void setGroupInfo(DataGroupInfoPersist groupInfo) { +// this.groupInfo = groupInfo; +// } + + public Map getProperties() { + return properties; + } + + @JsonAnySetter + public void add(String property, Object value) { + properties.put(property, value); + } + + @Component(IndicatorPointEventValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class IndicatorPointEventValidator extends BaseValidator { + + public static final String ValidatorName = "IndicatorPointEventValidator"; + + private final MessageSource messageSource; + + private final ValidatorFactory validatorFactory; + + protected IndicatorPointEventValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + super(conventionService, errors); + this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + @Override + protected Class modelClass() { + return IndicatorPointEvent.class; + } + + @Override + protected List specifications(IndicatorPointEvent item) { + return Arrays.asList( + this.spec() + .must(() -> this.isValidGuid(item.getIndicatorId())) + .failOn(IndicatorPointEvent._indicatorId).failWith(messageSource.getMessage("Validation_Required", new Object[]{IndicatorPointEvent._indicatorId}, LocaleContextHolder.getLocale())) +// this.refSpec() +// .iff(() -> !this.isNull(item.getGroupInfo())) +// .on(QueueIndicatorPointEvent._groupInfo) +// .over(item.getGroupInfo()) +// .using(() -> this.validatorFactory.validator(DataGroupInfoPersist.DataGroupInfoPersistValidator.class)) + ); + } + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandler.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandler.java new file mode 100644 index 000000000..51f9b0a13 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandler.java @@ -0,0 +1,7 @@ +package org.opencdmp.integrationevent.outbox.indicatorpoint; + +public interface IndicatorPointEventHandler { + + void handle(IndicatorPointEvent event); + +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandlerImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandlerImpl.java new file mode 100644 index 000000000..055ac683b --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/indicatorpoint/IndicatorPointEventHandlerImpl.java @@ -0,0 +1,41 @@ +package org.opencdmp.integrationevent.outbox.indicatorpoint; + +import gr.cite.tools.logging.LoggerService; +import org.opencdmp.integrationevent.outbox.OutboxIntegrationEvent; +import org.opencdmp.integrationevent.outbox.OutboxService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class IndicatorPointEventHandlerImpl implements IndicatorPointEventHandler { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(IndicatorPointEventHandlerImpl.class)); + + private final OutboxService outboxService; + + private final ApplicationContext applicationContext; + + @Autowired + public IndicatorPointEventHandlerImpl(OutboxService outboxService, ApplicationContext applicationContext) { + this.outboxService = outboxService; + this.applicationContext = applicationContext; + } + + @Override + public void handle(IndicatorPointEvent event) { + OutboxIntegrationEvent message = new OutboxIntegrationEvent(); + message.setMessageId(UUID.randomUUID()); + message.setType(OutboxIntegrationEvent.INDICATOR_POINT_ENTRY); + message.setEvent(event); + message.setTenantId(null); + + this.outboxService.publish(message); + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiConfiguration.java b/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiConfiguration.java new file mode 100644 index 000000000..f2f424dd1 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiConfiguration.java @@ -0,0 +1,20 @@ +package org.opencdmp.service.maintenance; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(KpiProperties.class) +public class KpiConfiguration { + private final KpiProperties properties; + + @Autowired + public KpiConfiguration(KpiProperties properties) { + this.properties = properties; + } + + public KpiProperties getProperties() { + return this.properties; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiProperties.java b/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiProperties.java new file mode 100644 index 000000000..d796c766a --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/maintenance/KpiProperties.java @@ -0,0 +1,68 @@ +package org.opencdmp.service.maintenance; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.UUID; + +@ConfigurationProperties(prefix = "kpi.user-indicator") +public class KpiProperties { + private UUID id; + + private UUID user; + + private String label; + + private String description; + + private String url; + + private String code; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getUser() { + return user; + } + + public void setUser(UUID user) { + this.user = user; + } + + 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 String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceService.java b/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceService.java index c10f181db..d2805e265 100644 --- a/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceService.java +++ b/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceService.java @@ -29,4 +29,10 @@ public interface MaintenanceService { void sendUserAccountingEntriesEvents() throws InvalidApplicationException; + void sendIndicatorCreateEntryEvents() throws InvalidApplicationException; + + void sendIndicatorAccessEntryEvents() throws InvalidApplicationException; + + void sendIndicatorPointEntryEvents() throws InvalidApplicationException; + } diff --git a/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceServiceImpl.java index d82d24bb0..85b9588bf 100644 --- a/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/maintenance/MaintenanceServiceImpl.java @@ -2,17 +2,24 @@ package org.opencdmp.service.maintenance; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.validation.ValidatorFactory; import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.enums.UsageLimitTargetMetric; -import org.opencdmp.commons.enums.accounting.AccountingValueType; import org.opencdmp.commons.scope.tenant.TenantScope; +import org.opencdmp.commons.types.indicator.IndicatorFieldBaseType; import org.opencdmp.data.*; import org.opencdmp.integrationevent.outbox.accountingentrycreated.AccountingEntryCreatedIntegrationEventHandler; import org.opencdmp.integrationevent.outbox.annotationentityremoval.AnnotationEntityRemovalIntegrationEventHandler; import org.opencdmp.integrationevent.outbox.annotationentitytouch.AnnotationEntityTouchedIntegrationEventHandler; +import org.opencdmp.integrationevent.outbox.indicator.*; +import org.opencdmp.integrationevent.outbox.indicatoraccess.IndicatorAccessEvent; +import org.opencdmp.integrationevent.outbox.indicatoraccess.IndicatorAccessEventHandler; +import org.opencdmp.integrationevent.outbox.indicatorpoint.IndicatorPointEvent; +import org.opencdmp.integrationevent.outbox.indicatorpoint.IndicatorPointEventHandler; import org.opencdmp.integrationevent.outbox.tenantremoval.TenantRemovalIntegrationEventHandler; import org.opencdmp.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEvent; import org.opencdmp.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEventHandler; @@ -20,6 +27,7 @@ import org.opencdmp.integrationevent.outbox.userremoval.UserRemovalIntegrationEv import org.opencdmp.integrationevent.outbox.usertouched.UserTouchedIntegrationEventHandler; import org.opencdmp.model.DescriptionTemplateType; import org.opencdmp.model.Tenant; +import org.opencdmp.model.TenantUser; import org.opencdmp.model.description.Description; import org.opencdmp.model.descriptiontemplate.DescriptionTemplate; import org.opencdmp.model.plan.Plan; @@ -35,9 +43,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.ArrayList; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; @Service public class MaintenanceServiceImpl implements MaintenanceService { @@ -47,13 +56,9 @@ public class MaintenanceServiceImpl implements MaintenanceService { private final TenantEntityManager entityManager; private final AuthorizationService authorizationService; private final QueryFactory queryFactory; - private final UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler; - private final UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler; - private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler; - private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler; private final AnnotationEntityRemovalIntegrationEventHandler annotationEntityRemovalIntegrationEventHandler; private final AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler; @@ -61,12 +66,16 @@ public class MaintenanceServiceImpl implements MaintenanceService { private final TenantScope tenantScope; private final TenantEntityManager tenantEntityManager; private final AccountingProperties accountingProperties; - private final AccountingService accountingService; + private final KpiProperties kpiProperties; + private final IndicatorElasticEventHandler indicatorElasticEventHandler; + private final IndicatorAccessEventHandler indicatorAccessEventHandler; + private final IndicatorPointEventHandler indicatorPointEventHandler; + private final ValidatorFactory validatorFactory; public MaintenanceServiceImpl( TenantEntityManager entityManager, AuthorizationService authorizationService, - QueryFactory queryFactory, UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler, UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, AnnotationEntityRemovalIntegrationEventHandler annotationEntityRemovalIntegrationEventHandler, AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler, AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler, TenantScope tenantScope, TenantEntityManager tenantEntityManager, AccountingProperties accountingProperties, AccountingService accountingService) { + QueryFactory queryFactory, UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler, UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, AnnotationEntityRemovalIntegrationEventHandler annotationEntityRemovalIntegrationEventHandler, AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler, AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler, TenantScope tenantScope, TenantEntityManager tenantEntityManager, AccountingProperties accountingProperties, AccountingService accountingService, KpiProperties kpiProperties, IndicatorElasticEventHandler indicatorElasticEventHandler, IndicatorAccessEventHandler indicatorAccessEventHandler, IndicatorPointEventHandler indicatorPointEventHandler, ValidatorFactory validatorFactory) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.queryFactory = queryFactory; @@ -81,6 +90,11 @@ public class MaintenanceServiceImpl implements MaintenanceService { this.tenantEntityManager = tenantEntityManager; this.accountingProperties = accountingProperties; this.accountingService = accountingService; + this.kpiProperties = kpiProperties; + this.indicatorElasticEventHandler = indicatorElasticEventHandler; + this.indicatorAccessEventHandler = indicatorAccessEventHandler; + this.indicatorPointEventHandler = indicatorPointEventHandler; + this.validatorFactory = validatorFactory; } @@ -396,4 +410,101 @@ public class MaintenanceServiceImpl implements MaintenanceService { this.tenantEntityManager.reloadTenantFilters(); } } + + @Override + public void sendIndicatorCreateEntryEvents() throws InvalidApplicationException { + IndicatorElasticEvent event = new IndicatorElasticEvent(); + event.setId(this.kpiProperties.getId()); + IndicatorMetadata metadata = new IndicatorMetadata(); + metadata.setCode(this.kpiProperties.getCode()); + metadata.setLabel(this.kpiProperties.getLabel()); + metadata.setDescription(this.kpiProperties.getDescription()); + metadata.setUrl(this.kpiProperties.getUrl()); + metadata.setDate(Instant.now()); + + event.setMetadata(metadata); + + try { + this.tenantEntityManager.disableTenantFilters(); + List tenantUserEntities = this.queryFactory.query(TenantUserQuery.class).disableTracking().userIds(this.kpiProperties.getUser()).collectAs(new BaseFieldSet().ensure(TenantUser._tenant)); + List fields = new ArrayList<>(); + if (tenantUserEntities != null) { + List tenantEntities = this.queryFactory.query(TenantQuery.class).disableTracking().ids(tenantUserEntities.stream().map(TenantUserEntity::getTenantId).distinct().toList()).collect(); + if (tenantEntities != null) { + for (TenantEntity tenant: tenantEntities) { + IndicatorField field = new IndicatorField(); + field.setCode("tenant_code"); + field.setName("Tenant Code"); + field.setValueField(tenant.getCode()); + field.setBasetype(IndicatorFieldBaseType.String); + fields.add(field); + } + } + + } + IndicatorField field1 = new IndicatorField(); + field1.setCode("user_id"); + field1.setName("User Id"); + field1.setValueField(this.kpiProperties.getUser().toString()); + field1.setBasetype(IndicatorFieldBaseType.String); + fields.add(field1); + + IndicatorField field2 = new IndicatorField(); + field2.setCode("created_at"); + field2.setName("Created at"); + field2.setValueField(Instant.now().toString()); + field2.setBasetype(IndicatorFieldBaseType.Date); + fields.add(field2); + + UserEntity user = this.queryFactory.query(UserQuery.class).disableTracking().ids(this.kpiProperties.getUser()).firstAs(new BaseFieldSet().ensure(User._name)); + if (user == null) { + throw new MyApplicationException("user not found"); + } + IndicatorField field3 = new IndicatorField(); + field3.setCode("user_name"); + field3.setName("User Name"); + field3.setValueField(user.getName()); + field3.setBasetype(IndicatorFieldBaseType.String); + fields.add(field3); + + IndicatorSchema schema = new IndicatorSchema(); + schema.setId(this.kpiProperties.getId()); + schema.setFields(fields); + + event.setSchema(schema); + + this.validatorFactory.validator(IndicatorElasticEvent.IndicatorElasticEventValidator.class).validateForce(event); + this.indicatorElasticEventHandler.handle(event); + } finally { + this.tenantEntityManager.reloadTenantFilters(); + } + } + + @Override + public void sendIndicatorAccessEntryEvents() throws InvalidApplicationException { + IndicatorAccessEvent event = new IndicatorAccessEvent(); + event.setIndicatorId(this.kpiProperties.getId()); + event.setUserId(this.kpiProperties.getUser()); + + try { + this.tenantEntityManager.disableTenantFilters(); + List tenantUserEntities = this.queryFactory.query(TenantUserQuery.class).disableTracking().userIds(this.kpiProperties.getUser()).collectAs(new BaseFieldSet().ensure(TenantUser._tenant)); + if (tenantUserEntities != null) { + for (TenantUserEntity user: tenantUserEntities) { + this.indicatorAccessEventHandler.handle(event, user.getTenantId()); + } + } + } finally { + this.tenantEntityManager.reloadTenantFilters(); + } + } + + @Override + public void sendIndicatorPointEntryEvents() throws InvalidApplicationException { + IndicatorPointEvent event = new IndicatorPointEvent(); + event.setIndicatorId(this.kpiProperties.getId()); + + this.validatorFactory.validator(IndicatorPointEvent.IndicatorPointEventValidator.class).validateForce(event); + this.indicatorPointEventHandler.handle(event); + } } diff --git a/backend/web/src/main/java/org/opencdmp/controllers/MaintenanceController.java b/backend/web/src/main/java/org/opencdmp/controllers/MaintenanceController.java index 519577ce8..7bd21a0e2 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/MaintenanceController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/MaintenanceController.java @@ -181,4 +181,34 @@ public class MaintenanceController { this.auditService.track(AuditableAction.Maintenance_SendUserAccountingEntriesEvents); } + + @RequestMapping(method = RequestMethod.POST, value = "/events/indicator-entry") + public void sendIndicatorCreateEvents() throws InvalidApplicationException { + logger.debug("send indicator create entry queue events"); + this.authorizationService.authorizeForce(Permission.ManageQueueEvents); + + this.maintenanceService.sendIndicatorCreateEntryEvents(); + + this.auditService.track(AuditableAction.Maintenance_SendIndicatorCreateEntryEvents); + } + + @RequestMapping(method = RequestMethod.POST, value = "/events/indicator-access-entry") + public void sendIndicatorAccessEvents() throws InvalidApplicationException { + logger.debug("send indicator create entry queue events"); + this.authorizationService.authorizeForce(Permission.ManageQueueEvents); + + this.maintenanceService.sendIndicatorAccessEntryEvents(); + + this.auditService.track(AuditableAction.Maintenance_SendIndicatorAccessEntryEvents); + } + + @RequestMapping(method = RequestMethod.POST, value = "/events/indicator-point-entry") + public void sendIndicatorPointEvents() throws InvalidApplicationException { + logger.debug("send indicator point entry queue events"); + this.authorizationService.authorizeForce(Permission.ManageQueueEvents); + + this.maintenanceService.sendIndicatorPointEntryEvents(); + + this.auditService.track(AuditableAction.Maintenance_SendIndicatorPointEntryEvents); + } } diff --git a/backend/web/src/main/resources/config/application.yml b/backend/web/src/main/resources/config/application.yml index ee9a88e38..89759d1b5 100644 --- a/backend/web/src/main/resources/config/application.yml +++ b/backend/web/src/main/resources/config/application.yml @@ -34,7 +34,8 @@ spring: optional:classpath:config/field-set-expander.yml[.yml], optional:classpath:config/field-set-expander-${spring.profiles.active}.yml[.yml], optional:file:../config/field-set-expander-${spring.profiles.active}.yml[.yml], optional:classpath:config/lock.yml[.yml], optional:classpath:config/lock-${spring.profiles.active}.yml[.yml], optional:file:../config/lock-${spring.profiles.active}.yml[.yml], optional:classpath:config/usage-limits.yml[.yml], optional:classpath:config/usage-limits-${spring.profiles.active}.yml[.yml], optional:file:../config/usage-limits-${spring.profiles.active}.yml[.yml], - optional:classpath:config/accounting.yml[.yml], optional:classpath:config/accounting-${spring.profiles.active}.yml[.yml], optional:file:../config/accounting-${spring.profiles.active}.yml[.yml] + optional:classpath:config/accounting.yml[.yml], optional:classpath:config/accounting-${spring.profiles.active}.yml[.yml], optional:file:../config/accounting-${spring.profiles.active}.yml[.yml], + optional:classpath:config/kpi.yml[.yml], optional:classpath:config/kpi-${spring.profiles.active}.yml[.yml], optional:file:../config/kpi-${spring.profiles.active}.yml[.yml] diff --git a/backend/web/src/main/resources/config/kpi.yml b/backend/web/src/main/resources/config/kpi.yml new file mode 100644 index 000000000..bf86ecba7 --- /dev/null +++ b/backend/web/src/main/resources/config/kpi.yml @@ -0,0 +1,8 @@ +kpi: + user-indicator: + id: 97c2d685-d7d2-4bd1-a287-ba329ad45d74 + user: 8552f758-f196-4a51-a3fd-154c088d85c4 + label: test + description: test + url: url test + code: test \ No newline at end of file diff --git a/backend/web/src/main/resources/config/queue.yml b/backend/web/src/main/resources/config/queue.yml index 3ff558a99..19b7f00dd 100644 --- a/backend/web/src/main/resources/config/queue.yml +++ b/backend/web/src/main/resources/config/queue.yml @@ -43,6 +43,9 @@ queue: annotation-entities-removal-topic: annotation.entities.remove what-you-know-about-me-completed-topic: whatyouknowaboutme.completed accounting-entry-created-topic: accountingentry.create + indicator-topic: indicator.entry + indicator-point-topic: indicator_point.entry + indicator-access-topic: indicator_access.entry generate-file-topic: generate.file rabbitmq: enable: true diff --git a/frontend/src/app/core/services/maintenance/maintenance.service.ts b/frontend/src/app/core/services/maintenance/maintenance.service.ts index 7cf0ea0b0..d1145d24b 100644 --- a/frontend/src/app/core/services/maintenance/maintenance.service.ts +++ b/frontend/src/app/core/services/maintenance/maintenance.service.ts @@ -113,4 +113,25 @@ export class MaintenanceService extends BaseService { .post(url, null).pipe( catchError((error: any) => throwError(error))); } + + sendIndicatorCreateEvents(): Observable { + const url = `${this.apiBase}/events/indicator-entry`; + return this.http + .post(url, null).pipe( + catchError((error: any) => throwError(error))); + } + + sendIndicatorAccessEvents(): Observable { + const url = `${this.apiBase}/events/indicator-access-entry`; + return this.http + .post(url, null).pipe( + catchError((error: any) => throwError(error))); + } + + sendIndicatorPointEvents(): Observable { + const url = `${this.apiBase}/events/indicator-point-entry`; + return this.http + .post(url, null).pipe( + catchError((error: any) => throwError(error))); + } } diff --git a/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html b/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html index dc43708f1..09eb6cae3 100644 --- a/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html +++ b/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html @@ -48,6 +48,12 @@ +
+

{{language.instant('MAINTENANCE-TASKS.SECTIONS.EVENTS.INDICATOR-TITLE')}}

+ + + +
diff --git a/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts b/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts index 230c423e9..518e77759 100644 --- a/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts +++ b/frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts @@ -465,6 +465,103 @@ export class MaintenanceTasksComponent extends BaseComponent implements OnInit { ); } + sendIndicatorCreateEvents(ev: Event) { + this.dialog.open(ConfirmationDialogComponent, { + data: { + message: this.language.instant('MAINTENANCE-TASKS.CONFIRMATION.MESSAGE'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + }, + maxWidth: '30em' + }) + .afterClosed() + .subscribe(confirm => { + if (confirm) { + this.doSendIndicatorCreateEvents(ev); + } + }); + } + + private doSendIndicatorCreateEvents(ev: Event) { + (ev.target as HTMLButtonElement).disabled = true; + this.maintenanceService.sendIndicatorCreateEvents().pipe(takeUntil(this._destroyed)).subscribe( + _ => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackSuccess(); + }, + error => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackError(error); + } + ); + } + + sendIndicatorAccessEvents(ev: Event) { + this.dialog.open(ConfirmationDialogComponent, { + data: { + message: this.language.instant('MAINTENANCE-TASKS.CONFIRMATION.MESSAGE'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + }, + maxWidth: '30em' + }) + .afterClosed() + .subscribe(confirm => { + if (confirm) { + this.doSendIndicatorAccessEvents(ev); + } + }); + } + + + + private doSendIndicatorAccessEvents(ev: Event) { + (ev.target as HTMLButtonElement).disabled = true; + this.maintenanceService.sendIndicatorAccessEvents().pipe(takeUntil(this._destroyed)).subscribe( + _ => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackSuccess(); + }, + error => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackError(error); + } + ); + } + + sendIndicatorPointEvents(ev: Event) { + this.dialog.open(ConfirmationDialogComponent, { + data: { + message: this.language.instant('MAINTENANCE-TASKS.CONFIRMATION.MESSAGE'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + }, + maxWidth: '30em' + }) + .afterClosed() + .subscribe(confirm => { + if (confirm) { + this.doSendIndicatorPointEvents(ev); + } + }); + } + + + + private doSendIndicatorPointEvents(ev: Event) { + (ev.target as HTMLButtonElement).disabled = true; + this.maintenanceService.sendIndicatorPointEvents().pipe(takeUntil(this._destroyed)).subscribe( + _ => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackSuccess(); + }, + error => { + (ev.target as HTMLButtonElement).disabled = false; + this.onCallbackError(error); + } + ); + } + onCallbackSuccess(): void { this.uiNotificationService.snackBarNotification(this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); this.router.navigate(['/reload']).then(() => this.router.navigate([this.routerUtils.generateUrl('/maintenance-tasks')])); diff --git a/frontend/src/assets/i18n/baq.json b/frontend/src/assets/i18n/baq.json index 42d529741..57ec6187c 100644 --- a/frontend/src/assets/i18n/baq.json +++ b/frontend/src/assets/i18n/baq.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/de.json b/frontend/src/assets/i18n/de.json index 12ea4e12c..b4f758086 100644 --- a/frontend/src/assets/i18n/de.json +++ b/frontend/src/assets/i18n/de.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json index f0d909d18..25a1be27e 100644 --- a/frontend/src/assets/i18n/en.json +++ b/frontend/src/assets/i18n/en.json @@ -422,6 +422,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/es.json b/frontend/src/assets/i18n/es.json index 0a79f99d5..c4de95b82 100644 --- a/frontend/src/assets/i18n/es.json +++ b/frontend/src/assets/i18n/es.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/gr.json b/frontend/src/assets/i18n/gr.json index 64dc6286c..67b9a4d08 100644 --- a/frontend/src/assets/i18n/gr.json +++ b/frontend/src/assets/i18n/gr.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/hr.json b/frontend/src/assets/i18n/hr.json index 48fe6ac61..2e990f14f 100644 --- a/frontend/src/assets/i18n/hr.json +++ b/frontend/src/assets/i18n/hr.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/pl.json b/frontend/src/assets/i18n/pl.json index 5a2040ad6..42e986ec3 100644 --- a/frontend/src/assets/i18n/pl.json +++ b/frontend/src/assets/i18n/pl.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/pt.json b/frontend/src/assets/i18n/pt.json index 3991da27a..b79f387fc 100644 --- a/frontend/src/assets/i18n/pt.json +++ b/frontend/src/assets/i18n/pt.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/sk.json b/frontend/src/assets/i18n/sk.json index abc3e9eaf..feb090656 100644 --- a/frontend/src/assets/i18n/sk.json +++ b/frontend/src/assets/i18n/sk.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/sr.json b/frontend/src/assets/i18n/sr.json index 8483eda0b..da107d87d 100644 --- a/frontend/src/assets/i18n/sr.json +++ b/frontend/src/assets/i18n/sr.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } } diff --git a/frontend/src/assets/i18n/tr.json b/frontend/src/assets/i18n/tr.json index 0f96a683f..645e5de73 100644 --- a/frontend/src/assets/i18n/tr.json +++ b/frontend/src/assets/i18n/tr.json @@ -424,6 +424,7 @@ "SEND-REFERENCE-TYPE-ACCOUNTING-ENTRIES": "Send reference type accounting entries events", "SEND-USER-ACCOUNTING-ENTRIES": "Send user accounting entries events", "SEND-INDICATOR-CREATE-ENTRY": "Send indicator create entry events", + "SEND-INDICATOR-ACCESS-ENTRY": "Send indicator access entry events", "SEND-INDICATOR-POINT-ENTRY": "Send indicator point entry events" } }