tenant configuration changes

This commit is contained in:
Efstratios Giannopoulos 2024-04-23 18:09:31 +03:00
parent e7a500e3ec
commit f5b0af516a
30 changed files with 687 additions and 164 deletions

View File

@ -17,6 +17,9 @@ public class EventBroker {
public void emit(ApiKeyStaleEvent event) { public void emit(ApiKeyStaleEvent event) {
this.applicationEventPublisher.publishEvent(event); this.applicationEventPublisher.publishEvent(event);
} }
public void emit(TenantConfigurationTouchedEvent event) {
this.applicationEventPublisher.publishEvent(event);
}
public void emit(TenantTouchedEvent event) { public void emit(TenantTouchedEvent event) {
this.applicationEventPublisher.publishEvent(event); this.applicationEventPublisher.publishEvent(event);

View File

@ -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;
}
}

View File

@ -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<FileTransformerConfiguration> configurations;
public TransformerCacheModel() {
}
public TransformerCacheModel(List<FileTransformerConfiguration> formats) {
this.configurations = formats;
}
public List<FileTransformerConfiguration> getConfigurations() {
return configurations;
}
public void setConfigurations(List<FileTransformerConfiguration> configurations) {
this.configurations = configurations;
}
}

View File

@ -4,6 +4,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
@EnableConfigurationProperties({DepositProperties.class, DepositCacheOptions.class}) @EnableConfigurationProperties({DepositProperties.class})
public class DepositConfiguration { public class DepositConfiguration {
} }

View File

@ -15,12 +15,14 @@ public class DepositConfigurationCacheService extends CacheService<DepositConfig
public DepositConfigurationCacheValue() { public DepositConfigurationCacheValue() {
} }
public DepositConfigurationCacheValue(String repositoryId, DepositConfiguration configuration) { public DepositConfigurationCacheValue(String repositoryId, String tenantCode, DepositConfiguration configuration) {
this.repositoryId = repositoryId; this.repositoryId = repositoryId;
this.configuration = configuration; this.configuration = configuration;
this.tenantCode = tenantCode == null ? "" : tenantCode;
} }
private String repositoryId; private String repositoryId;
private String tenantCode;
public String getRepositoryId() { public String getRepositoryId() {
return repositoryId; return repositoryId;
@ -39,6 +41,14 @@ public class DepositConfigurationCacheService extends CacheService<DepositConfig
public void setConfiguration(DepositConfiguration configuration) { public void setConfiguration(DepositConfiguration configuration) {
this.configuration = configuration; this.configuration = configuration;
} }
public String getTenantCode() {
return tenantCode;
}
public void setTenantCode(String tenantCode) {
this.tenantCode = tenantCode;
}
} }
@ -54,13 +64,14 @@ public class DepositConfigurationCacheService extends CacheService<DepositConfig
@Override @Override
public String keyOf(DepositConfigurationCacheValue value) { public String keyOf(DepositConfigurationCacheValue value) {
return this.buildKey(value.getRepositoryId()); return this.buildKey(value.getRepositoryId(), value.getTenantCode());
} }
public String buildKey(String subject) { public String buildKey(String repositoryId, String tenantCod) {
HashMap<String, String> keyParts = new HashMap<>(); HashMap<String, String> keyParts = new HashMap<>();
keyParts.put("$repositoryId$", subject); keyParts.put("$repositoryId$", repositoryId);
keyParts.put("$tenantCode$", tenantCod);
return this.generateKey(keyParts); return this.generateKey(keyParts);
} }
} }

View File

