Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-04-26 18:38:07 +03:00
commit 0c54b11923
48 changed files with 214 additions and 2066 deletions

View File

@ -1,129 +0,0 @@
package gr.cite.annotation.web.controllers;
import gr.cite.annotation.audit.AuditableAction;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.data.TenantConfigurationEntity;
import gr.cite.annotation.model.TenantConfiguration;
import gr.cite.annotation.model.builder.TenantConfigurationBuilder;
import gr.cite.annotation.model.censorship.TenantConfigurationCensor;
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationEmailClientPersist;
import gr.cite.annotation.query.TenantConfigurationQuery;
import gr.cite.annotation.query.lookup.TenantConfigurationLookup;
import gr.cite.annotation.service.tenantconfiguration.TenantConfigurationService;
import gr.cite.annotation.web.model.QueryResult;
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 org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import java.util.*;
@RestController
@RequestMapping(path = "api/annotation/tenant-configuration")
public class TenantConfigurationController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantConfigurationController.class));
private final BuilderFactory builderFactory;
private final AuditService auditService;
private final TenantConfigurationService tenantConfigurationService;
private final CensorFactory censorFactory;
private final QueryFactory queryFactory;
private final MessageSource messageSource;
@Autowired
public TenantConfigurationController(BuilderFactory builderFactory,
AuditService auditService,
TenantConfigurationService tenantConfigurationService, CensorFactory censorFactory,
QueryFactory queryFactory,
MessageSource messageSource) {
this.builderFactory = builderFactory;
this.auditService = auditService;
this.tenantConfigurationService = tenantConfigurationService;
this.censorFactory = censorFactory;
this.queryFactory = queryFactory;
this.messageSource = messageSource;
}
@PostMapping("query")
public QueryResult<TenantConfiguration> query(@RequestBody TenantConfigurationLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", TenantConfiguration.class.getSimpleName());
this.censorFactory.censor(TenantConfigurationCensor.class).censor(lookup.getProject());
TenantConfigurationQuery query = lookup.enrich(this.queryFactory);
List<TenantConfigurationEntity> data = query.collectAs(lookup.getProject());
List<TenantConfiguration> models = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermissionAssociated).build(lookup.getProject(), data);
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
this.auditService.track(AuditableAction.Tenant_Configuration_Query, "lookup", lookup);
return new QueryResult<>(models, count);
}
@GetMapping("{id}")
@Transactional
public TenantConfiguration get(@PathVariable UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + TenantConfiguration.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(TenantConfigurationCensor.class).censor(fieldSet);
TenantConfigurationQuery query = this.queryFactory.query(TenantConfigurationQuery.class).ids(id);
TenantConfiguration model = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermissionAssociated).build(fieldSet, query.firstAs(fieldSet));
if (model == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, TenantConfiguration.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.Tenant_Configuration_Lookup, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
));
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
return model;
}
@PostMapping("persist/email-client")
@Transactional
@ValidationFilterAnnotation(validator = TenantConfigurationEmailClientPersist.TenantConfigurationEmailClientPersistValidator.ValidatorName, argumentName = "model")
public TenantConfiguration persist(@RequestBody TenantConfigurationEmailClientPersist model, FieldSet fieldSet)
{
logger.debug(new MapLogEntry("persisting").And("type", TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION).And("model", model).And("fields", fieldSet));
TenantConfiguration persisted = this.tenantConfigurationService.persist(model, fieldSet);
this.auditService.track(AuditableAction.Tenant_Configuration_Persist, Map.of(
"type", TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION,
"model", model,
"fields", fieldSet
));
//this._auditService.TrackIdentity(AuditableAction.IdentityTracking_Action);
return persisted;
}
@DeleteMapping("{id}")
@Transactional
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("deleting" + TenantConfiguration.class.getSimpleName()).And("id", id));
this.tenantConfigurationService.deleteAndSave(id);
this.auditService.track(AuditableAction.Tenant_Configuration_Delete, "id", id);
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
}
}

View File

@ -1,35 +0,0 @@
package gr.cite.annotation.common.types.tenant;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)
public class TenantConfigEntity {
@XmlElement(name = "deposit-configuration")
private TenantDepositConfigEntity deposit;
@XmlElement(name = "file-transformers-configuration")
private TenantFileTransformersConfigEntity fileTransformers;
public TenantDepositConfigEntity getDeposit() {
return deposit;
}
public void setDeposit(TenantDepositConfigEntity deposit) {
this.deposit = deposit;
}
public TenantFileTransformersConfigEntity getFileTransformers() {
return fileTransformers;
}
public void setFileTransformers(TenantFileTransformersConfigEntity fileTransformers) {
this.fileTransformers = fileTransformers;
}
}

View File

@ -1,25 +0,0 @@
package gr.cite.annotation.common.types.tenant;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class TenantDepositConfigEntity {
@XmlElementWrapper(name = "sources")
@XmlElement(name = "source")
private List<TenantSourceEntity> sources;
public List<TenantSourceEntity> getSources() {
return sources;
}
public void setSources(List<TenantSourceEntity> sources) {
this.sources = sources;
}
}

View File

@ -1,24 +0,0 @@
package gr.cite.annotation.common.types.tenant;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class TenantFileTransformersConfigEntity {
@XmlElementWrapper(name = "sources")
@XmlElement(name = "source")
private List<TenantSourceEntity> sources;
public List<TenantSourceEntity> getSources() {
return sources;
}
public void setSources(List<TenantSourceEntity> sources) {
this.sources = sources;
}
}

View File

