add accounting client and accounting entry changes

This commit is contained in:
amentis 2024-07-19 17:24:07 +03:00
parent 772550d90d
commit 1ac8257fba
14 changed files with 556 additions and 28 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 AccountingAggregateType implements DatabaseEnum<Short> {
Sum((short) 0),
Average((short) 1),
Max((short) 2),
Min((short) 3);
private final Short value;
AccountingAggregateType(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, AccountingAggregateType> map = EnumUtils.getEnumValueMap(AccountingAggregateType.class);
public static AccountingAggregateType of(Short i) {
return map.get(i);
}
}

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 AccountingDataRangeType implements DatabaseEnum<Short> {
Custom((short) 0),
Today((short) 1),
ThisMonth((short) 2),
ThisYear((short) 3);
private final Short value;
AccountingDataRangeType(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, AccountingDataRangeType> map = EnumUtils.getEnumValueMap(AccountingDataRangeType.class);
public static AccountingDataRangeType of(Short i) {
return map.get(i);
}
}

View File

@ -0,0 +1,59 @@
package org.opencdmp.commons.types.accounting;
public class AccountingSourceEntity {
private String repositoryId;
private String url;
private String issuerUrl;
private String clientId;
private String clientSecret;
private String scope;
public String getRepositoryId() {
return this.repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getIssuerUrl() {
return this.issuerUrl;
}
public void setIssuerUrl(String issuerUrl) {
this.issuerUrl = issuerUrl;
}
public String getClientId() {
return this.clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return this.clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return this.scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@ -12,12 +12,16 @@ public class AccountingEntryCreatedIntegrationEvent extends TrackedEvent {
private Instant timeStamp;
private String serviceId;
public static final String _serviceId = "service";
private String resource;
public static final String _resource = "resource";
private String action;
public static final String _action = "action";
private String userId;
public static final String _userId = "user";
private AccountingMeasureType measure;

View File

@ -7,5 +7,5 @@ import java.util.UUID;
public interface AccountingEntryCreatedIntegrationEventHandler {
void handleAccountingEntry(String metric, AccountingValueType valueType, String subjectId, UUID tenantId) throws InvalidApplicationException;
void handleAccountingEntry(String metric, AccountingValueType valueType, String subjectId, UUID tenantId, String tenantCode) throws InvalidApplicationException;
}

View File

@ -39,14 +39,14 @@ public class AccountingEntryCreatedIntegrationEventHandlerImpl implements Accoun
}
@Override
public void handleAccountingEntry(String metric, AccountingValueType valueType, String subjectId, UUID tenantId) throws InvalidApplicationException {
AccountingEntryCreatedIntegrationEvent event = new AccountingEntryCreatedIntegrationEvent();
public void handleAccountingEntry(String metric, AccountingValueType valueType, String subjectId, UUID tenantId, String tenantCode) throws InvalidApplicationException {
AccountingEntryCreatedIntegrationEvent event = new AccountingEntryCreatedIntegrationEvent();
event.setTimeStamp(Instant.now());
event.setServiceId(accountingProperties.getServiceId());
event.setAction(accountingProperties.getAction());
event.setAction(metric);
event.setMeasure(AccountingMeasureType.Unit);
event.setType(valueType);
event.setResource(metric);
event.setResource(tenantCode);
event.setUserId(subjectId);
event.setValue(1.0);
event.setTenant(tenantId);

View File

@ -0,0 +1,44 @@
package org.opencdmp.model;
public class AccountingAggregateResultItem {
private Double sum;
private Double average;
private Double min;
private Double max;
public Double getSum() {
return sum;
}
public void setSum(Double sum) {
this.sum = sum;
}
public Double getAverage() {
return average;
}
public void setAverage(Double average) {
this.average = average;
}
public Double getMin() {
return min;
}
public void setMin(Double min) {
this.min = min;
}
public Double getMax() {
return max;
}
public void setMax(Double max) {
this.max = max;
}
}

View File

@ -0,0 +1,145 @@
package org.opencdmp.query.lookup.accounting;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.enums.accounting.AccountingAggregateType;
import org.opencdmp.commons.enums.accounting.AccountingDataRangeType;
import org.opencdmp.commons.enums.accounting.AccountingMeasureType;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
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.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class AccountingInfoLookup {
private Instant from;
public static final String _from = "from";
private Instant to;
public static final String _to = "to";
private List<AccountingValueType> types;
public static final String _types = "types";
private List<AccountingAggregateType> aggregateTypes;
public static final String _aggregateTypes = "aggregateTypes";
private AccountingDataRangeType dateRangeType;
public static final String _dateRangeType = "dateRangeType";
private AccountingMeasureType measure;
public static final String _measure = "measure";
private Set<String> groupingFields;
public static final String _groupingFields = "groupingFields";
public Instant getFrom() {
return from;
}
public void setFrom(Instant from) {
this.from = from;
}
public Instant getTo() {
return to;
}
public void setTo(Instant to) {
this.to = to;
}
public List<AccountingValueType> getTypes() {
return types;
}
public void setTypes(List<AccountingValueType> types) {
this.types = types;
}
public List<AccountingAggregateType> getAggregateTypes() {
return aggregateTypes;
}
public void setAggregateTypes(List<AccountingAggregateType> aggregateTypes) {
this.aggregateTypes = aggregateTypes;
}
public AccountingDataRangeType getDateRangeType() {
return dateRangeType;
}
public void setDateRangeType(AccountingDataRangeType dateRangeType) {
this.dateRangeType = dateRangeType;
}
public AccountingMeasureType getMeasure() {
return measure;
}
public void setMeasure(AccountingMeasureType measure) {
this.measure = measure;
}
public Set<String> getGroupingFields() {
return groupingFields;
}
public void setGroupingFields(Set<String> groupingFields) {
this.groupingFields = groupingFields;
}
@Component(AccountingInfoLookup.AccountingInfoLookupValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class AccountingInfoLookupValidator extends BaseValidator<AccountingInfoLookup> {
public static final String ValidatorName = "AccountingInfoLookupValidator";
private final MessageSource messageSource;
protected AccountingInfoLookupValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
super(conventionService, errors);
this.messageSource = messageSource;
}
@Override
protected Class<AccountingInfoLookup> modelClass() {
return AccountingInfoLookup.class;
}
@Override
protected List<Specification> specifications(AccountingInfoLookup item) {
return Arrays.asList(
this.spec()
.must(() -> !this.isNull(item.getMeasure()))
.failOn(AccountingInfoLookup._measure).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._measure}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getDateRangeType()))
.failOn(AccountingInfoLookup._dateRangeType).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._dateRangeType}, LocaleContextHolder.getLocale())),
this.spec()
.iff(()-> !this.isNull(item.getDateRangeType()) && item.getDateRangeType().equals(AccountingDataRangeType.Custom))
.must(() -> !this.isNull(item.getFrom()))
.failOn(AccountingInfoLookup._from).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._from}, LocaleContextHolder.getLocale())),
this.spec()
.iff(()-> !this.isNull(item.getDateRangeType()) && item.getDateRangeType().equals(AccountingDataRangeType.Custom))
.must(() -> !this.isNull(item.getTo()))
.failOn(AccountingInfoLookup._to).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._to}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isListNullOrEmpty(item.getAggregateTypes()))
.failOn(AccountingInfoLookup._aggregateTypes).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._aggregateTypes}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getGroupingFields()))
.failOn(AccountingInfoLookup._groupingFields).failWith(messageSource.getMessage("Validation_Required", new Object[]{AccountingInfoLookup._groupingFields}, LocaleContextHolder.getLocale()))
);
}
}
}