@ -6,14 +6,21 @@ import eu.eudat.model.persist.deposit.DepositRequest;
import eu.eudat.model.deposit.DepositConfiguration; import eu.eudat.model.deposit.DepositConfiguration;
import gr.cite.tools.fieldset.FieldSet; 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; import java.util.List;
public interface DepositService { public interface DepositService {
List<eu.eudat.model.deposit.DepositConfiguration> getAvailableConfigurations(FieldSet fieldSet); List<eu.eudat.model.deposit.DepositConfiguration> getAvailableConfigurations(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
EntityDoi deposit(DepositRequest dmpDepositModel) throws Exception; 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;
} }

View File

@ -9,16 +9,22 @@ import eu.eudat.commons.JsonHandlingService;
import eu.eudat.commons.enums.ContactInfoType; import eu.eudat.commons.enums.ContactInfoType;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.enums.StorageType; import eu.eudat.commons.enums.StorageType;
import eu.eudat.commons.enums.TenantConfigurationType;
import eu.eudat.commons.notification.NotificationProperties; import eu.eudat.commons.notification.NotificationProperties;
import eu.eudat.commons.scope.tenant.TenantScope;
import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.scope.user.UserScope;
import eu.eudat.commons.types.deposit.DepositSourceEntity; import eu.eudat.commons.types.deposit.DepositSourceEntity;
import eu.eudat.commons.types.notification.*; import eu.eudat.commons.types.notification.*;
import eu.eudat.commons.types.tenantconfiguration.DepositTenantConfigurationEntity;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpEntity;
import eu.eudat.data.DmpUserEntity; import eu.eudat.data.DmpUserEntity;
import eu.eudat.data.TenantConfigurationEntity;
import eu.eudat.data.UserEntity; import eu.eudat.data.UserEntity;
import eu.eudat.depositinterface.repository.DepositClient; import eu.eudat.depositinterface.repository.DepositClient;
import eu.eudat.depositinterface.repository.DepositConfiguration; 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.NotifyIntegrationEvent;
import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler;
import eu.eudat.model.EntityDoi; 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.DepositAuthenticateRequest;
import eu.eudat.model.persist.deposit.DepositRequest; import eu.eudat.model.persist.deposit.DepositRequest;
import eu.eudat.model.persist.EntityDoiPersist; import eu.eudat.model.persist.EntityDoiPersist;
import eu.eudat.query.DmpQuery; import eu.eudat.model.tenantconfiguration.TenantConfiguration;
import eu.eudat.query.DmpUserQuery; import eu.eudat.query.*;
import eu.eudat.query.UserContactInfoQuery; import eu.eudat.service.encryption.EncryptionService;
import eu.eudat.query.UserQuery;
import eu.eudat.service.entitydoi.EntityDoiService; import eu.eudat.service.entitydoi.EntityDoiService;
import eu.eudat.service.storage.StorageFileProperties; import eu.eudat.service.storage.StorageFileProperties;
import eu.eudat.service.storage.StorageFileService; import eu.eudat.service.storage.StorageFileService;
import eu.eudat.service.filetransformer.FileTransformerService; 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.oidc.filter.webflux.TokenExchangeCacheService;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction;
@ -54,14 +60,20 @@ import org.slf4j.Logger;
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.event.EventListener;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient; 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 javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -89,6 +101,11 @@ public class DepositServiceImpl implements DepositService {
private final JsonHandlingService jsonHandlingService; private final JsonHandlingService jsonHandlingService;
private final NotificationProperties notificationProperties; private final NotificationProperties notificationProperties;
private final NotifyIntegrationEventHandler eventHandler; private final NotifyIntegrationEventHandler eventHandler;
private final TenantScope tenantScope;
private final EncryptionService encryptionService;
private final TenantProperties tenantProperties;
private final DepositSourcesCacheService depositSourcesCacheService;
@Autowired @Autowired
public DepositServiceImpl(DepositProperties depositProperties, public DepositServiceImpl(DepositProperties depositProperties,
TokenExchangeCacheService tokenExchangeCacheService, TokenExchangeCacheService tokenExchangeCacheService,
@ -96,7 +113,7 @@ public class DepositServiceImpl implements DepositService {
EntityDoiService doiService, EntityDoiService doiService,
QueryFactory queryFactory, QueryFactory queryFactory,
MessageSource messageSource, 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.depositProperties = depositProperties;
this.tokenExchangeCacheService = tokenExchangeCacheService; this.tokenExchangeCacheService = tokenExchangeCacheService;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
@ -115,46 +132,123 @@ public class DepositServiceImpl implements DepositService {
this.jsonHandlingService = jsonHandlingService; this.jsonHandlingService = jsonHandlingService;
this.notificationProperties = notificationProperties; this.notificationProperties = notificationProperties;
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.tenantScope = tenantScope;
this.encryptionService = encryptionService;
this.tenantProperties = tenantProperties;
this.depositSourcesCacheService = depositSourcesCacheService;
this.clients = new HashMap<>(); this.clients = new HashMap<>();
} }
private DepositClient getDepositClient(String repositoryId) { private DepositClient getDepositClient(String repositoryId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
if (this.clients.containsKey(repositoryId)) return this.clients.get(repositoryId); String repositoryIdByTenant = this.getRepositoryIdByTenant(repositoryId);
if (this.clients.containsKey(repositoryIdByTenant)) return this.clients.get(repositoryIdByTenant);
//GK: It's register time //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) { if (source != null) {
String host = URI.create(source.getUrl()).getHost(); TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("deposit:" + repositoryIdByTenant, source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("deposit:" + source.getRepositoryId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
TokenExchangeFilterFunction apiKeyExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); TokenExchangeFilterFunction apiKeyExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel);
WebClient webClient = WebClient.builder().baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build(); WebClient webClient = WebClient.builder().baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build();
DepositClientImpl repository = new DepositClientImpl(webClient); DepositClientImpl repository = new DepositClientImpl(webClient);
this.clients.put(source.getRepositoryId(), repository); this.clients.put(repositoryIdByTenant, repository);
return repository; return repository;
} }
return null; return null;
} }
private List<DepositSourceEntity> 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<DepositSourceEntity> 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<DepositSourceEntity> buildDepositSourceItems(List<DepositSourceEntity> sources) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
List<DepositSourceEntity> 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 @Override
public List<eu.eudat.model.deposit.DepositConfiguration> getAvailableConfigurations(FieldSet fieldSet) { public List<eu.eudat.model.deposit.DepositConfiguration> getAvailableConfigurations(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation); this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation);
List<eu.eudat.model.deposit.DepositConfiguration> configurations = new ArrayList<>(); List<eu.eudat.model.deposit.DepositConfiguration> configurations = new ArrayList<>();
for (DepositSourceEntity depositSource : depositProperties.getSources()) { for (DepositSourceEntity depositSource : this.getDepositSources()) {
DepositConfigurationCacheService.DepositConfigurationCacheValue cacheValue = this.depositConfigurationCacheService.lookup(this.depositConfigurationCacheService.buildKey(depositSource.getRepositoryId()));
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){ if (cacheValue == null){
try {
DepositClient depositClient = getDepositClient(depositSource.getRepositoryId()); DepositClient depositClient = getDepositClient(depositSource.getRepositoryId());
if (depositClient == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{depositSource.getRepositoryId(), DepositClient.class.getSimpleName()}, LocaleContextHolder.getLocale())); if (depositClient == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{depositSource.getRepositoryId(), DepositClient.class.getSimpleName()}, LocaleContextHolder.getLocale()));
DepositConfiguration configuration = depositClient.getConfiguration(); DepositConfiguration configuration = depositClient.getConfiguration();
cacheValue = new DepositConfigurationCacheService.DepositConfigurationCacheValue(depositSource.getRepositoryId(), configuration); cacheValue = new DepositConfigurationCacheService.DepositConfigurationCacheValue(depositSource.getRepositoryId(), tenantCode, configuration);
this.depositConfigurationCacheService.put(cacheValue); 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()); eu.eudat.model.deposit.DepositConfiguration depositConfiguration = this.builderFactory.builder(DepositConfigurationBuilder.class).build(fieldSet, cacheValue.getConfiguration());
configurations.add(depositConfiguration); configurations.add(depositConfiguration);
} }
}
return configurations; return configurations;
} }
@ -172,7 +266,7 @@ public class DepositServiceImpl implements DepositService {
//GK: Forth make the required files to be uploaded with the deposit //GK: Forth make the required files to be uploaded with the deposit
//TODO: Properly create required files //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())); 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"); 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"); throw new MyNotFoundException("Dmp does not have Users");
} }
List<UserEntity> users = this.queryFactory.query(UserQuery.class).ids(dmpUsers.stream().map(x -> x.getUserId()).collect(Collectors.toList())).isActive(IsActive.Active).collect(); List<UserEntity> users = this.queryFactory.query(UserQuery.class).ids(dmpUsers.stream().map(DmpUserEntity::getUserId).collect(Collectors.toList())).isActive(IsActive.Active).collect();
for (UserEntity user: users) { 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()))){ 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 @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); this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation);
DepositClient depositClient = getDepositClient(repositoryId); DepositClient depositClient = getDepositClient(repositoryId);
@ -272,7 +366,7 @@ public class DepositServiceImpl implements DepositService {
} }
@Override @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); this.authorizationService.authorizeForce(Permission.BrowseDeposit, Permission.DeferredAffiliation);
DepositClient depositClient = getDepositClient(model.getRepositoryId()); DepositClient depositClient = getDepositClient(model.getRepositoryId());