@ -1,79 +0,0 @@
package gr.cite.annotation.common.types.tenant;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class TenantSourceEntity {
@XmlElement(name = "url")
private String url;
@XmlElementWrapper(name = "codes")
@XmlElement(name = "code")
private List<String> codes;
@XmlElement(name = "issuer-url")
private String issuerUrl;
@XmlElement(name = "client-id")
private String clientId;
@XmlElement(name = "client-secret")
private String clientSecret;
@XmlElement(name = "scope")
private String scope;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<String> getCodes() {
return codes;
}
public void setCodes(List<String> codes) {
this.codes = codes;
}
public String getIssuerUrl() {
return issuerUrl;
}
public void setIssuerUrl(String issuerUrl) {
this.issuerUrl = issuerUrl;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@ -1,37 +0,0 @@
package gr.cite.annotation.common.types.tenantconfiguration;
public class DefaultUserLocaleConfigurationDataContainer {
public static class Field {
public static final String LANGUAGE = "language";
public static final String TIME_ZONE = "timeZone";
public static final String CULTURE = "culture";
}
private String language;
private String timeZone;
private String culture;
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getCulture() {
return culture;
}
public void setCulture(String culture) {
this.culture = culture;
}
}

View File

@ -1,87 +0,0 @@
package gr.cite.annotation.common.types.tenantconfiguration;
public class EmailClientConfigurationDataContainer {
public static class Field {
public static final String REQUIRE_CREDENTIALS = "requireCredentials";
public static final String ENABLE_SSL = "enableSSL";
public static final String CERTIFICATE_PATH = "certificatePath";
public static final String HOST_SERVER = "hostServer";
public static final String HOST_PORT_NO = "hostPortNo";
public static final String EMAIL_ADDRESS = "emailAddress";
public static final String EMAIL_USER_NAME = "emailUserName";
public static final String EMAIL_PASSWORD = "emailPassword";
}
private Boolean requireCredentials;
private Boolean enableSSL;
private String certificatePath;
private String hostServer;
private Integer hostPortNo;
private String emailAddress;
private String emailUserName;
private String emailPassword;
public Boolean getRequireCredentials() {
return requireCredentials;
}
public void setRequireCredentials(Boolean requireCredentials) {
this.requireCredentials = requireCredentials;
}
public Boolean getEnableSSL() {
return enableSSL;
}
public void setEnableSSL(Boolean enableSSL) {
this.enableSSL = enableSSL;
}
public String getCertificatePath() {
return certificatePath;
}
public void setCertificatePath(String certificatePath) {
this.certificatePath = certificatePath;
}
public String getHostServer() {
return hostServer;
}
public void setHostServer(String hostServer) {
this.hostServer = hostServer;
}
public Integer getHostPortNo() {
return hostPortNo;
}
public void setHostPortNo(Integer hostPortNo) {
this.hostPortNo = hostPortNo;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getEmailUserName() {
return emailUserName;
}
public void setEmailUserName(String emailUserName) {
this.emailUserName = emailUserName;
}
public String getEmailPassword() {
return emailPassword;
}
public void setEmailPassword(String emailPassword) {
this.emailPassword = emailPassword;
}
}

View File

@ -1,113 +0,0 @@
package gr.cite.annotation.data;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.data.conventers.IsActiveConverter;
import gr.cite.annotation.data.conventers.TenantConfigurationTypeConverter;
import gr.cite.annotation.data.tenant.TenantScopedBaseEntity;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;
@Entity
@Table(name = "\"TenantConfiguration\"")
public class TenantConfigurationEntity extends TenantScopedBaseEntity {
@Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public static final String _id = "id";
@Column(name = "type", nullable = false)
@Convert(converter = TenantConfigurationTypeConverter.class)
private TenantConfigurationType type;
public static final String _type = "type";
@Column(name = "value", nullable = false)
private String value;
public static final String _value = "value";
@Column(name = "\"tenant\"", columnDefinition = "uuid")
private UUID tenantId;
public static final String _tenantId = "tenantId";
@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";
@Column(name = "is_active", nullable = false)
@Convert(converter = IsActiveConverter.class)
private IsActive isActive;
public static final String _isActive = "isActive";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public TenantConfigurationType getType() {
return type;
}
public void setType(TenantConfigurationType type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public UUID getTenantId() {
return tenantId;
}
@Override
public void setTenantId(UUID tenantId) {
this.tenantId = tenantId;
}
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 IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
}

View File

@ -1,132 +0,0 @@
package gr.cite.annotation.model;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.common.types.tenantconfiguration.DefaultUserLocaleConfigurationDataContainer;
import gr.cite.annotation.common.types.tenantconfiguration.EmailClientConfigurationDataContainer;
import java.time.Instant;
import java.util.UUID;
public class TenantConfiguration {
private UUID id;
public static final String _id = "id";
private UUID tenantId;
public static final String _tenantId = "tenantId";
private TenantConfigurationType type;
public static final String _type = "type";
private String value;
public static final String _value = "value";
private EmailClientConfigurationDataContainer emailClientData;
public static final String _emailClientData = "emailClientData";
private DefaultUserLocaleConfigurationDataContainer defaultUserLocaleData;
public static final String _defaultUserLocaleData = "defaultUserLocaleData";
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";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getTenantId() {
return tenantId;
}
public void setTenantId(UUID tenantId) {
this.tenantId = tenantId;
}
public TenantConfigurationType getType() {
return type;
}
public void setType(TenantConfigurationType type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public EmailClientConfigurationDataContainer getEmailClientData() {
return emailClientData;
}
public void setEmailClientData(EmailClientConfigurationDataContainer emailClientData) {
this.emailClientData = emailClientData;
}
public DefaultUserLocaleConfigurationDataContainer getDefaultUserLocaleData() {
return defaultUserLocaleData;
}
public void setDefaultUserLocaleData(DefaultUserLocaleConfigurationDataContainer defaultUserLocaleData) {
this.defaultUserLocaleData = defaultUserLocaleData;
}
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;
}
}

View File

@ -1,117 +0,0 @@
package gr.cite.annotation.model.builder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.types.tenantconfiguration.DefaultUserLocaleConfigurationDataContainer;
import gr.cite.annotation.common.types.tenantconfiguration.EmailClientConfigurationDataContainer;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.data.TenantConfigurationEntity;
import gr.cite.annotation.model.TenantConfiguration;
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.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import java.util.*;
@Component
@RequestScope
public class TenantConfigurationBuilder extends BaseBuilder<TenantConfiguration, TenantConfigurationEntity> {
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
private final ObjectMapper mapper;
@Autowired
public TenantConfigurationBuilder(ConventionService conventionService) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(TenantConfigurationBuilder.class)));
this.mapper = new ObjectMapper();
}
public TenantConfigurationBuilder authorize(EnumSet<AuthorizationFlags> values){
this.authorize = values;
return this;
}
@Override
public List<TenantConfiguration> build(FieldSet fields, List<TenantConfigurationEntity> 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<TenantConfiguration> models = new ArrayList<>();
for(TenantConfigurationEntity d : data){
TenantConfiguration m = new TenantConfiguration();
if(fields.hasField(this.asIndexer(TenantConfiguration._id))) m.setId(d.getId());
if(fields.hasField(this.asIndexer(TenantConfiguration._tenantId))) m.setTenantId(d.getTenantId());
if(fields.hasField(this.asIndexer(TenantConfiguration._type))) m.setType(d.getType());
if(fields.hasField(this.asIndexer(TenantConfiguration._value))) m.setValue(d.getValue());
if(fields.hasField(this.asIndexer(TenantConfiguration._defaultUserLocaleData))) {
try {
m.setDefaultUserLocaleData(mapper.readValue(d.getValue(), DefaultUserLocaleConfigurationDataContainer.class));
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
}
if (!fields.extractPrefixed(this.asIndexer(TenantConfiguration._defaultUserLocaleData)).isEmpty()) {
try {
DefaultUserLocaleConfigurationDataContainer container = mapper.readValue(d.getValue(), DefaultUserLocaleConfigurationDataContainer.class);
if (container != null) {
m.setDefaultUserLocaleData(new DefaultUserLocaleConfigurationDataContainer());
if (fields.hasField(this.asIndexer(TenantConfiguration._defaultUserLocaleData, DefaultUserLocaleConfigurationDataContainer.Field.LANGUAGE)))
m.getDefaultUserLocaleData().setLanguage(container.getLanguage());
if (fields.hasField(this.asIndexer(TenantConfiguration._defaultUserLocaleData, DefaultUserLocaleConfigurationDataContainer.Field.TIME_ZONE)))
m.getDefaultUserLocaleData().setTimeZone(container.getTimeZone());
if (fields.hasField(this.asIndexer(TenantConfiguration._defaultUserLocaleData, DefaultUserLocaleConfigurationDataContainer.Field.CULTURE)))
m.getDefaultUserLocaleData().setCulture(container.getCulture());
}
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
}
if(fields.hasField(this.asIndexer(TenantConfiguration._emailClientData))) {
try {
m.setEmailClientData(mapper.readValue(d.getValue(), EmailClientConfigurationDataContainer.class));
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
}
if (!fields.extractPrefixed(this.asIndexer(TenantConfiguration._emailClientData)).isEmpty()) {
try {
EmailClientConfigurationDataContainer container = mapper.readValue(d.getValue(), EmailClientConfigurationDataContainer.class);
if (container != null) {
m.setEmailClientData(new EmailClientConfigurationDataContainer());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.ENABLE_SSL)))
m.getEmailClientData().setEnableSSL(container.getEnableSSL());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.REQUIRE_CREDENTIALS)))
m.getEmailClientData().setRequireCredentials(container.getRequireCredentials());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.HOST_SERVER)))
m.getEmailClientData().setHostServer(container.getHostServer());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.HOST_PORT_NO)))
m.getEmailClientData().setHostPortNo(container.getHostPortNo());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.CERTIFICATE_PATH)))
m.getEmailClientData().setCertificatePath(container.getCertificatePath());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.EMAIL_ADDRESS)))
m.getEmailClientData().setEmailAddress(container.getEmailAddress());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.EMAIL_USER_NAME)))
m.getEmailClientData().setEmailUserName(container.getEmailUserName());
if (fields.hasField(this.asIndexer(TenantConfiguration._emailClientData, EmailClientConfigurationDataContainer.Field.EMAIL_PASSWORD)))
m.getEmailClientData().setEmailPassword(container.getEmailPassword());
}
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
}
if(fields.hasField(this.asIndexer(TenantConfiguration._isActive))) m.setIsActive(d.getIsActive());
if(fields.hasField(this.asIndexer(TenantConfiguration._createdAt))) m.setCreatedAt(d.getCreatedAt());
if(fields.hasField(this.asIndexer(TenantConfiguration._updatedAt))) m.setUpdatedAt(d.getUpdatedAt());
if(fields.hasField(this.asIndexer(TenantConfiguration._hash))) m.setHash(this.hashValue(d.getUpdatedAt()));
models.add(m);
}
this.logger.debug("build {} items",Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -1,60 +0,0 @@
package gr.cite.annotation.model.builder.tenantconfig;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.types.tenant.TenantConfigEntity;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.model.builder.BaseBuilder;
import gr.cite.annotation.model.tenantconfig.TenantConfig;
import gr.cite.tools.data.builder.BuilderFactory;
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.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 TenantConfigBuilder extends BaseBuilder<TenantConfig, TenantConfigEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public TenantConfigBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(TenantConfigBuilder.class)));
this.builderFactory = builderFactory;
}
public TenantConfigBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<TenantConfig> build(FieldSet fields, List<TenantConfigEntity> 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<>();
FieldSet depositFields = fields.extractPrefixed(this.asPrefix(TenantConfig._deposit));
FieldSet fileFields = fields.extractPrefixed(this.asPrefix(TenantConfig._fileTransformers));
List<TenantConfig> models = new ArrayList<>();
for (TenantConfigEntity d : data) {
TenantConfig m = new TenantConfig();
if (!depositFields.isEmpty() && d.getDeposit() != null) m.setDeposit(this.builderFactory.builder(TenantDepositConfigBuilder.class).authorize(this.authorize).build(depositFields, d.getDeposit()));
if (!fileFields.isEmpty() && d.getFileTransformers() != null) m.setFileTransformers(this.builderFactory.builder(TenantFileTransformersBuilder.class).authorize(this.authorize).build(fileFields, d.getFileTransformers()));
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -1,61 +0,0 @@
package gr.cite.annotation.model.builder.tenantconfig;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.types.tenant.TenantDepositConfigEntity;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.model.builder.BaseBuilder;
import gr.cite.annotation.model.tenantconfig.TenantDepositConfig;
import gr.cite.tools.data.builder.BuilderFactory;
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.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 TenantDepositConfigBuilder extends BaseBuilder<TenantDepositConfig, TenantDepositConfigEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public TenantDepositConfigBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(TenantDepositConfigBuilder.class)));
this.builderFactory = builderFactory;
}
public TenantDepositConfigBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<TenantDepositConfig> build(FieldSet fields, List<TenantDepositConfigEntity> 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<>();
FieldSet sourcesFields = fields.extractPrefixed(this.asPrefix(TenantDepositConfig._sources));
List<TenantDepositConfig> models = new ArrayList<>();
for (TenantDepositConfigEntity d : data) {
TenantDepositConfig m = new TenantDepositConfig();
if (!sourcesFields.isEmpty() && d.getSources() != null) {
m.setSources(this.builderFactory.builder(TenantSourceBuilder.class).authorize(this.authorize).build(sourcesFields, d.getSources()));
}
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -1,61 +0,0 @@
package gr.cite.annotation.model.builder.tenantconfig;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.types.tenant.TenantFileTransformersConfigEntity;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.model.builder.BaseBuilder;
import gr.cite.annotation.model.tenantconfig.TenantFileTransformersConfig;
import gr.cite.tools.data.builder.BuilderFactory;
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.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 TenantFileTransformersBuilder extends BaseBuilder<TenantFileTransformersConfig, TenantFileTransformersConfigEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public TenantFileTransformersBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(TenantFileTransformersBuilder.class)));
this.builderFactory = builderFactory;
}
public TenantFileTransformersBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<TenantFileTransformersConfig> build(FieldSet fields, List<TenantFileTransformersConfigEntity> 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<>();
FieldSet sourcesFields = fields.extractPrefixed(this.asPrefix(TenantFileTransformersConfig._sources));
List<TenantFileTransformersConfig> models = new ArrayList<>();
for (TenantFileTransformersConfigEntity d : data) {
TenantFileTransformersConfig m = new TenantFileTransformersConfig();
if (!sourcesFields.isEmpty() && d.getSources() != null) {
m.setSources(this.builderFactory.builder(TenantSourceBuilder.class).authorize(this.authorize).build(sourcesFields, d.getSources()));
}
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -1,62 +0,0 @@
package gr.cite.annotation.model.builder.tenantconfig;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.common.types.tenant.TenantSourceEntity;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.model.builder.BaseBuilder;
import gr.cite.annotation.model.tenantconfig.TenantSource;
import gr.cite.tools.data.builder.BuilderFactory;
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.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 TenantSourceBuilder extends BaseBuilder<TenantSource, TenantSourceEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public TenantSourceBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(TenantSourceBuilder.class)));
this.builderFactory = builderFactory;
}
public TenantSourceBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<TenantSource> build(FieldSet fields, List<TenantSourceEntity> 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<TenantSource> models = new ArrayList<>();
for (TenantSourceEntity d : data) {
TenantSource m = new TenantSource();
if (fields.hasField(this.asIndexer(TenantSource._url))) m.setUrl(d.getUrl());
if (fields.hasField(this.asIndexer(TenantSource._codes))) m.setCodes(d.getCodes());
if (fields.hasField(this.asIndexer(TenantSource._issuerUrl))) m.setIssuerUrl(d.getIssuerUrl());
if (fields.hasField(this.asIndexer(TenantSource._clientId))) m.setClientId(d.getClientId());
if (fields.hasField(this.asIndexer(TenantSource._clientSecret))) m.setClientSecret(d.getClientSecret());
if (fields.hasField(this.asIndexer(TenantSource._scope))) m.setScope(d.getScope());
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -1,32 +0,0 @@
package gr.cite.annotation.model.censorship;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.annotation.authorization.Permission;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
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;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TenantConfigurationCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantConfigurationCensor.class));
private final AuthorizationService authService;
@Autowired
public TenantConfigurationCensor(ConventionService conventionService, AuthorizationService authService) {
super(conventionService);
this.authService = authService;
}
public void censor(FieldSet fields) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (this.isEmpty(fields)) return;
this.authService.authorizeForce(Permission.BrowseTenantConfiguration);
}
}

