diff --git a/core/pom.xml b/core/pom.xml index 8bdbba8..07a8016 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -45,7 +45,7 @@ gr.cite.opendmp repositorydepositbase - 1.0.0-SNAPSHOT + 2.0.0 diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/configuration/zenodo/ZenodoProperties.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/configuration/zenodo/ZenodoProperties.java index 883135d..d9bfc3c 100644 --- a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/configuration/zenodo/ZenodoProperties.java +++ b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/configuration/zenodo/ZenodoProperties.java @@ -1,219 +1,57 @@ package eu.eudat.depositinterface.zenodorepository.configuration.zenodo; -import eu.eudat.depositinterface.enums.DepositType; -import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; +import eu.eudat.depositinterface.repository.DepositConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.ConstructorBinding; - -import java.util.List; -import java.util.Map; @ConfigurationProperties(prefix = "zenodo") public class ZenodoProperties { + private String logo; - private String tempStorage; + private String community; - private List configuration; + private String domain; + private String affiliation; - public String getTempStorage() { - return tempStorage; + private DepositConfiguration depositConfiguration; + + public void setLogo(String logo) { + this.logo = logo; } - public List getConfiguration() { - return configuration; + public String getLogo() { + return logo; } - public void setTempStorage(String tempStorage) { - this.tempStorage = tempStorage; + public String getCommunity() { + return community; } - public void setConfiguration(List configuration) { - this.configuration = configuration; + public void setCommunity(String community) { + this.community = community; } - public static class ZenodoConfig extends RepositoryDepositConfiguration { - private DepositType depositType; - private String repositoryId; - private String accessToken; - private String repositoryUrl; - private String repositoryAuthorizationUrl; - private String repositoryRecordUrl; - private String repositoryAccessTokenUrl; - private String repositoryClientId; - private String repositoryClientSecret; - private String redirectUri; - private boolean hasLogo; - private String logo; - private String doiFunder; - private String community; - private String affiliation; - private String domain; + public String getDomain() { + return domain; + } - @Override - public DepositType getDepositType() { - return depositType; - } + public void setDomain(String domain) { + this.domain = domain; + } - @Override - public void setDepositType(DepositType depositType) { - this.depositType = depositType; - } + public String getAffiliation() { + return affiliation; + } - @Override - public String getRepositoryId() { - return repositoryId; - } + public void setAffiliation(String affiliation) { + this.affiliation = affiliation; + } - @Override - public void setRepositoryId(String repositoryId) { - this.repositoryId = repositoryId; - } + public DepositConfiguration getDepositConfiguration() { + return depositConfiguration; + } - @Override - public String getAccessToken() { - return accessToken; - } - - @Override - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - @Override - public String getRepositoryUrl() { - return repositoryUrl; - } - - @Override - public void setRepositoryUrl(String repositoryUrl) { - this.repositoryUrl = repositoryUrl; - } - - @Override - public String getRepositoryAuthorizationUrl() { - return repositoryAuthorizationUrl; - } - - @Override - public void setRepositoryAuthorizationUrl(String repositoryAuthorizationUrl) { - this.repositoryAuthorizationUrl = repositoryAuthorizationUrl; - } - - @Override - public String getRepositoryRecordUrl() { - return repositoryRecordUrl; - } - - @Override - public void setRepositoryRecordUrl(String repositoryRecordUrl) { - this.repositoryRecordUrl = repositoryRecordUrl; - } - - @Override - public String getRepositoryAccessTokenUrl() { - return repositoryAccessTokenUrl; - } - - @Override - public void setRepositoryAccessTokenUrl(String repositoryAccessTokenUrl) { - this.repositoryAccessTokenUrl = repositoryAccessTokenUrl; - } - - @Override - public String getRepositoryClientId() { - return repositoryClientId; - } - - @Override - public void setRepositoryClientId(String repositoryClientId) { - this.repositoryClientId = repositoryClientId; - } - - @Override - public String getRepositoryClientSecret() { - return repositoryClientSecret; - } - - @Override - public void setRepositoryClientSecret(String repositoryClientSecret) { - this.repositoryClientSecret = repositoryClientSecret; - } - - @Override - public String getRedirectUri() { - return redirectUri; - } - - @Override - public void setRedirectUri(String redirectUri) { - this.redirectUri = redirectUri; - } - - @Override - public boolean isHasLogo() { - return hasLogo; - } - - @Override - public void setHasLogo(boolean hasLogo) { - this.hasLogo = hasLogo; - } - - public String getLogo() { - return logo; - } - - public void setLogo(String logo) { - this.logo = logo; - } - - public String getDoiFunder() { - return doiFunder; - } - - public void setDoiFunder(String doiFunder) { - this.doiFunder = doiFunder; - } - - public String getCommunity() { - return community; - } - - public void setCommunity(String community) { - this.community = community; - } - - public String getAffiliation() { - return affiliation; - } - - public void setAffiliation(String affiliation) { - this.affiliation = affiliation; - } - - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public RepositoryDepositConfiguration toRepoConfig() { - RepositoryDepositConfiguration config = new RepositoryDepositConfiguration(); - config.setDepositType(this.depositType); - config.setRepositoryId(this.repositoryId); - config.setAccessToken(this.accessToken); - config.setRepositoryUrl(this.repositoryUrl); - config.setRepositoryAuthorizationUrl(this.repositoryAuthorizationUrl); - config.setRepositoryRecordUrl(this.repositoryRecordUrl); - config.setRepositoryAccessTokenUrl(this.repositoryAccessTokenUrl); - config.setRepositoryClientId(this.repositoryClientId); - config.setRepositoryClientSecret(this.repositoryClientSecret); - config.setRedirectUri(this.redirectUri); - config.setHasLogo(this.hasLogo); - return config; - } + public void setDepositConfiguration(DepositConfiguration depositConfiguration) { + this.depositConfiguration = depositConfiguration; } } diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/model/builder/ZenodoBuilder.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/model/builder/ZenodoBuilder.java index 364ca43..4cc51c5 100644 --- a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/model/builder/ZenodoBuilder.java +++ b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/model/builder/ZenodoBuilder.java @@ -49,7 +49,7 @@ public class ZenodoBuilder { this.funderProperties = funderProperties; } - public ZenodoDeposit build(DmpDepositModel dmp, ZenodoProperties.ZenodoConfig zenodoConfig) throws JsonProcessingException { + public ZenodoDeposit build(DmpDepositModel dmp, ZenodoProperties zenodoConfig) throws JsonProcessingException { ZenodoDeposit deposit = new ZenodoDeposit(); this.applyZenodoRelator(dmp, deposit); deposit.getMetadata().setTitle(dmp.getLabel()); @@ -76,33 +76,26 @@ public class ZenodoBuilder { return deposit; } - private List findSchematicValues(String relatedId, List fields){ + private List findSchematicValues(String relatedId, List fields){ return fields.stream().filter(f -> f.getSchematics().contains(relatedId)).collect(Collectors.toList()); } - private Set extractSchematicValues(List fields, List acceptedPidTypes) throws JsonProcessingException{ + private Set extractSchematicValues(List fields, List acceptedPidTypes) throws JsonProcessingException{ ObjectMapper objectMapper = new ObjectMapper(); Set values = new HashSet<>(); - for(DatasetFieldsDepositModel field: fields){ - String value = (String) field.getValue(); - if(value != null && !value.isEmpty()) { + for(DescriptionFieldDepositModel field: fields){ + //TODO: Check how to parse this values after update the logic of description persist from the main app + List value =field.getValues() == null ? new ArrayList<>() : field.getValues().stream().map(x-> (String)x).filter(x-> x == null || x.isEmpty()).toList(); + if(!value.isEmpty()) { switch (field.getFieldType()) { case FREE_TEXT: case TEXT_AREA: case RICH_TEXT_AREA: case RADIO_BOX: case DATE_PICKER: - values.add(value); - break; case AUTO_COMPLETE: case WORD_LIST: - if (field.isMultiple()) { - List selected = objectMapper.readValue(value, new TypeReference>() {}); - values.addAll(selected); - } - else { - values.add(value); - } + values.addAll(value); break; case SERVICES: case EXTERNAL_DATASETS: @@ -111,19 +104,9 @@ public class ZenodoBuilder { case JOURNAL_REPOSITORIES: case TAXONOMIES: case PUBLICATIONS: - if (field.isMultiple()) { - List selected = objectMapper.readValue(value, new TypeReference>() {}); - for (String s : selected) { - Map valueMap = objectMapper.readValue(s, new TypeReference>() {}); - String pid = valueMap.get(this.pidProperties.getFields().getPidName()); - String pidType = valueMap.get(this.pidProperties.getFields().getPidTypeName()); - if (acceptedPidTypes.contains(pidType)) { - values.add(pid); - } - } - } - else { - Map valueMap = objectMapper.readValue(value, new TypeReference>() {}); + for (String s : value) { + Map valueMap = objectMapper.readValue(s, new TypeReference>() { + }); String pid = valueMap.get(this.pidProperties.getFields().getPidName()); String pidType = valueMap.get(this.pidProperties.getFields().getPidTypeName()); if (acceptedPidTypes.contains(pidType)) { @@ -133,18 +116,8 @@ public class ZenodoBuilder { break; case ORGANIZATIONS: case RESEARCHERS: - if (field.isMultiple()) { - List selected = objectMapper.readValue(value, new TypeReference>() {}); - for (String s : selected) { - Map valueMap = objectMapper.readValue(s, new TypeReference>() {}); - String pid = valueMap.get("reference"); - if(pid != null) { - values.add(pid); - } - } - } - else { - Map valueMap = objectMapper.readValue(value, new TypeReference>() {}); + for (String s : value) { + Map valueMap = objectMapper.readValue(s, new TypeReference>() {}); String pid = valueMap.get("reference"); if(pid != null) { values.add(pid); @@ -152,8 +125,10 @@ public class ZenodoBuilder { } break; case DATASET_IDENTIFIER: - Map valueMap = objectMapper.readValue(value, new TypeReference>() {}); - values.add(valueMap.get("identifier")); + for (String s : value) { + Map valueMap = objectMapper.readValue(s, new TypeReference>() {}); + values.add(valueMap.get("identifier")); + } break; } } @@ -173,7 +148,7 @@ public class ZenodoBuilder { List relatedIdentifiers = new ArrayList<>(); for(DescriptionDepositModel descriptionDepositModel: dmp.getDescriptions()){ for(String relatedId: this.identifierProperties.getRelated()){ - List fields = findSchematicValues(relatedId, descriptionDepositModel.getFields()); + List fields = findSchematicValues(relatedId, descriptionDepositModel.getFields()); Set values = extractSchematicValues(fields, acceptedPidTypes); for(String value: values){ ZenodoRelator relator = new ZenodoRelator(); @@ -210,7 +185,7 @@ public class ZenodoBuilder { } } - private void applyIsIdenticalTo(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties.ZenodoConfig zenodoConfig){ + private void applyIsIdenticalTo(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){ if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata()); if (dmp.getAccessType().equals(DmpAccessType.Public)) { @@ -289,7 +264,7 @@ public class ZenodoBuilder { } } - private void applyContributors(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties.ZenodoConfig zenodoConfig){ + private void applyContributors(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){ if (dmp.getUsers() == null) return; if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata()); @@ -298,7 +273,7 @@ public class ZenodoBuilder { String zenodoAffiliation = zenodoConfig.getAffiliation(); List contributors = new ArrayList<>(); - for (UserDmpDepositModel userDMP: dmp.getUsers()) { + for (DmpUserDepositModel userDMP: dmp.getUsers()) { ZenodoContributor contributor = new ZenodoContributor(); contributor.setName(userDMP.getUser().getName()); contributor.setType(CONTRIBUTOR_TYPE_PROJECT_MANAGER); @@ -317,7 +292,7 @@ public class ZenodoBuilder { } - private void applyCreators(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties.ZenodoConfig zenodoConfig){ + private void applyCreators(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){ if (dmp.getUsers() == null) return; if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata()); @@ -326,7 +301,7 @@ public class ZenodoBuilder { String zenodoAffiliation = zenodoConfig.getAffiliation(); ZenodoCreator creator = new ZenodoCreator(); - UserDmpDepositModel dmpDepositModel = dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(DmpUserRole.Owner)).findFirst().orElse(null); + DmpUserDepositModel dmpDepositModel = dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(DmpUserRole.Owner)).findFirst().orElse(null); if (dmpDepositModel == null || dmpDepositModel.getUser() == null) return; creator.setName(dmpDepositModel.getUser().getName()); diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheOptions.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheOptions.java deleted file mode 100644 index 556709d..0000000 --- a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheOptions.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.eudat.depositinterface.zenodorepository.service; - -import gr.cite.tools.cache.CacheOptions; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConfigurationProperties(prefix = "cache.logo-by-repository") -public class RepositoryLogoCacheOptions extends CacheOptions { -} diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheService.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheService.java deleted file mode 100644 index cab83b9..0000000 --- a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/RepositoryLogoCacheService.java +++ /dev/null @@ -1,65 +0,0 @@ -package eu.eudat.depositinterface.zenodorepository.service; - -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 RepositoryLogoCacheService extends CacheService { - - public static class RepositoryLogoCacheValue { - - public RepositoryLogoCacheValue() { - } - - public RepositoryLogoCacheValue(String repositoryId, byte[] logo) { - this.repositoryId = repositoryId; - this.logo = logo; - } - - private String repositoryId; - - public String getRepositoryId() { - return repositoryId; - } - - public void setRepositoryId(String repositoryId) { - this.repositoryId = repositoryId; - } - - private byte[] logo; - - public byte[] getLogo() { - return logo; - } - - public void setLogo(byte[] logo) { - this.logo = logo; - } - } - - - @Autowired - public RepositoryLogoCacheService(RepositoryLogoCacheOptions options) { - super(options); - } - - @Override - protected Class valueClass() { - return RepositoryLogoCacheValue.class; - } - - @Override - public String keyOf(RepositoryLogoCacheValue value) { - return this.buildKey(value.getRepositoryId()); - } - - - public String buildKey(String repositoryId) { - HashMap keyParts = new HashMap<>(); - keyParts.put("$repo$", repositoryId); - return this.generateKey(keyParts); - } -} diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositService.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositService.java index e7dbe7f..cbd1c12 100644 --- a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositService.java +++ b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositService.java @@ -1,335 +1,14 @@ package eu.eudat.depositinterface.zenodorepository.service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.depositinterface.models.DmpDepositModel; -import eu.eudat.depositinterface.models.FileEnvelope; -import eu.eudat.depositinterface.repository.RepositoryDeposit; -import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; -import eu.eudat.depositinterface.zenodorepository.configuration.zenodo.ZenodoProperties; -import eu.eudat.depositinterface.zenodorepository.model.ZenodoDeposit; -import eu.eudat.depositinterface.zenodorepository.model.builder.ZenodoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.http.*; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ResourceUtils; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.WebClient; +import eu.eudat.depositinterface.repository.DepositConfiguration; -import java.io.*; -import java.util.*; -import java.util.stream.Collectors; +public interface ZenodoDepositService { + String deposit(DmpDepositModel dmpDepositModel, String zenodoToken) throws Exception; -@Component -public class ZenodoDepositService implements RepositoryDeposit { - private static final String PUBLISH_ID = "conceptdoi"; + DepositConfiguration getConfiguration(); - private static final String CLIENT_ID = "client_id"; - private static final String CLIENT_SECRET = "client_secret"; - private static final String GRANT_TYPE = "grant_type"; - private static final String AUTHORIZATION_CODE = "authorization_code"; - private static final String CODE = "code"; - private static final String ZENODO_LINKS = "links"; - private static final String REDIRECT_URI = "redirect_uri"; - private static final String ACCESS_TOKEN = "access_token"; - private static final String ZENODO_LINKS_BUCKET = "bucket"; - private static final String ZENODO_LINKS_PUBLISH = "publish"; - private static final String ZENODO_LINKS_SELF = "self"; - private static final String ZENODO_LINKS_LATEST_DRAFT = "latest_draft"; - private static final String ZENODO_METADATA = "metadata"; - private static final String ZENODO_METADATA_VERSION = "version"; + String authenticate(String code); - private static final Logger logger = LoggerFactory.getLogger(ZenodoDepositService.class); - private static final ObjectMapper objectMapper = new ObjectMapper(); - - private final ZenodoProperties zenodoProperties; - private final ZenodoBuilder mapper; - - private final RepositoryLogoCacheService repositoryLogoCacheService; - - @Autowired - public ZenodoDepositService(ZenodoProperties zenodoProperties, ZenodoBuilder mapper, RepositoryLogoCacheService repositoryLogoCacheService){ - this.zenodoProperties = zenodoProperties; - this.mapper = mapper; - this.repositoryLogoCacheService = repositoryLogoCacheService; - } - - @Override - public String deposit(String repositoryId, DmpDepositModel dmpDepositModel, String zenodoToken) throws Exception { - - RepositoryDepositConfiguration repositoryDepositConfiguration = this.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); - - if(repositoryDepositConfiguration != null) { - - if (zenodoToken == null || zenodoToken.isEmpty()) { - zenodoToken = repositoryDepositConfiguration.getAccessToken(); - } - - String zenodoUrl = repositoryDepositConfiguration.getRepositoryUrl(); - - // First step, post call to Zenodo, to create the entry. - WebClient zenodoClient = WebClient.builder().build(); - - ZenodoProperties.ZenodoConfig zenodoConfig = this.zenodoProperties.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); - if (zenodoConfig == null) return null; - eu.eudat.depositinterface.zenodorepository.model.ZenodoDeposit deposit = mapper.build(dmpDepositModel, zenodoConfig); - - LinkedHashMap links; - String previousDOI = dmpDepositModel.getPreviousDOI(); - String unpublishedUrl = null; - String publishUrl; - try { - - if (previousDOI == null) { - links = deposit(zenodoToken, zenodoUrl, zenodoClient, deposit); - } else { - unpublishedUrl = this.getUnpublishedDOI(zenodoUrl, previousDOI, zenodoToken, dmpDepositModel.getVersion()); - if (unpublishedUrl == null) { - //It requires more than one step to create a new version - //First, get the deposit related to the concept DOI - links = depositNewVersion(zenodoToken, zenodoUrl, previousDOI, zenodoClient, deposit); - } else { - links = depositFromPreviousDoi(zenodoToken, zenodoUrl, previousDOI, zenodoClient); - } - } - - if (unpublishedUrl == null) { - // Second step, add the file to the entry. - FileEnvelope pdfEnvelope = dmpDepositModel.getPdfFile(); - - if (links == null || !links.containsKey(ZENODO_LINKS_BUCKET)) throw new Exception("bucket not found"); - - String addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + pdfEnvelope.getFilename() + "?access_token=" + zenodoToken; - zenodoClient.put().uri(addFileUrl) - .body(BodyInserters - .fromResource(new ByteArrayResource(pdfEnvelope.getFile()))) - .retrieve().toEntity(Map.class).block(); - FileEnvelope rdaJsonEnvelope = dmpDepositModel.getRdaJsonFile(); - - String jsonFileName = rdaJsonEnvelope.getFilename(); - addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + jsonFileName + "?access_token=" + zenodoToken; - zenodoClient.put().uri(addFileUrl).headers(httpHeaders -> httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM)).body(BodyInserters.fromResource(new ByteArrayResource(rdaJsonEnvelope.getFile()))).retrieve().toEntity(Map.class).block(); - - if (dmpDepositModel.getSupportingFilesZip() != null) { - String supportingFilesZipName = dmpDepositModel.getSupportingFilesZip().getFilename(); - - addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + supportingFilesZipName + "?access_token=" + zenodoToken; - zenodoClient.put().uri(addFileUrl).body(BodyInserters.fromResource(new ByteArrayResource(supportingFilesZipName.getBytes()))).retrieve().toEntity(Map.class).block(); - } - - // Third post call to Zenodo to publish the entry and return the DOI. - publishUrl = links.get(ZENODO_LINKS_PUBLISH) + "?access_token=" + zenodoToken; - } else { - publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; - } - - return this.publish(publishUrl); - - } catch (HttpClientErrorException | HttpServerErrorException ex) { - Map parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), Map.class); - throw new IOException(parsedException.get("message"), ex); - } - - } - - return null; - - } - - private static LinkedHashMap depositNewVersion(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient, ZenodoDeposit deposit) throws Exception { - Map> createResponse; - LinkedHashMap links; - String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; - logger.debug("listUrl = " + listUrl); - ResponseEntity> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); - if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; - createResponse = (Map>) listResponses.getBody().get(0); - logger.debug("createResponse-previousDoi:"); - logger.debug(objectMapper.writeValueAsString(createResponse)); - links = (LinkedHashMap) createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); - - //Second, make the new version (not in the links?) - if (!links.containsKey(ZENODO_LINKS_LATEST_DRAFT)) throw new Exception("previousDOI not found"); - String newVersionUrl = links.get(ZENODO_LINKS_LATEST_DRAFT) + "/actions/newversion" + "?access_token=" + zenodoToken; - logger.debug("new version url: " + newVersionUrl); - createResponse = zenodoClient.post().uri(newVersionUrl) - .bodyValue(null).exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>>() {})).block(); - logger.debug("createResponse-newVersion:"); - logger.debug(objectMapper.writeValueAsString(createResponse)); - links = createResponse == null ? new LinkedHashMap<>() : createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); - - //Third, get the new deposit - if (!links.containsKey(ZENODO_LINKS_LATEST_DRAFT)) throw new Exception("can not create latest draft"); - String latestDraftUrl = links.get(ZENODO_LINKS_LATEST_DRAFT) + "?access_token=" + zenodoToken; - createResponse = zenodoClient.get().uri(latestDraftUrl) - .exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>>() {})).block(); - logger.debug("createResponse-latestDraft:"); - logger.debug(objectMapper.writeValueAsString(createResponse)); - links = createResponse == null ? new LinkedHashMap<>() : createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); - - //At this point it might fail to perform the next requests so enclose them with try catch - try { - //Forth, update the new deposit's metadata - String updateUrl = links.get(ZENODO_LINKS_SELF) + "?access_token=" + zenodoToken; - zenodoClient.put().uri(updateUrl) - .headers(httpHeaders -> { - httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - }) - .bodyValue(deposit).retrieve().toEntity(Map.class).block(); - //And finally remove pre-existing files from it - String fileListUrl = links.get(ZENODO_LINKS_SELF) + "/files" + "?access_token=" + zenodoToken; - ResponseEntity> fileListResponse = zenodoClient.get().uri(fileListUrl).retrieve().toEntityList(Map.class).block(); - for (Map file : fileListResponse.getBody()) { - String fileDeleteUrl = links.get(ZENODO_LINKS_SELF) + "/files/" + file.get("id") + "?access_token=" + zenodoToken; - zenodoClient.delete().uri(fileDeleteUrl).retrieve().toEntity(Map.class).block(); - } - } catch (Exception e) { - //In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed) - //restTemplate.delete(latestDraftUrl); - zenodoClient.delete().uri(latestDraftUrl).retrieve().toEntity(Map.class).block(); - throw e; - } - return links; - } - - private static LinkedHashMap depositFromPreviousDoi(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient) { - Map> createResponse; - String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; - ResponseEntity> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); - if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; - - createResponse = (Map>) listResponses.getBody().get(0); - - return createResponse.getOrDefault(ZENODO_LINKS, null); - } - - private LinkedHashMap deposit(String zenodoToken, String zenodoUrl, WebClient zenodoClient, ZenodoDeposit deposit) { - Map createResponse; - String createUrl = zenodoUrl + "deposit/depositions" + "?access_token=" + zenodoToken; - createResponse = zenodoClient.post().uri(createUrl).headers(httpHeaders -> { - httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - }) - .bodyValue(deposit).exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>() {})).block(); - return (LinkedHashMap) createResponse.getOrDefault(ZENODO_LINKS, null); - } - - private String publish(String publishUrl){ - WebClient webClient = WebClient.builder().build(); - Map publishResponse = webClient.post().uri(publishUrl).bodyValue("").exchangeToMono(mono -> { - if (!mono.statusCode().is2xxSuccessful()) { - mono.createException(); - throw new UnsupportedOperationException("Failed to publish to Zenodo"); - } - return mono.bodyToMono(new ParameterizedTypeReference>() { - }); - }).block(); - if (publishResponse == null) throw new UnsupportedOperationException("Failed to publish to Zenodo"); - return (String) publishResponse.get(PUBLISH_ID); - } - - - @Override - public List getConfiguration() { - List zenodoConfigs = this.zenodoProperties.getConfiguration(); - return (zenodoConfigs != null) ? zenodoConfigs.stream().map(ZenodoProperties.ZenodoConfig::toRepoConfig).collect(Collectors.toList()) : null; - } - - @Override - public String authenticate(String repositoryId, String code){ - - RepositoryDepositConfiguration repositoryDepositConfiguration = this.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); - - if(repositoryDepositConfiguration != null) { - - WebClient client = WebClient.builder().defaultHeaders(httpHeaders -> { - httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); - }).build(); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add(CLIENT_ID, repositoryDepositConfiguration.getRepositoryClientId()); - map.add(CLIENT_SECRET, repositoryDepositConfiguration.getRepositoryClientSecret()); - map.add(GRANT_TYPE, AUTHORIZATION_CODE); - map.add(CODE, code); - map.add(REDIRECT_URI, repositoryDepositConfiguration.getRedirectUri()); - - try { - Map values = client.post().uri(repositoryDepositConfiguration.getRepositoryAccessTokenUrl()).bodyValue(map).exchangeToMono(mono -> { - if (!mono.statusCode().is2xxSuccessful()) { - mono.createException(); - throw new HttpClientErrorException(mono.statusCode()); - } - return mono.bodyToMono(new ParameterizedTypeReference>() { - }); - }).block(); - - return values != null ? (String) values.getOrDefault(ACCESS_TOKEN, null) : null; - } catch (HttpClientErrorException ex) { - logger.error(ex.getResponseBodyAsString(), ex); - return null; - } - } - - return null; - } - - @Override - public String getLogo(String repositoryId) { - ZenodoProperties.ZenodoConfig zenodoConfig = this.zenodoProperties.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null); - if(zenodoConfig != null && zenodoConfig.isHasLogo() && zenodoConfig.getLogo() != null && !zenodoConfig.getLogo().isBlank()) { - RepositoryLogoCacheService.RepositoryLogoCacheValue cacheValue = this.repositoryLogoCacheService.lookup(this.repositoryLogoCacheService.buildKey(repositoryId)); - byte[] logo = null; - if (cacheValue != null) { - logo = cacheValue.getLogo(); - } else { - try { - java.io.File logoFile = ResourceUtils.getFile(zenodoConfig.getLogo()); - if (!logoFile.exists()) return null; - try(InputStream inputStream = new FileInputStream(logoFile)){ - logo = inputStream.readAllBytes(); - }; - } catch (IOException e) { - throw new RuntimeException(e); - } - this.repositoryLogoCacheService.put(new RepositoryLogoCacheService.RepositoryLogoCacheValue(repositoryId, logo)); - } - return (logo != null && logo.length != 0) ? Base64.getEncoder().encodeToString(logo) : null; - } - return null; - } - - private String getUnpublishedDOI(String zenodoUrl, String doi, String token, Short version) { - try { - WebClient client = WebClient.builder().build(); - Map> createResponse = null; - LinkedHashMap links; - LinkedHashMap metadata; - String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + doi + "\"&access_token=" + token; - ResponseEntity> listResponses = client.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); - if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; - - createResponse = (Map>) listResponses.getBody().get(0); - metadata = createResponse.getOrDefault(ZENODO_METADATA, new LinkedHashMap<>()); - links = createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); - - if (metadata.get(ZENODO_METADATA_VERSION).equals(version.toString())) { - return links.get(ZENODO_LINKS_PUBLISH); - } else { - return null; - } - }catch (Exception e) { - logger.warn(e.getMessage(), e); - return null; - } - } + String getLogo(); } diff --git a/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositServiceImpl.java b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositServiceImpl.java new file mode 100644 index 0000000..756727e --- /dev/null +++ b/core/src/main/java/eu/eudat/depositinterface/zenodorepository/service/ZenodoDepositServiceImpl.java @@ -0,0 +1,326 @@ +package eu.eudat.depositinterface.zenodorepository.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.depositinterface.models.DmpDepositModel; +import eu.eudat.depositinterface.models.FileEnvelope; +import eu.eudat.depositinterface.repository.DepositConfiguration; +import eu.eudat.depositinterface.zenodorepository.configuration.zenodo.ZenodoProperties; +import eu.eudat.depositinterface.zenodorepository.model.ZenodoDeposit; +import eu.eudat.depositinterface.zenodorepository.model.builder.ZenodoBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.ResourceUtils; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; + +import java.io.*; +import java.util.*; + +@Component +public class ZenodoDepositServiceImpl implements ZenodoDepositService { + private static final String PUBLISH_ID = "conceptdoi"; + + private static final String CLIENT_ID = "client_id"; + private static final String CLIENT_SECRET = "client_secret"; + private static final String GRANT_TYPE = "grant_type"; + private static final String AUTHORIZATION_CODE = "authorization_code"; + private static final String CODE = "code"; + private static final String ZENODO_LINKS = "links"; + private static final String REDIRECT_URI = "redirect_uri"; + private static final String ACCESS_TOKEN = "access_token"; + private static final String ZENODO_LINKS_BUCKET = "bucket"; + private static final String ZENODO_LINKS_PUBLISH = "publish"; + private static final String ZENODO_LINKS_SELF = "self"; + private static final String ZENODO_LINKS_LATEST_DRAFT = "latest_draft"; + private static final String ZENODO_METADATA = "metadata"; + private static final String ZENODO_METADATA_VERSION = "version"; + + private static final Logger logger = LoggerFactory.getLogger(ZenodoDepositServiceImpl.class); + private static final ObjectMapper objectMapper = new ObjectMapper(); + + private final ZenodoProperties zenodoProperties; + private final ZenodoBuilder mapper; + + private byte[] logo; + + @Autowired + public ZenodoDepositServiceImpl(ZenodoProperties zenodoProperties, ZenodoBuilder mapper){ + this.zenodoProperties = zenodoProperties; + this.mapper = mapper; + this.logo = null; + } + + @Override + public String deposit(DmpDepositModel dmpDepositModel, String zenodoToken) throws Exception { + + DepositConfiguration depositConfiguration = this.getConfiguration(); + + if(depositConfiguration != null) { + + if (zenodoToken == null || zenodoToken.isEmpty()) { + zenodoToken = depositConfiguration.getAccessToken(); + } + + String zenodoUrl = depositConfiguration.getRepositoryUrl(); + + // First step, post call to Zenodo, to create the entry. + WebClient zenodoClient = WebClient.builder().build(); + + DepositConfiguration zenodoConfig = this.zenodoProperties.getDepositConfiguration(); + if (zenodoConfig == null) return null; + eu.eudat.depositinterface.zenodorepository.model.ZenodoDeposit deposit = mapper.build(dmpDepositModel, this.zenodoProperties); + + LinkedHashMap links; + String previousDOI = dmpDepositModel.getPreviousDOI(); + String unpublishedUrl = null; + String publishUrl; + try { + + if (previousDOI == null) { + links = deposit(zenodoToken, zenodoUrl, zenodoClient, deposit); + } else { + unpublishedUrl = this.getUnpublishedDOI(zenodoUrl, previousDOI, zenodoToken, dmpDepositModel.getVersion()); + if (unpublishedUrl == null) { + //It requires more than one step to create a new version + //First, get the deposit related to the concept DOI + links = depositNewVersion(zenodoToken, zenodoUrl, previousDOI, zenodoClient, deposit); + } else { + links = depositFromPreviousDoi(zenodoToken, zenodoUrl, previousDOI, zenodoClient); + } + } + + if (unpublishedUrl == null) { + // Second step, add the file to the entry. + FileEnvelope pdfEnvelope = dmpDepositModel.getPdfFile(); + + if (links == null || !links.containsKey(ZENODO_LINKS_BUCKET)) throw new Exception("bucket not found"); + + String addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + pdfEnvelope.getFilename() + "?access_token=" + zenodoToken; + zenodoClient.put().uri(addFileUrl) + .body(BodyInserters + .fromResource(new ByteArrayResource(pdfEnvelope.getFile()))) + .retrieve().toEntity(Map.class).block(); + FileEnvelope rdaJsonEnvelope = dmpDepositModel.getRdaJsonFile(); + + String jsonFileName = rdaJsonEnvelope.getFilename(); + addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + jsonFileName + "?access_token=" + zenodoToken; + zenodoClient.put().uri(addFileUrl).headers(httpHeaders -> httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM)).body(BodyInserters.fromResource(new ByteArrayResource(rdaJsonEnvelope.getFile()))).retrieve().toEntity(Map.class).block(); + + if (dmpDepositModel.getSupportingFilesZip() != null) { + String supportingFilesZipName = dmpDepositModel.getSupportingFilesZip().getFilename(); + + addFileUrl = links.get(ZENODO_LINKS_BUCKET) + "/" + supportingFilesZipName + "?access_token=" + zenodoToken; + zenodoClient.put().uri(addFileUrl).body(BodyInserters.fromResource(new ByteArrayResource(supportingFilesZipName.getBytes()))).retrieve().toEntity(Map.class).block(); + } + + // Third post call to Zenodo to publish the entry and return the DOI. + publishUrl = links.get(ZENODO_LINKS_PUBLISH) + "?access_token=" + zenodoToken; + } else { + publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; + } + + return this.publish(publishUrl); + + } catch (HttpClientErrorException | HttpServerErrorException ex) { + Map parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), Map.class); + throw new IOException(parsedException.get("message"), ex); + } + + } + + return null; + + } + + private static LinkedHashMap depositNewVersion(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient, ZenodoDeposit deposit) throws Exception { + Map> createResponse; + LinkedHashMap links; + String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; + logger.debug("listUrl = " + listUrl); + ResponseEntity> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); + if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; + createResponse = (Map>) listResponses.getBody().get(0); + logger.debug("createResponse-previousDoi:"); + logger.debug(objectMapper.writeValueAsString(createResponse)); + links = (LinkedHashMap) createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); + + //Second, make the new version (not in the links?) + if (!links.containsKey(ZENODO_LINKS_LATEST_DRAFT)) throw new Exception("previousDOI not found"); + String newVersionUrl = links.get(ZENODO_LINKS_LATEST_DRAFT) + "/actions/newversion" + "?access_token=" + zenodoToken; + logger.debug("new version url: " + newVersionUrl); + createResponse = zenodoClient.post().uri(newVersionUrl) + .bodyValue(null).exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>>() {})).block(); + logger.debug("createResponse-newVersion:"); + logger.debug(objectMapper.writeValueAsString(createResponse)); + links = createResponse == null ? new LinkedHashMap<>() : createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); + + //Third, get the new deposit + if (!links.containsKey(ZENODO_LINKS_LATEST_DRAFT)) throw new Exception("can not create latest draft"); + String latestDraftUrl = links.get(ZENODO_LINKS_LATEST_DRAFT) + "?access_token=" + zenodoToken; + createResponse = zenodoClient.get().uri(latestDraftUrl) + .exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>>() {})).block(); + logger.debug("createResponse-latestDraft:"); + logger.debug(objectMapper.writeValueAsString(createResponse)); + links = createResponse == null ? new LinkedHashMap<>() : createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); + + //At this point it might fail to perform the next requests so enclose them with try catch + try { + //Forth, update the new deposit's metadata + String updateUrl = links.get(ZENODO_LINKS_SELF) + "?access_token=" + zenodoToken; + zenodoClient.put().uri(updateUrl) + .headers(httpHeaders -> { + httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + }) + .bodyValue(deposit).retrieve().toEntity(Map.class).block(); + //And finally remove pre-existing files from it + String fileListUrl = links.get(ZENODO_LINKS_SELF) + "/files" + "?access_token=" + zenodoToken; + ResponseEntity> fileListResponse = zenodoClient.get().uri(fileListUrl).retrieve().toEntityList(Map.class).block(); + for (Map file : fileListResponse.getBody()) { + String fileDeleteUrl = links.get(ZENODO_LINKS_SELF) + "/files/" + file.get("id") + "?access_token=" + zenodoToken; + zenodoClient.delete().uri(fileDeleteUrl).retrieve().toEntity(Map.class).block(); + } + } catch (Exception e) { + //In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed) + //restTemplate.delete(latestDraftUrl); + zenodoClient.delete().uri(latestDraftUrl).retrieve().toEntity(Map.class).block(); + throw e; + } + return links; + } + + private static LinkedHashMap depositFromPreviousDoi(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient) { + Map> createResponse; + String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; + ResponseEntity> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); + if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; + + createResponse = (Map>) listResponses.getBody().get(0); + + return createResponse.getOrDefault(ZENODO_LINKS, null); + } + + private LinkedHashMap deposit(String zenodoToken, String zenodoUrl, WebClient zenodoClient, ZenodoDeposit deposit) { + Map createResponse; + String createUrl = zenodoUrl + "deposit/depositions" + "?access_token=" + zenodoToken; + createResponse = zenodoClient.post().uri(createUrl).headers(httpHeaders -> { + httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + }) + .bodyValue(deposit).exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>() {})).block(); + return (LinkedHashMap) createResponse.getOrDefault(ZENODO_LINKS, null); + } + + private String publish(String publishUrl){ + WebClient webClient = WebClient.builder().build(); + Map publishResponse = webClient.post().uri(publishUrl).bodyValue("").exchangeToMono(mono -> { + if (!mono.statusCode().is2xxSuccessful()) { + mono.createException(); + throw new UnsupportedOperationException("Failed to publish to Zenodo"); + } + return mono.bodyToMono(new ParameterizedTypeReference>() { + }); + }).block(); + if (publishResponse == null) throw new UnsupportedOperationException("Failed to publish to Zenodo"); + return (String) publishResponse.get(PUBLISH_ID); + } + + + @Override + public DepositConfiguration getConfiguration() { + return this.zenodoProperties.getDepositConfiguration(); + } + + @Override + public String authenticate(String code){ + + DepositConfiguration depositConfiguration = this.getConfiguration(); + + if(depositConfiguration != null) { + + WebClient client = WebClient.builder().defaultHeaders(httpHeaders -> { + httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); + }).build(); + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add(CLIENT_ID, depositConfiguration.getRepositoryClientId()); + map.add(CLIENT_SECRET, depositConfiguration.getRepositoryClientSecret()); + map.add(GRANT_TYPE, AUTHORIZATION_CODE); + map.add(CODE, code); + map.add(REDIRECT_URI, depositConfiguration.getRedirectUri()); + + try { + Map values = client.post().uri(depositConfiguration.getRepositoryAccessTokenUrl()).bodyValue(map).exchangeToMono(mono -> { + if (!mono.statusCode().is2xxSuccessful()) { + mono.createException(); + throw new HttpClientErrorException(mono.statusCode()); + } + return mono.bodyToMono(new ParameterizedTypeReference>() { + }); + }).block(); + + return values != null ? (String) values.getOrDefault(ACCESS_TOKEN, null) : null; + } catch (HttpClientErrorException ex) { + logger.error(ex.getResponseBodyAsString(), ex); + return null; + } + } + + return null; + } + + @Override + public String getLogo() { + DepositConfiguration zenodoConfig = this.zenodoProperties.getDepositConfiguration(); + if(zenodoConfig != null && zenodoConfig.isHasLogo() && this.zenodoProperties.getLogo() != null && !this.zenodoProperties.getLogo().isBlank()) { + if (this.logo == null) { + try { + java.io.File logoFile = ResourceUtils.getFile(this.zenodoProperties.getLogo()); + if (!logoFile.exists()) return null; + try(InputStream inputStream = new FileInputStream(logoFile)){ + this.logo = inputStream.readAllBytes(); + }; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return (this.logo != null && this.logo.length != 0) ? Base64.getEncoder().encodeToString(this.logo) : null; + } + return null; + } + + private String getUnpublishedDOI(String zenodoUrl, String doi, String token, Short version) { + try { + WebClient client = WebClient.builder().build(); + Map> createResponse = null; + LinkedHashMap links; + LinkedHashMap metadata; + String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + doi + "\"&access_token=" + token; + ResponseEntity> listResponses = client.get().uri(listUrl).retrieve().toEntityList(Map.class).block(); + if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null; + + createResponse = (Map>) listResponses.getBody().get(0); + metadata = createResponse.getOrDefault(ZENODO_METADATA, new LinkedHashMap<>()); + links = createResponse.getOrDefault(ZENODO_LINKS, new LinkedHashMap<>()); + + if (metadata.get(ZENODO_METADATA_VERSION).equals(version.toString())) { + return links.get(ZENODO_LINKS_PUBLISH); + } else { + return null; + } + }catch (Exception e) { + logger.warn(e.getMessage(), e); + return null; + } + } +} diff --git a/web/src/main/java/eu/eudat/deposit/controller/DepositController.java b/web/src/main/java/eu/eudat/deposit/controller/DepositController.java index edb961a..1f28e60 100644 --- a/web/src/main/java/eu/eudat/deposit/controller/DepositController.java +++ b/web/src/main/java/eu/eudat/deposit/controller/DepositController.java @@ -1,8 +1,8 @@ package eu.eudat.deposit.controller; import eu.eudat.depositinterface.models.DmpDepositModel; -import eu.eudat.depositinterface.repository.RepositoryDeposit; -import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; +import eu.eudat.depositinterface.repository.DepositConfiguration; +import eu.eudat.depositinterface.zenodorepository.service.ZenodoDepositService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -10,33 +10,29 @@ import java.util.List; @RestController @RequestMapping("/api/deposit") -public class DepositController { +public class DepositController implements eu.eudat.depositinterface.repository.DepositController { - private final RepositoryDeposit repositoryDeposit; + private final ZenodoDepositService depositClient; @Autowired - public DepositController(RepositoryDeposit repositoryDeposit) { - this.repositoryDeposit = repositoryDeposit; + public DepositController(ZenodoDepositService depositClient) { + this.depositClient = depositClient; } - @PostMapping("/{id}") - public String deposit(@PathVariable("id") String repositoryId, @RequestBody DmpDepositModel dmpDepositModel, @RequestParam("authToken")String authToken) throws Exception { - return repositoryDeposit.deposit(repositoryId, dmpDepositModel, authToken); + public String deposit(@RequestBody DmpDepositModel dmpDepositModel, @RequestParam("authToken")String authToken) throws Exception { + return depositClient.deposit(dmpDepositModel, authToken); } - @GetMapping("/authenticate/{id}") - public String authenticate(@PathVariable("id") String repositoryId, @RequestParam("authToken") String authToken) { - return repositoryDeposit.authenticate(repositoryId, authToken); + public String authenticate(@RequestParam("authToken") String code) { + return depositClient.authenticate(code); } - @GetMapping("/configuration") - public List getConfiguration() { - return repositoryDeposit.getConfiguration(); + public DepositConfiguration getConfiguration() { + return depositClient.getConfiguration(); } - @GetMapping("/logo/{id}") - public String getLogo(@PathVariable("id") String repositoryId) { - return repositoryDeposit.getLogo(repositoryId); + public String getLogo() { + return depositClient.getLogo(); } } diff --git a/web/src/main/resources/config/zenodo-dev.yml b/web/src/main/resources/config/zenodo-dev.yml index c3c2b44..fce99db 100644 --- a/web/src/main/resources/config/zenodo-dev.yml +++ b/web/src/main/resources/config/zenodo-dev.yml @@ -1,18 +1,17 @@ zenodo: - configuration: - - deposit-type: 2 - repository-id: Zenodo - access-token: ${ZENODO_ACCESS_TOKEN} - repository-url: https://sandbox.zenodo.org/api/ - repository-authorization-url: https://sandbox.zenodo.org/oauth/authorize - repository-record-url: https://sandbox.zenodo.org/record/ - repository-access-token-url: https://sandbox.zenodo.org/oauth/token - repository-client-id: - repository-client-secret: - redirect-uri: http://localhost:4200/login/external/zenodo - has-logo: true - logo: classpath:zenodo.jpg - doi-funder: - community: argos - affiliation: ARGOS - domain: https://argos.openaire.eu/ \ No newline at end of file + community: argos + affiliation: ARGOS + domain: https://argos.openaire.eu/ + logo: classpath:zenodo.jpg + depositConfiguration: + deposit-type: 2 + repository-id: Zenodo + access-token: ${ZENODO_ACCESS_TOKEN} + repository-url: https://sandbox.zenodo.org/api/ + repository-authorization-url: https://sandbox.zenodo.org/oauth/authorize + repository-record-url: https://sandbox.zenodo.org/record/ + repository-access-token-url: https://sandbox.zenodo.org/oauth/token + repository-client-id: + repository-client-secret: + redirect-uri: http://localhost:4200/login/external/zenodo + has-logo: true \ No newline at end of file diff --git a/web/src/main/resources/config/zenodo.yml b/web/src/main/resources/config/zenodo.yml index 6b6aa66..4d561fd 100644 --- a/web/src/main/resources/config/zenodo.yml +++ b/web/src/main/resources/config/zenodo.yml @@ -1,3 +1 @@ zenodo: - storage: - temp: ${STORAGE_TMP_ZENODO} \ No newline at end of file