View File

@ -4,6 +4,7 @@ import gr.cite.tools.cache.CacheOptions;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ConfigurationProperties(prefix = "cache.deposit") @Configuration
public class DepositCacheOptions extends CacheOptions { @ConfigurationProperties(prefix = "cache.deposit-sources-by-tenant")
public class DepositSourcesCacheOptions extends CacheOptions {
} }

View File

@ -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<DepositSourcesCacheService.DepositSourceCacheValue> {
public static class DepositSourceCacheValue {
public DepositSourceCacheValue() {
}
public DepositSourceCacheValue(String tenantCode, List<DepositSourceEntity> sources) {
this.tenantCode = tenantCode;
this.sources = sources;
}
private String tenantCode;
private List<DepositSourceEntity> sources;
public List<DepositSourceEntity> getSources() {
return sources;
}
public void setSources(List<DepositSourceEntity> 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<DepositSourceCacheValue> valueClass() {
return DepositSourceCacheValue.class;
}
@Override
public String keyOf(DepositSourceCacheValue value) {
return this.buildKey(value.getTenantCode());
}
public String buildKey(String tenantCod) {
HashMap<String, String> keyParts = new HashMap<>();
keyParts.put("$tenantCode$", tenantCod);
return this.generateKey(keyParts);
}
}

View File

@ -15,8 +15,14 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -34,7 +40,7 @@ public interface DescriptionService {
void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException; void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException;
ResponseEntity<byte[]> export(UUID id, String exportType) throws InvalidApplicationException, IOException; ResponseEntity<byte[]> export(UUID id, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException; StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException;
StorageFileEntity getFieldFile(UUID descriptionId, UUID storageFileId); StorageFileEntity getFieldFile(UUID descriptionId, UUID storageFileId);

View File

@ -67,9 +67,15 @@ import org.springframework.stereotype.Service;
import org.springframework.util.unit.DataSize; import org.springframework.util.unit.DataSize;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.*;
@ -868,7 +874,7 @@ public class DescriptionServiceImpl implements DescriptionService {
//region file export //region file export
@Override @Override
public ResponseEntity<byte[]> export(UUID id, String exportType) throws InvalidApplicationException, IOException { public ResponseEntity<byte[]> export(UUID id, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
FileEnvelope fileEnvelope = this.fileTransformerService.exportDescription(id, null, exportType); //TODO get repo from config FileEnvelope fileEnvelope = this.fileTransformerService.exportDescription(id, null, exportType); //TODO get repo from config

View File

@ -12,10 +12,16 @@ import gr.cite.tools.fieldset.FieldSet;
import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.JAXBException;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -38,7 +44,7 @@ public interface DmpService {
List<DmpUser> assignUsers(UUID dmp, List<DmpUserPersist> model, FieldSet fields, boolean disableDelete) throws InvalidApplicationException, IOException; List<DmpUser> assignUsers(UUID dmp, List<DmpUserPersist> model, FieldSet fields, boolean disableDelete) throws InvalidApplicationException, IOException;
Dmp removeUser(DmpUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException; Dmp removeUser(DmpUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException;
ResponseEntity<byte[]> export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException; ResponseEntity<byte[]> export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
void inviteUserOrAssignUsers(UUID id, List<DmpUserPersist> users) throws InvalidApplicationException, JAXBException, IOException; void inviteUserOrAssignUsers(UUID id, List<DmpUserPersist> users) throws InvalidApplicationException, JAXBException, IOException;

View File

@ -76,8 +76,14 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -650,7 +656,7 @@ public class DmpServiceImpl implements DmpService {
} }
@Override @Override
public ResponseEntity<byte[]> export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException { public ResponseEntity<byte[]> export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(id, transformerId, exportType); FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(id, transformerId, exportType);

View File

@ -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 {
}

View File

@ -4,6 +4,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
@EnableConfigurationProperties({FileTransformerProperties.class, FileTransformerCacheOptions.class}) @EnableConfigurationProperties({FileTransformerProperties.class})
public class FileTransformerConfiguration { public class FileTransformerConfiguration {
} }

View File

@ -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<TransformerCacheModel> {
@Autowired
public FileTransformerConfigurationCache(FileTransformerCacheOptions options) {
super(options);
}
@Override
protected Class<TransformerCacheModel> valueClass() {
return TransformerCacheModel.class;
}
}

View File

@ -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 {
}

View File

@ -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<FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue> {
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<FileTransformerConfigurationCacheService.FileTransformerConfigurationCacheValue> 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<String, String> keyParts = new HashMap<>();
keyParts.put("$transformerId$", transformerId);
keyParts.put("$tenantCode$", tenantCod);
return this.generateKey(keyParts);
}
}

View File

@ -2,13 +2,20 @@ package eu.eudat.service.filetransformer;
import eu.eudat.model.file.RepositoryFileFormat; 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.List;
import java.util.UUID; import java.util.UUID;
public interface FileTransformerService { public interface FileTransformerService {
List<RepositoryFileFormat> getAvailableExportFileFormats(); List<RepositoryFileFormat> 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;
} }

View File

@ -5,18 +5,29 @@ import eu.eudat.authorization.Permission;
import eu.eudat.commonmodels.models.FileEnvelopeModel; import eu.eudat.commonmodels.models.FileEnvelopeModel;
import eu.eudat.commonmodels.models.description.DescriptionModel; import eu.eudat.commonmodels.models.description.DescriptionModel;
import eu.eudat.commonmodels.models.dmp.DmpModel; 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.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.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.file.transformer.interfaces.FileTransformerConfiguration;
import eu.eudat.model.Description; import eu.eudat.model.Description;
import eu.eudat.model.Dmp; import eu.eudat.model.Dmp;
import eu.eudat.model.builder.commonmodels.description.DescriptionCommonModelBuilder; import eu.eudat.model.builder.commonmodels.description.DescriptionCommonModelBuilder;
import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder;
import eu.eudat.model.file.RepositoryFileFormat; 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.DescriptionQuery;
import eu.eudat.query.DmpQuery; 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.storage.StorageFileService;
import eu.eudat.service.tenant.TenantProperties;
import gr.cite.commons.web.authz.service.AuthorizationService; 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.TokenExchangeCacheService;
import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; 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.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.BaseFieldSet;
import org.slf4j.Logger; import org.slf4j.Logger;
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.event.EventListener;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono; 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.*; import java.util.*;
@Service @Service
@ -44,88 +63,164 @@ public class FileTransformerServiceImpl implements FileTransformerService {
private final FileTransformerProperties fileTransformerProperties; private final FileTransformerProperties fileTransformerProperties;
private final Map<String, FileTransformerRepository> clients; private final Map<String, FileTransformerRepository> clients;
private final TokenExchangeCacheService tokenExchangeCacheService; private final TokenExchangeCacheService tokenExchangeCacheService;
private final FileTransformerConfigurationCache fileTransformerConfigurationCache; private final FileTransformerConfigurationCacheService fileTransformerConfigurationCacheService;
private final AuthorizationService authorizationService; private final AuthorizationService authorizationService;
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final BuilderFactory builderFactory; private final BuilderFactory builderFactory;
private final StorageFileService storageFileService; private final StorageFileService storageFileService;
private final MessageSource messageSource; 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 @Autowired
public FileTransformerServiceImpl(FileTransformerProperties fileTransformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCache fileTransformerConfigurationCache, AuthorizationService authorizationService, public FileTransformerServiceImpl(FileTransformerProperties fileTransformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCacheService fileTransformerConfigurationCacheService, AuthorizationService authorizationService,
QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource) { QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource, ConventionService conventionService, TenantScope tenantScope, EncryptionService encryptionService, TenantProperties tenantProperties, JsonHandlingService jsonHandlingService, FileTransformerSourcesCacheService fileTransformerSourcesCacheService) {
this.fileTransformerProperties = fileTransformerProperties; this.fileTransformerProperties = fileTransformerProperties;
this.tokenExchangeCacheService = tokenExchangeCacheService; this.tokenExchangeCacheService = tokenExchangeCacheService;
this.fileTransformerConfigurationCache = fileTransformerConfigurationCache; this.fileTransformerConfigurationCacheService = fileTransformerConfigurationCacheService;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.queryFactory = queryFactory; this.queryFactory = queryFactory;
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
this.storageFileService = storageFileService; this.storageFileService = storageFileService;
this.messageSource = messageSource; 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<>(); this.clients = new HashMap<>();
} }
private FileTransformerRepository getRepository(String repoId) { private FileTransformerRepository getRepository(String repoId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
if (this.clients.containsKey(repoId)) return this.clients.get(repoId); String repositoryIdByTenant = this.getRepositoryIdByTenant(repoId);
if (this.clients.containsKey(repositoryIdByTenant)) return this.clients.get(repositoryIdByTenant);
//GK: It's register time //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) { if (source != null) {
String host = URI.create(source.getUrl()).getHost(); TokenExchangeModel tokenExchangeModel = new TokenExchangeModel("file_transformer:" + repositoryIdByTenant, source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
TokenExchangeModel tokenExchangeModel = new TokenExchangeModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel);
FileTransformerRepository repository = new FileTransformerRepository(WebClient.builder().baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> { FileTransformerRepository repository = new FileTransformerRepository(WebClient.builder().baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> {
exchangeFilterFunctions.add(tokenExchangeFilterFunction); exchangeFilterFunctions.add(tokenExchangeFilterFunction);
exchangeFilterFunctions.add(logRequest()); exchangeFilterFunctions.add(logRequest());
}).build()); }).build());
this.clients.put(source.getTransformerId(), repository); this.clients.put(repositoryIdByTenant, repository);
return repository; return repository;
} }
return null; return null;
} }
private List<FileTransformerSourceEntity> 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<FileTransformerSourceEntity> 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<FileTransformerSourceEntity> buildFileTransformerSourceItems(List<FileTransformerSourceEntity> sources) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
List<FileTransformerSourceEntity> 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 @Override
public List<RepositoryFileFormat> getAvailableExportFileFormats() { public List<RepositoryFileFormat> getAvailableExportFileFormats() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
List<RepositoryFileFormat> formats = new ArrayList<>(); List<RepositoryFileFormat> formats = new ArrayList<>();
List<FileTransformerConfiguration> configurations = this.getAvailableConfigurations(); List<FileTransformerConfiguration> configurations = this.getAvailableConfigurations();
if(configurations != null){
for (FileTransformerConfiguration configuration : configurations){ 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()); if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants().stream().map(x-> new RepositoryFileFormat(configuration.getFileTransformerId(), x, configuration.getExportEntityTypes())).toList());
} }
}
return formats; return formats;
} }
private List<FileTransformerConfiguration> getAvailableConfigurations() { private List<FileTransformerConfiguration> getAvailableConfigurations() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
TransformerCacheModel configs = fileTransformerConfigurationCache.lookup("base");
if (configs == null) {
List<FileTransformerConfiguration> configurations = new ArrayList<>(); List<FileTransformerConfiguration> configurations = new ArrayList<>();
//GK: So much for lazy loading
List<FileTransformerRepository> repositories = fileTransformerProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getTransformerId())).toList();
repositories = new ArrayList<>(repositories); for (FileTransformerSourceEntity transformerSource : this.getFileTransformerSources()) {
repositories.forEach((client) -> {
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 { try {
FileTransformerConfiguration repositoryConfig = client.getConfiguration(); FileTransformerRepository fileTransformerRepository = getRepository(transformerSource.getTransformerId());
if (repositoryConfig != null) { if (fileTransformerRepository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{transformerSource.getTransformerId(), FileTransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale()));
configurations.add(repositoryConfig);
}
} catch (Exception e) {
logger.warn(e.getLocalizedMessage(), e);
}
});
configs = new TransformerCacheModel(configurations); FileTransformerConfiguration configuration = fileTransformerRepository.getConfiguration();
this.fileTransformerConfigurationCache.put("base", configs); 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 @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); this.authorizationService.authorize(Permission.EditDmp);
//GK: First get the right client //GK: First get the right client
FileTransformerRepository repository = getRepository(repositoryId); FileTransformerRepository repository = getRepository(repositoryId);
@ -145,7 +240,7 @@ public class FileTransformerServiceImpl implements FileTransformerService {
} }
@Override @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); this.authorizationService.authorize(Permission.EditDmp);
//GK: First get the right client //GK: First get the right client
FileTransformerRepository repository = getRepository(repositoryId); FileTransformerRepository repository = getRepository(repositoryId);

View File

@ -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 {
}

View File

@ -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<FileTransformerSourcesCacheService.FileTransformerSourceCacheValue> {
public static class FileTransformerSourceCacheValue {
public FileTransformerSourceCacheValue() {
}
public FileTransformerSourceCacheValue(String tenantCode, List<FileTransformerSourceEntity> sources) {
this.tenantCode = tenantCode;
this.sources = sources;
}
private String tenantCode;
private List<FileTransformerSourceEntity> sources;
public String getTenantCode() {
return tenantCode;
}
public void setTenantCode(String tenantCode) {
this.tenantCode = tenantCode;
}
public List<FileTransformerSourceEntity> getSources() {
return sources;
}
public void setSources(List<FileTransformerSourceEntity> sources) {
this.sources = sources;
}
}
@Autowired
public FileTransformerSourcesCacheService(FileTransformerSourcesCacheOptions options) {
super(options);
}
@Override
protected Class<FileTransformerSourceCacheValue> valueClass() {
return FileTransformerSourceCacheValue.class;
}
@Override
public String keyOf(FileTransformerSourceCacheValue value) {
return this.buildKey(value.getTenantCode());
}
public String buildKey(String tenantCod) {
HashMap<String, String> keyParts = new HashMap<>();
keyParts.put("$tenantCode$", tenantCod);
return this.generateKey(keyParts);
}
}

View File

@ -69,11 +69,7 @@ public class TenantServiceImpl implements TenantService {
private final ConventionService conventionService; private final ConventionService conventionService;
private final MessageSource messageSource; private final MessageSource messageSource;
private final XmlHandlingService xmlHandlingService;
private final ErrorThesaurusProperties errors; private final ErrorThesaurusProperties errors;
private final EncryptionService encryptionService;
private final TenantProperties properties;
private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler; private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler;
private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler; private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler;
private final KeycloakService keycloakService; private final KeycloakService keycloakService;
@ -90,19 +86,14 @@ public class TenantServiceImpl implements TenantService {
BuilderFactory builderFactory, BuilderFactory builderFactory,
ConventionService conventionService, ConventionService conventionService,
MessageSource messageSource, MessageSource messageSource,
XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) {
ErrorThesaurusProperties errors,
EncryptionService encryptionService, TenantProperties properties, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) {
this.entityManager = entityManager; this.entityManager = entityManager;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory; this.deleterFactory = deleterFactory;
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
this.conventionService = conventionService; this.conventionService = conventionService;
this.messageSource = messageSource; this.messageSource = messageSource;
this.xmlHandlingService = xmlHandlingService;
this.errors = errors; this.errors = errors;
this.encryptionService = encryptionService;
this.properties = properties;
this.tenantTouchedIntegrationEventHandler = tenantTouchedIntegrationEventHandler; this.tenantTouchedIntegrationEventHandler = tenantTouchedIntegrationEventHandler;
this.tenantRemovalIntegrationEventHandler = tenantRemovalIntegrationEventHandler; this.tenantRemovalIntegrationEventHandler = tenantRemovalIntegrationEventHandler;
this.keycloakService = keycloakService; this.keycloakService = keycloakService;

View File

@ -7,13 +7,17 @@ import eu.eudat.commons.JsonHandlingService;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.enums.StorageType; import eu.eudat.commons.enums.StorageType;
import eu.eudat.commons.enums.TenantConfigurationType; 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.deposit.DepositSourceEntity;
import eu.eudat.commons.types.filetransformer.FileTransformerSourceEntity; import eu.eudat.commons.types.filetransformer.FileTransformerSourceEntity;
import eu.eudat.commons.types.tenantconfiguration.*; import eu.eudat.commons.types.tenantconfiguration.*;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.data.TenantConfigurationEntity; import eu.eudat.data.TenantConfigurationEntity;
import eu.eudat.data.TenantEntity;
import eu.eudat.data.TenantEntityManager; import eu.eudat.data.TenantEntityManager;
import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.event.EventBroker;
import eu.eudat.event.TenantConfigurationTouchedEvent;
import eu.eudat.model.StorageFile; import eu.eudat.model.StorageFile;
import eu.eudat.model.builder.tenantconfiguration.TenantConfigurationBuilder; import eu.eudat.model.builder.tenantconfiguration.TenantConfigurationBuilder;
import eu.eudat.model.deleter.TenantConfigurationDeleter; import eu.eudat.model.deleter.TenantConfigurationDeleter;
@ -82,6 +86,8 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic
private final TenantProperties tenantProperties; private final TenantProperties tenantProperties;
private final StorageFileService storageFileService; private final StorageFileService storageFileService;
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final EventBroker eventBroker;
private final TenantScope tenantScope;
@Autowired @Autowired
public TenantConfigurationServiceImpl( public TenantConfigurationServiceImpl(
TenantEntityManager entityManager, TenantEntityManager entityManager,
@ -90,7 +96,7 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic
BuilderFactory builderFactory, BuilderFactory builderFactory,
ConventionService conventionService, ConventionService conventionService,
ErrorThesaurusProperties errors, 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.entityManager = entityManager;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory; this.deleterFactory = deleterFactory;
@ -103,6 +109,8 @@ public class TenantConfigurationServiceImpl implements TenantConfigurationServic
this.tenantProperties = tenantProperties; this.tenantProperties = tenantProperties;
this.storageFileService = storageFileService; this.storageFileService = storageFileService;
this.queryFactory = queryFactory; 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 { 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(); 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); 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)); if (oldValue != null && oldValue.getStorageFileId() != null) this.storageFileService.updatePurgeAt(oldValue.getStorageFileId(), Instant.now().minusSeconds(60));
} }
this.deleterFactory.deleter(TenantConfigurationDeleter.class).deleteAndSaveByIds(List.of(id)); 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()));
}
} }
} }

