From f5b0af516a84ab87be91b68278ef72f6a0fdbac6 Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Tue, 23 Apr 2024 18:09:31 +0300 Subject: [PATCH] tenant configuration changes --- .../main/java/eu/eudat/event/EventBroker.java | 3 + .../TenantConfigurationTouchedEvent.java | 44 +++++ .../model/file/TransformerCacheModel.java | 23 --- .../service/deposit/DepositConfiguration.java | 2 +- .../DepositConfigurationCacheService.java | 19 +- .../eudat/service/deposit/DepositService.java | 13 +- .../service/deposit/DepositServiceImpl.java | 152 ++++++++++++--- ...s.java => DepositSourcesCacheOptions.java} | 5 +- .../deposit/DepositSourcesCacheService.java | 66 +++++++ .../description/DescriptionService.java | 8 +- .../description/DescriptionServiceImpl.java | 8 +- .../java/eu/eudat/service/dmp/DmpService.java | 8 +- .../eu/eudat/service/dmp/DmpServiceImpl.java | 8 +- .../FileTransformerCacheOptions.java | 8 - .../FileTransformerConfiguration.java | 2 +- .../FileTransformerConfigurationCache.java | 20 -- ...eTransformerConfigurationCacheOptions.java | 10 + ...eTransformerConfigurationCacheService.java | 77 ++++++++ .../FileTransformerService.java | 13 +- .../FileTransformerServiceImpl.java | 175 ++++++++++++++---- .../FileTransformerSourcesCacheOptions.java | 10 + .../FileTransformerSourcesCacheService.java | 67 +++++++ .../service/tenant/TenantServiceImpl.java | 11 +- .../TenantConfigurationServiceImpl.java | 26 ++- .../eudat/controllers/DepositController.java | 13 +- .../controllers/DescriptionController.java | 8 +- .../eu/eudat/controllers/DmpController.java | 8 +- .../FileTransformerController.java | 12 +- .../web/src/main/resources/config/cache.yml | 28 ++- .../main/resources/config/deposit-devel.yml | 4 +- 30 files changed, 687 insertions(+), 164 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/event/TenantConfigurationTouchedEvent.java delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/file/TransformerCacheModel.java rename dmp-backend/core/src/main/java/eu/eudat/service/deposit/{DepositCacheOptions.java => DepositSourcesCacheOptions.java} (59%) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheService.java delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerCacheOptions.java delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCache.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheOptions.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheService.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheOptions.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheService.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java index 62cc50830..1cb8b875a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java +++ b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java @@ -17,6 +17,9 @@ public class EventBroker { public void emit(ApiKeyStaleEvent event) { this.applicationEventPublisher.publishEvent(event); } + public void emit(TenantConfigurationTouchedEvent event) { + this.applicationEventPublisher.publishEvent(event); + } public void emit(TenantTouchedEvent event) { this.applicationEventPublisher.publishEvent(event); diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/TenantConfigurationTouchedEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/TenantConfigurationTouchedEvent.java new file mode 100644 index 000000000..4fdaf9cb1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/TenantConfigurationTouchedEvent.java @@ -0,0 +1,44 @@ +package eu.eudat.event; + +import eu.eudat.commons.enums.TenantConfigurationType; + +import java.util.UUID; + +public class TenantConfigurationTouchedEvent { + public TenantConfigurationTouchedEvent() { + } + + public TenantConfigurationTouchedEvent(UUID tenantId, String tenantCode, TenantConfigurationType type) { + this.tenantId = tenantId; + this.tenantCode = tenantCode; + this.type = type; + } + + private UUID tenantId; + private String tenantCode; + private TenantConfigurationType type; + + 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 getTenantCode() { + return tenantCode; + } + + public void setTenantCode(String tenantCode) { + this.tenantCode = tenantCode; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/file/TransformerCacheModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/file/TransformerCacheModel.java deleted file mode 100644 index 7f1b523ba..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/model/file/TransformerCacheModel.java +++ /dev/null @@ -1,23 +0,0 @@ -package eu.eudat.model.file; -import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration; - -import java.util.List; - -public class TransformerCacheModel { - private List configurations; - - public TransformerCacheModel() { - } - - public TransformerCacheModel(List formats) { - this.configurations = formats; - } - - public List getConfigurations() { - return configurations; - } - - public void setConfigurations(List configurations) { - this.configurations = configurations; - } -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfiguration.java index 603374d5a..fc9020f79 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfiguration.java @@ -4,6 +4,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Configuration; @Configuration -@EnableConfigurationProperties({DepositProperties.class, DepositCacheOptions.class}) +@EnableConfigurationProperties({DepositProperties.class}) public class DepositConfiguration { } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfigurationCacheService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfigurationCacheService.java index ed1911de5..6d1a38255 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfigurationCacheService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositConfigurationCacheService.java @@ -15,12 +15,14 @@ public class DepositConfigurationCacheService extends CacheService keyParts = new HashMap<>(); - keyParts.put("$repositoryId$", subject); + keyParts.put("$repositoryId$", repositoryId); + keyParts.put("$tenantCode$", tenantCod); return this.generateKey(keyParts); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositService.java index 2d0ad9fed..d1870c86f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositService.java @@ -6,14 +6,21 @@ import eu.eudat.model.persist.deposit.DepositRequest; import eu.eudat.model.deposit.DepositConfiguration; import gr.cite.tools.fieldset.FieldSet; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.management.InvalidApplicationException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; public interface DepositService { - List getAvailableConfigurations(FieldSet fieldSet); + List getAvailableConfigurations(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; EntityDoi deposit(DepositRequest dmpDepositModel) throws Exception; - String getLogo(String repositoryId); + String getLogo(String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; - String authenticate(DepositAuthenticateRequest model); + String authenticate(DepositAuthenticateRequest model) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java index 402e37233..73fa15e89 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java @@ -9,16 +9,22 @@ import eu.eudat.commons.JsonHandlingService; import eu.eudat.commons.enums.ContactInfoType; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.StorageType; +import eu.eudat.commons.enums.TenantConfigurationType; import eu.eudat.commons.notification.NotificationProperties; +import eu.eudat.commons.scope.tenant.TenantScope; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.deposit.DepositSourceEntity; import eu.eudat.commons.types.notification.*; +import eu.eudat.commons.types.tenantconfiguration.DepositTenantConfigurationEntity; import eu.eudat.convention.ConventionService; import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpUserEntity; +import eu.eudat.data.TenantConfigurationEntity; import eu.eudat.data.UserEntity; import eu.eudat.depositinterface.repository.DepositClient; import eu.eudat.depositinterface.repository.DepositConfiguration; +import eu.eudat.event.TenantConfigurationTouchedEvent; +import eu.eudat.event.UserAddedToTenantEvent; import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent; import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import eu.eudat.model.EntityDoi; @@ -30,14 +36,14 @@ import eu.eudat.model.persist.StorageFilePersist; import eu.eudat.model.persist.deposit.DepositAuthenticateRequest; import eu.eudat.model.persist.deposit.DepositRequest; import eu.eudat.model.persist.EntityDoiPersist; -import eu.eudat.query.DmpQuery; -import eu.eudat.query.DmpUserQuery; -import eu.eudat.query.UserContactInfoQuery; -import eu.eudat.query.UserQuery; +import eu.eudat.model.tenantconfiguration.TenantConfiguration; +import eu.eudat.query.*; +import eu.eudat.service.encryption.EncryptionService; import eu.eudat.service.entitydoi.EntityDoiService; import eu.eudat.service.storage.StorageFileProperties; import eu.eudat.service.storage.StorageFileService; import eu.eudat.service.filetransformer.FileTransformerService; +import eu.eudat.service.tenant.TenantProperties; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; @@ -54,14 +60,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; +import org.springframework.context.event.EventListener; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; -import java.net.URI; import java.net.URLConnection; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.time.Duration; import java.util.*; import java.util.stream.Collectors; @@ -89,6 +101,11 @@ public class DepositServiceImpl implements DepositService { private final JsonHandlingService jsonHandlingService; private final NotificationProperties notificationProperties; private final NotifyIntegrationEventHandler eventHandler; + private final TenantScope tenantScope; + private final EncryptionService encryptionService; + private final TenantProperties tenantProperties; + private final DepositSourcesCacheService depositSourcesCacheService; + @Autowired public DepositServiceImpl(DepositProperties depositProperties, TokenExchangeCacheService tokenExchangeCacheService, @@ -96,7 +113,7 @@ public class DepositServiceImpl implements DepositService { EntityDoiService doiService, QueryFactory queryFactory, MessageSource messageSource, - BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService, FileTransformerService fileTransformerService, StorageFileService storageFileService, UserScope userScope, ValidatorFactory validatorFactory, StorageFileProperties storageFileProperties, AuthorizationContentResolver authorizationContentResolver, ConventionService conventionService, JsonHandlingService jsonHandlingService, NotificationProperties notificationProperties, NotifyIntegrationEventHandler eventHandler) { + BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService, FileTransformerService fileTransformerService, StorageFileService storageFileService, UserScope userScope, ValidatorFactory validatorFactory, StorageFileProperties storageFileProperties, AuthorizationContentResolver authorizationContentResolver, ConventionService conventionService, JsonHandlingService jsonHandlingService, NotificationProperties notificationProperties, NotifyIntegrationEventHandler eventHandler, TenantScope tenantScope, EncryptionService encryptionService, TenantProperties tenantProperties, DepositSourcesCacheService depositSourcesCacheService) { this.depositProperties = depositProperties; this.tokenExchangeCacheService = tokenExchangeCacheService; this.authorizationService = authorizationService; @@ -115,45 +132,122 @@ public class DepositServiceImpl implements DepositService { this.jsonHandlingService = jsonHandlingService; this.notificationProperties = notificationProperties; this.eventHandler = eventHandler; - this.clients = new HashMap<>(); + this.tenantScope = tenantScope; + this.encryptionService = encryptionService; + this.tenantProperties = tenantProperties; + this.depositSourcesCacheService = depositSourcesCacheService; + this.clients = new HashMap<>(); } - - private DepositClient getDepositClient(String repositoryId) { - if (this.clients.containsKey(repositoryId)) return this.clients.get(repositoryId); + + private DepositClient getDepositClient(String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + String repositoryIdByTenant = this.getRepositoryIdByTenant(repositoryId); + if (this.clients.containsKey(repositoryIdByTenant)) return this.clients.get(repositoryIdByTenant); //GK: It's register time - DepositSourceEntity source = depositProperties.getSources().stream().filter(depositSource -> depositSource.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); + DepositSourceEntity source = this.getDepositSources().stream().filter(depositSource -> depositSource.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); if (source != null) { - String host = URI.create(source.getUrl()).getHost(); - TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("deposit:" + source.getRepositoryId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); + TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("deposit:" + repositoryIdByTenant, source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); TokenExchangeFilterFunction apiKeyExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); WebClient webClient = WebClient.builder().baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build(); DepositClientImpl repository = new DepositClientImpl(webClient); - this.clients.put(source.getRepositoryId(), repository); + this.clients.put(repositoryIdByTenant, repository); return repository; } return null; } + private List getDepositSources() throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + String tenantCode = this.tenantScope.isSet() && this.tenantScope.isMultitenant() ? this.tenantScope.getTenantCode() : ""; + DepositSourcesCacheService.DepositSourceCacheValue cacheValue = this.depositSourcesCacheService.lookup(this.depositSourcesCacheService.buildKey(tenantCode)); + if (cacheValue == null) { + List depositSourceEntities = new ArrayList<>(depositProperties.getSources()); + if (this.tenantScope.isSet() && this.tenantScope.isMultitenant()) { + TenantConfigurationQuery tenantConfigurationQuery = this.queryFactory.query(TenantConfigurationQuery.class).isActive(IsActive.Active).types(TenantConfigurationType.DepositPlugins); + if (this.tenantScope.isDefaultTenant()) tenantConfigurationQuery.tenantIsSet(false); + else tenantConfigurationQuery.tenantIsSet(true).tenantIds(this.tenantScope.getTenant()); + TenantConfigurationEntity tenantConfiguration = tenantConfigurationQuery.firstAs(new BaseFieldSet().ensure(TenantConfiguration._depositPlugins)); + + if (tenantConfiguration != null && !this.conventionService.isNullOrEmpty(tenantConfiguration.getValue())) { + DepositTenantConfigurationEntity depositTenantConfiguration = this.jsonHandlingService.fromJsonSafe(DepositTenantConfigurationEntity.class, tenantConfiguration.getValue()); + if (depositTenantConfiguration != null) { + if (depositTenantConfiguration.getDisableSystemSources()) depositSourceEntities = new ArrayList<>(); + depositSourceEntities.addAll(this.buildDepositSourceItems(depositTenantConfiguration.getSources())); + } + } + } + cacheValue = new DepositSourcesCacheService.DepositSourceCacheValue(tenantCode, depositSourceEntities); + this.depositSourcesCacheService.put(cacheValue); + } + return cacheValue.getSources(); + } + + @EventListener + public void handleTenantConfigurationTouchedEvent(TenantConfigurationTouchedEvent event) { + if (!event.getType().equals(TenantConfigurationType.DepositPlugins)) return; + DepositSourcesCacheService.DepositSourceCacheValue depositSourceCacheValue = this.depositSourcesCacheService.lookup(this.depositSourcesCacheService.buildKey(event.getTenantCode())); + if (depositSourceCacheValue != null && depositSourceCacheValue.getSources() != null){ + for (DepositSourceEntity source : depositSourceCacheValue.getSources()){ + String repositoryIdByTenant = source.getRepositoryId() + "_" + event.getTenantCode(); + this.clients.remove(repositoryIdByTenant); + this.depositConfigurationCacheService.evict(this.depositConfigurationCacheService.buildKey(source.getRepositoryId(), event.getTenantCode())); + } + } + this.depositSourcesCacheService.evict(this.depositSourcesCacheService.buildKey(event.getTenantCode())); + } + + private List buildDepositSourceItems(List sources) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + List items = new ArrayList<>(); + if (this.conventionService.isListNullOrEmpty(sources)) return items; + for (DepositSourceEntity source : sources){ + DepositSourceEntity item = new DepositSourceEntity(); + item.setRepositoryId(source.getRepositoryId()); + item.setUrl(source.getUrl()); + item.setIssuerUrl(source.getIssuerUrl()); + item.setClientId(source.getClientId()); + if (!this.conventionService.isNullOrEmpty(source.getClientSecret())) item.setClientSecret(this.encryptionService.decryptAES(source.getClientSecret(), tenantProperties.getConfigEncryptionAesKey(), tenantProperties.getConfigEncryptionAesIv())); + item.setScope(source.getScope()); + item.setRdaTransformerId(source.getRdaTransformerId()); + item.setPdfTransformerId(source.getPdfTransformerId()); + items.add(item); + } + return items; + } + + private String getRepositoryIdByTenant(String repositoryId) throws InvalidApplicationException { + if (this.tenantScope.isSet() && this.tenantScope.isMultitenant()) { + return repositoryId + "_" + this.tenantScope.getTenantCode(); + } else { + return repositoryId; + } + } + @Override - public List getAvailableConfigurations(FieldSet fieldSet) { + public List getAvailableConfigurations(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation); List configurations = new ArrayList<>(); - for (DepositSourceEntity depositSource : depositProperties.getSources()) { - DepositConfigurationCacheService.DepositConfigurationCacheValue cacheValue = this.depositConfigurationCacheService.lookup(this.depositConfigurationCacheService.buildKey(depositSource.getRepositoryId())); - if (cacheValue == null){ - DepositClient depositClient = getDepositClient(depositSource.getRepositoryId()); - if (depositClient == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{depositSource.getRepositoryId(), DepositClient.class.getSimpleName()}, LocaleContextHolder.getLocale())); + for (DepositSourceEntity depositSource : this.getDepositSources()) { - DepositConfiguration configuration = depositClient.getConfiguration(); - cacheValue = new DepositConfigurationCacheService.DepositConfigurationCacheValue(depositSource.getRepositoryId(), configuration); - this.depositConfigurationCacheService.put(cacheValue); + String tenantCode = this.tenantScope.isSet() && this.tenantScope.isMultitenant() ? this.tenantScope.getTenantCode() : ""; + DepositConfigurationCacheService.DepositConfigurationCacheValue cacheValue = this.depositConfigurationCacheService.lookup(this.depositConfigurationCacheService.buildKey(depositSource.getRepositoryId(), tenantCode)); + if (cacheValue == null){ + try { + DepositClient depositClient = getDepositClient(depositSource.getRepositoryId()); + if (depositClient == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{depositSource.getRepositoryId(), DepositClient.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + DepositConfiguration configuration = depositClient.getConfiguration(); + cacheValue = new DepositConfigurationCacheService.DepositConfigurationCacheValue(depositSource.getRepositoryId(), tenantCode, configuration); + this.depositConfigurationCacheService.put(cacheValue); + }catch (Exception e){ + logger.error(e.getMessage(), e); + } + } + if (cacheValue != null) { + eu.eudat.model.deposit.DepositConfiguration depositConfiguration = this.builderFactory.builder(DepositConfigurationBuilder.class).build(fieldSet, cacheValue.getConfiguration()); + configurations.add(depositConfiguration); } - eu.eudat.model.deposit.DepositConfiguration depositConfiguration = this.builderFactory.builder(DepositConfigurationBuilder.class).build(fieldSet, cacheValue.getConfiguration()); - configurations.add(depositConfiguration); } return configurations; @@ -172,7 +266,7 @@ public class DepositServiceImpl implements DepositService { //GK: Forth make the required files to be uploaded with the deposit //TODO: Properly create required files - DepositSourceEntity source = depositProperties.getSources().stream().filter(depositSource -> depositSource.getRepositoryId().equals(dmpDepositModel.getRepositoryId())).findFirst().orElse(null); + DepositSourceEntity source = this.getDepositSources().stream().filter(depositSource -> depositSource.getRepositoryId().equals(dmpDepositModel.getRepositoryId())).findFirst().orElse(null); if (source == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{dmpDepositModel.getRepositoryId(), DepositSourceEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); eu.eudat.model.file.FileEnvelope pdfFile = this.fileTransformerService.exportDmp(dmpEntity.getId(), source.getPdfTransformerId(),"pdf"); @@ -217,7 +311,7 @@ public class DepositServiceImpl implements DepositService { throw new MyNotFoundException("Dmp does not have Users"); } - List users = this.queryFactory.query(UserQuery.class).ids(dmpUsers.stream().map(x -> x.getUserId()).collect(Collectors.toList())).isActive(IsActive.Active).collect(); + List users = this.queryFactory.query(UserQuery.class).ids(dmpUsers.stream().map(DmpUserEntity::getUserId).collect(Collectors.toList())).isActive(IsActive.Active).collect(); for (UserEntity user: users) { if (!user.getId().equals(this.userScope.getUserIdSafe()) && !this.conventionService.isListNullOrEmpty(dmpUsers.stream().filter(x -> x.getUserId().equals(user.getId())).collect(Collectors.toList()))){ @@ -263,7 +357,7 @@ public class DepositServiceImpl implements DepositService { } @Override - public String getLogo(String repositoryId) { + public String getLogo(String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation); DepositClient depositClient = getDepositClient(repositoryId); @@ -272,7 +366,7 @@ public class DepositServiceImpl implements DepositService { } @Override - public String authenticate(DepositAuthenticateRequest model) { + public String authenticate(DepositAuthenticateRequest model) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation); DepositClient depositClient = getDepositClient(model.getRepositoryId()); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheOptions.java similarity index 59% rename from dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositCacheOptions.java rename to dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheOptions.java index 7c20baa1b..3e42fc171 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositCacheOptions.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheOptions.java @@ -4,6 +4,7 @@ import gr.cite.tools.cache.CacheOptions; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; -@ConfigurationProperties(prefix = "cache.deposit") -public class DepositCacheOptions extends CacheOptions { +@Configuration +@ConfigurationProperties(prefix = "cache.deposit-sources-by-tenant") +public class DepositSourcesCacheOptions extends CacheOptions { } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheService.java new file mode 100644 index 000000000..c99996a4a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositSourcesCacheService.java @@ -0,0 +1,66 @@ +package eu.eudat.service.deposit; + +import eu.eudat.commons.types.deposit.DepositSourceEntity; +import gr.cite.tools.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; + +@Service +public class DepositSourcesCacheService extends CacheService { + + public static class DepositSourceCacheValue { + + public DepositSourceCacheValue() { + } + + public DepositSourceCacheValue(String tenantCode, List sources) { + this.tenantCode = tenantCode; + this.sources = sources; + } + + private String tenantCode; + + private List sources; + + public List getSources() { + return sources; + } + + public void setSources(List sources) { + this.sources = sources; + } + + public String getTenantCode() { + return tenantCode; + } + + public void setTenantCode(String tenantCode) { + this.tenantCode = tenantCode; + } + } + + + @Autowired + public DepositSourcesCacheService(DepositSourcesCacheOptions options) { + super(options); + } + + @Override + protected Class valueClass() { + return DepositSourceCacheValue.class; + } + + @Override + public String keyOf(DepositSourceCacheValue value) { + return this.buildKey(value.getTenantCode()); + } + + public String buildKey(String tenantCod) { + HashMap keyParts = new HashMap<>(); + keyParts.put("$tenantCode$", tenantCod); + return this.generateKey(keyParts); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java index 67a848213..f7ddafb08 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java @@ -15,8 +15,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.multipart.MultipartFile; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; import java.util.UUID; @@ -34,7 +40,7 @@ public interface DescriptionService { void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException; - ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException; + ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException; StorageFileEntity getFieldFile(UUID descriptionId, UUID storageFileId); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java index c04eea681..ac508aa75 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java @@ -67,9 +67,15 @@ import org.springframework.stereotype.Service; import org.springframework.util.unit.DataSize; import org.springframework.web.multipart.MultipartFile; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; import java.net.URLConnection; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.time.Duration; import java.time.Instant; import java.util.*; @@ -868,7 +874,7 @@ public class DescriptionServiceImpl implements DescriptionService { //region file export @Override - public ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException { + public ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { HttpHeaders headers = new HttpHeaders(); FileEnvelope fileEnvelope = this.fileTransformerService.exportDescription(id, null, exportType); //TODO get repo from config diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java index bcdc72300..4e61b5d74 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java @@ -12,10 +12,16 @@ import gr.cite.tools.fieldset.FieldSet; import jakarta.xml.bind.JAXBException; import org.springframework.http.ResponseEntity; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.UUID; @@ -38,7 +44,7 @@ public interface DmpService { List assignUsers(UUID dmp, List model, FieldSet fields, boolean disableDelete) throws InvalidApplicationException, IOException; Dmp removeUser(DmpUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException; - ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException; + ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; void inviteUserOrAssignUsers(UUID id, List users) throws InvalidApplicationException, JAXBException, IOException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 7be41d4fb..901256711 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -76,8 +76,14 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -650,7 +656,7 @@ public class DmpServiceImpl implements DmpService { } @Override - public ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException { + public ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { HttpHeaders headers = new HttpHeaders(); FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(id, transformerId, exportType); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerCacheOptions.java deleted file mode 100644 index 76dda8b8d..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerCacheOptions.java +++ /dev/null @@ -1,8 +0,0 @@ -package eu.eudat.service.filetransformer; - -import gr.cite.tools.cache.CacheOptions; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(prefix = "cache.file-transformer") -public class FileTransformerCacheOptions extends CacheOptions { -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfiguration.java index 0fa778b50..c52521da4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfiguration.java @@ -4,6 +4,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Configuration; @Configuration -@EnableConfigurationProperties({FileTransformerProperties.class, FileTransformerCacheOptions.class}) +@EnableConfigurationProperties({FileTransformerProperties.class}) public class FileTransformerConfiguration { } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCache.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCache.java deleted file mode 100644 index e94258db8..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCache.java +++ /dev/null @@ -1,20 +0,0 @@ -package eu.eudat.service.filetransformer; - - -import eu.eudat.model.file.TransformerCacheModel; -import gr.cite.tools.cache.CacheService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class FileTransformerConfigurationCache extends CacheService { - @Autowired - public FileTransformerConfigurationCache(FileTransformerCacheOptions options) { - super(options); - } - - @Override - protected Class valueClass() { - return TransformerCacheModel.class; - } -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheOptions.java new file mode 100644 index 000000000..3f9e17aed --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheOptions.java @@ -0,0 +1,10 @@ +package eu.eudat.service.filetransformer; + +import gr.cite.tools.cache.CacheOptions; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "cache.file-transformer-config-by-id") +public class FileTransformerConfigurationCacheOptions extends CacheOptions { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheService.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheService.java new file mode 100644 index 000000000..878d2e94b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerConfigurationCacheService.java @@ -0,0 +1,77 @@ +package eu.eudat.service.filetransformer; + +import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration; +import gr.cite.tools.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; + +@Service +public class FileTransformerConfigurationCacheService extends CacheService { + + public static class FileTransformerConfigurationCacheValue { + + public FileTransformerConfigurationCacheValue() { + } + + public FileTransformerConfigurationCacheValue(String repositoryId, String tenantCode, FileTransformerConfiguration configuration) { + this.transformerId = repositoryId; + this.configuration = configuration; + this.tenantCode = tenantCode == null ? "" : tenantCode; + } + + private String transformerId; + private String tenantCode; + + public String getTransformerId() { + return transformerId; + } + + public void setTransformerId(String transformerId) { + this.transformerId = transformerId; + } + + private FileTransformerConfiguration configuration; + + public FileTransformerConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(FileTransformerConfiguration configuration) { + this.configuration = configuration; + } + + public String getTenantCode() { + return tenantCode; + } + + public void setTenantCode(String tenantCode) { + this.tenantCode = tenantCode; + } + } + + + @Autowired + public FileTransformerConfigurationCacheService(FileTransformerConfigurationCacheOptions options) { + super(options); + } + + @Override + protected Class valueClass() { + return FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue.class; + } + + @Override + public String keyOf(FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue value) { + return this.buildKey(value.getTransformerId(), value.getTenantCode()); + } + + + public String buildKey(String transformerId, String tenantCod) { + HashMap keyParts = new HashMap<>(); + keyParts.put("$transformerId$", transformerId); + keyParts.put("$tenantCode$", tenantCod); + return this.generateKey(keyParts); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerService.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerService.java index a238ee76d..c8aa202b0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerService.java @@ -2,13 +2,20 @@ package eu.eudat.service.filetransformer; import eu.eudat.model.file.RepositoryFileFormat; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.management.InvalidApplicationException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.UUID; public interface FileTransformerService { - List getAvailableExportFileFormats(); + List getAvailableExportFileFormats() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; - eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format); + eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; - eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String repositoryId, String format); + eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerServiceImpl.java index 3ecc56270..6d656ebf7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerServiceImpl.java @@ -5,18 +5,29 @@ import eu.eudat.authorization.Permission; import eu.eudat.commonmodels.models.FileEnvelopeModel; import eu.eudat.commonmodels.models.description.DescriptionModel; import eu.eudat.commonmodels.models.dmp.DmpModel; +import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.StorageType; +import eu.eudat.commons.enums.TenantConfigurationType; +import eu.eudat.commons.scope.tenant.TenantScope; import eu.eudat.commons.types.filetransformer.FileTransformerSourceEntity; +import eu.eudat.commons.types.tenantconfiguration.FileTransformerTenantConfigurationEntity; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.TenantConfigurationEntity; +import eu.eudat.event.TenantConfigurationTouchedEvent; import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration; import eu.eudat.model.Description; import eu.eudat.model.Dmp; import eu.eudat.model.builder.commonmodels.description.DescriptionCommonModelBuilder; import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; import eu.eudat.model.file.RepositoryFileFormat; -import eu.eudat.model.file.TransformerCacheModel; +import eu.eudat.model.tenantconfiguration.TenantConfiguration; import eu.eudat.query.DescriptionQuery; import eu.eudat.query.DmpQuery; +import eu.eudat.query.TenantConfigurationQuery; +import eu.eudat.service.encryption.EncryptionService; import eu.eudat.service.storage.StorageFileService; +import eu.eudat.service.tenant.TenantProperties; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; @@ -24,17 +35,25 @@ import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.BaseFieldSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; +import org.springframework.context.event.EventListener; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; -import java.net.URI; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.management.InvalidApplicationException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.*; @Service @@ -44,88 +63,164 @@ public class FileTransformerServiceImpl implements FileTransformerService { private final FileTransformerProperties fileTransformerProperties; private final Map clients; private final TokenExchangeCacheService tokenExchangeCacheService; - private final FileTransformerConfigurationCache fileTransformerConfigurationCache; + private final FileTransformerConfigurationCacheService fileTransformerConfigurationCacheService; private final AuthorizationService authorizationService; private final QueryFactory queryFactory; private final BuilderFactory builderFactory; private final StorageFileService storageFileService; private final MessageSource messageSource; + private final ConventionService conventionService; + private final TenantScope tenantScope; + private final EncryptionService encryptionService; + private final TenantProperties tenantProperties; + private final JsonHandlingService jsonHandlingService; + private final FileTransformerSourcesCacheService fileTransformerSourcesCacheService; @Autowired - public FileTransformerServiceImpl(FileTransformerProperties fileTransformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCache fileTransformerConfigurationCache, AuthorizationService authorizationService, - QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource) { + public FileTransformerServiceImpl(FileTransformerProperties fileTransformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCacheService fileTransformerConfigurationCacheService, AuthorizationService authorizationService, + QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource, ConventionService conventionService, TenantScope tenantScope, EncryptionService encryptionService, TenantProperties tenantProperties, JsonHandlingService jsonHandlingService, FileTransformerSourcesCacheService fileTransformerSourcesCacheService) { this.fileTransformerProperties = fileTransformerProperties; this.tokenExchangeCacheService = tokenExchangeCacheService; - this.fileTransformerConfigurationCache = fileTransformerConfigurationCache; - this.authorizationService = authorizationService; + this.fileTransformerConfigurationCacheService = fileTransformerConfigurationCacheService; + this.authorizationService = authorizationService; this.queryFactory = queryFactory; this.builderFactory = builderFactory; this.storageFileService = storageFileService; this.messageSource = messageSource; + this.conventionService = conventionService; + this.tenantScope = tenantScope; + this.encryptionService = encryptionService; + this.tenantProperties = tenantProperties; + this.jsonHandlingService = jsonHandlingService; + this.fileTransformerSourcesCacheService = fileTransformerSourcesCacheService; this.clients = new HashMap<>(); } - private FileTransformerRepository getRepository(String repoId) { - if (this.clients.containsKey(repoId)) return this.clients.get(repoId); + private FileTransformerRepository getRepository(String repoId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + String repositoryIdByTenant = this.getRepositoryIdByTenant(repoId); + if (this.clients.containsKey(repositoryIdByTenant)) return this.clients.get(repositoryIdByTenant); //GK: It's register time - FileTransformerSourceEntity source = fileTransformerProperties.getSources().stream().filter(depositSource -> depositSource.getTransformerId().equals(repoId)).findFirst().orElse(null); + FileTransformerSourceEntity source = this.getFileTransformerSources().stream().filter(fileTransformerSourceEntity -> fileTransformerSourceEntity.getTransformerId().equals(repoId)).findFirst().orElse(null); if (source != null) { - String host = URI.create(source.getUrl()).getHost(); - TokenExchangeModel tokenExchangeModel = new TokenExchangeModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); + TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("file_transformer:" + repositoryIdByTenant, source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); - FileTransformerRepository repository = new FileTransformerRepository(WebClient.builder().baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> { exchangeFilterFunctions.add(tokenExchangeFilterFunction); exchangeFilterFunctions.add(logRequest()); }).build()); - this.clients.put(source.getTransformerId(), repository); + this.clients.put(repositoryIdByTenant, repository); return repository; } return null; } + + private List getFileTransformerSources() throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + String tenantCode = this.tenantScope.isSet() && this.tenantScope.isMultitenant() ? this.tenantScope.getTenantCode() : ""; + FileTransformerSourcesCacheService.FileTransformerSourceCacheValue cacheValue = this.fileTransformerSourcesCacheService.lookup(this.fileTransformerSourcesCacheService.buildKey(tenantCode)); + if (cacheValue == null) { + List fileTransformerSourceEntities = new ArrayList<>(fileTransformerProperties.getSources()); + if (this.tenantScope.isSet() && this.tenantScope.isMultitenant()) { + TenantConfigurationQuery tenantConfigurationQuery = this.queryFactory.query(TenantConfigurationQuery.class).isActive(IsActive.Active).types(TenantConfigurationType.FileTransformerPlugins); + if (this.tenantScope.isDefaultTenant()) tenantConfigurationQuery.tenantIsSet(false); + else tenantConfigurationQuery.tenantIsSet(true).tenantIds(this.tenantScope.getTenant()); + TenantConfigurationEntity tenantConfiguration = tenantConfigurationQuery.firstAs(new BaseFieldSet().ensure(TenantConfiguration._fileTransformerPlugins)); + + if (tenantConfiguration != null && !this.conventionService.isNullOrEmpty(tenantConfiguration.getValue())) { + FileTransformerTenantConfigurationEntity fileTransformerTenantConfigurationEntity = this.jsonHandlingService.fromJsonSafe(FileTransformerTenantConfigurationEntity.class, tenantConfiguration.getValue()); + if (fileTransformerTenantConfigurationEntity != null) { + if (fileTransformerTenantConfigurationEntity.getDisableSystemSources()) fileTransformerSourceEntities = new ArrayList<>(); + fileTransformerSourceEntities.addAll(this.buildFileTransformerSourceItems(fileTransformerTenantConfigurationEntity.getSources())); + } + } + } + cacheValue = new FileTransformerSourcesCacheService.FileTransformerSourceCacheValue(tenantCode, fileTransformerSourceEntities); + this.fileTransformerSourcesCacheService.put(cacheValue); + } + return cacheValue.getSources(); + } + + @EventListener + public void handleTenantConfigurationTouchedEvent(TenantConfigurationTouchedEvent event) { + if (!event.getType().equals(TenantConfigurationType.FileTransformerPlugins)) return; + FileTransformerSourcesCacheService.FileTransformerSourceCacheValue fileTransformerSourceCacheValue = this.fileTransformerSourcesCacheService.lookup(this.fileTransformerSourcesCacheService.buildKey(event.getTenantCode())); + if (fileTransformerSourceCacheValue != null && fileTransformerSourceCacheValue.getSources() != null){ + for (FileTransformerSourceEntity source : fileTransformerSourceCacheValue.getSources()){ + String repositoryIdByTenant = source.getTransformerId() + "_" + event.getTenantCode(); + this.clients.remove(repositoryIdByTenant); + this.fileTransformerConfigurationCacheService.evict(this.fileTransformerConfigurationCacheService.buildKey(source.getTransformerId(), event.getTenantCode())); + } + } + this.fileTransformerSourcesCacheService.evict(this.fileTransformerSourcesCacheService.buildKey(event.getTenantCode())); + } + + private List buildFileTransformerSourceItems(List sources) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + List items = new ArrayList<>(); + if (this.conventionService.isListNullOrEmpty(sources)) return items; + for (FileTransformerSourceEntity source : sources){ + FileTransformerSourceEntity item = new FileTransformerSourceEntity(); + item.setTransformerId(source.getTransformerId()); + item.setUrl(source.getUrl()); + item.setIssuerUrl(source.getIssuerUrl()); + item.setClientId(source.getClientId()); + if (!this.conventionService.isNullOrEmpty(source.getClientSecret())) item.setClientSecret(this.encryptionService.decryptAES(source.getClientSecret(), tenantProperties.getConfigEncryptionAesKey(), tenantProperties.getConfigEncryptionAesIv())); + item.setScope(source.getScope()); + items.add(item); + } + return items; + } + + private String getRepositoryIdByTenant(String repositoryId) throws InvalidApplicationException { + if (this.tenantScope.isSet() && this.tenantScope.isMultitenant()) { + return repositoryId + "_" + this.tenantScope.getTenantCode(); + } else { + return repositoryId; + } + } + + @Override - public List getAvailableExportFileFormats() { + public List getAvailableExportFileFormats() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { List formats = new ArrayList<>(); List configurations = this.getAvailableConfigurations(); - if(configurations != null){ - for (FileTransformerConfiguration configuration : configurations){ - if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants().stream().map(x-> new RepositoryFileFormat(configuration.getFileTransformerId(), x, configuration.getExportEntityTypes())).toList()); - } + for (FileTransformerConfiguration configuration : configurations){ + if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants().stream().map(x-> new RepositoryFileFormat(configuration.getFileTransformerId(), x, configuration.getExportEntityTypes())).toList()); } return formats; } - private List getAvailableConfigurations() { - TransformerCacheModel configs = fileTransformerConfigurationCache.lookup("base"); - if (configs == null) { - List configurations = new ArrayList<>(); - //GK: So much for lazy loading - List repositories = fileTransformerProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getTransformerId())).toList(); + private List getAvailableConfigurations() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + + List configurations = new ArrayList<>(); - repositories = new ArrayList<>(repositories); - repositories.forEach((client) -> { + for (FileTransformerSourceEntity transformerSource : this.getFileTransformerSources()) { + + String tenantCode = this.tenantScope.isSet() && this.tenantScope.isMultitenant() ? this.tenantScope.getTenantCode() : ""; + FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue cacheValue = this.fileTransformerConfigurationCacheService.lookup(this.fileTransformerConfigurationCacheService.buildKey(transformerSource.getTransformerId(), tenantCode)); + if (cacheValue == null){ try { - FileTransformerConfiguration repositoryConfig = client.getConfiguration(); - if (repositoryConfig != null) { - configurations.add(repositoryConfig); - } - } catch (Exception e) { - logger.warn(e.getLocalizedMessage(), e); - } - }); + FileTransformerRepository fileTransformerRepository = getRepository(transformerSource.getTransformerId()); + if (fileTransformerRepository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{transformerSource.getTransformerId(), FileTransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale())); - configs = new TransformerCacheModel(configurations); - this.fileTransformerConfigurationCache.put("base", configs); + FileTransformerConfiguration configuration = fileTransformerRepository.getConfiguration(); + cacheValue = new FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue(transformerSource.getTransformerId(), tenantCode, configuration); + this.fileTransformerConfigurationCacheService.put(cacheValue); + }catch (Exception e){ + logger.error(e.getMessage(), e); + } + } + if (cacheValue != null) { + configurations.add(cacheValue.getConfiguration()); + } } - return configs.getConfigurations(); + return configurations; } @Override - public eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) { + public eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { this.authorizationService.authorize(Permission.EditDmp); //GK: First get the right client FileTransformerRepository repository = getRepository(repositoryId); @@ -145,7 +240,7 @@ public class FileTransformerServiceImpl implements FileTransformerService { } @Override - public eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String repositoryId, String format) { + public eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { this.authorizationService.authorize(Permission.EditDmp); //GK: First get the right client FileTransformerRepository repository = getRepository(repositoryId); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheOptions.java new file mode 100644 index 000000000..9ba515040 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheOptions.java @@ -0,0 +1,10 @@ +package eu.eudat.service.filetransformer; + +import gr.cite.tools.cache.CacheOptions; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "cache.file-transformer-sources-by-tenant") +public class FileTransformerSourcesCacheOptions extends CacheOptions { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheService.java b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheService.java new file mode 100644 index 000000000..762c18dee --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/filetransformer/FileTransformerSourcesCacheService.java @@ -0,0 +1,67 @@ +package eu.eudat.service.filetransformer; + +import eu.eudat.commons.types.filetransformer.FileTransformerSourceEntity; +import gr.cite.tools.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; + +@Service +public class FileTransformerSourcesCacheService extends CacheService { + + public static class FileTransformerSourceCacheValue { + + public FileTransformerSourceCacheValue() { + } + + public FileTransformerSourceCacheValue(String tenantCode, List sources) { + this.tenantCode = tenantCode; + this.sources = sources; + } + + private String tenantCode; + + private List sources; + + + public String getTenantCode() { + return tenantCode; + } + + public void setTenantCode(String tenantCode) { + this.tenantCode = tenantCode; + } + + public List getSources() { + return sources; + } + + public void setSources(List sources) { + this.sources = sources; + } + } + + + @Autowired + public FileTransformerSourcesCacheService(FileTransformerSourcesCacheOptions options) { + super(options); + } + + @Override + protected Class valueClass() { + return FileTransformerSourceCacheValue.class; + } + + @Override + public String keyOf(FileTransformerSourceCacheValue value) { + return this.buildKey(value.getTenantCode()); + } + + public String buildKey(String tenantCod) { + HashMap keyParts = new HashMap<>(); + keyParts.put("$tenantCode$", tenantCod); + return this.generateKey(keyParts); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/tenant/TenantServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/tenant/TenantServiceImpl.java index a1f729271..4d8884467 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/tenant/TenantServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/tenant/TenantServiceImpl.java @@ -69,11 +69,7 @@ public class TenantServiceImpl implements TenantService { private final ConventionService conventionService; private final MessageSource messageSource; - private final XmlHandlingService xmlHandlingService; private final ErrorThesaurusProperties errors; - private final EncryptionService encryptionService; - - private final TenantProperties properties; private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler; private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler; private final KeycloakService keycloakService; @@ -90,19 +86,14 @@ public class TenantServiceImpl implements TenantService { BuilderFactory builderFactory, ConventionService conventionService, MessageSource messageSource, - XmlHandlingService xmlHandlingService, - ErrorThesaurusProperties errors, - EncryptionService encryptionService, TenantProperties properties, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) { + ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; this.builderFactory = builderFactory; this.conventionService = conventionService; this.messageSource = messageSource; - this.xmlHandlingService = xmlHandlingService; this.errors = errors; - this.encryptionService = encryptionService; - this.properties = properties; this.tenantTouchedIntegrationEventHandler = tenantTouchedIntegrationEventHandler; this.tenantRemovalIntegrationEventHandler = tenantRemovalIntegrationEventHandler; this.keycloakService = keycloakService; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java index bdbbc6323..e0a943d93 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/tenantconfiguration/TenantConfigurationServiceImpl.java @@ -7,13 +7,17 @@ import eu.eudat.commons.JsonHandlingService; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.StorageType; import eu.eudat.commons.enums.TenantConfigurationType; +import eu.eudat.commons.scope.tenant.TenantScope; import eu.eudat.commons.types.deposit.DepositSourceEntity; import eu.eudat.commons.types.filetransformer.FileTransformerSourceEntity; import eu.eudat.commons.types.tenantconfiguration.*; import eu.eudat.convention.ConventionService; import eu.eudat.data.TenantConfigurationEntity; +import eu.eudat.data.TenantEntity; import eu.eudat.data.TenantEntityManager; import eu.eudat.errorcode.ErrorThesaurusProperties; +import eu.eudat.event.EventBroker; +import eu.eudat.event.TenantConfigurationTouchedEvent; import eu.eudat.model.StorageFile; import eu.eudat.model.builder.tenantconfiguration.TenantConfigurationBuilder; import eu.eudat.model.deleter.TenantConfigurationDeleter; @@ -82,6 +86,8 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic private final TenantProperties tenantProperties; private final StorageFileService storageFileService; private final QueryFactory queryFactory; + private final EventBroker eventBroker; + private final TenantScope tenantScope; @Autowired public TenantConfigurationServiceImpl( TenantEntityManager entityManager, @@ -90,7 +96,7 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic BuilderFactory builderFactory, ConventionService conventionService, ErrorThesaurusProperties errors, - MessageSource messageSource, JsonHandlingService jsonHandlingService, EncryptionService encryptionService, TenantProperties tenantProperties, StorageFileService storageFileService, QueryFactory queryFactory) { + MessageSource messageSource, JsonHandlingService jsonHandlingService, EncryptionService encryptionService, TenantProperties tenantProperties, StorageFileService storageFileService, QueryFactory queryFactory, EventBroker eventBroker, TenantScope tenantScope) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -103,6 +109,8 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic this.tenantProperties = tenantProperties; this.storageFileService = storageFileService; this.queryFactory = queryFactory; + this.eventBroker = eventBroker; + this.tenantScope = tenantScope; } public TenantConfiguration persist(TenantConfigurationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { @@ -150,6 +158,14 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic this.entityManager.flush(); + if (data.getTenantId() != null) { + TenantEntity tenant = this.entityManager.find(TenantEntity.class, data.getTenantId()); + if (tenant == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getTenantId(), TenantEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + this.eventBroker.emit(new TenantConfigurationTouchedEvent(tenant.getId(), tenant.getCode(), data.getType())); + } else { + this.eventBroker.emit(new TenantConfigurationTouchedEvent(data.getId(), this.tenantScope.getDefaultTenantCode(), data.getType())); + } + return this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, TenantConfiguration._id), data); } @@ -253,6 +269,14 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic if (oldValue != null && oldValue.getStorageFileId() != null) this.storageFileService.updatePurgeAt(oldValue.getStorageFileId(), Instant.now().minusSeconds(60)); } this.deleterFactory.deleter(TenantConfigurationDeleter.class).deleteAndSaveByIds(List.of(id)); + + if (data.getTenantId() != null) { + TenantEntity tenant = this.entityManager.find(TenantEntity.class, data.getTenantId()); + if (tenant == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getTenantId(), TenantEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + this.eventBroker.emit(new TenantConfigurationTouchedEvent(tenant.getId(), tenant.getCode(), data.getType())); + } else { + this.eventBroker.emit(new TenantConfigurationTouchedEvent(data.getId(), this.tenantScope.getDefaultTenantCode(), data.getType())); + } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java index fcbf32fcb..dbed14a39 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java @@ -19,6 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.management.InvalidApplicationException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.AbstractMap; import java.util.List; import java.util.Map; @@ -45,7 +52,7 @@ public class DepositController { } @GetMapping("/repositories/available") - public List getAvailableRepos(FieldSet fieldSet) { + public List getAvailableRepos(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("retrieving" + DepositConfiguration.class.getSimpleName()).And("fields", fieldSet)); this.censorFactory.censor(DepositConfigurationCensor.class).censor(fieldSet, null); @@ -60,7 +67,7 @@ public class DepositController { @PostMapping("/get-access-token") @ValidationFilterAnnotation(validator = DepositAuthenticateRequest.DepositAuthenticateRequestValidator.ValidatorName, argumentName = "model") - public String getAccessToken(@RequestBody DepositAuthenticateRequest model) { + public String getAccessToken(@RequestBody DepositAuthenticateRequest model) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("get access token" + DepositAuthenticateRequest.class.getSimpleName()).And("model", model)); String accessToken = this.depositService.authenticate(model); @@ -87,7 +94,7 @@ public class DepositController { } @GetMapping("/repositories/{repositoryId}/logo") - public String getLogo(@PathVariable("repositoryId") String repositoryId) { + public String getLogo(@PathVariable("repositoryId") String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("get logo" + DepositConfiguration.class.getSimpleName()).And("repositoryId", repositoryId)); String logo = this.depositService.getLogo(repositoryId); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java index 028b0d501..4619ce30b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java @@ -47,8 +47,14 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.*; import static eu.eudat.authorization.AuthorizationFlags.Public; @@ -227,7 +233,7 @@ public class DescriptionController { } @GetMapping("{id}/export/{type}") - public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { + public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("exporting description")); return this.descriptionService.export(id, exportType); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java index 1e64954d4..8f97c92ef 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java @@ -35,10 +35,16 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.*; import static eu.eudat.authorization.AuthorizationFlags.Public; @@ -284,7 +290,7 @@ public class DmpController { } @GetMapping("{id}/export/{transformerId}/{type}") - public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("transformerId") String transformerId, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { + public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("transformerId") String transformerId, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("exporting dmp").And("id", id).And("transformerId", transformerId).And("exportType", exportType)); ResponseEntity bytes = this.dmpService.export(id, transformerId, exportType); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java index 894aab4c7..b0080443a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java @@ -16,8 +16,14 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.management.InvalidApplicationException; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.List; @RestController @@ -37,7 +43,7 @@ public class FileTransformerController { } @GetMapping("/available") - public List getAvailableConfigurations() { + public List getAvailableConfigurations() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("getAvailableConfigurations")); List model = this.fileTransformerService.getAvailableExportFileFormats(); @@ -48,7 +54,7 @@ public class FileTransformerController { } @PostMapping("/export-dmp") - public ResponseEntity export(@RequestBody ExportRequestModel requestModel) throws InvalidApplicationException, IOException { + public ResponseEntity export(@RequestBody ExportRequestModel requestModel) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("exporting dmp")); HttpHeaders headers = new HttpHeaders(); @@ -60,7 +66,7 @@ public class FileTransformerController { } @PostMapping("/export-description") - public ResponseEntity exportDescription(@RequestBody ExportRequestModel requestModel) { + public ResponseEntity exportDescription(@RequestBody ExportRequestModel requestModel) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { logger.debug(new MapLogEntry("exporting dmp")); HttpHeaders headers = new HttpHeaders(); diff --git a/dmp-backend/web/src/main/resources/config/cache.yml b/dmp-backend/web/src/main/resources/config/cache.yml index cd63200b4..61a104eb1 100644 --- a/dmp-backend/web/src/main/resources/config/cache.yml +++ b/dmp-backend/web/src/main/resources/config/cache.yml @@ -26,6 +26,12 @@ cache: maximumSize: 500 enableRecordStats: false expireAfterWriteSeconds: 600 + - names: [ "depositSourcesByTenant" ] + allowNullValues: true + initialCapacity: 100 + maximumSize: 500 + enableRecordStats: false + expireAfterWriteSeconds: 600 - names: [ "affiliation" ] allowNullValues: true initialCapacity: 100 @@ -38,7 +44,13 @@ cache: maximumSize: 500 enableRecordStats: false expireAfterWriteSeconds: 30 - - names: [ "fileTransformer" ] + - names: [ "fileTransformerConfigById" ] + allowNullValues: true + initialCapacity: 100 + maximumSize: 500 + enableRecordStats: false + expireAfterWriteSeconds: 600 + - names: [ "fileTransformerSourcesByTenant" ] allowNullValues: true initialCapacity: 100 maximumSize: 500 @@ -101,10 +113,16 @@ cache: keyPattern: dashboard_stats_by_usr_$key$:v0 depositConfigById: name: depositConfigById - keyPattern: deposit_config_by_id_$repositoryId$:v0 - fileTransformer: - name: fileTransformer - keyPattern: base:v0 + keyPattern: deposit_config_by_id_$repositoryId$_$tenantCode$:v0 + depositSourcesByTenant: + name: depositSourcesByTenant + keyPattern: deposit_sources_by_tenant_$tenantCode$:v0 + fileTransformerConfigById: + name: fileTransformerConfigById + keyPattern: file_transformer_config_by_id_$transformerId$_$tenantCode$:v0 + fileTransformerSourcesByTenant: + name: fileTransformerSourcesByTenant + keyPattern: ile_transformer_sources_by_tenant_$tenantCode$:v0 token-exchange-key: name: tokenExchangeKey keyPattern: resolve_$keyhash$:v0 diff --git a/dmp-backend/web/src/main/resources/config/deposit-devel.yml b/dmp-backend/web/src/main/resources/config/deposit-devel.yml index d806116c7..79d67a7d0 100644 --- a/dmp-backend/web/src/main/resources/config/deposit-devel.yml +++ b/dmp-backend/web/src/main/resources/config/deposit-devel.yml @@ -1,7 +1,7 @@ deposit: sources: - url: http://dev04.local.cite.gr:55330/zenodo - repositoryId: zenodo + repositoryId: Zenodo pdfTransformerId: docx-file-transformer rdaTransformerId: rda-file-transformer issuer-url: ${IDP_ISSUER_URI_TOKEN} @@ -9,7 +9,7 @@ deposit: client-secret: ${IDP_APIKEY_CLIENT_SECRET} scope: ${IDP_APIKEY_SCOPE} - url: http://dev04.local.cite.gr:55330/zenodo1 - repositoryId: zenodo1 + repositoryId: Zenodo1 pdfTransformerId: docx-file-transformer rdaTransformerId: rda-file-transformer issuer-url: ${IDP_ISSUER_URI_TOKEN}