View File

@ -1,78 +0,0 @@
package gr.cite.annotation.model.deleter;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.data.TenantConfigurationEntity;
import gr.cite.annotation.data.TenantEntityManager;
import gr.cite.annotation.query.TenantConfigurationQuery;
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.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;
import java.util.stream.Collectors;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TenantConfigurationDeleter implements Deleter {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantConfigurationDeleter.class));
private final TenantEntityManager entityManager;
protected final QueryFactory queryFactory;
private final DeleterFactory deleterFactory;
@Autowired
public TenantConfigurationDeleter(
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<TenantConfigurationEntity> data = this.queryFactory.query(TenantConfigurationQuery.class).ids(ids).collect();
logger.trace("received {} items", Optional.of(data).map(List::size).orElse(0));
this.deleteAndSave(data);
}
public void deleteAndSave(List<TenantConfigurationEntity> 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<TenantConfigurationEntity> datas) throws InvalidApplicationException {
logger.debug("will delete {} items", Optional.ofNullable(datas).map(List::size).orElse(0));
if (datas == null || datas.isEmpty()) return;
List<UUID> ids = datas.stream().map(TenantConfigurationEntity::getId).distinct().collect(Collectors.toList());
Instant now = Instant.now();
for (TenantConfigurationEntity item : datas) {
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");
}
}
}

View File

@ -1,177 +0,0 @@
package gr.cite.annotation.model.persist.tenantconfiguration;
import gr.cite.annotation.common.validation.BaseValidator;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
import gr.cite.tools.validation.specification.Specification;
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 TenantConfigurationEmailClientPersist {
private UUID id;
public static final String _id = "id";
private Boolean requireCredentials;
public static final String _requireCredentials = "requireCredentials";
private Boolean enableSSL;
public static final String _enableSSL = "enableSSL";
private String certificatePath;
public static final String _certificatePath = "certificatePath";
private String hostServer;
public static final String _hostServer = "hostServer";
private Integer hostPortNo;
public static final String _hostPortNo = "hostPortNo";
private String emailAddress;
public static final String _emailAddress = "emailAddress";
private String emailUserName;
public static final String _emailUserName = "emailUserName";
private String emailPassword;
public static final String _emailPassword = "emailPassword";
private String hash;
public static final String _hash = "hash";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Boolean getRequireCredentials() {
return requireCredentials;
}
public void setRequireCredentials(Boolean requireCredentials) {
this.requireCredentials = requireCredentials;
}
public Boolean getEnableSSL() {
return enableSSL;
}
public void setEnableSSL(Boolean enableSSL) {
this.enableSSL = enableSSL;
}
public String getCertificatePath() {
return certificatePath;
}
public void setCertificatePath(String certificatePath) {
this.certificatePath = certificatePath;
}
public String getHostServer() {
return hostServer;
}
public void setHostServer(String hostServer) {
this.hostServer = hostServer;
}
public Integer getHostPortNo() {
return hostPortNo;
}
public void setHostPortNo(Integer hostPortNo) {
this.hostPortNo = hostPortNo;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getEmailUserName() {
return emailUserName;
}
public void setEmailUserName(String emailUserName) {
this.emailUserName = emailUserName;
}
public String getEmailPassword() {
return emailPassword;
}
public void setEmailPassword(String emailPassword) {
this.emailPassword = emailPassword;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
@Component(TenantConfigurationEmailClientPersist.TenantConfigurationEmailClientPersistValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class TenantConfigurationEmailClientPersistValidator extends BaseValidator<TenantConfigurationEmailClientPersist> {
public static final String ValidatorName = "TenantConfigurationEmailClientPersistValidator";
private final MessageSource messageSource;
protected TenantConfigurationEmailClientPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
super(conventionService, errors);
this.messageSource = messageSource;
}
@Override
protected Class<TenantConfigurationEmailClientPersist> modelClass() {
return TenantConfigurationEmailClientPersist.class;
}
@Override
protected List<Specification> specifications(TenantConfigurationEmailClientPersist item) {
return Arrays.asList(
this.spec()
.iff(() -> this.isValidGuid(item.getId()))
.must(() -> this.isValidHash(item.getHash()))
.failOn(TenantConfigurationEmailClientPersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._hash}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isValidGuid(item.getId()))
.must(() -> !this.isValidHash(item.getHash()))
.failOn(TenantConfigurationEmailClientPersist._hash).failWith(messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getRequireCredentials()))
.failOn(TenantConfigurationEmailClientPersist._requireCredentials).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._requireCredentials}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getEnableSSL()))
.failOn(TenantConfigurationEmailClientPersist._enableSSL).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._enableSSL}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getCertificatePath()))
.failOn(TenantConfigurationEmailClientPersist._certificatePath).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._certificatePath}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getHostServer()))
.failOn(TenantConfigurationEmailClientPersist._hostServer).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._hostServer}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getHostPortNo()))
.failOn(TenantConfigurationEmailClientPersist._hostPortNo).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._hostPortNo}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getEmailAddress()))
.failOn(TenantConfigurationEmailClientPersist._emailAddress).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._emailAddress}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getEmailUserName()))
.failOn(TenantConfigurationEmailClientPersist._emailUserName).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._emailUserName}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getEmailPassword()))
.failOn(TenantConfigurationEmailClientPersist._emailPassword).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationEmailClientPersist._emailPassword}, LocaleContextHolder.getLocale()))
);
}
}
}

View File

@ -1,92 +0,0 @@
package gr.cite.annotation.model.persist.tenantconfiguration;
import gr.cite.annotation.common.validation.BaseValidator;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
import gr.cite.tools.validation.specification.Specification;
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;
public class TenantConfigurationUserLocaleIntegrationPersist {
private String language;
public static final String _language = "language";
private String timeZone;
public static final String _timeZone = "timeZone";
private String culture;
public static final String _culture = "culture";
private String hash;
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getCulture() {
return culture;
}
public void setCulture(String culture) {
this.culture = culture;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
@Component(TenantConfigurationUserLocaleIntegrationPersist.TenantConfigurationUserLocaleIntegrationPersistValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class TenantConfigurationUserLocaleIntegrationPersistValidator extends BaseValidator<TenantConfigurationUserLocaleIntegrationPersist> {
public static final String ValidatorName = "TenantConfigurationUserLocaleIntegrationPersistValidator";
private final MessageSource messageSource;
protected TenantConfigurationUserLocaleIntegrationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
super(conventionService, errors);
this.messageSource = messageSource;
}
@Override
protected Class<TenantConfigurationUserLocaleIntegrationPersist> modelClass() {
return TenantConfigurationUserLocaleIntegrationPersist.class;
}
@Override
protected List<Specification> specifications(TenantConfigurationUserLocaleIntegrationPersist item) {
return Arrays.asList(
this.spec()
.must(() -> !this.isNull(item.getLanguage()))
.failOn(TenantConfigurationUserLocaleIntegrationPersist._language).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationUserLocaleIntegrationPersist._language}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getTimeZone()))
.failOn(TenantConfigurationUserLocaleIntegrationPersist._timeZone).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationUserLocaleIntegrationPersist._timeZone}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getCulture()))
.failOn(TenantConfigurationUserLocaleIntegrationPersist._culture).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantConfigurationUserLocaleIntegrationPersist._culture}, LocaleContextHolder.getLocale()))
);
}
}
}

View File

@ -1,28 +0,0 @@
package gr.cite.annotation.model.tenantconfig;
public class TenantConfig {
public static final String _deposit = "deposit";
private TenantDepositConfig deposit;
public static final String _fileTransformers = "fileTransformers";
private TenantFileTransformersConfig fileTransformers;
public TenantDepositConfig getDeposit() {
return deposit;
}
public void setDeposit(TenantDepositConfig deposit) {
this.deposit = deposit;
}
public TenantFileTransformersConfig getFileTransformers() {
return fileTransformers;
}
public void setFileTransformers(TenantFileTransformersConfig fileTransformers) {
this.fileTransformers = fileTransformers;
}
}

View File

