add accounting entry created event

This commit is contained in:
amentis 2024-07-16 14:23:45 +03:00
parent 508ae03468
commit 6bfc186297
17 changed files with 330 additions and 24 deletions

View File

@ -0,0 +1,33 @@
package org.opencdmp.commons.enums.accounting;
import com.fasterxml.jackson.annotation.JsonValue;
import org.opencdmp.commons.enums.EnumUtils;
import org.opencdmp.data.converters.enums.DatabaseEnum;
import java.util.Map;
public enum AccountingMeasureType implements DatabaseEnum<Short> {
Time((short) 0),
Information((short) 1),
Throughput((short) 2),
Unit((short) 3);
private final Short value;
AccountingMeasureType(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, AccountingMeasureType> map = EnumUtils.getEnumValueMap(AccountingMeasureType.class);
public static AccountingMeasureType of(Short i) {
return map.get(i);
}
}

View File

@ -0,0 +1,32 @@
package org.opencdmp.commons.enums.accounting;
import com.fasterxml.jackson.annotation.JsonValue;
import org.opencdmp.commons.enums.EnumUtils;
import org.opencdmp.data.converters.enums.DatabaseEnum;
import java.util.Map;
public enum AccountingValueType implements DatabaseEnum<Short> {
Plus((short) 0),
Minus((short) 1),
Reset((short) 3);
private final Short value;
AccountingValueType(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, AccountingValueType> map = EnumUtils.getEnumValueMap(AccountingValueType.class);
public static AccountingValueType of(Short i) {
return map.get(i);
}
}

View File

@ -30,6 +30,8 @@ public class OutboxIntegrationEvent extends IntegrationEvent {
public static final String WHAT_YOU_KNOW_ABOUT_ME_COMPLETED = "WHAT_YOU_KNOW_ABOUT_ME_COMPLETED"; public static final String WHAT_YOU_KNOW_ABOUT_ME_COMPLETED = "WHAT_YOU_KNOW_ABOUT_ME_COMPLETED";
public static final String ACCOUNTING_ENTRY_CREATED = "ACCOUNTING_ENTRY_CREATED";
public static final String GENERATE_FILE = "GENERATE_FILE"; public static final String GENERATE_FILE = "GENERATE_FILE";
private TrackedEvent event; private TrackedEvent event;

View File

@ -34,6 +34,8 @@ public class OutboxProperties {
private final String whatYouKnowAboutMeCompletedTopic; private final String whatYouKnowAboutMeCompletedTopic;
private final String accountingEntryCreatedTopic;
private final String generateFileTopic; private final String generateFileTopic;
public OutboxProperties(String exchange, int handleAckRetries, int handleNackRetries, int handleAckWaitInMilliSeconds, int handleNackWaitInMilliSeconds, public OutboxProperties(String exchange, int handleAckRetries, int handleNackRetries, int handleAckWaitInMilliSeconds, int handleNackWaitInMilliSeconds,
@ -50,7 +52,7 @@ public class OutboxProperties {
String notifyTopic, String notifyTopic,
String forgetMeCompletedTopic, String forgetMeCompletedTopic,
String whatYouKnowAboutMeCompletedTopic, String whatYouKnowAboutMeCompletedTopic,
String generateFileTopic String accountingEntryCreatedTopic, String generateFileTopic
) { ) {
this.exchange = exchange; this.exchange = exchange;
this.handleAckRetries = handleAckRetries; this.handleAckRetries = handleAckRetries;
@ -70,6 +72,7 @@ public class OutboxProperties {
this.notifyTopic = notifyTopic; this.notifyTopic = notifyTopic;
this.forgetMeCompletedTopic = forgetMeCompletedTopic; this.forgetMeCompletedTopic = forgetMeCompletedTopic;
this.whatYouKnowAboutMeCompletedTopic = whatYouKnowAboutMeCompletedTopic; this.whatYouKnowAboutMeCompletedTopic = whatYouKnowAboutMeCompletedTopic;
this.accountingEntryCreatedTopic = accountingEntryCreatedTopic;
this.generateFileTopic = generateFileTopic; this.generateFileTopic = generateFileTopic;
} }
@ -145,6 +148,10 @@ public class OutboxProperties {
return this.whatYouKnowAboutMeCompletedTopic; return this.whatYouKnowAboutMeCompletedTopic;
} }
public String getAccountingEntryCreatedTopic() {
return accountingEntryCreatedTopic;
}
public String getGenerateFileTopic() { public String getGenerateFileTopic() {
return this.generateFileTopic; return this.generateFileTopic;
} }

View File

@ -486,6 +486,10 @@ public class OutboxRepositoryImpl implements OutboxRepository {
routingKey = this.outboxProperties.getWhatYouKnowAboutMeCompletedTopic(); routingKey = this.outboxProperties.getWhatYouKnowAboutMeCompletedTopic();
break; break;
} }
case OutboxIntegrationEvent.ACCOUNTING_ENTRY_CREATED: {
routingKey = this.outboxProperties.getAccountingEntryCreatedTopic();
break;
}
case OutboxIntegrationEvent.GENERATE_FILE: { case OutboxIntegrationEvent.GENERATE_FILE: {
routingKey = this.outboxProperties.getGenerateFileTopic(); routingKey = this.outboxProperties.getGenerateFileTopic();
break; break;

View File

@ -0,0 +1,91 @@
package org.opencdmp.integrationevent.outbox.accountingentrycreated;
import org.opencdmp.commons.enums.accounting.AccountingMeasureType;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
import org.opencdmp.integrationevent.TrackedEvent;
import java.time.Instant;
import java.util.UUID;
public class AccountingEntryCreatedIntegrationEvent extends TrackedEvent {
private Instant timeStamp;
private String serviceId;
private String resource;
private String action;
private String userId;
private AccountingMeasureType measure;
private AccountingValueType type;
private UUID tenant;
public Instant getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(Instant timeStamp) {
this.timeStamp = timeStamp;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public AccountingMeasureType getMeasure() {
return measure;
}
public void setMeasure(AccountingMeasureType measure) {
this.measure = measure;
}
public AccountingValueType getType() {
return type;
}
public void setType(AccountingValueType type) {
this.type = type;
}
public UUID getTenant() {
return tenant;
}
public void setTenant(UUID tenant) {
this.tenant = tenant;
}
}

View File

@ -0,0 +1,10 @@
package org.opencdmp.integrationevent.outbox.accountingentrycreated;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
import javax.management.InvalidApplicationException;
public interface AccountingEntryCreatedIntegrationEventHandler {
void handleAccountingEntry(String metric, AccountingValueType valueType) throws InvalidApplicationException;
}

View File

@ -0,0 +1,65 @@
package org.opencdmp.integrationevent.outbox.accountingentrycreated;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.logging.LoggerService;
import org.opencdmp.commons.enums.accounting.AccountingMeasureType;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
import org.opencdmp.commons.scope.tenant.TenantScope;
import org.opencdmp.integrationevent.outbox.OutboxIntegrationEvent;
import org.opencdmp.integrationevent.outbox.OutboxService;
import org.opencdmp.service.accounting.AccountingProperties;
import org.slf4j.LoggerFactory;
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.UUID;
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class AccountingEntryCreatedIntegrationEventHandlerImpl implements AccountingEntryCreatedIntegrationEventHandler {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AccountingEntryCreatedIntegrationEventHandlerImpl.class));
private final OutboxService outboxService;
private final QueryFactory queryFactory;
private final TenantScope tenantScope;
private final AccountingProperties accountingProperties;
public AccountingEntryCreatedIntegrationEventHandlerImpl(OutboxService outboxService, QueryFactory queryFactory, TenantScope tenantScope, TenantScope tenantScope1, AccountingProperties accountingProperties) {
this.outboxService = outboxService;
this.queryFactory = queryFactory;
this.tenantScope = tenantScope1;
this.accountingProperties = accountingProperties;
}
private void handle(AccountingEntryCreatedIntegrationEvent event) {
OutboxIntegrationEvent message = new OutboxIntegrationEvent();
message.setMessageId(UUID.randomUUID());
message.setType(OutboxIntegrationEvent.ACCOUNTING_ENTRY_CREATED);
message.setEvent(event);
this.outboxService.publish(message);
}
@Override
public void handleAccountingEntry(String metric, AccountingValueType valueType) throws InvalidApplicationException {
AccountingEntryCreatedIntegrationEvent event = new AccountingEntryCreatedIntegrationEvent();
event.setTimeStamp(Instant.now());
event.setServiceId(accountingProperties.getServiceId());
event.setAction(accountingProperties.getAction());
event.setMeasure(AccountingMeasureType.Unit);
event.setType(valueType);
event.setResource(metric);
if (this.tenantScope.getTenantCode() != null && !this.tenantScope.getTenantCode().equals(this.tenantScope.getDefaultTenantCode())){
event.setTenant(this.tenantScope.getTenant());
}
this.handle(event);
}
}

View File

@ -0,0 +1,20 @@
package org.opencdmp.service.accounting;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(AccountingProperties.class)
public class AccountingConfiguration {
private final AccountingProperties properties;
@Autowired
public AccountingConfiguration(AccountingProperties properties) {
this.properties = properties;
}
public AccountingProperties getProperties() {
return this.properties;
}
}

View File

@ -0,0 +1,26 @@
package org.opencdmp.service.accounting;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "accounting")
public class AccountingProperties {
private String serviceId;
private String action;
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}

View File

@ -2,13 +2,15 @@ package org.opencdmp.service.accounting;
import org.opencdmp.commons.enums.UsageLimitTargetMetric; import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import javax.management.InvalidApplicationException;
public interface AccountingService { public interface AccountingService {
Integer getCurrentMetricValue(UsageLimitTargetMetric metric); Integer getCurrentMetricValue(UsageLimitTargetMetric metric);
void set(String metric); void set(String metric);
void increase(String metric); void increase(String metric) throws InvalidApplicationException;
void decrease(String metric); void decrease(String metric) throws InvalidApplicationException;
} }

View File

@ -3,13 +3,17 @@ package org.opencdmp.service.accounting;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import org.opencdmp.commons.enums.UsageLimitTargetMetric; import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
import org.opencdmp.convention.ConventionService; import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties; import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.opencdmp.integrationevent.outbox.accountingentrycreated.AccountingEntryCreatedIntegrationEventHandler;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.management.InvalidApplicationException;
@Service @Service
public class AccountingServiceImpl implements AccountingService { public class AccountingServiceImpl implements AccountingService {
@ -21,16 +25,20 @@ public class AccountingServiceImpl implements AccountingService {
private final MessageSource messageSource; private final MessageSource messageSource;
private final AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler;
@Autowired @Autowired
public AccountingServiceImpl( public AccountingServiceImpl(
AuthorizationService authorizationService, AuthorizationService authorizationService,
ConventionService conventionService, ConventionService conventionService,
ErrorThesaurusProperties errors, ErrorThesaurusProperties errors,
MessageSource messageSource) { MessageSource messageSource,
AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler) {
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.conventionService = conventionService; this.conventionService = conventionService;
this.errors = errors; this.errors = errors;
this.messageSource = messageSource; this.messageSource = messageSource;
this.accountingEntryCreatedIntegrationEventHandler = accountingEntryCreatedIntegrationEventHandler;
} }
public Integer getCurrentMetricValue(UsageLimitTargetMetric metric) { public Integer getCurrentMetricValue(UsageLimitTargetMetric metric) {
@ -43,12 +51,12 @@ public class AccountingServiceImpl implements AccountingService {
//TODO //TODO
} }
public void increase(String metric) { public void increase(String metric) throws InvalidApplicationException {
//TODO this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Plus);
} }
public void decrease(String metric) { public void decrease(String metric) throws InvalidApplicationException {
//TODO this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Minus);
} }
} }

View File

@ -385,7 +385,7 @@ public class DepositServiceImpl implements DepositService {
return persisted.getFileRef(); return persisted.getFileRef();
} }
private void increaseTargetMetricWithRepositoryId(UsageLimitTargetMetric metric, String repositoryId){ private void increaseTargetMetricWithRepositoryId(UsageLimitTargetMetric metric, String repositoryId) throws InvalidApplicationException {
this.accountingService.increase(metric.getValue() + repositoryId); this.accountingService.increase(metric.getValue() + repositoryId);
} }

View File

@ -429,7 +429,7 @@ public class FileTransformerServiceImpl implements FileTransformerService {
return repository.preprocessingPlan(fileEnvelope); return repository.preprocessingPlan(fileEnvelope);
} }
private void increaseTargetMetricWithRepositoryId(UsageLimitTargetMetric metric, String repositoryId){ private void increaseTargetMetricWithRepositoryId(UsageLimitTargetMetric metric, String repositoryId) throws InvalidApplicationException {
this.accountingService.increase(metric.getValue() + repositoryId); this.accountingService.increase(metric.getValue() + repositoryId);
} }

View File

@ -0,0 +1,3 @@
accounting:
serviceId: ${SERVICE_ID}
action: ${ACCOUNTING_ACTION}

View File

@ -33,6 +33,8 @@ spring:
optional:classpath:config/metrics.yml[.yml], optional:classpath:config/metrics-${spring.profiles.active}.yml[.yml], optional:file:../config/metrics-${spring.profiles.active}.yml[.yml], optional:classpath:config/metrics.yml[.yml], optional:classpath:config/metrics-${spring.profiles.active}.yml[.yml], optional:file:../config/metrics-${spring.profiles.active}.yml[.yml],
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/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/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/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]

View File

@ -42,6 +42,7 @@ queue:
annotation-entities-touch-topic: annotation.entities.touch annotation-entities-touch-topic: annotation.entities.touch
annotation-entities-removal-topic: annotation.entities.remove annotation-entities-removal-topic: annotation.entities.remove
what-you-know-about-me-completed-topic: whatyouknowaboutme.completed what-you-know-about-me-completed-topic: whatyouknowaboutme.completed
accounting-entry-created-topic: accountingentry.created
generate-file-topic: generate.file generate-file-topic: generate.file
rabbitmq: rabbitmq:
enable: true enable: true