implement checkIncrease function for Usage Limit

This commit is contained in:
amentis 2024-07-12 17:04:37 +03:00
parent 50e38c6854
commit 970662c9c2
18 changed files with 161 additions and 51 deletions

View File

@ -388,4 +388,14 @@ public class ErrorThesaurusProperties {
public void setMaxDescriptionsExceeded(ErrorDescription maxDescriptionsExceeded) {
this.maxDescriptionsExceeded = maxDescriptionsExceeded;
}
private ErrorDescription usageLimitException;
public ErrorDescription getUsageLimitException() {
return usageLimitException;
}
public void setUsageLimitException(ErrorDescription usageLimitException) {
this.usageLimitException = usageLimitException;
}
}

View File

@ -1,26 +1,14 @@
package org.opencdmp.service.accounting;
public class AccountingService {
import org.opencdmp.commons.enums.UsageLimitTargetMetric;
private Integer getCurrentMetricValue(String metric) {
return 10;
}
public interface AccountingService {
private void set(String metric) {
//Get/Calculate current metric value
//Find metric value from db
// compare these two and throw UsageLimitException when current > metric value
}
Integer getCurrentMetricValue(UsageLimitTargetMetric metric);
private void increase(String metric) {
//Get/Calculate current metric value
//Find metric value from db
// compare these two and throw UsageLimitException when current > metric value
}
void set(UsageLimitTargetMetric metric);
private void decrease(String metric) {
//Get/Calculate current metric value
//Find metric value from db
// compare these two and throw UsageLimitException when current > metric value
}
void increase(UsageLimitTargetMetric metric);
void decrease(UsageLimitTargetMetric metric);
}

View File

@ -0,0 +1,54 @@
package org.opencdmp.service.accounting;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.logging.LoggerService;
import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
@Service
public class AccountingServiceImpl implements AccountingService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AccountingServiceImpl.class));
private final AuthorizationService authorizationService;
private final ConventionService conventionService;
private final ErrorThesaurusProperties errors;
private final MessageSource messageSource;
@Autowired
public AccountingServiceImpl(
AuthorizationService authorizationService,
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource) {
this.authorizationService = authorizationService;
this.conventionService = conventionService;
this.errors = errors;
this.messageSource = messageSource;
}
public Integer getCurrentMetricValue(UsageLimitTargetMetric metric) {
//TODO
//Get/Calculate current metric value from accountingService
return 10;
}
public void set(UsageLimitTargetMetric metric) {
//TODO
}
public void increase(UsageLimitTargetMetric metric) {
//TODO
}
public void decrease(UsageLimitTargetMetric metric) {
//TODO
}
}

View File

@ -14,6 +14,7 @@ import gr.cite.tools.logging.MapLogEntry;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.DescriptionTemplateTypeEntity;
import org.opencdmp.data.TenantEntityManager;
@ -24,6 +25,8 @@ import org.opencdmp.model.DescriptionTemplateType;
import org.opencdmp.model.builder.DescriptionTemplateTypeBuilder;
import org.opencdmp.model.deleter.DescriptionTemplateTypeDeleter;
import org.opencdmp.model.persist.DescriptionTemplateTypePersist;
import org.opencdmp.service.accounting.AccountingService;
import org.opencdmp.service.usagelimit.UsageLimitServiceImpl;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
@ -56,6 +59,10 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
private final EventBroker eventBroker;
private final UsageLimitServiceImpl usageLimitService;
private final AccountingService accountingService;
@Autowired
public DescriptionTemplateTypeServiceImpl(
TenantEntityManager entityManager,
@ -65,7 +72,7 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource,
EventBroker eventBroker) {
EventBroker eventBroker, UsageLimitServiceImpl usageLimitService, AccountingService accountingService) {
this.entityManager = entityManager;
this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory;
@ -74,6 +81,8 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
this.errors = errors;
this.messageSource = messageSource;
this.eventBroker = eventBroker;
this.usageLimitService = usageLimitService;
this.accountingService = accountingService;
}
public DescriptionTemplateType persist(DescriptionTemplateTypePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
@ -89,6 +98,7 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplateType.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
} else {
this.usageLimitService.checkIncrease(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT);
data = new DescriptionTemplateTypeEntity();
data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active);
@ -100,8 +110,10 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
data.setUpdatedAt(Instant.now());
if (isUpdate)
this.entityManager.merge(data);
else
else{
this.entityManager.persist(data);
this.accountingService.increase(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT);
}
this.entityManager.flush();
@ -115,6 +127,7 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy
this.authorizationService.authorizeForce(Permission.DeleteDescriptionTemplateType);
this.deleterFactory.deleter(DescriptionTemplateTypeDeleter.class).deleteAndSaveByIds(List.of(id));
this.accountingService.decrease(UsageLimitTargetMetric.DESCRIPTION_TEMPLATE_TYPE_COUNT);
}
}

View File