@ -1,17 +0,0 @@
package gr.cite.annotation.model.tenantconfig;
import java.util.List;
public class TenantDepositConfig {
public static final String _sources = "sources";
private List<TenantSource> sources;
public List<TenantSource> getSources() {
return sources;
}
public void setSources(List<TenantSource> sources) {
this.sources = sources;
}
}

View File

@ -1,17 +0,0 @@
package gr.cite.annotation.model.tenantconfig;
import java.util.List;
public class TenantFileTransformersConfig {
public static final String _sources = "sources";
private List<TenantSource> sources;
public List<TenantSource> getSources() {
return sources;
}
public void setSources(List<TenantSource> sources) {
this.sources = sources;
}
}

View File

@ -1,73 +0,0 @@
package gr.cite.annotation.model.tenantconfig;
import java.util.List;
public class TenantSource {
public static final String _url = "url";
private String url;
public static final String _codes = "codes";
private List<String> codes;
public static final String _issuerUrl = "issuerUrl";
private String issuerUrl;
public static final String _clientId = "clientId";
private String clientId;
public static final String _clientSecret = "clientSecret";
private String clientSecret;
public static final String _scope = "scope";
private String scope;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<String> getCodes() {
return codes;
}
public void setCodes(List<String> codes) {
this.codes = codes;
}
public String getIssuerUrl() {
return issuerUrl;
}
public void setIssuerUrl(String issuerUrl) {
this.issuerUrl = issuerUrl;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@ -1,129 +0,0 @@
package gr.cite.annotation.query;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.data.TenantConfigurationEntity;
import gr.cite.annotation.model.TenantConfiguration;
import gr.cite.tools.data.query.FieldResolver;
import gr.cite.tools.data.query.QueryBase;
import gr.cite.tools.data.query.QueryContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.Predicate;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.*;
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class TenantConfigurationQuery extends QueryBase<TenantConfigurationEntity> {
private List<UUID> ids;
private List<IsActive> isActives;
private List<TenantConfigurationType> type;
public TenantConfigurationQuery ids(UUID... ids) {
this.ids = Arrays.asList(ids);
return this;
}
public TenantConfigurationQuery ids(List<UUID> ids) {
this.ids = ids;
return this;
}
public TenantConfigurationQuery isActive(IsActive... isActives) {
this.isActives = Arrays.asList(isActives);
return this;
}
public TenantConfigurationQuery isActive(List<IsActive> isActive) {
this.isActives = isActive;
return this;
}
public TenantConfigurationQuery type(TenantConfigurationType... type) {
this.type = Arrays.asList(type);
return this;
}
public TenantConfigurationQuery type(List<TenantConfigurationType> type) {
this.type = type;
return this;
}
@Override
protected Boolean isFalseQuery() {
return this.isEmpty(this.ids) || this.isEmpty(this.isActives);
}
@Override
protected Class<TenantConfigurationEntity> entityClass() {
return TenantConfigurationEntity.class;
}
@Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
predicates.add(queryContext.Root.get(TenantConfigurationEntity._id).in(ids));
}
if (this.isActives != null) {
predicates.add(queryContext.Root.get(TenantConfigurationEntity._isActive).in(isActives));
}
if (type != null) {
predicates.add(queryContext.Root.get(TenantConfigurationEntity._type).in(type));
}
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {
return null;
}
}
@Override
protected String fieldNameOf(FieldResolver item) {
if (item.match(TenantConfiguration._id))
return TenantConfigurationEntity._id;
else if (item.match(TenantConfiguration._tenantId))
return TenantConfigurationEntity._tenantId;
else if (item.match(TenantConfiguration._defaultUserLocaleData))
return TenantConfiguration._defaultUserLocaleData;
else if (item.match(TenantConfiguration._emailClientData))
return TenantConfiguration._emailClientData;
else if (item.match(TenantConfiguration._type))
return TenantConfigurationEntity._type;
else if (item.match(TenantConfiguration._value))
return TenantConfigurationEntity._value;
else if (item.match(TenantConfiguration._createdAt))
return TenantConfigurationEntity._createdAt;
else if (item.match(TenantConfiguration._updatedAt))
return TenantConfigurationEntity._updatedAt;
else if (item.match(TenantConfiguration._isActive))
return TenantConfigurationEntity._isActive;
else
return null;
}
@Override
protected TenantConfigurationEntity convert(Tuple tuple, Set<String> columns) {
TenantConfigurationEntity item = new TenantConfigurationEntity();
item.setId(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._id, UUID.class));
item.setValue(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._value, String.class));
item.setType(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._type, TenantConfigurationType.class));
item.setTenantId(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._tenantId, UUID.class));
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._createdAt, Instant.class));
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._updatedAt, Instant.class));
item.setIsActive(QueryBase.convertSafe(tuple, columns, TenantConfigurationEntity._isActive, IsActive.class));
return item;
}
}

View File

@ -1,52 +0,0 @@
package gr.cite.annotation.query.lookup;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.query.TenantConfigurationQuery;
import gr.cite.tools.data.query.Lookup;
import gr.cite.tools.data.query.QueryFactory;
import java.util.List;
import java.util.UUID;
public class TenantConfigurationLookup extends Lookup {
private List<UUID> ids;
private List<IsActive> isActives;
private List<TenantConfigurationType> type;
public List<IsActive> getIsActives() {
return isActives;
}
public void setIsActives(List<IsActive> isActive) {
this.isActives = isActive;
}
public List<UUID> getIds() {
return ids;
}
public void setIds(List<UUID> ids) {
this.ids = ids;
}
public List<TenantConfigurationType> getType() {
return type;
}
public void setType(List<TenantConfigurationType> type) {
this.type = type;
}
public TenantConfigurationQuery enrich(QueryFactory queryFactory) {
TenantConfigurationQuery query = queryFactory.query(TenantConfigurationQuery.class);
if (this.isActives != null) query.isActive(this.isActives);
if (this.ids != null) query.ids(this.ids);
if (this.type != null) query.type(this.type);
this.enrichCommon(query);
return query;
}
}

View File

@ -1,20 +0,0 @@
package gr.cite.annotation.service.tenantconfiguration;
import gr.cite.annotation.common.types.tenantconfiguration.DefaultUserLocaleConfigurationDataContainer;
import gr.cite.annotation.common.types.tenantconfiguration.EmailClientConfigurationDataContainer;
import gr.cite.annotation.model.TenantConfiguration;
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationEmailClientPersist;
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationUserLocaleIntegrationPersist;
import gr.cite.tools.fieldset.FieldSet;
import javax.management.InvalidApplicationException;
import java.util.UUID;
public interface TenantConfigurationService {
EmailClientConfigurationDataContainer collectTenantEmailClient();
DefaultUserLocaleConfigurationDataContainer collectTenantUserLocale();
TenantConfiguration persist(TenantConfigurationEmailClientPersist emailClientPersist, FieldSet fieldSet);
TenantConfiguration persist(TenantConfigurationUserLocaleIntegrationPersist userLocaleIntegrationPersist, FieldSet fieldSet);
void deleteAndSave(UUID id) throws InvalidApplicationException;
}

View File