View File

@ -19,6 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; 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.AbstractMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -45,7 +52,7 @@ public class DepositController {
} }
@GetMapping("/repositories/available") @GetMapping("/repositories/available")
public List<eu.eudat.model.deposit.DepositConfiguration> getAvailableRepos(FieldSet fieldSet) { public List<eu.eudat.model.deposit.DepositConfiguration> getAvailableRepos(FieldSet fieldSet) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("retrieving" + DepositConfiguration.class.getSimpleName()).And("fields", fieldSet)); logger.debug(new MapLogEntry("retrieving" + DepositConfiguration.class.getSimpleName()).And("fields", fieldSet));
this.censorFactory.censor(DepositConfigurationCensor.class).censor(fieldSet, null); this.censorFactory.censor(DepositConfigurationCensor.class).censor(fieldSet, null);
@ -60,7 +67,7 @@ public class DepositController {
@PostMapping("/get-access-token") @PostMapping("/get-access-token")
@ValidationFilterAnnotation(validator = DepositAuthenticateRequest.DepositAuthenticateRequestValidator.ValidatorName, argumentName = "model") @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)); logger.debug(new MapLogEntry("get access token" + DepositAuthenticateRequest.class.getSimpleName()).And("model", model));
String accessToken = this.depositService.authenticate(model); String accessToken = this.depositService.authenticate(model);
@ -87,7 +94,7 @@ public class DepositController {
} }
@GetMapping("/repositories/{repositoryId}/logo") @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)); logger.debug(new MapLogEntry("get logo" + DepositConfiguration.class.getSimpleName()).And("repositoryId", repositoryId));
String logo = this.depositService.getLogo(repositoryId); String logo = this.depositService.getLogo(repositoryId);