View File

@ -0,0 +1,10 @@
package org.opencdmp.service.accounting;
import org.opencdmp.model.AccountingAggregateResultItem;
import org.opencdmp.query.lookup.accounting.AccountingInfoLookup;
public interface AccountingClient {
AccountingAggregateResultItem calculate(AccountingInfoLookup lookup) throws Exception;
}

View File

@ -0,0 +1,26 @@
package org.opencdmp.service.accounting;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import org.opencdmp.model.AccountingAggregateResultItem;
import org.opencdmp.query.lookup.accounting.AccountingInfoLookup;
import org.slf4j.LoggerFactory;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class AccountingClientImpl implements AccountingClient {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AccountingClientImpl.class));
private final WebClient accountingClient;
public AccountingClientImpl(WebClient accountingClient) {
this.accountingClient = accountingClient;
}
@Override
public AccountingAggregateResultItem calculate(AccountingInfoLookup lookup) throws Exception {
logger.debug(new MapLogEntry("calculate").And("lookup", lookup));
return this.accountingClient.post().uri("/accounting/calculate", uriBuilder -> uriBuilder.build()).bodyValue(lookup).exchangeToMono(mono -> mono.statusCode().isError() ? mono.createException().flatMap(Mono::error) : mono.bodyToMono(AccountingAggregateResultItem.class)).block();
}
}

View File

