argos/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java

214 lines
10 KiB
Java

package eu.eudat.service.deposit;
import eu.eudat.authorization.Permission;
import eu.eudat.cache.deposit.RepositoryDepositConfigurationCache;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.configurations.deposit.DepositProperties;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpEntity;
import eu.eudat.data.EntityDoiEntity;
import eu.eudat.depositinterface.models.DMPDepositModel;
import eu.eudat.depositinterface.models.FileEnvelope;
import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration;
import eu.eudat.model.EntityDoi;
import eu.eudat.model.doi.DepositRequest;
import eu.eudat.model.doi.RepositoryConfig;
import eu.eudat.model.doi.RepositoryConfigs;
import eu.eudat.model.mapper.deposit.DmpEntityDepositMapper;
import eu.eudat.model.persist.EntityDoiPersist;
import eu.eudat.query.DmpQuery;
import eu.eudat.query.EntityDoiQuery;
import eu.eudat.repository.DepositRepository;
import eu.eudat.service.entitydoi.EntityDoiService;
import eu.eudat.utilities.pdf.PDFUtils;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.commons.web.oidc.apikey.ApiKeyCacheService;
//import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyExchangeFilterFunction;
//import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyWebfluxModel;
import gr.cite.tools.data.query.Ordering;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import jakarta.persistence.EntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.web.reactive.function.client.WebClient;
import javax.management.InvalidApplicationException;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.*;
@Service
public class RepositoryDepositService {
private static final Logger logger = LoggerFactory.getLogger(RepositoryDepositService.class);
private final DepositProperties depositProperties;
private final Map<String, DepositRepository> clients;
private final ApiKeyCacheService apiKeyCacheService;
private final RepositoryDepositConfigurationCache repositoryDepositConfigurationCache;
private final AuthorizationService authorizationService;
private final ConventionService conventionService;
private final Environment environment;
private final DmpEntityDepositMapper depositMapper;
private final WebClient.Builder webClientBuilder;
private final EntityDoiService doiService;
private final ApplicationContext applicationContext;
@Autowired
public RepositoryDepositService(DepositProperties depositProperties, ApiKeyCacheService apiKeyCacheService, RepositoryDepositConfigurationCache repositoryDepositConfigurationCache, WebClient.Builder builder, EntityManager entityManager, AuthorizationService authorizationService, ConventionService conventionService, Environment environment, DmpEntityDepositMapper depositMapper, DmpQuery dmpQuery, EntityDoiQuery doiQuery, EntityDoiService doiService, ApplicationContext applicationContext) {
this.depositProperties = depositProperties;
this.apiKeyCacheService = apiKeyCacheService;
this.repositoryDepositConfigurationCache = repositoryDepositConfigurationCache;
this.authorizationService = authorizationService;
this.conventionService = conventionService;
this.environment = environment;
this.depositMapper = depositMapper;
this.webClientBuilder = builder;
this.doiService = doiService;
this.applicationContext = applicationContext;
this.clients = new HashMap<>();
}
private DepositRepository getRepository(String repoId) {
if (this.clients.containsKey(repoId)) return this.clients.get(repoId);
//GK: It's register time
DepositProperties.DepositSource source = depositProperties.getSources().stream().filter(depositSource -> depositSource.getCodes().contains(repoId)).findFirst().orElse(null);
if (source != null) {
String host = URI.create(source.getUrl()).getHost();
// ApiKeyWebfluxModel apiKeyWebfluxModel = new ApiKeyWebfluxModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope());
// ApiKeyExchangeFilterFunction apiKeyExchangeFilterFunction = new ApiKeyExchangeFilterFunction(this.apiKeyCacheService, apiKeyWebfluxModel);
// DepositRepository repository = new DepositRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build());
// source.getCodes().forEach(code -> this.clients.put(code, repository));
// return repository;
}
return null;
}
public List<RepositoryConfig> getAvailableConfigurations() {
RepositoryConfigs configs = repositoryDepositConfigurationCache.lookup("base");
if (configs == null) {
List<RepositoryConfig> configurations = new ArrayList<>();
//GK: So much for lazy loading
List<DepositRepository> repositories = depositProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getCodes().get(0))).toList();
repositories.forEach((client) -> {
List<RepositoryDepositConfiguration> repositoryConfigs = client.getConfiguration();
if (repositoryConfigs != null && !repositoryConfigs.isEmpty()) {
configurations.addAll(repositoryConfigs.stream().map(RepositoryConfig::toModel).toList());
}
});
configs = new RepositoryConfigs(configurations);
this.repositoryDepositConfigurationCache.put("base", configs);
}
return configs.getRepositoryConfigs();
}
public EntityDoi deposit(DepositRequest dmpDepositModel) throws InvalidApplicationException {
this.authorizationService.authorize(Permission.EditDmp);
//GK: Why it is in that service, and why it's not static?
this.conventionService.isValidGuid(UUID.fromString(dmpDepositModel.getDmpId()));
//GK: First get the right client
DepositRepository repository = getRepository(dmpDepositModel.getRepositoryId());
//GK: Second get the Target Data Management Plan
DmpQuery dmpQuery = applicationContext.getBean(DmpQuery.class);
DmpEntity dmpEntity = dmpQuery.ids(UUID.fromString(dmpDepositModel.getDmpId())).first();
//GK: Third get the DOI from the previous Data Management Plan (if it exists)
String previousDOI = null;
if (dmpEntity.getVersion() > 1) { //TODO: Will it start from 1 or 0?
previousDOI = this.getPreviousDOI(dmpEntity.getGroupId(), dmpEntity.getId(), dmpDepositModel.getRepositoryId());
}
//GK: Forth make the required files to be uploaded with the deposit
//TODO: Properly create required files
FileEnvelope docEnvelope = new FileEnvelope();
FileEnvelope pdfEnvelope = new FileEnvelope();
FileEnvelope jsonEnvelope = new FileEnvelope();
File zip = new File(environment.getProperty("temp.temp") + UUID.randomUUID() + ".zip");
try {
File documentFile = ResourceUtils.getFile(this.environment.getProperty("configuration.h2020template"));
docEnvelope.setFilename("test.docx");
docEnvelope.setFile(documentFile);
File pdfFile = PDFUtils.convertToPDF(docEnvelope, environment);
pdfEnvelope.setFilename("test.pdf");
pdfEnvelope.setFile(pdfFile);
File jsonFile = new File(this.environment.getProperty("temp.temp") + UUID.randomUUID() + ".json");
jsonEnvelope.setFilename("test.json");
jsonEnvelope.setFile(jsonFile);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
//GK: Fifth Transform them to the DepositModel
DMPDepositModel depositModel = depositMapper.toDeposit(dmpEntity, zip, pdfEnvelope, jsonEnvelope, previousDOI);
//GK: Sixth Perform the deposit
String doi = "";
try {
doi = repository.deposit(dmpDepositModel.getRepositoryId(), depositModel, "");
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
//GK: Something has gone wrong return null
if (doi.isEmpty())
return null;
//GK: doi is fine store it in database
EntityDoiPersist doiPersist = new EntityDoiPersist();
doiPersist.setRepositoryId(dmpDepositModel.getRepositoryId());
doiPersist.setDoi(doi);
doiPersist.setEntityId(dmpEntity.getId());
FieldSet fieldSet = new BaseFieldSet();
return doiService.persist(doiPersist, fieldSet);
}
public String getLogo(String repoId) {
//GK: First get the right client
DepositRepository repository = getRepository(repoId);
if (repository != null) {
return repository.getLogo(repoId);
}
return null;
}
private String getPreviousDOI(UUID groupId, UUID currentId, String repoId) {
EntityDoiEntity doiEntity = null;
//GK: Step one get the previous version of the Data management plan
DmpQuery dmpQuery = this.applicationContext.getBean(DmpQuery.class);
Ordering ordering = new Ordering();
ordering.setItems(List.of("-version"));
dmpQuery.setOrder(ordering);
FieldSet fieldSet = new BaseFieldSet();
fieldSet.ensure("id");
List<UUID> dmpIds = dmpQuery.groupIds(groupId).isActive(IsActive.Active).collectAs(fieldSet).stream().map(DmpEntity::getId).toList();
//GK: Step two get it's doiEntity
EntityDoiQuery doiQuery = this.applicationContext.getBean(EntityDoiQuery.class);
List<EntityDoiEntity> dois = doiQuery.entityIds(dmpIds).isActive(IsActive.Active).collect();
for(UUID uuid: dmpIds)
{
if (uuid.equals(currentId))
continue;
doiEntity = dois.stream()
.filter(entityDoiEntity -> entityDoiEntity.getEntityId().equals(uuid)).findFirst().orElse(null);
if (doiEntity != null)
break;
}
return doiEntity != null ? doiEntity.getDoi() : null;
}
}