@ -15,16 +15,18 @@ import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.commons.enums.UsageLimitTargetMetric;
import org.opencdmp.commons.scope.user.UserScope;
import gr.cite.tools.data.query.QueryFactory;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.TenantEntityManager;
import org.opencdmp.data.UsageLimitEntity;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.opencdmp.model.Tag;
import org.opencdmp.model.UsageLimit;
import org.opencdmp.model.builder.UsageLimitBuilder;
import org.opencdmp.model.deleter.UsageLimitDeleter;
import org.opencdmp.model.persist.UsageLimitPersist;
import org.opencdmp.query.UsageLimitQuery;
import org.opencdmp.service.accounting.AccountingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
@ -40,6 +42,7 @@ import java.util.UUID;
public class UsageLimitServiceImpl implements UsageLimitService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UsageLimitServiceImpl.class));
private static final Logger log = LoggerFactory.getLogger(UsageLimitServiceImpl.class);
private final TenantEntityManager entityManager;
@ -55,7 +58,11 @@ public class UsageLimitServiceImpl implements UsageLimitService {
private final MessageSource messageSource;
private final UserScope userScope;
private final QueryFactory queryFactory;
private final TenantEntityManager tenantEntityManager;
private final AccountingService accountingService;
@Autowired
@ -67,7 +74,7 @@ public class UsageLimitServiceImpl implements UsageLimitService {
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource,
UserScope userScope) {
QueryFactory queryFactory, TenantEntityManager tenantEntityManager, AccountingService accountingService) {
this.entityManager = entityManager;
this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory;
@ -75,11 +82,13 @@ public class UsageLimitServiceImpl implements UsageLimitService {
this.conventionService = conventionService;
this.errors = errors;
this.messageSource = messageSource;
this.userScope = userScope;
this.queryFactory = queryFactory;
this.tenantEntityManager = tenantEntityManager;
this.accountingService = accountingService;
}
public UsageLimit persist(UsageLimitPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("persisting data tag").And("model", model).And("fields", fields));
logger.debug(new MapLogEntry("persisting data UsageLimit").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.EditUsageLimit);
@ -88,7 +97,7 @@ public class UsageLimitServiceImpl implements UsageLimitService {
UsageLimitEntity data;
if (isUpdate) {
data = this.entityManager.find(UsageLimitEntity.class, model.getId());
if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Tag.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), UsageLimit.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
} else {
data = new UsageLimitEntity();
@ -119,7 +128,26 @@ public class UsageLimitServiceImpl implements UsageLimitService {
}
public void checkIncrease(UsageLimitTargetMetric metric) {
//TODO
if (metric == null) throw new MyApplicationException("Target Metric not defined");
Integer currentValue = this.accountingService.getCurrentMetricValue(metric);
try {
this.tenantEntityManager.loadExplicitTenantFilters();
UsageLimitEntity usageLimitEntity = this.queryFactory.query(UsageLimitQuery.class).disableTracking().usageLimitTargetMetrics(metric).isActive(IsActive.Active).firstAs(new BaseFieldSet().ensure(UsageLimit._targetMetric).ensure(UsageLimit._value));
if (usageLimitEntity != null && currentValue > usageLimitEntity.getValue()) throw new MyValidationException(this.errors.getUsageLimitException().getCode(), this.errors.getUsageLimitException().getMessage());
} catch (InvalidApplicationException e) {
log.error(e.getMessage(), e);
throw new MyApplicationException(e.getMessage());
} finally {
try {
this.tenantEntityManager.reloadTenantFilters();
} catch (InvalidApplicationException e) {
log.error(e.getMessage(), e);
throw new MyApplicationException(e.getMessage());
}
}
}
}

View File

@ -122,3 +122,6 @@ error-thesaurus:
maxDescriptionsExceeded:
code: 144
message: Max descriptions exceeded for this plan
usageLimitException:
code: 145
message: Usage limit exception for this target metric

View File

@ -40,6 +40,7 @@ export enum ResponseErrorCode {
InviteUserAlreadyConfirmed = 142,
RequestHasExpired = 143,
MaxDescriptionsExceeded = 144,
UsageLimitException = 145,
// Notification & Annotation Errors
InvalidApiKey = 200,
@ -154,6 +155,8 @@ export class ResponseErrorCodeHelper {
return language.instant("GENERAL.BACKEND-ERRORS.REQUEST-HAS-EXPIRED");
case ResponseErrorCode.MaxDescriptionsExceeded:
return language.instant("GENERAL.BACKEND-ERRORS.MAX-DESCRIPTION-EXCEEDED");
case ResponseErrorCode.UsageLimitException:
return language.instant("GENERAL.BACKEND-ERRORS.USAGE-LIMIT-EXCEPTION");
default:
return language.instant("GENERAL.SNACK-BAR.NOT-FOUND");
}

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Kontuz!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Warnung!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Warning!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Atención!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Προσοχή!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Oprez!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Ostrzeżenie!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Atenção!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Upozornenie!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Oprez!",

View File

@ -79,7 +79,8 @@
"DUPLICATE-PLAN-USER": "You can't invite authors with same role and plan section more than once",
"INVITE-USER-ALREADY-CONFIRMED": "Ιnvitation has already confirmed",
"REQUEST-HAS-EXPIRED": "Request has expired",
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template"
"MAX-DESCRIPTION-EXCEEDED": "This plan has reached the maximun descriptions for this description template",
"USAGE-LIMIT-EXCEPTION": "You have reached the available number of items for this entity "
},
"FORM-VALIDATION-DISPLAY-DIALOG": {
"WARNING": "Uyarı!",