@ -1,207 +0,0 @@
package gr.cite.annotation.service.tenantconfiguration;
import com.fasterxml.jackson.core.JsonProcessingException;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.annotation.authorization.Permission;
import gr.cite.annotation.common.JsonHandlingService;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.common.enums.TenantConfigurationType;
import gr.cite.annotation.common.types.tenantconfiguration.DefaultUserLocaleConfigurationDataContainer;
import gr.cite.annotation.common.types.tenantconfiguration.EmailClientConfigurationDataContainer;
import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.data.TenantConfigurationEntity;
import gr.cite.annotation.data.TenantEntityManager;
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
import gr.cite.annotation.model.TenantConfiguration;
import gr.cite.annotation.model.builder.TenantConfigurationBuilder;
import gr.cite.annotation.model.deleter.TenantConfigurationDeleter;
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationEmailClientPersist;
import gr.cite.annotation.model.persist.tenantconfiguration.TenantConfigurationUserLocaleIntegrationPersist;
import gr.cite.annotation.query.TenantConfigurationQuery;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.deleter.DeleterFactory;
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 org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
@Component
@RequestScope
public class TenantConfigurationServiceImpl implements TenantConfigurationService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantConfigurationServiceImpl.class));
private final ApplicationContext applicationContext;
private final JsonHandlingService jsonHandlingService;
private final AuthorizationService authorizationService;
private final ConventionService conventionService;
private final ErrorThesaurusProperties errors;
private final MessageSource messageSource;
private final BuilderFactory builderFactory;
private final TenantEntityManager dbContext;
private final DeleterFactory deleterFactory;
@Autowired
public TenantConfigurationServiceImpl(ApplicationContext applicationContext, JsonHandlingService jsonHandlingService, AuthorizationService authorizationService, ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, BuilderFactory builderFactory, TenantEntityManager dbContext, DeleterFactory deleterFactory) {
this.applicationContext = applicationContext;
this.jsonHandlingService = jsonHandlingService;
this.authorizationService = authorizationService;
this.conventionService = conventionService;
this.errors = errors;
this.messageSource = messageSource;
this.builderFactory = builderFactory;
this.dbContext = dbContext;
this.deleterFactory = deleterFactory;
}
@Override
public EmailClientConfigurationDataContainer collectTenantEmailClient() {
TenantConfigurationQuery query = applicationContext.getBean(TenantConfigurationQuery.class);
String data = query.isActive(IsActive.Active).type(TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION).first().getValue();
if (data == null) return null;
try {
EmailClientConfigurationDataContainer emailClientData = this.jsonHandlingService.fromJson(EmailClientConfigurationDataContainer.class, data);
return emailClientData;
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public DefaultUserLocaleConfigurationDataContainer collectTenantUserLocale() {
TenantConfigurationQuery query = applicationContext.getBean(TenantConfigurationQuery.class);
TenantConfigurationEntity entity = query.isActive(IsActive.Active).type(TenantConfigurationType.DEFAULT_USER_LOCALE).first();
if(entity == null){
return null;
}
String data = entity.getValue();
if (data == null) return null;
try {
DefaultUserLocaleConfigurationDataContainer userLocaleData = this.jsonHandlingService.fromJson(DefaultUserLocaleConfigurationDataContainer.class, data);
return userLocaleData;
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public TenantConfiguration persist(TenantConfigurationEmailClientPersist emailClientPersist, FieldSet fieldSet) {
EmailClientConfigurationDataContainer container = new EmailClientConfigurationDataContainer();
container.setEnableSSL(emailClientPersist.getEnableSSL());
container.setRequireCredentials(emailClientPersist.getRequireCredentials());
container.setHostServer(emailClientPersist.getHostServer());
container.setHostPortNo(emailClientPersist.getHostPortNo());
container.setCertificatePath(emailClientPersist.getCertificatePath());
container.setEmailAddress(emailClientPersist.getEmailAddress());
container.setEmailUserName(emailClientPersist.getEmailUserName());
container.setEmailPassword(emailClientPersist.getEmailPassword());
try {
String value = jsonHandlingService.toJson(container);
return this.persist(emailClientPersist.getId(), emailClientPersist.getHash(), TenantConfigurationType.EMAIL_CLIENT_CONFIGURATION, value, fieldSet);
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public TenantConfiguration persist(TenantConfigurationUserLocaleIntegrationPersist userLocaleIntegrationPersist, FieldSet fieldSet) {
this.authorizationService.authorizeForce(Permission.EditTenantConfiguration);
TenantConfigurationQuery tenantConfigurationQuery = applicationContext.getBean(TenantConfigurationQuery.class);
TenantConfigurationEntity data = tenantConfigurationQuery.isActive(IsActive.Active).type(TenantConfigurationType.DEFAULT_USER_LOCALE).first();
Boolean isUpdate = data != null;
if (!isUpdate) {
data = new TenantConfigurationEntity();
data.setCreatedAt(Instant.now());
data.setIsActive(IsActive.Active);
data.setType(TenantConfigurationType.DEFAULT_USER_LOCALE);
}
try {
DefaultUserLocaleConfigurationDataContainer container = new DefaultUserLocaleConfigurationDataContainer();
container.setCulture(userLocaleIntegrationPersist.getCulture());
container.setTimeZone(userLocaleIntegrationPersist.getTimeZone());
container.setLanguage(userLocaleIntegrationPersist.getLanguage());
String value = jsonHandlingService.toJson(container);
data.setValue(value);
data.setUpdatedAt(Instant.now());
this.dbContext.merge(data);
} catch (InvalidApplicationException | JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
//this._eventBroker.EmitTenantConfigurationTouched(this._scope.Tenant, type);
TenantConfiguration persisted = this.builderFactory.builder(TenantConfigurationBuilder.class).build(fieldSet.merge(new BaseFieldSet(TenantConfiguration._id, TenantConfiguration._hash)), data);
return persisted;
}
@Override
public void deleteAndSave(UUID id) throws InvalidApplicationException {
logger.debug("deleting tenant Configuration: {}", id);
this.authorizationService.authorizeForce(Permission.EditTenantConfiguration);
this.deleterFactory.deleter(TenantConfigurationDeleter.class).deleteAndSaveByIds(List.of(id));
}
private TenantConfiguration persist(UUID modelId, String modelHash, TenantConfigurationType type, String value, FieldSet fieldSet) {
this.authorizationService.authorizeForce(Permission.EditTenantConfiguration);
Boolean isUpdate = this.conventionService.isValidGuid(modelId);
TenantConfigurationQuery tenantConfigurationQuery = applicationContext.getBean(TenantConfigurationQuery.class);
List<UUID> existingConfigIds = tenantConfigurationQuery.isActive(IsActive.Active).type(type).collectAs(new BaseFieldSet(TenantConfigurationEntity._id)).stream().map(TenantConfigurationEntity::getId).toList();
TenantConfigurationEntity data = null;
if (isUpdate) {
if (!existingConfigIds.contains(modelId)) throw new MyValidationException(this.errors.getSingleTenantConfigurationPerTypeSupported().getCode(), this.errors.getSingleTenantConfigurationPerTypeSupported().getMessage());
if (existingConfigIds.size() > 1) throw new MyValidationException(this.errors.getSingleTenantConfigurationPerTypeSupported().getCode(), this.errors.getSingleTenantConfigurationPerTypeSupported().getMessage());
data = tenantConfigurationQuery.ids(modelId).first();
if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{modelId, TenantConfigurationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!modelHash.equals(this.conventionService.hashValue(data.getUpdatedAt()))) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
if (!data.getType().equals(type)) throw new MyValidationException(this.errors.getIncompatibleTenantConfigurationTypes().getCode(), this.errors.getIncompatibleTenantConfigurationTypes().getMessage());
} else {
if (!existingConfigIds.isEmpty()) throw new MyValidationException(this.errors.getSingleTenantConfigurationPerTypeSupported().getCode(), this.errors.getSingleTenantConfigurationPerTypeSupported().getMessage());
data = new TenantConfigurationEntity();
data.setCreatedAt(Instant.now());
data.setIsActive(IsActive.Active);
data.setType(type);
}
data.setValue(value);
data.setUpdatedAt(Instant.now());
try {
this.dbContext.merge(data);
} catch (InvalidApplicationException e) {
logger.error(e.getMessage(), e);
}
//this._eventBroker.EmitTenantConfigurationTouched(this._scope.Tenant, type);
TenantConfiguration persisted = this.builderFactory.builder(TenantConfigurationBuilder.class).build(fieldSet.merge(new BaseFieldSet(TenantConfiguration._id, TenantConfiguration._hash)), data);
return persisted;
//return null;
}
}

View File

@ -94,10 +94,7 @@ public class CloneDmpPersist {
.failOn(CloneDmpPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{CloneDmpPersist._label}, LocaleContextHolder.getLocale())), .failOn(CloneDmpPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{CloneDmpPersist._label}, LocaleContextHolder.getLocale())),
this.spec() this.spec()
.must(() -> !this.isEmpty(item.getDescription())) .must(() -> !this.isEmpty(item.getDescription()))
.failOn(CloneDmpPersist._description).failWith(messageSource.getMessage("Validation_Required", new Object[]{CloneDmpPersist._description}, LocaleContextHolder.getLocale())), .failOn(CloneDmpPersist._description).failWith(messageSource.getMessage("Validation_Required", new Object[]{CloneDmpPersist._description}, LocaleContextHolder.getLocale()))
this.spec()
.must(() -> !this.isNull(item.getDescriptions()))
.failOn(CloneDmpPersist._descriptions).failWith(messageSource.getMessage("Validation_Required", new Object[]{CloneDmpPersist._descriptions}, LocaleContextHolder.getLocale()))
); );
} }
} }

View File

@ -580,6 +580,11 @@ public class DmpServiceImpl implements DmpService {
this.annotationEntityTouchedIntegrationEventHandler.handleDmp(newDmp.getId()); this.annotationEntityTouchedIntegrationEventHandler.handleDmp(newDmp.getId());
DmpEntity resultingDmpEntity = this.queryFactory.query(DmpQuery.class).ids(newDmp.getId()).firstAs(fields); DmpEntity resultingDmpEntity = this.queryFactory.query(DmpQuery.class).ids(newDmp.getId()).firstAs(fields);
if (!this.conventionService.isListNullOrEmpty(model.getDescriptions())){
for (UUID description: model.getDescriptions()) {
descriptionService.clone(newDmp.getId(), description);
}
}
return this.builderFactory.builder(DmpBuilder.class).build(fields, resultingDmpEntity); return this.builderFactory.builder(DmpBuilder.class).build(fields, resultingDmpEntity);
} }

View File

@ -6,15 +6,16 @@ BEGIN
CREATE TABLE public."ntf_UserNotificationPreference" CREATE TABLE public."ntf_UserNotificationPreference"
( (
id uuid NOT NULL,
"user" uuid NOT NULL, "user" uuid NOT NULL,
"type" uuid NOT NULL, "type" uuid NOT NULL,
"channel" smallint NOT NULL, "channel" smallint NOT NULL,
"ordinal" numeric NOT NULL, "ordinal" numeric NOT NULL,
"tenant" uuid, "tenant" uuid NULL,
"created_at" timestamp without time zone NOT NULL, "created_at" timestamp without time zone NOT NULL,
"updated_at" timestamp without time zone NOT NULL, "updated_at" timestamp without time zone NOT NULL,
"is_active" smallint NOT NULL DEFAULT 1, "is_active" smallint NOT NULL DEFAULT 1,
CONSTRAINT "ntf_UserNotificationPreference_pkey" PRIMARY KEY ("user", "type", "channel"), CONSTRAINT "ntf_UserNotificationPreference_pkey" PRIMARY KEY (id),
CONSTRAINT "ntf_UserNotificationPreference_tenant_fkey" FOREIGN KEY ("tenant") CONSTRAINT "ntf_UserNotificationPreference_tenant_fkey" FOREIGN KEY ("tenant")
REFERENCES public."ntf_Tenant" (id) MATCH SIMPLE REFERENCES public."ntf_Tenant" (id) MATCH SIMPLE
ON UPDATE NO ACTION ON UPDATE NO ACTION

View File

@ -13,23 +13,7 @@ BEGIN
is_active smallint NOT NULL DEFAULT 1, is_active smallint NOT NULL DEFAULT 1,
CONSTRAINT "ant_Tenant_pkey" PRIMARY KEY (id) CONSTRAINT "ant_Tenant_pkey" PRIMARY KEY (id)
); );
CREATE TABLE public."ant_TenantConfiguration"
(
id uuid NOT NULL,
tenant uuid NOT NULL,
type smallint NOT NULL,
value character varying COLLATE pg_catalog."default" NOT NULL,
is_active smallint NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
CONSTRAINT "ant_TenantConfguration_pkey" PRIMARY KEY (id),
CONSTRAINT "ant_TenantConfiguration_tenant_fkey" FOREIGN KEY (tenant)
REFERENCES public."ant_Tenant" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
);
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.048', '2024-02-13 12:00:00.000000+02', now(), 'Add tables ant_Tenant and ant_TenantConfiguration.'); INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.048', '2024-02-13 12:00:00.000000+02', now(), 'Add tables ant_Tenant and ant_TenantConfiguration.');
END$$; END$$;

