add UsageLimit backend stack
This commit is contained in:
parent
91103ee8ef
commit
09ed61ce6f
|
@ -178,6 +178,11 @@ public class AuditableAction {
|
||||||
|
|
||||||
public static final EventId Annotation_Created_Notify = new EventId(280000, "Annotation_Created_Notify");
|
public static final EventId Annotation_Created_Notify = new EventId(280000, "Annotation_Created_Notify");
|
||||||
|
|
||||||
|
public static final EventId UsageLimit_Query = new EventId(290000, "UsageLimit_Query");
|
||||||
|
public static final EventId UsageLimit_Lookup = new EventId(290001, "UsageLimit_Lookup");
|
||||||
|
public static final EventId UsageLimit_Persist = new EventId(290002, "UsageLimit_Persist");
|
||||||
|
public static final EventId UsageLimit_Delete = new EventId(290003, "UsageLimit_Delete");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,11 @@ public final class Permission {
|
||||||
public static String EditPrefillingSource= "EditPrefillingSource";
|
public static String EditPrefillingSource= "EditPrefillingSource";
|
||||||
public static String DeletePrefillingSource = "DeletePrefillingSource";
|
public static String DeletePrefillingSource = "DeletePrefillingSource";
|
||||||
|
|
||||||
|
//UsageLimit
|
||||||
|
public static String BrowseUsageLimit = "BrowseUsageLimit";
|
||||||
|
public static String EditUsageLimit = "EditUsageLimit";
|
||||||
|
public static String DeleteUsageLimit = "DeleteUsageLimit";
|
||||||
|
|
||||||
//NotificationTemplate
|
//NotificationTemplate
|
||||||
public static String BrowseStatus = "BrowseStatus";
|
public static String BrowseStatus = "BrowseStatus";
|
||||||
public static String EditStatus = "EditStatus";
|
public static String EditStatus = "EditStatus";
|
||||||
|
@ -220,6 +225,7 @@ public final class Permission {
|
||||||
public static String ViewReferenceTypePage = "ViewReferenceTypePage";
|
public static String ViewReferenceTypePage = "ViewReferenceTypePage";
|
||||||
public static String ViewReferencePaPlge = "ViewReferencePage";
|
public static String ViewReferencePaPlge = "ViewReferencePage";
|
||||||
public static String ViewEntityLockPage = "ViewEntityLockPage";
|
public static String ViewEntityLockPage = "ViewEntityLockPage";
|
||||||
|
public static String ViewUsageLimitPage = "ViewUsageLimitPage";
|
||||||
public static String ViewDescriptionTemplatePage = "ViewDescriptionTemplatePage";
|
public static String ViewDescriptionTemplatePage = "ViewDescriptionTemplatePage";
|
||||||
public static String ViewPlanBlueprintPage = "ViewPlanBlueprintPage";
|
public static String ViewPlanBlueprintPage = "ViewPlanBlueprintPage";
|
||||||
public static String ViewPublicDescriptionPage = "ViewPublicDescriptionPage";
|
public static String ViewPublicDescriptionPage = "ViewPublicDescriptionPage";
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.opencdmp.commons.enums;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
import org.opencdmp.data.converters.enums.DatabaseEnum;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum UsageLimitMetricValue implements DatabaseEnum<String> {
|
||||||
|
USER_COUNT(MetricValues.UserCount),
|
||||||
|
PLAN_COUNT(MetricValues.PlanCount),
|
||||||
|
BLUEPRINT_COUNT(MetricValues.BlueprintCount),
|
||||||
|
DESCRIPTION_COUNT(MetricValues.DescriptionCount),
|
||||||
|
DESCRIPTION_TEMPLATE_COUNT(MetricValues.DescriptionTemplateCount),
|
||||||
|
DESCRIPTION_TEMPLATE_TYPE_COUNT(MetricValues.DescriptionTemplateTypeCount),
|
||||||
|
PREFILLING_SOURCES_COUNT(MetricValues.PrefillingSourcesCount),
|
||||||
|
REFERENCE_TYPE_COUNT(MetricValues.ReferenceTypeCount);
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public static class MetricValues {
|
||||||
|
public static final String UserCount = "user_count";
|
||||||
|
public static final String PlanCount = "plan_count";
|
||||||
|
public static final String BlueprintCount = "blueprint_count";
|
||||||
|
public static final String DescriptionCount = "description_count";
|
||||||
|
public static final String DescriptionTemplateCount = "description_template_count";
|
||||||
|
public static final String DescriptionTemplateTypeCount = "description_template_type_count";
|
||||||
|
public static final String PrefillingSourcesCount = "prefilling_sources_count";
|
||||||
|
public static final String ReferenceTypeCount = "reference_type_count";
|
||||||
|
}
|
||||||
|
|
||||||
|
UsageLimitMetricValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public String getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<String, UsageLimitMetricValue> map = EnumUtils.getEnumValueMap(UsageLimitMetricValue.class);
|
||||||
|
|
||||||
|
public static UsageLimitMetricValue of(String i) {
|
||||||
|
return map.get(i);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package org.opencdmp.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.data.converters.enums.IsActiveConverter;
|
||||||
|
import org.opencdmp.data.tenant.TenantScopedBaseEntity;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "\"UsageLimit\"")
|
||||||
|
public class UsageLimitEntity extends TenantScopedBaseEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
|
||||||
|
private UUID id;
|
||||||
|
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
@Column(name = "label", length = _labelLength, nullable = false)
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public static final String _label = "label";
|
||||||
|
|
||||||
|
public static final int _labelLength = 250;
|
||||||
|
|
||||||
|
|
||||||
|
@Column(name = "metric_value", nullable = false)
|
||||||
|
private UsageLimitMetricValue metricValue;
|
||||||
|
|
||||||
|
public static final String _metricValue = "metricValue";
|
||||||
|
|
||||||
|
@Column(name = "value", nullable = false)
|
||||||
|
private Long value;
|
||||||
|
|
||||||
|
public static final String _value = "value";
|
||||||
|
|
||||||
|
@Column(name = "is_active", nullable = false)
|
||||||
|
@Convert(converter = IsActiveConverter.class)
|
||||||
|
private IsActive isActive;
|
||||||
|
|
||||||
|
public static final String _isActive = "isActive";
|
||||||
|
|
||||||
|
@Column(name = "created_at", nullable = false)
|
||||||
|
private Instant createdAt;
|
||||||
|
|
||||||
|
public static final String _createdAt = "createdAt";
|
||||||
|
|
||||||
|
@Column(name = "updated_at", nullable = false)
|
||||||
|
private Instant updatedAt;
|
||||||
|
|
||||||
|
public static final String _updatedAt = "updatedAt";
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitMetricValue getMetricValue() {
|
||||||
|
return metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetricValue(UsageLimitMetricValue metricValue) {
|
||||||
|
this.metricValue = metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsActive getIsActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsActive(IsActive isActive) {
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(Instant createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdatedAt(Instant updatedAt) {
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
package org.opencdmp.model;
|
||||||
|
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UsageLimit {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
public static final String _label = "label";
|
||||||
|
|
||||||
|
private UsageLimitMetricValue metricValue;
|
||||||
|
public static final String _metricValue = "metricValue";
|
||||||
|
|
||||||
|
private Long value;
|
||||||
|
public static final String _value = "value";
|
||||||
|
|
||||||
|
private IsActive isActive;
|
||||||
|
public static final String _isActive = "isActive";
|
||||||
|
|
||||||
|
private Instant createdAt;
|
||||||
|
public static final String _createdAt = "createdAt";
|
||||||
|
|
||||||
|
private Instant updatedAt;
|
||||||
|
public static final String _updatedAt = "updatedAt";
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
public static final String _hash = "hash";
|
||||||
|
|
||||||
|
private Boolean belongsToCurrentTenant;
|
||||||
|
public static final String _belongsToCurrentTenant = "belongsToCurrentTenant";
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitMetricValue getMetricValue() {
|
||||||
|
return metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetricValue(UsageLimitMetricValue metricValue) {
|
||||||
|
this.metricValue = metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsActive getIsActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsActive(IsActive isActive) {
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(Instant createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdatedAt(Instant updatedAt) {
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(String hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getBelongsToCurrentTenant() {
|
||||||
|
return belongsToCurrentTenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBelongsToCurrentTenant(Boolean belongsToCurrentTenant) {
|
||||||
|
this.belongsToCurrentTenant = belongsToCurrentTenant;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.opencdmp.model.builder;
|
||||||
|
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.DataLogEntry;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.opencdmp.authorization.AuthorizationFlags;
|
||||||
|
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||||
|
import org.opencdmp.convention.ConventionService;
|
||||||
|
import org.opencdmp.data.UsageLimitEntity;
|
||||||
|
import org.opencdmp.model.UsageLimit;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class UsageLimitBuilder extends BaseBuilder<UsageLimit, UsageLimitEntity> {
|
||||||
|
|
||||||
|
private final TenantScope tenantScope;
|
||||||
|
|
||||||
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UsageLimitBuilder(
|
||||||
|
ConventionService conventionService,
|
||||||
|
TenantScope tenantScope) {
|
||||||
|
super(conventionService, new LoggerService(LoggerFactory.getLogger(UsageLimitBuilder.class)));
|
||||||
|
this.tenantScope = tenantScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitBuilder authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
|
this.authorize = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UsageLimit> build(FieldSet fields, List<UsageLimitEntity> data) throws MyApplicationException {
|
||||||
|
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
|
||||||
|
this.logger.trace(new DataLogEntry("requested fields", fields));
|
||||||
|
if (fields == null || data == null || fields.isEmpty())
|
||||||
|
return new ArrayList<>();
|
||||||
|
|
||||||
|
List<UsageLimit> models = new ArrayList<>();
|
||||||
|
for (UsageLimitEntity d : data) {
|
||||||
|
UsageLimit m = new UsageLimit();
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._id)))
|
||||||
|
m.setId(d.getId());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._label)))
|
||||||
|
m.setLabel(d.getLabel());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._metricValue)))
|
||||||
|
m.setMetricValue(d.getMetricValue());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._value)))
|
||||||
|
m.setValue(d.getValue());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._createdAt)))
|
||||||
|
m.setCreatedAt(d.getCreatedAt());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._updatedAt)))
|
||||||
|
m.setUpdatedAt(d.getUpdatedAt());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._isActive)))
|
||||||
|
m.setIsActive(d.getIsActive());
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._hash)))
|
||||||
|
m.setHash(this.hashValue(d.getUpdatedAt()));
|
||||||
|
if (fields.hasField(this.asIndexer(UsageLimit._belongsToCurrentTenant))) m.setBelongsToCurrentTenant(this.getBelongsToCurrentTenant(d, this.tenantScope));
|
||||||
|
|
||||||
|
models.add(m);
|
||||||
|
}
|
||||||
|
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.opencdmp.model.censorship;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.censor.CensorFactory;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.DataLogEntry;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.opencdmp.authorization.Permission;
|
||||||
|
import org.opencdmp.convention.ConventionService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class UsageLimitsCensor extends BaseCensor {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UsageLimitsCensor.class));
|
||||||
|
|
||||||
|
protected final AuthorizationService authService;
|
||||||
|
protected final CensorFactory censorFactory;
|
||||||
|
|
||||||
|
public UsageLimitsCensor(ConventionService conventionService,
|
||||||
|
AuthorizationService authService,
|
||||||
|
CensorFactory censorFactory) {
|
||||||
|
super(conventionService);
|
||||||
|
this.authService = authService;
|
||||||
|
this.censorFactory = censorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void censor(FieldSet fields) {
|
||||||
|
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||||
|
if (fields == null || fields.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.authService.authorizeForce(Permission.BrowseUsageLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.opencdmp.model.deleter;
|
||||||
|
|
||||||
|
import gr.cite.tools.data.deleter.Deleter;
|
||||||
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.data.TenantEntityManager;
|
||||||
|
import org.opencdmp.data.UsageLimitEntity;
|
||||||
|
import org.opencdmp.query.UsageLimitQuery;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class UsageLimitDeleter implements Deleter {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UsageLimitDeleter.class));
|
||||||
|
|
||||||
|
private final TenantEntityManager entityManager;
|
||||||
|
|
||||||
|
protected final QueryFactory queryFactory;
|
||||||
|
|
||||||
|
protected final DeleterFactory deleterFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UsageLimitDeleter(
|
||||||
|
TenantEntityManager entityManager,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
DeleterFactory deleterFactory
|
||||||
|
) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.deleterFactory = deleterFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSaveByIds(List<UUID> ids) throws InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids));
|
||||||
|
List<UsageLimitEntity> data = this.queryFactory.query(UsageLimitQuery.class).ids(ids).collect();
|
||||||
|
logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
this.deleteAndSave(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSave(List<UsageLimitEntity> data) throws InvalidApplicationException {
|
||||||
|
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
this.delete(data);
|
||||||
|
logger.trace("saving changes");
|
||||||
|
this.entityManager.flush();
|
||||||
|
logger.trace("changes saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(List<UsageLimitEntity> data) throws InvalidApplicationException {
|
||||||
|
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
if (data == null || data.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instant now = Instant.now();
|
||||||
|
|
||||||
|
for (UsageLimitEntity item : data) {
|
||||||
|
logger.trace("deleting item {}", item.getId());
|
||||||
|
item.setIsActive(IsActive.Inactive);
|
||||||
|
item.setUpdatedAt(now);
|
||||||
|
logger.trace("updating item");
|
||||||
|
this.entityManager.merge(item);
|
||||||
|
logger.trace("updated item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package org.opencdmp.model.persist;
|
||||||
|
|
||||||
|
import gr.cite.tools.validation.specification.Specification;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.commons.validation.BaseValidator;
|
||||||
|
import org.opencdmp.convention.ConventionService;
|
||||||
|
import org.opencdmp.data.UsageLimitEntity;
|
||||||
|
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 UsageLimitPersist {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
public static final String _label = "label";
|
||||||
|
|
||||||
|
private UsageLimitMetricValue metricValue;;
|
||||||
|
public static final String _metricValue = "metricValue";
|
||||||
|
|
||||||
|
private Long value;
|
||||||
|
public static final String _value = "value";
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
public static final String _hash = "hash";
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return this.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitMetricValue getMetricValue() {
|
||||||
|
return metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetricValue(UsageLimitMetricValue metricValue) {
|
||||||
|
this.metricValue = metricValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return this.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(String hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component(UsageLimitPersistValidator.ValidatorName)
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public static class UsageLimitPersistValidator extends BaseValidator<UsageLimitPersist> {
|
||||||
|
|
||||||
|
public static final String ValidatorName = "UsageLimitPersistValidator";
|
||||||
|
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
|
||||||
|
protected UsageLimitPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
|
||||||
|
super(conventionService, errors);
|
||||||
|
this.messageSource = messageSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<UsageLimitPersist> modelClass() {
|
||||||
|
return UsageLimitPersist.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Specification> specifications(UsageLimitPersist item) {
|
||||||
|
return Arrays.asList(
|
||||||
|
this.spec()
|
||||||
|
.iff(() -> this.isValidGuid(item.getId()))
|
||||||
|
.must(() -> this.isValidHash(item.getHash()))
|
||||||
|
.failOn(UsageLimitPersist._hash).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UsageLimitPersist._hash}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.iff(() -> !this.isValidGuid(item.getId()))
|
||||||
|
.must(() -> !this.isValidHash(item.getHash()))
|
||||||
|
.failOn(UsageLimitPersist._hash).failWith(this.messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.must(() -> !this.isEmpty(item.getLabel()))
|
||||||
|
.failOn(UsageLimitPersist._label).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UsageLimitPersist._label}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.iff(() -> !this.isEmpty(item.getLabel()))
|
||||||
|
.must(() -> this.lessEqualLength(item.getLabel(), UsageLimitEntity._labelLength))
|
||||||
|
.failOn(UsageLimitPersist._label).failWith(this.messageSource.getMessage("Validation_MaxLength", new Object[]{UsageLimitPersist._label}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.must(() -> !this.isNull(item.getMetricValue()))
|
||||||
|
.failOn(UsageLimitPersist._metricValue).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UsageLimitPersist._metricValue}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.must(() -> !this.isNull(item.getValue()))
|
||||||
|
.failOn(UsageLimitPersist._value).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UsageLimitPersist._value}, LocaleContextHolder.getLocale()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
package org.opencdmp.query;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.query.FieldResolver;
|
||||||
|
import gr.cite.tools.data.query.QueryBase;
|
||||||
|
import gr.cite.tools.data.query.QueryContext;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.Tuple;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import org.opencdmp.authorization.AuthorizationFlags;
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.commons.scope.user.UserScope;
|
||||||
|
import org.opencdmp.data.*;
|
||||||
|
import org.opencdmp.model.UsageLimit;
|
||||||
|
import org.opencdmp.query.utils.QueryUtilsService;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class UsageLimitQuery extends QueryBase<UsageLimitEntity> {
|
||||||
|
|
||||||
|
private String like;
|
||||||
|
|
||||||
|
private Collection<UUID> ids;
|
||||||
|
|
||||||
|
private Collection<IsActive> isActives;
|
||||||
|
|
||||||
|
private Collection<UsageLimitMetricValue> usageLimitMetricValues;
|
||||||
|
|
||||||
|
private Collection<UUID> excludedIds;
|
||||||
|
|
||||||
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||||
|
|
||||||
|
public UsageLimitQuery like(String value) {
|
||||||
|
this.like = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery ids(UUID value) {
|
||||||
|
this.ids = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery ids(UUID... value) {
|
||||||
|
this.ids = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery ids(Collection<UUID> values) {
|
||||||
|
this.ids = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery isActive(IsActive value) {
|
||||||
|
this.isActives = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery isActive(IsActive... value) {
|
||||||
|
this.isActives = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery isActive(Collection<IsActive> values) {
|
||||||
|
this.isActives = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery excludedIds(Collection<UUID> values) {
|
||||||
|
this.excludedIds = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery excludedIds(UUID value) {
|
||||||
|
this.excludedIds = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery excludedIds(UUID... value) {
|
||||||
|
this.excludedIds = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery usageLimitMetricValues(UsageLimitMetricValue value) {
|
||||||
|
this.usageLimitMetricValues = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery usageLimitMetricValues(UsageLimitMetricValue... value) {
|
||||||
|
this.usageLimitMetricValues = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery usageLimitMetricValues(Collection<UsageLimitMetricValue> values) {
|
||||||
|
this.usageLimitMetricValues = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
|
this.authorize = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery enableTracking() {
|
||||||
|
this.noTracking = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery disableTracking() {
|
||||||
|
this.noTracking = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final UserScope userScope;
|
||||||
|
|
||||||
|
private final AuthorizationService authService;
|
||||||
|
|
||||||
|
private final QueryUtilsService queryUtilsService;
|
||||||
|
private final TenantEntityManager tenantEntityManager;
|
||||||
|
|
||||||
|
public UsageLimitQuery(
|
||||||
|
UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) {
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.authService = authService;
|
||||||
|
this.queryUtilsService = queryUtilsService;
|
||||||
|
this.tenantEntityManager = tenantEntityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager entityManager(){
|
||||||
|
return this.tenantEntityManager.getEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<UsageLimitEntity> entityClass() {
|
||||||
|
return UsageLimitEntity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean isFalseQuery() {
|
||||||
|
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.usageLimitMetricValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
|
||||||
|
List<Predicate> predicates = new ArrayList<>();
|
||||||
|
if (this.ids != null) {
|
||||||
|
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UsageLimitEntity._id));
|
||||||
|
for (UUID item : this.ids)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.like != null && !this.like.isBlank()) {
|
||||||
|
predicates.add(this.queryUtilsService.ilike(queryContext.CriteriaBuilder, queryContext.Root.get(UsageLimitEntity._label), this.like));
|
||||||
|
}
|
||||||
|
if (this.isActives != null) {
|
||||||
|
CriteriaBuilder.In<IsActive> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UsageLimitEntity._isActive));
|
||||||
|
for (IsActive item : this.isActives)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.usageLimitMetricValues != null) {
|
||||||
|
CriteriaBuilder.In<UsageLimitMetricValue> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UsageLimitEntity._metricValue));
|
||||||
|
for (UsageLimitMetricValue item : this.usageLimitMetricValues)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.excludedIds != null) {
|
||||||
|
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceEntity._id));
|
||||||
|
for (UUID item : this.excludedIds)
|
||||||
|
notInClause.value(item);
|
||||||
|
predicates.add(notInClause.not());
|
||||||
|
}
|
||||||
|
if (!predicates.isEmpty()) {
|
||||||
|
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||||
|
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UsageLimitEntity convert(Tuple tuple, Set<String> columns) {
|
||||||
|
UsageLimitEntity item = new UsageLimitEntity();
|
||||||
|
item.setId(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._id, UUID.class));
|
||||||
|
item.setTenantId(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._tenantId, UUID.class));
|
||||||
|
item.setLabel(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._label, String.class));
|
||||||
|
item.setMetricValue(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._metricValue, UsageLimitMetricValue.class));
|
||||||
|
item.setValue(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._value, Long.class));
|
||||||
|
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._createdAt, Instant.class));
|
||||||
|
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._updatedAt, Instant.class));
|
||||||
|
item.setIsActive(QueryBase.convertSafe(tuple, columns, UsageLimitEntity._isActive, IsActive.class));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String fieldNameOf(FieldResolver item) {
|
||||||
|
if (item.match(UsageLimit._id))
|
||||||
|
return UsageLimitEntity._id;
|
||||||
|
else if (item.match(UsageLimit._label))
|
||||||
|
return UsageLimitEntity._label;
|
||||||
|
else if (item.match(UsageLimit._metricValue))
|
||||||
|
return UsageLimitEntity._metricValue;
|
||||||
|
else if (item.match(UsageLimit._value))
|
||||||
|
return UsageLimitEntity._value;
|
||||||
|
else if (item.match(UsageLimit._createdAt))
|
||||||
|
return UsageLimitEntity._createdAt;
|
||||||
|
else if (item.match(UsageLimit._updatedAt))
|
||||||
|
return UsageLimitEntity._updatedAt;
|
||||||
|
else if (item.match(UsageLimit._hash))
|
||||||
|
return UsageLimitEntity._updatedAt;
|
||||||
|
else if (item.match(UsageLimit._isActive))
|
||||||
|
return UsageLimitEntity._isActive;
|
||||||
|
else if (item.prefix(UsageLimit._belongsToCurrentTenant))
|
||||||
|
return UsageLimitEntity._tenantId;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package org.opencdmp.query.lookup;
|
||||||
|
|
||||||
|
import gr.cite.tools.data.query.Lookup;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.query.UsageLimitQuery;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UsageLimitLookup extends Lookup {
|
||||||
|
|
||||||
|
private String like;
|
||||||
|
private List<IsActive> isActive;
|
||||||
|
private List<UUID> ids;
|
||||||
|
private List<UsageLimitMetricValue> usageLimitMetricValues;
|
||||||
|
private List<UUID> excludedIds;
|
||||||
|
|
||||||
|
public String getLike() {
|
||||||
|
return like;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLike(String like) {
|
||||||
|
this.like = like;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IsActive> getIsActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsActive(List<IsActive> isActive) {
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UUID> getIds() {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIds(List<UUID> ids) { this.ids = ids; }
|
||||||
|
|
||||||
|
public List<UsageLimitMetricValue> getUsageLimitsMetricValues() {
|
||||||
|
return usageLimitMetricValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsageLimitsMetricValues(List<UsageLimitMetricValue> usageLimitMetricValues) {
|
||||||
|
this.usageLimitMetricValues = usageLimitMetricValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UUID> getExcludedIds() {
|
||||||
|
return excludedIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExcludedIds(List<UUID> excludeIds) {
|
||||||
|
this.excludedIds = excludeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsageLimitQuery enrich(QueryFactory queryFactory) {
|
||||||
|
UsageLimitQuery query = queryFactory.query(UsageLimitQuery.class);
|
||||||
|
if (this.like != null) query.like(this.like);
|
||||||
|
if (this.isActive != null) query.isActive(this.isActive);
|
||||||
|
if (this.ids != null) query.ids(this.ids);
|
||||||
|
if (this.usageLimitMetricValues != null) query.usageLimitMetricValues(this.usageLimitMetricValues);
|
||||||
|
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
|
||||||
|
|
||||||
|
this.enrichCommon(query);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,23 @@
|
||||||
package org.opencdmp.service.usagelimit;
|
package org.opencdmp.service.usagelimit;
|
||||||
|
|
||||||
public class UsageLimitService {
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.exception.MyValidationException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.model.UsageLimit;
|
||||||
|
import org.opencdmp.model.persist.UsageLimitPersist;
|
||||||
|
|
||||||
private void checkIncrease(String metric) {
|
import javax.management.InvalidApplicationException;
|
||||||
//Get/Calculate current metric value from accountingService
|
import java.util.UUID;
|
||||||
//Find metric value from db
|
|
||||||
// compare these two and throw UsageLimitException when current > metric value
|
public interface UsageLimitService {
|
||||||
}
|
|
||||||
|
UsageLimit persist(UsageLimitPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException;
|
||||||
|
|
||||||
|
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException;
|
||||||
|
|
||||||
|
void checkIncrease(UsageLimitMetricValue metric);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
package org.opencdmp.service.usagelimit;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.exception.MyValidationException;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import org.opencdmp.authorization.AuthorizationFlags;
|
||||||
|
import org.opencdmp.authorization.Permission;
|
||||||
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
|
import org.opencdmp.commons.enums.UsageLimitMetricValue;
|
||||||
|
import org.opencdmp.commons.scope.user.UserScope;
|
||||||
|
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.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 javax.management.InvalidApplicationException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UsageLimitServiceImpl implements UsageLimitService {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UsageLimitServiceImpl.class));
|
||||||
|
|
||||||
|
private final TenantEntityManager entityManager;
|
||||||
|
|
||||||
|
private final AuthorizationService authorizationService;
|
||||||
|
|
||||||
|
private final DeleterFactory deleterFactory;
|
||||||
|
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
|
||||||
|
private final ConventionService conventionService;
|
||||||
|
|
||||||
|
private final ErrorThesaurusProperties errors;
|
||||||
|
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
|
||||||
|
private final UserScope userScope;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UsageLimitServiceImpl(
|
||||||
|
TenantEntityManager entityManager,
|
||||||
|
AuthorizationService authorizationService,
|
||||||
|
DeleterFactory deleterFactory,
|
||||||
|
BuilderFactory builderFactory,
|
||||||
|
ConventionService conventionService,
|
||||||
|
ErrorThesaurusProperties errors,
|
||||||
|
MessageSource messageSource,
|
||||||
|
UserScope userScope) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
this.authorizationService = authorizationService;
|
||||||
|
this.deleterFactory = deleterFactory;
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
this.conventionService = conventionService;
|
||||||
|
this.errors = errors;
|
||||||
|
this.messageSource = messageSource;
|
||||||
|
this.userScope = userScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
this.authorizationService.authorizeForce(Permission.EditUsageLimit);
|
||||||
|
|
||||||
|
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
||||||
|
|
||||||
|
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 (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
|
||||||
|
} else {
|
||||||
|
data = new UsageLimitEntity();
|
||||||
|
data.setId(UUID.randomUUID());
|
||||||
|
data.setIsActive(IsActive.Active);
|
||||||
|
data.setCreatedAt(Instant.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setLabel(model.getLabel());
|
||||||
|
data.setMetricValue(model.getMetricValue());
|
||||||
|
data.setValue(model.getValue());
|
||||||
|
data.setUpdatedAt(Instant.now());
|
||||||
|
if (isUpdate)
|
||||||
|
this.entityManager.merge(data);
|
||||||
|
else
|
||||||
|
this.entityManager.persist(data);
|
||||||
|
|
||||||
|
this.entityManager.flush();
|
||||||
|
return this.builderFactory.builder(UsageLimitBuilder.class).authorize(AuthorizationFlags.AllExceptPublic).build(BaseFieldSet.build(fields, UsageLimit._id), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||||
|
logger.debug("deleting UsageLimit: {}", id);
|
||||||
|
|
||||||
|
this.authorizationService.authorizeForce(Permission.DeleteUsageLimit);
|
||||||
|
|
||||||
|
this.deleterFactory.deleter(UsageLimitDeleter.class).deleteAndSaveByIds(List.of(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkIncrease(UsageLimitMetricValue metric) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package org.opencdmp.controllers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import gr.cite.tools.auditing.AuditService;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.censor.CensorFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import gr.cite.tools.validation.ValidationFilterAnnotation;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import jakarta.xml.bind.JAXBException;
|
||||||
|
import org.opencdmp.audit.AuditableAction;
|
||||||
|
import org.opencdmp.authorization.AuthorizationFlags;
|
||||||
|
import org.opencdmp.data.UsageLimitEntity;
|
||||||
|
import org.opencdmp.model.UsageLimit;
|
||||||
|
import org.opencdmp.model.builder.UsageLimitBuilder;
|
||||||
|
import org.opencdmp.model.censorship.UsageLimitsCensor;
|
||||||
|
import org.opencdmp.model.persist.UsageLimitPersist;
|
||||||
|
import org.opencdmp.model.result.QueryResult;
|
||||||
|
import org.opencdmp.query.UsageLimitQuery;
|
||||||
|
import org.opencdmp.query.lookup.UsageLimitLookup;
|
||||||
|
import org.opencdmp.service.usagelimit.UsageLimitService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(path = "api/usage-limit")
|
||||||
|
public class UsageFilterController {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UsageFilterController.class));
|
||||||
|
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
|
private final UsageLimitService usageLimitService;
|
||||||
|
|
||||||
|
private final CensorFactory censorFactory;
|
||||||
|
|
||||||
|
private final QueryFactory queryFactory;
|
||||||
|
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
|
||||||
|
public UsageFilterController(
|
||||||
|
BuilderFactory builderFactory,
|
||||||
|
AuditService auditService,
|
||||||
|
UsageLimitService usageLimitService,
|
||||||
|
CensorFactory censorFactory,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
MessageSource messageSource) {
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
this.auditService = auditService;
|
||||||
|
this.usageLimitService = usageLimitService;
|
||||||
|
this.censorFactory = censorFactory;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.messageSource = messageSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("query")
|
||||||
|
public QueryResult<UsageLimit> query(@RequestBody UsageLimitLookup lookup) throws MyApplicationException, MyForbiddenException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, InvalidApplicationException {
|
||||||
|
logger.debug("querying {}", UsageLimit.class.getSimpleName());
|
||||||
|
|
||||||
|
this.censorFactory.censor(UsageLimitsCensor.class).censor(lookup.getProject());
|
||||||
|
UsageLimitQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.AllExceptPublic);
|
||||||
|
|
||||||
|
List<UsageLimitEntity> data = query.collectAs(lookup.getProject());
|
||||||
|
List<UsageLimit> models = this.builderFactory.builder(UsageLimitBuilder.class).authorize(AuthorizationFlags.AllExceptPublic).build(lookup.getProject(), data);
|
||||||
|
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.UsageLimit_Query, "lookup", lookup);
|
||||||
|
|
||||||
|
return new QueryResult<>(models, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("{id}")
|
||||||
|
public UsageLimit get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("retrieving" + UsageLimit.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||||
|
|
||||||
|
this.censorFactory.censor(UsageLimitsCensor.class).censor(fieldSet);
|
||||||
|
|
||||||
|
UsageLimitQuery query = this.queryFactory.query(UsageLimitQuery.class).disableTracking().authorize(AuthorizationFlags.AllExceptPublic).ids(id);
|
||||||
|
UsageLimit model = this.builderFactory.builder(UsageLimitBuilder.class).authorize(AuthorizationFlags.AllExceptPublic).build(fieldSet, query.firstAs(fieldSet));
|
||||||
|
if (model == null)
|
||||||
|
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, UsageLimit.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.UsageLimit_Lookup, Map.ofEntries(
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("id", id),
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||||
|
));
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("persist")
|
||||||
|
@Transactional
|
||||||
|
@ValidationFilterAnnotation(validator = UsageLimitPersist.UsageLimitPersistValidator.ValidatorName, argumentName = "model")
|
||||||
|
public UsageLimit persist(@RequestBody UsageLimitPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
|
||||||
|
logger.debug(new MapLogEntry("persisting" + UsageLimit.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
|
||||||
|
this.censorFactory.censor(UsageLimitsCensor.class).censor(fieldSet);
|
||||||
|
|
||||||
|
UsageLimit persisted = this.usageLimitService.persist(model, fieldSet);
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.UsageLimit_Persist, Map.ofEntries(
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("model", model),
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||||
|
));
|
||||||
|
|
||||||
|
return persisted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("{id}")
|
||||||
|
@Transactional
|
||||||
|
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("retrieving" + UsageLimit.class.getSimpleName()).And("id", id));
|
||||||
|
|
||||||
|
this.usageLimitService.deleteAndSave(id);
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.UsageLimit_Delete, "id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1063,6 +1063,28 @@ permissions:
|
||||||
clients: [ ]
|
clients: [ ]
|
||||||
allowAnonymous: false
|
allowAnonymous: false
|
||||||
allowAuthenticated: false
|
allowAuthenticated: false
|
||||||
|
|
||||||
|
# Tenant Permissions
|
||||||
|
BrowseUsageLimit:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
EditUsageLimit:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
DeleteUsageLimit:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
claims: [ ]
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
BrowseStatus:
|
BrowseStatus:
|
||||||
roles:
|
roles:
|
||||||
|
@ -1179,6 +1201,12 @@ permissions:
|
||||||
clients: [ ]
|
clients: [ ]
|
||||||
allowAnonymous: false
|
allowAnonymous: false
|
||||||
allowAuthenticated: false
|
allowAuthenticated: false
|
||||||
|
ViewUsageLimitPage:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
ViewDescriptionTemplatePage:
|
ViewDescriptionTemplatePage:
|
||||||
roles:
|
roles:
|
||||||
- Admin
|
- Admin
|
||||||
|
|
|
@ -4,7 +4,7 @@ BEGIN
|
||||||
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
||||||
IF FOUND THEN RETURN; END IF;
|
IF FOUND THEN RETURN; END IF;
|
||||||
|
|
||||||
CREATE TABLE public."UsageLimits"
|
CREATE TABLE public."UsageLimit"
|
||||||
(
|
(
|
||||||
id uuid NOT NULL,
|
id uuid NOT NULL,
|
||||||
label character varying NOT NULL,
|
label character varying NOT NULL,
|
||||||
|
@ -15,13 +15,13 @@ BEGIN
|
||||||
is_active smallint NOT NULL,
|
is_active smallint NOT NULL,
|
||||||
tenant uuid,
|
tenant uuid,
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
CONSTRAINT "UsageLimits_tenant_fkey" FOREIGN KEY (tenant)
|
CONSTRAINT "UsageLimit_tenant_fkey" FOREIGN KEY (tenant)
|
||||||
REFERENCES public."Tenant" (id) MATCH SIMPLE
|
REFERENCES public."Tenant" (id) MATCH SIMPLE
|
||||||
ON UPDATE NO ACTION
|
ON UPDATE NO ACTION
|
||||||
ON DELETE NO ACTION
|
ON DELETE NO ACTION
|
||||||
NOT VALID
|
NOT VALID
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.067', '2024-11-07 12:00:00.000000+02', now(), 'Add UsageLimits table.');
|
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.067', '2024-11-07 12:00:00.000000+02', now(), 'Add UsageLimit table.');
|
||||||
|
|
||||||
END$$;
|
END$$;
|
Loading…
Reference in New Issue