View File

@ -47,8 +47,14 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*; import java.util.*;
import static eu.eudat.authorization.AuthorizationFlags.Public; import static eu.eudat.authorization.AuthorizationFlags.Public;
@ -227,7 +233,7 @@ public class DescriptionController {
} }
@GetMapping("{id}/export/{type}") @GetMapping("{id}/export/{type}")
public ResponseEntity<byte[]> export(@PathVariable("id") UUID id, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { public ResponseEntity<byte[]> export(@PathVariable("id") UUID id, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("exporting description")); logger.debug(new MapLogEntry("exporting description"));
return this.descriptionService.export(id, exportType); return this.descriptionService.export(id, exportType);

View File

@ -35,10 +35,16 @@ import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*; import java.util.*;
import static eu.eudat.authorization.AuthorizationFlags.Public; import static eu.eudat.authorization.AuthorizationFlags.Public;
@ -284,7 +290,7 @@ public class DmpController {
} }
@GetMapping("{id}/export/{transformerId}/{type}") @GetMapping("{id}/export/{transformerId}/{type}")
public ResponseEntity<byte[]> export(@PathVariable("id") UUID id, @PathVariable("transformerId") String transformerId, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { public ResponseEntity<byte[]> 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)); logger.debug(new MapLogEntry("exporting dmp").And("id", id).And("transformerId", transformerId).And("exportType", exportType));
ResponseEntity<byte[]> bytes = this.dmpService.export(id, transformerId, exportType); ResponseEntity<byte[]> bytes = this.dmpService.export(id, transformerId, exportType);

View File

@ -16,8 +16,14 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException; import javax.management.InvalidApplicationException;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
@RestController @RestController
@ -37,7 +43,7 @@ public class FileTransformerController {
} }
@GetMapping("/available") @GetMapping("/available")
public List<RepositoryFileFormat> getAvailableConfigurations() { public List<RepositoryFileFormat> getAvailableConfigurations() throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("getAvailableConfigurations")); logger.debug(new MapLogEntry("getAvailableConfigurations"));
List<RepositoryFileFormat> model = this.fileTransformerService.getAvailableExportFileFormats(); List<RepositoryFileFormat> model = this.fileTransformerService.getAvailableExportFileFormats();
@ -48,7 +54,7 @@ public class FileTransformerController {
} }
@PostMapping("/export-dmp") @PostMapping("/export-dmp")
public ResponseEntity<byte[]> export(@RequestBody ExportRequestModel requestModel) throws InvalidApplicationException, IOException { public ResponseEntity<byte[]> export(@RequestBody ExportRequestModel requestModel) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("exporting dmp")); logger.debug(new MapLogEntry("exporting dmp"));
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
@ -60,7 +66,7 @@ public class FileTransformerController {
} }
@PostMapping("/export-description") @PostMapping("/export-description")
public ResponseEntity<byte[]> exportDescription(@RequestBody ExportRequestModel requestModel) { public ResponseEntity<byte[]> exportDescription(@RequestBody ExportRequestModel requestModel) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("exporting dmp")); logger.debug(new MapLogEntry("exporting dmp"));
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();