View File

@ -36,7 +36,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
this.descriptionTemplateId = item.descriptionTemplate?.id; this.descriptionTemplateId = item.descriptionTemplate?.id;
this.status = item.status ?? DescriptionStatus.Draft; this.status = item.status ?? DescriptionStatus.Draft;
this.description = item.description; this.description = item.description;
this.tags = item.descriptionTags?.map(x => x.tag?.label); this.tags = item.descriptionTags?.filter(x => x.isActive === IsActive.Active).map(x => x.tag?.label);
this.properties = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).fromModel(item.properties, descriptionTemplate, item.descriptionReferences); this.properties = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).fromModel(item.properties, descriptionTemplate, item.descriptionReferences);
} }
return this; return this;

View File

@ -75,6 +75,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
[nameof<Description>(x => x.descriptionTags), nameof<DescriptionTag>(x => x.id),].join('.'), [nameof<Description>(x => x.descriptionTags), nameof<DescriptionTag>(x => x.id),].join('.'),
[nameof<Description>(x => x.descriptionTags), nameof<DescriptionTag>(x => x.tag), nameof<Tag>(x => x.label)].join('.'), [nameof<Description>(x => x.descriptionTags), nameof<DescriptionTag>(x => x.tag), nameof<Tag>(x => x.label)].join('.'),
[nameof<Description>(x => x.descriptionTags), nameof<DescriptionTag>(x => x.tag), nameof<Tag>(x => x.isActive)].join('.'),
[nameof<Description>(x => x.descriptionReferences), nameof<DescriptionReference>(x => x.data), nameof<DescriptionReferenceData>(x => x.fieldId)].join('.'), [nameof<Description>(x => x.descriptionReferences), nameof<DescriptionReference>(x => x.data), nameof<DescriptionReferenceData>(x => x.fieldId)].join('.'),
[nameof<Description>(x => x.descriptionReferences), nameof<DescriptionReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'), [nameof<Description>(x => x.descriptionReferences), nameof<DescriptionReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),

View File

@ -19,7 +19,7 @@ export class DmpCloneDialogEditorModel implements CloneDmpPersist {
public fromModel(item: Dmp): DmpCloneDialogEditorModel { public fromModel(item: Dmp): DmpCloneDialogEditorModel {
if (item) { if (item) {
this.id = item.id; this.id = item.id;
this.label = item.label; this.label = item.label + " New";
this.description = item.description; this.description = item.description;
if (item.descriptions) { this.descriptions = item.descriptions.map(x => x.id); } if (item.descriptions) { this.descriptions = item.descriptions.map(x => x.id); }
} }

View File

@ -63,6 +63,7 @@ export class TagsComponent extends BaseComponent implements OnInit {
if (index >= 0) { if (index >= 0) {
this.tags.splice(index, 1); this.tags.splice(index, 1);
this.form.setValue(this.tags);
} }
} }

View File

@ -1,8 +1,9 @@
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { NotificationType } from '@notification-service/core/enum/notification-type.enum'; import { NotificationType } from '@notification-service/core/enum/notification-type.enum';
import { NotificationContactType } from '../enum/notification-contact-type'; import { NotificationContactType } from '../enum/notification-contact-type';
import { BaseEntity, BaseEntityPersist } from '@common/base/base-entity.model';
export interface UserNotificationPreference { export interface UserNotificationPreference extends BaseEntity {
userId?: Guid; userId?: Guid;
type: NotificationType; type: NotificationType;
channel: NotificationContactType; channel: NotificationContactType;
@ -10,7 +11,7 @@ export interface UserNotificationPreference {
createdAt?: Date; createdAt?: Date;
} }
export interface UserNotificationPreferencePersist { export interface UserNotificationPreferencePersist extends BaseEntityPersist {
userId?: Guid; userId?: Guid;
notificationPreferences: { [key: string]: NotificationContactType[] }; notificationPreferences: { [key: string]: NotificationContactType[] };
} }

View File

@ -4,6 +4,8 @@ import { NotificationType } from '@notification-service/core/enum/notification-t
import { NotificationContactType } from '../enum/notification-contact-type'; import { NotificationContactType } from '../enum/notification-contact-type';
export class UserNotificationPreferenceLookup extends Lookup implements UserNotificationPreferenceFilter { export class UserNotificationPreferenceLookup extends Lookup implements UserNotificationPreferenceFilter {
ids: Guid[];
excludedIds: Guid[];
userIds?: Guid[]; userIds?: Guid[];
type?: NotificationType[]; type?: NotificationType[];
channel?: NotificationContactType[]; channel?: NotificationContactType[];
@ -14,6 +16,8 @@ export class UserNotificationPreferenceLookup extends Lookup implements UserNoti
} }
export interface UserNotificationPreferenceFilter { export interface UserNotificationPreferenceFilter {
ids: Guid[];
excludedIds: Guid[];
userIds?: Guid[]; userIds?: Guid[];
type?: NotificationType[]; type?: NotificationType[];
channel?: NotificationContactType[]; channel?: NotificationContactType[];

View File

@ -10,6 +10,7 @@ import { NotificationServiceEnumUtils } from '@notification-service/core/formatt
import { InAppNotificationService } from './http/inapp-notification.service'; import { InAppNotificationService } from './http/inapp-notification.service';
import { NotificationService } from './http/notification-service'; import { NotificationService } from './http/notification-service';
import { NotificationTemplateService } from './http/notification-template.service'; import { NotificationTemplateService } from './http/notification-template.service';
import { TenantConfigurationService } from './http/tenant-configuration.service';
// //
// //
@ -38,6 +39,7 @@ export class CoreNotificationServiceModule {
NotificationService, NotificationService,
InAppNotificationService, InAppNotificationService,
NotificationTemplateService, NotificationTemplateService,
TenantConfigurationService,
UserNotificationPreferenceService UserNotificationPreferenceService
], ],
}; };

View File

@ -4,8 +4,11 @@ import gr.cite.notification.audit.AuditableAction;
import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.TenantConfigurationType; import gr.cite.notification.common.enums.TenantConfigurationType;
import gr.cite.notification.common.scope.tenant.TenantScope;
import gr.cite.notification.common.types.tenantconfiguration.NotifierListTenantConfigurationEntity; import gr.cite.notification.common.types.tenantconfiguration.NotifierListTenantConfigurationEntity;
import gr.cite.notification.data.TenantEntity;
import gr.cite.notification.data.UserNotificationPreferenceEntity; import gr.cite.notification.data.UserNotificationPreferenceEntity;
import gr.cite.notification.event.TenantConfigurationTouchedEvent;
import gr.cite.notification.model.UserNotificationPreference; import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.notification.model.builder.UserNotificationPreferenceBuilder; import gr.cite.notification.model.builder.UserNotificationPreferenceBuilder;
import gr.cite.notification.model.censorship.UserNotificationPreferenceCensor; import gr.cite.notification.model.censorship.UserNotificationPreferenceCensor;
@ -30,9 +33,12 @@ import gr.cite.tools.validation.ValidationFilterAnnotation;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import javax.management.InvalidApplicationException;
import java.util.*; import java.util.*;
@RestController @RestController
@ -46,20 +52,22 @@ public class UserNotificationPreferenceController {
private final CensorFactory censorFactory; private final CensorFactory censorFactory;
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final MessageSource messageSource; private final MessageSource messageSource;
private final TenantScope tenantScope;
@Autowired @Autowired
public UserNotificationPreferenceController(BuilderFactory builderFactory, public UserNotificationPreferenceController(BuilderFactory builderFactory,
AuditService auditService, AuditService auditService,
UserNotificationPreferenceService userNotificationPreferenceService, UserNotificationPreferenceService userNotificationPreferenceService,
CensorFactory censorFactory, CensorFactory censorFactory,
QueryFactory queryFactory, QueryFactory queryFactory,
MessageSource messageSource) { MessageSource messageSource, TenantScope tenantScope) {
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
this.auditService = auditService; this.auditService = auditService;
this.userNotificationPreferenceService = userNotificationPreferenceService; this.userNotificationPreferenceService = userNotificationPreferenceService;
this.censorFactory = censorFactory; this.censorFactory = censorFactory;
this.queryFactory = queryFactory; this.queryFactory = queryFactory;
this.messageSource = messageSource; this.messageSource = messageSource;
this.tenantScope = tenantScope;
} }
@PostMapping("query") @PostMapping("query")
@ -80,7 +88,7 @@ public class UserNotificationPreferenceController {
@GetMapping("user/{userId}/current") @GetMapping("user/{userId}/current")
@Transactional @Transactional
public List<UserNotificationPreference> current(@PathVariable UUID userId, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { public List<UserNotificationPreference> current(@PathVariable UUID userId, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + UserNotificationPreference.class.getSimpleName()).And("userId", userId).And("fields", fieldSet)); logger.debug(new MapLogEntry("retrieving" + UserNotificationPreference.class.getSimpleName()).And("userId", userId).And("fields", fieldSet));
this.censorFactory.censor(UserNotificationPreferenceCensor.class).censor(fieldSet, userId); this.censorFactory.censor(UserNotificationPreferenceCensor.class).censor(fieldSet, userId);
@ -89,6 +97,13 @@ public class UserNotificationPreferenceController {
ordering.addAscending(UserNotificationPreference._ordinal); ordering.addAscending(UserNotificationPreference._ordinal);
UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(userId).isActives(IsActive.Active); UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(userId).isActives(IsActive.Active);
query.setOrder(ordering); query.setOrder(ordering);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
List<UserNotificationPreference> model = this.builderFactory.builder(UserNotificationPreferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.collectAs(fieldSet)); List<UserNotificationPreference> model = this.builderFactory.builder(UserNotificationPreferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.collectAs(fieldSet));
this.auditService.track(AuditableAction.User_Notification_Preference_Lookup, Map.ofEntries( this.auditService.track(AuditableAction.User_Notification_Preference_Lookup, Map.ofEntries(

View File

@ -2,7 +2,6 @@ package gr.cite.notification.data;
import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationContactType; import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.data.composite.CompositeUserNotificationPreferenceId;
import gr.cite.notification.data.conventers.IsActiveConverter; import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.conventers.NotificationContactTypeConverter; import gr.cite.notification.data.conventers.NotificationContactTypeConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity; import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
@ -13,22 +12,23 @@ import java.util.UUID;
@Entity @Entity
@Table(name = "\"UserNotificationPreference\"") @Table(name = "\"UserNotificationPreference\"")
@IdClass(CompositeUserNotificationPreferenceId.class)
public class UserNotificationPreferenceEntity extends TenantScopedBaseEntity { public class UserNotificationPreferenceEntity extends TenantScopedBaseEntity {
@Id @Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public static final String _id = "id";
@Column(name = "user", columnDefinition = "uuid", nullable = false) @Column(name = "user", columnDefinition = "uuid", nullable = false)
private UUID userId; private UUID userId;
public static final String _userId = "userId"; public static final String _userId = "userId";
@Id
@Column(name = "type", columnDefinition = "uuid", nullable = false) @Column(name = "type", columnDefinition = "uuid", nullable = false)
private UUID type; private UUID type;
public static final String _type = "type"; public static final String _type = "type";
@Id
@Column(name = "channel", nullable = false) @Column(name = "channel", nullable = false)
@Convert(converter = NotificationContactTypeConverter.class) @Convert(converter = NotificationContactTypeConverter.class)
private NotificationContactType channel; private NotificationContactType channel;
@ -56,6 +56,14 @@ public class UserNotificationPreferenceEntity extends TenantScopedBaseEntity {
public static final String _isActive = "isActive"; public static final String _isActive = "isActive";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getUserId() { public UUID getUserId() {
return userId; return userId;
} }

View File

@ -1,45 +0,0 @@
package gr.cite.notification.data.composite;
import gr.cite.notification.common.enums.NotificationContactType;
import java.io.Serializable;
import java.util.UUID;
public class CompositeUserNotificationPreferenceId implements Serializable {
private UUID userId;
private UUID type;
private NotificationContactType channel;
public CompositeUserNotificationPreferenceId() {
}
public CompositeUserNotificationPreferenceId(UUID userId, UUID type, NotificationContactType channel) {
this.userId = userId;
this.type = type;
this.channel = channel;
}
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public UUID getType() {
return type;
}
public void setType(UUID type) {
this.type = type;
}
public NotificationContactType getChannel() {
return channel;
}
public void setChannel(NotificationContactType channel) {
this.channel = channel;
}
}

View File

@ -8,6 +8,10 @@ import java.util.UUID;
public class UserNotificationPreference { public class UserNotificationPreference {
private UUID id;
public static final String _id = "id";
private UUID userId; private UUID userId;
public static final String _userId = "userId"; public static final String _userId = "userId";
@ -40,6 +44,14 @@ public class UserNotificationPreference {
public static final String _isActive = "isActive"; public static final String _isActive = "isActive";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getUserId() { public UUID getUserId() {
return userId; return userId;
} }

View File

@ -42,6 +42,7 @@ public class UserNotificationPreferenceBuilder extends BaseBuilder<UserNotificat
List<UserNotificationPreference> models = new ArrayList<>(); List<UserNotificationPreference> models = new ArrayList<>();
for(UserNotificationPreferenceEntity d : data){ for(UserNotificationPreferenceEntity d : data){
UserNotificationPreference m = new UserNotificationPreference(); UserNotificationPreference m = new UserNotificationPreference();
if(fields.hasField(this.asIndexer(UserNotificationPreference._id))) m.setId(d.getId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._userId))) m.setUserId(d.getUserId()); if(fields.hasField(this.asIndexer(UserNotificationPreference._userId))) m.setUserId(d.getUserId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._tenantId))) m.setTenantId(d.getTenantId()); if(fields.hasField(this.asIndexer(UserNotificationPreference._tenantId))) m.setTenantId(d.getTenantId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._type))) m.setType(d.getType()); if(fields.hasField(this.asIndexer(UserNotificationPreference._type))) m.setType(d.getType());

View File

@ -2,6 +2,8 @@ package gr.cite.notification.query;
import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationContactType; import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.data.TenantConfigurationEntity;
import gr.cite.notification.data.UserCredentialEntity;
import gr.cite.notification.data.UserNotificationPreferenceEntity; import gr.cite.notification.data.UserNotificationPreferenceEntity;
import gr.cite.notification.model.UserNotificationPreference; import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.FieldResolver;
@ -15,15 +17,16 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@Component @Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationPreferenceEntity> { public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationPreferenceEntity> {
private Collection<UUID> ids;
private Collection<UUID> excludedIds;
private List<UUID> userId; private List<UUID> userId;
private List<IsActive> isActives; private List<IsActive> isActives;
@ -32,6 +35,58 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
private List<NotificationContactType> channel; private List<NotificationContactType> channel;
private Collection<UUID> tenantIds;
private Boolean tenantIsSet;
public UserNotificationPreferenceQuery ids(UUID value) {
this.ids = List.of(value);
return this;
}
public UserNotificationPreferenceQuery ids(UUID... value) {
this.ids = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery ids(Collection<UUID> values) {
this.ids = values;
return this;
}
public UserNotificationPreferenceQuery tenantIds(UUID value) {
this.tenantIds = List.of(value);
return this;
}
public UserNotificationPreferenceQuery tenantIds(UUID... value) {
this.tenantIds = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery tenantIds(Collection<UUID> values) {
this.tenantIds = values;
return this;
}
public UserNotificationPreferenceQuery tenantIsSet(Boolean values) {
this.tenantIsSet = values;
return this;
}
public UserNotificationPreferenceQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public UserNotificationPreferenceQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public UserNotificationPreferenceQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery userId(UUID... userId) { public UserNotificationPreferenceQuery userId(UUID... userId) {
this.userId = List.of(userId); this.userId = List.of(userId);
return this; return this;
@ -74,7 +129,7 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override @Override
protected Boolean isFalseQuery() { protected Boolean isFalseQuery() {
return this.isNullOrEmpty(this.userId) && this.isNullOrEmpty(this.type) && this.isNullOrEmpty(this.channel); return this.isEmpty(this.ids) || this.isEmpty(this.tenantIds) ||this.isEmpty(this.excludedIds) ||this.isNullOrEmpty(this.userId) && this.isNullOrEmpty(this.type) && this.isNullOrEmpty(this.channel);
} }
@Override @Override
@ -85,6 +140,28 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override @Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) { protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>(); List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._id));
for (UUID item : this.ids)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.tenantIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId));
for (UUID item : this.tenantIds) inClause.value(item);
predicates.add(inClause);
}
if (this.tenantIsSet != null) {
if (this.tenantIsSet) predicates.add(queryContext.CriteriaBuilder.isNotNull(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId)));
else predicates.add(queryContext.CriteriaBuilder.isNull(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId)));
}
if (this.userId != null) { if (this.userId != null) {
predicates.add(queryContext.Root.get(UserNotificationPreferenceEntity._userId).in(this.userId)); predicates.add(queryContext.Root.get(UserNotificationPreferenceEntity._userId).in(this.userId));
} }
@ -119,6 +196,8 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
protected String fieldNameOf(FieldResolver item) { protected String fieldNameOf(FieldResolver item) {
if (item.match(UserNotificationPreference._userId)) if (item.match(UserNotificationPreference._userId))
return UserNotificationPreferenceEntity._userId; return UserNotificationPreferenceEntity._userId;
else if (item.match(UserNotificationPreference._id))
return UserNotificationPreferenceEntity._id;
else if (item.match(UserNotificationPreference._tenantId)) else if (item.match(UserNotificationPreference._tenantId))
return UserNotificationPreferenceEntity._tenantId; return UserNotificationPreferenceEntity._tenantId;
else if (item.match(UserNotificationPreference._type)) else if (item.match(UserNotificationPreference._type))
@ -140,6 +219,7 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override @Override
protected UserNotificationPreferenceEntity convert(Tuple tuple, Set<String> columns) { protected UserNotificationPreferenceEntity convert(Tuple tuple, Set<String> columns) {
UserNotificationPreferenceEntity item = new UserNotificationPreferenceEntity(); UserNotificationPreferenceEntity item = new UserNotificationPreferenceEntity();
item.setId(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._id, UUID.class));
item.setUserId(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._userId, UUID.class)); item.setUserId(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._userId, UUID.class));
item.setChannel(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._channel, NotificationContactType.class)); item.setChannel(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._channel, NotificationContactType.class));
item.setType(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._type, UUID.class)); item.setType(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._type, UUID.class));

View File

@ -12,6 +12,8 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class UserNotificationPreferenceLookup extends Lookup { public class UserNotificationPreferenceLookup extends Lookup {
private List<UUID> ids;
private List<UUID> excludedIds;
private List<UUID> userId; private List<UUID> userId;
private List<UUID> type; private List<UUID> type;
private List<NotificationContactType> channel; private List<NotificationContactType> channel;
@ -45,6 +47,8 @@ public class UserNotificationPreferenceLookup extends Lookup {
if (this.userId != null) query.userId(this.userId); if (this.userId != null) query.userId(this.userId);
if (this.channel != null) query.channel(this.channel); if (this.channel != null) query.channel(this.channel);
if (this.type != null) query.type(this.type); if (this.type != null) query.type(this.type);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
this.enrichCommon(query); this.enrichCommon(query);

View File

@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope; import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -104,8 +105,13 @@ public class ChannelResolutionServiceImpl implements ChannelResolutionService{
private Map<UUID, List<NotificationContactType>> lookupOrCollectUserPolicies(List<UUID> users, UUID type) { private Map<UUID, List<NotificationContactType>> lookupOrCollectUserPolicies(List<UUID> users, UUID type) {
Map<UUID, List<NotificationContactType>> contactsByUser = new HashMap<>(); Map<UUID, List<NotificationContactType>> contactsByUser = new HashMap<>();
Map<UUID, List<UserNotificationPreference>> userNotificationPreferences = this.userNotificationPreferenceService.collectUserNotificationPreferences(users); Map<UUID, List<UserNotificationPreference>> userNotificationPreferences = null;
for (Map.Entry<UUID, List<UserNotificationPreference>> notificationPreference: userNotificationPreferences.entrySet()) try {
userNotificationPreferences = this.userNotificationPreferenceService.collectUserNotificationPreferences(users);
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
for (Map.Entry<UUID, List<UserNotificationPreference>> notificationPreference: userNotificationPreferences.entrySet())
{ {
contactsByUser.put(notificationPreference.getKey(), notificationPreference.getValue().stream().filter(x -> x.getType() != null && x.getType() == type && x.getChannel() != null).sorted(Comparator.comparingInt(x -> x.getOrdinal())).map(x -> x.getChannel()).collect(Collectors.toList())); contactsByUser.put(notificationPreference.getKey(), notificationPreference.getValue().stream().filter(x -> x.getType() != null && x.getType() == type && x.getChannel() != null).sorted(Comparator.comparingInt(x -> x.getOrdinal())).map(x -> x.getChannel()).collect(Collectors.toList()));
} }

View File

@ -73,17 +73,18 @@ public class NotificationServiceImpl implements NotificationService {
private final NotifierFactory notifierFactory; private final NotifierFactory notifierFactory;
private final ApplicationContext applicationContext; private final ApplicationContext applicationContext;
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final TenantScope tenantScope;
@Autowired @Autowired
public NotificationServiceImpl( public NotificationServiceImpl(
TenantEntityManager entityManager, TenantEntityManager entityManager,
AuthorizationService authService, AuthorizationService authService,
DeleterFactory deleterFactory, DeleterFactory deleterFactory,
BuilderFactory builderFactory, BuilderFactory builderFactory,
ConventionService conventionService, ConventionService conventionService,
ErrorThesaurusProperties errors, ErrorThesaurusProperties errors,
MessageSource messageSource, MessageSource messageSource,
ChannelResolutionService channelResolutionService, MessageBuilderFactory messageBuilderFactory, ContactExtractorFactory contactExtractorFactory, NotifierFactory notifierFactory, ApplicationContext applicationContext, QueryFactory queryFactory) { ChannelResolutionService channelResolutionService, MessageBuilderFactory messageBuilderFactory, ContactExtractorFactory contactExtractorFactory, NotifierFactory notifierFactory, ApplicationContext applicationContext, QueryFactory queryFactory, TenantScope tenantScope) {
this.entityManager = entityManager; this.entityManager = entityManager;
this.authService = authService; this.authService = authService;
this.deleterFactory = deleterFactory; this.deleterFactory = deleterFactory;
@ -97,6 +98,7 @@ public class NotificationServiceImpl implements NotificationService {
this.notifierFactory = notifierFactory; this.notifierFactory = notifierFactory;
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
this.queryFactory = queryFactory; this.queryFactory = queryFactory;
this.tenantScope = tenantScope;
} }
@Override @Override
@ -146,6 +148,7 @@ public class NotificationServiceImpl implements NotificationService {
public SendNotificationResult doNotify(NotificationEntity notification) { public SendNotificationResult doNotify(NotificationEntity notification) {
List<NotificationContactType> contactTypes = this.orderContactTypesFromPreferences(notification); List<NotificationContactType> contactTypes = this.orderContactTypesFromPreferences(notification);
if (this.conventionService.isListNullOrEmpty(contactTypes)) contactTypes = this.orderContactTypes(notification); if (this.conventionService.isListNullOrEmpty(contactTypes)) contactTypes = this.orderContactTypes(notification);
if (contactTypes == null) return null;
for (NotificationContactType contactType: contactTypes) { for (NotificationContactType contactType: contactTypes) {
SendNotificationResult result = this.sendNotification(notification, contactType); SendNotificationResult result = this.sendNotification(notification, contactType);
@ -160,8 +163,14 @@ public class NotificationServiceImpl implements NotificationService {
UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(notification.getUserId()).type(notification.getType()).isActives(IsActive.Active); UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(notification.getUserId()).type(notification.getType()).isActives(IsActive.Active);
query.setOrder(ordering); query.setOrder(ordering);
List<UserNotificationPreferenceEntity> preferences = query.collectAs(new BaseFieldSet().ensure(UserNotificationPreference._channel)); List<UserNotificationPreferenceEntity> preferences = query.collectAs(new BaseFieldSet().ensure(UserNotificationPreference._channel).ensure(UserNotificationPreference._tenantId).ensure(UserNotificationPreference._id));
if (!this.conventionService.isListNullOrEmpty(preferences)) return preferences.stream().map(x -> x.getChannel()).collect(Collectors.toList()); if (!this.conventionService.isListNullOrEmpty(preferences)) return preferences.stream().filter(x -> {
try {
return !this.tenantScope.isMultitenant() || this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant();
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
}).map(UserNotificationPreferenceEntity::getChannel).collect(Collectors.toList());
return null; return null;
} }

View File

@ -5,6 +5,7 @@ import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.notification.model.persist.UserNotificationPreferencePersist; import gr.cite.notification.model.persist.UserNotificationPreferencePersist;
import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.fieldset.FieldSet;
import javax.management.InvalidApplicationException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -14,6 +15,6 @@ public interface UserNotificationPreferenceService {
List<UserNotificationPreference> persist(UserNotificationPreferencePersist model, FieldSet fieldSet); List<UserNotificationPreference> persist(UserNotificationPreferencePersist model, FieldSet fieldSet);
NotifierListTenantConfigurationEntity collectUserAvailableNotifierList(Set<UUID> notificationTypes); NotifierListTenantConfigurationEntity collectUserAvailableNotifierList(Set<UUID> notificationTypes);
List<UserNotificationPreference> collectUserNotificationPreferences(UUID id); List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) throws InvalidApplicationException;
Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids); Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) throws InvalidApplicationException;
} }

View File

@ -117,7 +117,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
} }
@Override @Override
public List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) { public List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) throws InvalidApplicationException {
Map<UUID, List<UserNotificationPreference>> result = this.collectUserNotificationPreferences(List.of(id)); Map<UUID, List<UserNotificationPreference>> result = this.collectUserNotificationPreferences(List.of(id));
if (result != null) { if (result != null) {
return result.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); return result.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
@ -127,18 +127,20 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
} }
@Override @Override
public Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) { public Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) throws InvalidApplicationException {
UserNotificationPreferenceQuery query = this.queryFactory
.query(UserNotificationPreferenceQuery.class)
.userId(ids);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
return this.builderFactory.builder(UserNotificationPreferenceBuilder.class) return this.builderFactory.builder(UserNotificationPreferenceBuilder.class)
.build(new BaseFieldSet(UserNotificationPreference._userId, UserNotificationPreference._type, .build(new BaseFieldSet(UserNotificationPreference._userId, UserNotificationPreference._type,
UserNotificationPreference._channel, UserNotificationPreference._ordinal), this.queryFactory UserNotificationPreference._channel, UserNotificationPreference._ordinal, UserNotificationPreference._tenantId, UserNotificationPreference._id), query.collect()).stream()
.query(UserNotificationPreferenceQuery.class)
.userId(ids).collect()).stream().filter(x -> {
try {
return !this.tenantScope.isMultitenant() || this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant();
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.groupingBy(UserNotificationPreference::getUserId)); //GK: Yep that exist on JAVA Streams .collect(Collectors.groupingBy(UserNotificationPreference::getUserId)); //GK: Yep that exist on JAVA Streams
} }
@ -178,22 +180,24 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
{ {
List<UserNotificationPreferenceEntity> preferences = null; List<UserNotificationPreferenceEntity> preferences = null;
try { try {
preferences = this.queryFactory UserNotificationPreferenceQuery query = this.queryFactory
.query(UserNotificationPreferenceQuery.class) .query(UserNotificationPreferenceQuery.class)
.type(type) .type(type)
.isActives(IsActive.Active) .isActives(IsActive.Active)
.userId(userId).collect(); .userId(userId);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
preferences = query.collect();
int ordinal = 0; int ordinal = 0;
List<UserNotificationPreferenceEntity> updatedPreferences = new ArrayList<>(); List<UserNotificationPreferenceEntity> updatedPreferences = new ArrayList<>();
for (NotificationContactType contactType : contactTypes) { for (NotificationContactType contactType : contactTypes) {
UserNotificationPreferenceEntity preference = preferences.stream().filter(x -> { UserNotificationPreferenceEntity preference = preferences.stream().filter(x -> x.getChannel() == contactType).findFirst().orElse(null);
try {
return x.getChannel() == contactType && (!this.tenantScope.isMultitenant() ||this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant());
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
}).findFirst().orElse(null);
boolean isUpdate = preference != null; boolean isUpdate = preference != null;
if (preference != null) { if (preference != null) {
@ -201,6 +205,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
} else { } else {
preference = new UserNotificationPreferenceEntity(); preference = new UserNotificationPreferenceEntity();
preference.setId(UUID.randomUUID());
preference.setUserId(userId); preference.setUserId(userId);
preference.setType(type); preference.setType(type);
preference.setOrdinal(ordinal); preference.setOrdinal(ordinal);
@ -215,7 +220,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
updatedPreferences.add(preference); updatedPreferences.add(preference);
ordinal++; ordinal++;
} }
List<UserNotificationPreferenceEntity> toDelete = preferences.stream().filter(x -> !updatedPreferences.stream().map(y-> y.getChannel()).collect(Collectors.toList()).contains(x.getChannel())).collect(Collectors.toList()); List<UserNotificationPreferenceEntity> toDelete = preferences.stream().filter(x -> !updatedPreferences.stream().map(UserNotificationPreferenceEntity::getChannel).toList().contains(x.getChannel())).toList();
for (UserNotificationPreferenceEntity deletable: toDelete) { for (UserNotificationPreferenceEntity deletable: toDelete) {
this.entityManager.remove(deletable); this.entityManager.remove(deletable);
} }