@ -1,7 +1,10 @@
package org.opencdmp.service.accounting;
import org.opencdmp.commons.types.accounting.AccountingSourceEntity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
@ConfigurationProperties(prefix = "accounting")
public class AccountingProperties {
private String serviceId;
@ -10,6 +13,8 @@ public class AccountingProperties {
private String subjectId;
private List<AccountingSourceEntity> sources;
public String getServiceId() {
return serviceId;
}
@ -33,4 +38,12 @@ public class AccountingProperties {
public void setSubjectId(String subjectId) {
this.subjectId = subjectId;
}
public List<AccountingSourceEntity> getSources() {
return sources;
}
public void setSources(List<AccountingSourceEntity> sources) {
this.sources = sources;
}
}

View File

@ -1,19 +1,49 @@
package org.opencdmp.service.accounting;
import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService;
import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction;
import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidatorFactory;
import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import org.opencdmp.commons.enums.accounting.AccountingAggregateType;
import org.opencdmp.commons.enums.accounting.AccountingDataRangeType;
import org.opencdmp.commons.enums.accounting.AccountingMeasureType;
import org.opencdmp.commons.enums.accounting.AccountingValueType;
import org.opencdmp.commons.scope.tenant.TenantScope;
import org.opencdmp.commons.scope.user.UserScope;
import org.opencdmp.commons.types.accounting.AccountingSourceEntity;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.UserCredentialEntity;
import org.opencdmp.integrationevent.outbox.accountingentrycreated.AccountingEntryCreatedIntegrationEvent;
import org.opencdmp.integrationevent.outbox.accountingentrycreated.AccountingEntryCreatedIntegrationEventHandler;
import org.opencdmp.model.AccountingAggregateResultItem;
import org.opencdmp.query.UserCredentialQuery;
import org.opencdmp.query.lookup.accounting.AccountingInfoLookup;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Service
public class AccountingServiceImpl implements AccountingService {
@ -23,20 +53,117 @@ public class AccountingServiceImpl implements AccountingService {
private final AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler;
private final UserScope userScope;
private final TenantScope tenantScope;
private final MessageSource messageSource;
private final ConventionService conventionService;
private final Map<String, AccountingClient> clients;
private final TokenExchangeCacheService tokenExchangeCacheService;
private final AccountingProperties accountingProperties;
private final ValidatorFactory validatorFactory;
@Autowired
public AccountingServiceImpl(
QueryFactory queryFactory, AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler, UserScope userScope, TenantScope tenantScope) {
QueryFactory queryFactory, AccountingEntryCreatedIntegrationEventHandler accountingEntryCreatedIntegrationEventHandler, UserScope userScope, TenantScope tenantScope, MessageSource messageSource, ConventionService conventionService, TokenExchangeCacheService tokenExchangeCacheService, AccountingProperties accountingProperties, ValidatorFactory validatorFactory) {
this.queryFactory = queryFactory;
this.accountingEntryCreatedIntegrationEventHandler = accountingEntryCreatedIntegrationEventHandler;
this.userScope = userScope;
this.tenantScope = tenantScope;
this.messageSource = messageSource;
this.conventionService = conventionService;
this.tokenExchangeCacheService = tokenExchangeCacheService;
this.accountingProperties = accountingProperties;
this.validatorFactory = validatorFactory;
this.clients = new HashMap<>();
}
private AccountingClient getAccountingClient(String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
if (this.clients.containsKey(repositoryId)) return this.clients.get(repositoryId);
//GK: It's register time
AccountingSourceEntity source = accountingProperties.getSources().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
if (source != null) {
TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("accounting:" + source, source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
TokenExchangeFilterFunction apiKeyExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel);
WebClient webClient = WebClient.builder().baseUrl(source.getUrl() + "/api/accounting-service")
.filters(exchangeFilterFunctions -> {
exchangeFilterFunctions.add(apiKeyExchangeFilterFunction);
exchangeFilterFunctions.add(logRequest());
exchangeFilterFunctions.add(logResponse());
}).codecs(codecs -> codecs
.defaultCodecs()
).build();
AccountingClientImpl accounting = new AccountingClientImpl(webClient);
this.clients.put(repositoryId, accounting);
return accounting;
}
return null;
}
private static ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
logger.debug(new MapLogEntry("Request").And("method", clientRequest.method().toString()).And("url", clientRequest.url()));
return Mono.just(clientRequest);
});
}
private static ExchangeFilterFunction logResponse() {
return ExchangeFilterFunction.ofResponseProcessor(response -> {
if (response.statusCode().isError()) {
return response.mutate().build().bodyToMono(String.class)
.flatMap(body -> {
logger.error(new MapLogEntry("Response").And("method", response.request().getMethod().toString()).And("url", response.request().getURI()).And("status", response.statusCode().toString()).And("body", body));
return Mono.just(response);
});
}
return Mono.just(response);
});
}
public Integer getCurrentMetricValue(UsageLimitTargetMetric metric) {
//TODO
//Get/Calculate current metric value from accountingService
return 10;
AccountingClient accountingClient = null;
try {
accountingClient = this.getAccountingClient(this.accountingProperties.getSources().getFirst().getRepositoryId());
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException(e);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (BadPaddingException e) {
throw new RuntimeException(e);
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
if (accountingClient == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{this.accountingProperties.getSources().getFirst().getRepositoryId(), AccountingClient.class.getSimpleName()}, LocaleContextHolder.getLocale()));
AccountingInfoLookup lookup = new AccountingInfoLookup();
lookup.setTo(Instant.now());
lookup.setDateRangeType(AccountingDataRangeType.ThisYear);
lookup.setMeasure(AccountingMeasureType.Unit);
lookup.setAggregateTypes(new ArrayList<>());
lookup.getAggregateTypes().add(AccountingAggregateType.Sum);
lookup.setGroupingFields(Set.of(
AccountingEntryCreatedIntegrationEvent._serviceId,
AccountingEntryCreatedIntegrationEvent._action,
AccountingEntryCreatedIntegrationEvent._resource,
AccountingEntryCreatedIntegrationEvent._userId
));
this.validatorFactory.validator(AccountingInfoLookup.AccountingInfoLookupValidator.class).validateForce(lookup);
AccountingAggregateResultItem accountingAggregateResultItem = null;
try {
accountingAggregateResultItem = accountingClient.calculate(lookup);
} catch (Exception e) {
throw new RuntimeException(e);
}
return accountingAggregateResultItem.getSum().intValue();
}
public void set(String metric) {
@ -50,7 +177,7 @@ public class AccountingServiceImpl implements AccountingService {
if (userCredential != null) subjectId = userCredential.getExternalId();
else subjectId = this.userScope.getUserId().toString();
this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Plus, subjectId, this.tenantScope.getTenant());
this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Plus, subjectId, this.tenantScope.getTenant(), this.tenantScope.getTenantCode() != null ? this.tenantScope.getTenantCode() : this.tenantScope.getDefaultTenantCode());
}
public void decrease(String metric) throws InvalidApplicationException {
@ -60,7 +187,7 @@ public class AccountingServiceImpl implements AccountingService {
if (userCredential != null) subjectId = userCredential.getExternalId();
else subjectId = this.userScope.getUserId().toString();
this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Minus, subjectId, this.tenantScope.getTenant());
this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(metric, AccountingValueType.Minus, subjectId, this.tenantScope.getTenant(), this.tenantScope.getTenantCode() != null ? this.tenantScope.getTenantCode() : this.tenantScope.getDefaultTenantCode());
}
}

