sync with new models
This commit is contained in:
parent
e636baf4b8
commit
15692d7afa
|
@ -45,7 +45,7 @@
|
|||
<dependency>
|
||||
<groupId>gr.cite.opendmp</groupId>
|
||||
<artifactId>repositorydepositbase</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -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<ZenodoConfig> 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<ZenodoConfig> 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<ZenodoConfig> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<DatasetFieldsDepositModel> findSchematicValues(String relatedId, List<DatasetFieldsDepositModel> fields){
|
||||
private List<DescriptionFieldDepositModel> findSchematicValues(String relatedId, List<DescriptionFieldDepositModel> fields){
|
||||
return fields.stream().filter(f -> f.getSchematics().contains(relatedId)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Set<String> extractSchematicValues(List<DatasetFieldsDepositModel> fields, List<String> acceptedPidTypes) throws JsonProcessingException{
|
||||
private Set<String> extractSchematicValues(List<DescriptionFieldDepositModel> fields, List<String> acceptedPidTypes) throws JsonProcessingException{
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Set<String> 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<String> 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<String> selected = objectMapper.readValue(value, new TypeReference<List<String>>() {});
|
||||
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<String> selected = objectMapper.readValue(value, new TypeReference<List<String>>() {});
|
||||
for (String s : selected) {
|
||||
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {});
|
||||
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<String, String> valueMap = objectMapper.readValue(value, new TypeReference<Map<String, String>>() {});
|
||||
for (String s : value) {
|
||||
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
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<String> selected = objectMapper.readValue(value, new TypeReference<List<String>>() {});
|
||||
for (String s : selected) {
|
||||
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {});
|
||||
String pid = valueMap.get("reference");
|
||||
if(pid != null) {
|
||||
values.add(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Map<String, String> valueMap = objectMapper.readValue(value, new TypeReference<Map<String, String>>() {});
|
||||
for (String s : value) {
|
||||
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {});
|
||||
String pid = valueMap.get("reference");
|
||||
if(pid != null) {
|
||||
values.add(pid);
|
||||
|
@ -152,8 +125,10 @@ public class ZenodoBuilder {
|
|||
}
|
||||
break;
|
||||
case DATASET_IDENTIFIER:
|
||||
Map<String, String> valueMap = objectMapper.readValue(value, new TypeReference<Map<String, String>>() {});
|
||||
values.add(valueMap.get("identifier"));
|
||||
for (String s : value) {
|
||||
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {});
|
||||
values.add(valueMap.get("identifier"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +148,7 @@ public class ZenodoBuilder {
|
|||
List<ZenodoRelator> relatedIdentifiers = new ArrayList<>();
|
||||
for(DescriptionDepositModel descriptionDepositModel: dmp.getDescriptions()){
|
||||
for(String relatedId: this.identifierProperties.getRelated()){
|
||||
List<DatasetFieldsDepositModel> fields = findSchematicValues(relatedId, descriptionDepositModel.getFields());
|
||||
List<DescriptionFieldDepositModel> fields = findSchematicValues(relatedId, descriptionDepositModel.getFields());
|
||||
Set<String> 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<ZenodoContributor> 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());
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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<RepositoryLogoCacheService.RepositoryLogoCacheValue> {
|
||||
|
||||
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<RepositoryLogoCacheValue> valueClass() {
|
||||
return RepositoryLogoCacheValue.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String keyOf(RepositoryLogoCacheValue value) {
|
||||
return this.buildKey(value.getRepositoryId());
|
||||
}
|
||||
|
||||
|
||||
public String buildKey(String repositoryId) {
|
||||
HashMap<String, String> keyParts = new HashMap<>();
|
||||
keyParts.put("$repo$", repositoryId);
|
||||
return this.generateKey(keyParts);
|
||||
}
|
||||
}
|
|
@ -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<String, String> 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<String, String> parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), Map.class);
|
||||
throw new IOException(parsedException.get("message"), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private static LinkedHashMap<String, String> depositNewVersion(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient, ZenodoDeposit deposit) throws Exception {
|
||||
Map<String, LinkedHashMap<String, String>> createResponse;
|
||||
LinkedHashMap<String, String> links;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
|
||||
logger.debug("listUrl = " + listUrl);
|
||||
ResponseEntity<List<Map>> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) listResponses.getBody().get(0);
|
||||
logger.debug("createResponse-previousDoi:");
|
||||
logger.debug(objectMapper.writeValueAsString(createResponse));
|
||||
links = (LinkedHashMap<String, String>) 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<Map<String, LinkedHashMap<String, String>>>() {})).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<Map<String, LinkedHashMap<String, String>>>() {})).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<List<Map>> 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<String, String> depositFromPreviousDoi(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient) {
|
||||
Map<String, LinkedHashMap<String, String>> createResponse;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
|
||||
ResponseEntity<List<Map>> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) listResponses.getBody().get(0);
|
||||
|
||||
return createResponse.getOrDefault(ZENODO_LINKS, null);
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, String> deposit(String zenodoToken, String zenodoUrl, WebClient zenodoClient, ZenodoDeposit deposit) {
|
||||
Map<String, Object> 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<Map<String, Object>>() {})).block();
|
||||
return (LinkedHashMap<String, String>) createResponse.getOrDefault(ZENODO_LINKS, null);
|
||||
}
|
||||
|
||||
private String publish(String publishUrl){
|
||||
WebClient webClient = WebClient.builder().build();
|
||||
Map<String, Object> 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<Map<String, Object>>() {
|
||||
});
|
||||
}).block();
|
||||
if (publishResponse == null) throw new UnsupportedOperationException("Failed to publish to Zenodo");
|
||||
return (String) publishResponse.get(PUBLISH_ID);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<RepositoryDepositConfiguration> getConfiguration() {
|
||||
List<ZenodoProperties.ZenodoConfig> 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<String, String> 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<String, Object> 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<Map<String, Object>>() {
|
||||
});
|
||||
}).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<String, LinkedHashMap<String, String>> createResponse = null;
|
||||
LinkedHashMap<String, String> links;
|
||||
LinkedHashMap<String, String> metadata;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + doi + "\"&access_token=" + token;
|
||||
ResponseEntity<List<Map>> listResponses = client.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) 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();
|
||||
}
|
||||
|
|
|
@ -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<String, String> 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<String, String> parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), Map.class);
|
||||
throw new IOException(parsedException.get("message"), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private static LinkedHashMap<String, String> depositNewVersion(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient, ZenodoDeposit deposit) throws Exception {
|
||||
Map<String, LinkedHashMap<String, String>> createResponse;
|
||||
LinkedHashMap<String, String> links;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
|
||||
logger.debug("listUrl = " + listUrl);
|
||||
ResponseEntity<List<Map>> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) listResponses.getBody().get(0);
|
||||
logger.debug("createResponse-previousDoi:");
|
||||
logger.debug(objectMapper.writeValueAsString(createResponse));
|
||||
links = (LinkedHashMap<String, String>) 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<Map<String, LinkedHashMap<String, String>>>() {})).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<Map<String, LinkedHashMap<String, String>>>() {})).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<List<Map>> 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<String, String> depositFromPreviousDoi(String zenodoToken, String zenodoUrl, String previousDOI, WebClient zenodoClient) {
|
||||
Map<String, LinkedHashMap<String, String>> createResponse;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
|
||||
ResponseEntity<List<Map>> listResponses = zenodoClient.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) listResponses.getBody().get(0);
|
||||
|
||||
return createResponse.getOrDefault(ZENODO_LINKS, null);
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, String> deposit(String zenodoToken, String zenodoUrl, WebClient zenodoClient, ZenodoDeposit deposit) {
|
||||
Map<String, Object> 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<Map<String, Object>>() {})).block();
|
||||
return (LinkedHashMap<String, String>) createResponse.getOrDefault(ZENODO_LINKS, null);
|
||||
}
|
||||
|
||||
private String publish(String publishUrl){
|
||||
WebClient webClient = WebClient.builder().build();
|
||||
Map<String, Object> 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<Map<String, Object>>() {
|
||||
});
|
||||
}).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<String, String> 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<String, Object> 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<Map<String, Object>>() {
|
||||
});
|
||||
}).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<String, LinkedHashMap<String, String>> createResponse = null;
|
||||
LinkedHashMap<String, String> links;
|
||||
LinkedHashMap<String, String> metadata;
|
||||
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + doi + "\"&access_token=" + token;
|
||||
ResponseEntity<List<Map>> listResponses = client.get().uri(listUrl).retrieve().toEntityList(Map.class).block();
|
||||
if (listResponses == null || listResponses.getBody() == null || listResponses.getBody().isEmpty()) return null;
|
||||
|
||||
createResponse = (Map<String, LinkedHashMap<String, String>>) 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<RepositoryDepositConfiguration> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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/
|
||||
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
|
|
@ -1,3 +1 @@
|
|||
zenodo:
|
||||
storage:
|
||||
temp: ${STORAGE_TMP_ZENODO}
|
Loading…
Reference in New Issue