178 lines
10 KiB
Java
178 lines
10 KiB
Java
package eu.eudat.service.transformer;
|
|
|
|
import eu.eudat.authorization.AuthorizationFlags;
|
|
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.enums.StorageType;
|
|
import eu.eudat.configurations.transformer.TransformerProperties;
|
|
import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration;
|
|
import eu.eudat.file.transformer.models.misc.FileFormat;
|
|
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.TransformerCacheModel;
|
|
import eu.eudat.query.DescriptionQuery;
|
|
import eu.eudat.query.DmpQuery;
|
|
import eu.eudat.repository.TransformerRepository;
|
|
import eu.eudat.service.storage.StorageFileService;
|
|
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;
|
|
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 org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.context.MessageSource;
|
|
import org.springframework.context.i18n.LocaleContextHolder;
|
|
import org.springframework.stereotype.Service;
|
|
import 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 java.util.*;
|
|
|
|
@Service
|
|
public class FileTransformerServiceImpl implements FileTransformerService {
|
|
private static final Logger logger = LoggerFactory.getLogger(FileTransformerServiceImpl.class);
|
|
|
|
private final TransformerProperties transformerProperties;
|
|
private final Map<String, TransformerRepository> clients;
|
|
private final TokenExchangeCacheService tokenExchangeCacheService;
|
|
private final FileTransformerConfigurationCache fileTransformerConfigurationCache;
|
|
private final AuthorizationService authorizationService;
|
|
private final WebClient.Builder webClientBuilder;
|
|
private final QueryFactory queryFactory;
|
|
private final BuilderFactory builderFactory;
|
|
private final StorageFileService storageFileService;
|
|
private final MessageSource messageSource;
|
|
|
|
@Autowired
|
|
public FileTransformerServiceImpl(TransformerProperties transformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCache fileTransformerConfigurationCache, WebClient.Builder builder, AuthorizationService authorizationService,
|
|
QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource) {
|
|
this.transformerProperties = transformerProperties;
|
|
this.tokenExchangeCacheService = tokenExchangeCacheService;
|
|
this.fileTransformerConfigurationCache = fileTransformerConfigurationCache;
|
|
this.authorizationService = authorizationService;
|
|
this.webClientBuilder = builder;
|
|
this.queryFactory = queryFactory;
|
|
this.builderFactory = builderFactory;
|
|
this.storageFileService = storageFileService;
|
|
this.messageSource = messageSource;
|
|
this.clients = new HashMap<>();
|
|
}
|
|
|
|
private TransformerRepository getRepository(String repoId) {
|
|
if (this.clients.containsKey(repoId)) return this.clients.get(repoId);
|
|
|
|
//GK: It's register time
|
|
TransformerProperties.TransformerSource source = transformerProperties.getSources().stream().filter(depositSource -> depositSource.getCodes().contains(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());
|
|
TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel);
|
|
TransformerRepository repository = new TransformerRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> {
|
|
exchangeFilterFunctions.add(tokenExchangeFilterFunction);
|
|
exchangeFilterFunctions.add(logRequest());
|
|
}).build());
|
|
source.getCodes().forEach(code -> this.clients.put(code, repository));
|
|
return repository;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
@Override
|
|
public List<FileFormat> getAvailableExportFileFormats() {
|
|
List<FileFormat> formats = new ArrayList<>();
|
|
List<FileTransformerConfiguration> configurations = this.getAvailableConfigurations();
|
|
if(configurations != null){
|
|
for (FileTransformerConfiguration configuration : configurations){
|
|
if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants());
|
|
}
|
|
}
|
|
return formats;
|
|
}
|
|
|
|
private List<FileTransformerConfiguration> getAvailableConfigurations() {
|
|
TransformerCacheModel configs = fileTransformerConfigurationCache.lookup("base");
|
|
if (configs == null) {
|
|
List<FileTransformerConfiguration> configurations = new ArrayList<>();
|
|
//GK: So much for lazy loading
|
|
List<TransformerRepository> repositories = transformerProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getCodes().getFirst())).toList();
|
|
|
|
repositories = new ArrayList<>(repositories);
|
|
repositories.forEach((client) -> {
|
|
try {
|
|
FileTransformerConfiguration repositoryConfig = client.getConfiguration();
|
|
if (repositoryConfig != null) {
|
|
configurations.add(repositoryConfig);
|
|
}
|
|
} catch (Exception e) {
|
|
logger.warn(e.getLocalizedMessage(), e);
|
|
}
|
|
});
|
|
|
|
configs = new TransformerCacheModel(configurations);
|
|
this.fileTransformerConfigurationCache.put("base", configs);
|
|
}
|
|
|
|
return configs.getConfigurations();
|
|
}
|
|
|
|
@Override
|
|
public eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) {
|
|
this.authorizationService.authorize(Permission.EditDmp);
|
|
//GK: First get the right client
|
|
TransformerRepository repository = getRepository(repositoryId);
|
|
if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{repositoryId, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
//GK: Second get the Target Data Management Plan
|
|
DmpQuery query = this.queryFactory.query(DmpQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).ids(dmpId);
|
|
DmpModel dmpFileTransformerModel = this.builderFactory.builder(DmpCommonModelBuilder.class).useSharedStorage(repository.getConfiguration().isUseSharedStorage()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(query.first());
|
|
if (dmpFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{dmpId, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
|
|
FileEnvelopeModel fileEnvelope = repository.exportDmp(dmpFileTransformerModel, format);
|
|
eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope();
|
|
|
|
byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile();
|
|
result.setFile(data);
|
|
result.setFilename(fileEnvelope.getFilename());
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String format) {
|
|
this.authorizationService.authorize(Permission.EditDmp);
|
|
//GK: First get the right client
|
|
TransformerRepository repository = getRepository(format);
|
|
if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{format, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
|
|
//GK: Second get the Target Data Management Plan
|
|
DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).ids(descriptionId);
|
|
DescriptionModel descriptionFileTransformerModel = this.builderFactory.builder(DescriptionCommonModelBuilder.class).useSharedStorage(repository.getConfiguration().isUseSharedStorage()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(query.first());
|
|
if (descriptionFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{descriptionId, Description.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
|
|
FileEnvelopeModel fileEnvelope = repository.exportDescription(descriptionFileTransformerModel, format);
|
|
eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope();
|
|
byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile(); //TODO: shared storage should be per repository
|
|
result.setFile(data);
|
|
result.setFilename(fileEnvelope.getFilename());
|
|
return result;
|
|
}
|
|
|
|
// This method returns filter function which will log request data
|
|
private static ExchangeFilterFunction logRequest() {
|
|
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
|
|
logger.info("Request: {} {}", clientRequest.method(), clientRequest.url());
|
|
clientRequest.headers().forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value)));
|
|
return Mono.just(clientRequest);
|
|
});
|
|
}
|
|
}
|