View File

@ -215,6 +215,7 @@ public class MaintenanceServiceImpl implements MaintenanceService {
this.tenantEntityManager.disableTenantFilters();
List<PlanEntity> items = this.queryFactory.query(PlanQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Plan._id).ensure(Plan._isActive).ensure(Plan._creator));
List<UserCredentialEntity> userCredentials = this.queryFactory.query(UserCredentialQuery.class).disableTracking().userIds(items.stream().map(x -> x.getCreatorId()).distinct().collect(Collectors.toList())).collect();
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (PlanEntity item : items) {
String subjectId;
@ -225,8 +226,9 @@ public class MaintenanceServiceImpl implements MaintenanceService {
} else {
subjectId = item.getCreatorId().toString();
}
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PLAN_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PLAN_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PLAN_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PLAN_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -241,11 +243,13 @@ public class MaintenanceServiceImpl implements MaintenanceService {
try {
this.tenantEntityManager.disableTenantFilters();
List<PlanBlueprintEntity> items = this.queryFactory.query(PlanBlueprintQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(PlanBlueprint._id).ensure(PlanBlueprint._isActive));
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (PlanBlueprintEntity item : items) {
String subjectId = accountingProperties.getSubjectId();
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.BLUEPRINT_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.BLUEPRINT_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.BLUEPRINT_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.BLUEPRINT_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -261,6 +265,7 @@ public class MaintenanceServiceImpl implements MaintenanceService {
this.tenantEntityManager.disableTenantFilters();
List<DescriptionEntity> items = this.queryFactory.query(DescriptionQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Description._id).ensure(Description._isActive).ensure(Description._createdBy));
List<UserCredentialEntity> userCredentials = this.queryFactory.query(UserCredentialQuery.class).disableTracking().userIds(items.stream().map(x -> x.getCreatedById()).distinct().collect(Collectors.toList())).collect();
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (DescriptionEntity item : items) {
String subjectId;
@ -271,8 +276,9 @@ public class MaintenanceServiceImpl implements MaintenanceService {
} else {
subjectId = item.getCreatedById().toString();
}
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -287,11 +293,13 @@ public class MaintenanceServiceImpl implements MaintenanceService {
try {
this.tenantEntityManager.disableTenantFilters();
List<DescriptionTemplateEntity> items = this.queryFactory.query(DescriptionTemplateQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(DescriptionTemplate._id).ensure(DescriptionTemplate._isActive));
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (DescriptionTemplateEntity item : items) {
String subjectId = accountingProperties.getSubjectId();
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -306,11 +314,13 @@ public class MaintenanceServiceImpl implements MaintenanceService {
try {
this.tenantEntityManager.disableTenantFilters();
List<DescriptionTemplateTypeEntity> items = this.queryFactory.query(DescriptionTemplateTypeQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(DescriptionTemplateType._id).ensure(DescriptionTemplateType._isActive));
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (DescriptionTemplateTypeEntity item : items) {
String subjectId = accountingProperties.getSubjectId();
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -325,11 +335,13 @@ public class MaintenanceServiceImpl implements MaintenanceService {
try {
this.tenantEntityManager.disableTenantFilters();
List<PrefillingSourceEntity> items = this.queryFactory.query(PrefillingSourceQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(PrefillingSource._id).ensure(PrefillingSource._isActive));
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (PrefillingSourceEntity item : items) {
String subjectId = accountingProperties.getSubjectId();
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PREFILLING_SOURCES_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PREFILLING_SOURCES_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PREFILLING_SOURCES_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.PREFILLING_SOURCES_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -344,11 +356,13 @@ public class MaintenanceServiceImpl implements MaintenanceService {
try {
this.tenantEntityManager.disableTenantFilters();
List<ReferenceTypeEntity> items = this.queryFactory.query(ReferenceTypeQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(ReferenceType._id).ensure(ReferenceType._isActive));
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (ReferenceTypeEntity item : items) {
String subjectId = accountingProperties.getSubjectId();
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.REFERENCE_TYPE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.REFERENCE_TYPE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.REFERENCE_TYPE_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.REFERENCE_TYPE_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
@ -364,6 +378,7 @@ public class MaintenanceServiceImpl implements MaintenanceService {
this.tenantEntityManager.disableTenantFilters();
List<TenantUserEntity> items = this.queryFactory.query(TenantUserQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(TenantUserEntity._id).ensure(TenantUserEntity._userId).ensure(TenantUserEntity._isActive));
List<UserCredentialEntity> userCredentials = this.queryFactory.query(UserCredentialQuery.class).disableTracking().userIds(items.stream().map(x -> x.getUserId()).distinct().collect(Collectors.toList())).collect();
List<TenantEntity> tenants = this.queryFactory.query(TenantQuery.class).disableTracking().collectAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
for (TenantUserEntity item : items) {
String subjectId;
@ -374,11 +389,22 @@ public class MaintenanceServiceImpl implements MaintenanceService {
} else {
subjectId = item.getUserId().toString();
}
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.USER_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId());
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.USER_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId());
String tenantCode = this.findTenantCode(tenants, item.getTenantId());
if (item.getIsActive().equals(IsActive.Active)) this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.USER_COUNT.getValue(), AccountingValueType.Plus, subjectId, item.getTenantId(), tenantCode);
else this.accountingEntryCreatedIntegrationEventHandler.handleAccountingEntry(UsageLimitTargetMetric.USER_COUNT.getValue(), AccountingValueType.Minus, subjectId, item.getTenantId(), tenantCode);
}
} finally {
this.tenantEntityManager.reloadTenantFilters();
}
}
private String findTenantCode(List<TenantEntity> tenants, UUID tenantId) {
if (tenants != null && !tenants.isEmpty() && tenantId != null){
TenantEntity tenant = tenants.stream().filter(x -> x.getId().equals(tenantId)).findFirst().orElse(null);
if (tenant != null) return tenant.getCode();
else return this.tenantScope.getDefaultTenantCode();
} else {
return this.tenantScope.getDefaultTenantCode();
}
}
}

View File

@ -0,0 +1,8 @@
accounting:
sources:
- url: http://localhost:50002
repositoryId: accounting
issuer-url: ${IDP_ISSUER_URI_TOKEN}
client-id: ${ACCOUNTING_CLIENT_ID}
client-secret: ${ACCOUNTING_CLIENT_SECRET}
scope: ${IDP_APIKEY_SCOPE}