View File

@ -26,6 +26,12 @@ cache:
maximumSize: 500 maximumSize: 500
enableRecordStats: false enableRecordStats: false
expireAfterWriteSeconds: 600 expireAfterWriteSeconds: 600
- names: [ "depositSourcesByTenant" ]
allowNullValues: true
initialCapacity: 100
maximumSize: 500
enableRecordStats: false
expireAfterWriteSeconds: 600
- names: [ "affiliation" ] - names: [ "affiliation" ]
allowNullValues: true allowNullValues: true
initialCapacity: 100 initialCapacity: 100
@ -38,7 +44,13 @@ cache:
maximumSize: 500 maximumSize: 500
enableRecordStats: false enableRecordStats: false
expireAfterWriteSeconds: 30 expireAfterWriteSeconds: 30
- names: [ "fileTransformer" ] - names: [ "fileTransformerConfigById" ]
allowNullValues: true
initialCapacity: 100
maximumSize: 500
enableRecordStats: false
expireAfterWriteSeconds: 600
- names: [ "fileTransformerSourcesByTenant" ]
allowNullValues: true allowNullValues: true
initialCapacity: 100 initialCapacity: 100
maximumSize: 500 maximumSize: 500
@ -101,10 +113,16 @@ cache:
keyPattern: dashboard_stats_by_usr_$key$:v0 keyPattern: dashboard_stats_by_usr_$key$:v0
depositConfigById: depositConfigById:
name: depositConfigById name: depositConfigById
keyPattern: deposit_config_by_id_$repositoryId$:v0 keyPattern: deposit_config_by_id_$repositoryId$_$tenantCode$:v0
fileTransformer: depositSourcesByTenant:
name: fileTransformer name: depositSourcesByTenant
keyPattern: base:v0 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: token-exchange-key:
name: tokenExchangeKey name: tokenExchangeKey
keyPattern: resolve_$keyhash$:v0 keyPattern: resolve_$keyhash$:v0

View File

@ -1,7 +1,7 @@
deposit: deposit:
sources: sources:
- url: http://dev04.local.cite.gr:55330/zenodo - url: http://dev04.local.cite.gr:55330/zenodo
repositoryId: zenodo repositoryId: Zenodo
pdfTransformerId: docx-file-transformer pdfTransformerId: docx-file-transformer
rdaTransformerId: rda-file-transformer rdaTransformerId: rda-file-transformer
issuer-url: ${IDP_ISSUER_URI_TOKEN} issuer-url: ${IDP_ISSUER_URI_TOKEN}
@ -9,7 +9,7 @@ deposit:
client-secret: ${IDP_APIKEY_CLIENT_SECRET} client-secret: ${IDP_APIKEY_CLIENT_SECRET}
scope: ${IDP_APIKEY_SCOPE} scope: ${IDP_APIKEY_SCOPE}
- url: http://dev04.local.cite.gr:55330/zenodo1 - url: http://dev04.local.cite.gr:55330/zenodo1
repositoryId: zenodo1 repositoryId: Zenodo1
pdfTransformerId: docx-file-transformer pdfTransformerId: docx-file-transformer
rdaTransformerId: rda-file-transformer rdaTransformerId: rda-file-transformer
issuer-url: ${IDP_ISSUER_URI_TOKEN} issuer-url: ${IDP_ISSUER_URI_TOKEN}