Compare commits

...

9 Commits

46 changed files with 1395 additions and 1224 deletions

122
core/pom.xml Normal file
View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repository-deposit-parent</artifactId>
<version>${revision}</version>
<relativePath>..</relativePath>
</parent>
<artifactId>repositorydepositzenodo</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<name>OpenDMP Repository Deposit Zenodo</name>
<description>OpenDMP Repository Deposit Zenodo</description>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo</url>
<licenses>
<license>
<name>MIT License</name>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo/src/branch/master/LICENSE.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>CITE S.A.</name>
<email>maven-central@cite.gr</email>
<organization>CITE S.A.</organization>
<organizationUrl>https://www.cite.gr</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:git://code-repo.d4science.org</connection>
<developerConnection>scm:git:ssh://code-repo.d4science.org</developerConnection>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo</url>
</scm>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<dependencies>
<dependency>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repositorydepositbase</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>cache</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>eu.eudat.EuDatApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.json</pattern>
<shadedPattern>zenodorepository.shaded.org.json</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package eu.eudat.depositinterface.zenodorepository.configuration;
import eu.eudat.depositinterface.zenodorepository.configuration.funder.FunderProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.identifier.IdentifierProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.pid.PidProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.zenodo.ZenodoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties({ZenodoProperties.class, PidProperties.class, FunderProperties.class, IdentifierProperties.class})
public class GenericConfiguration {
}

View File

@ -0,0 +1,41 @@
package eu.eudat.depositinterface.zenodorepository.configuration.funder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import java.util.List;
@ConfigurationProperties(prefix = "funder")
public class FunderProperties {
private List<DoiFunder> available;
public List<DoiFunder> getAvailable() {
return available;
}
public void setAvailable(List<DoiFunder> available) {
this.available = available;
}
public static class DoiFunder {
private String funder;
private String doi;
public String getFunder() {
return funder;
}
public String getDoi() {
return doi;
}
public void setFunder(String funder) {
this.funder = funder;
}
public void setDoi(String doi) {
this.doi = doi;
}
}
}

View File

@ -0,0 +1,19 @@
package eu.eudat.depositinterface.zenodorepository.configuration.identifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import java.util.List;
@ConfigurationProperties(prefix = "identifiers")
public class IdentifierProperties {
private List<String> related;
public List<String> getRelated() {
return related;
}
public void setRelated(List<String> related) {
this.related = related;
}
}

View File

@ -0,0 +1,50 @@
package eu.eudat.depositinterface.zenodorepository.configuration.pid;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import java.util.List;
@ConfigurationProperties(prefix = "pid")
public class PidProperties {
private List<String> acceptedTypes;
private PidFieldNames fields;
public List<String> getAcceptedTypes() {
return acceptedTypes;
}
public PidFieldNames getFields() {
return fields;
}
public void setAcceptedTypes(List<String> acceptedTypes) {
this.acceptedTypes = acceptedTypes;
}
public void setFields(PidFieldNames fields) {
this.fields = fields;
}
public static class PidFieldNames {
private String pidName;
private String pidTypeName;
public String getPidName() {
return pidName;
}
public void setPidName(String pidName) {
this.pidName = pidName;
}
public String getPidTypeName() {
return pidTypeName;
}
public void setPidTypeName(String pidTypeName) {
this.pidTypeName = pidTypeName;
}
}
}

View File

@ -0,0 +1,57 @@
package eu.eudat.depositinterface.zenodorepository.configuration.zenodo;
import eu.eudat.depositinterface.repository.DepositConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "zenodo")
public class ZenodoProperties {
private String logo;
private String community;
private String domain;
private String affiliation;
private DepositConfiguration depositConfiguration;
public void setLogo(String logo) {
this.logo = logo;
}
public String getLogo() {
return logo;
}
public String getCommunity() {
return community;
}
public void setCommunity(String community) {
this.community = community;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public DepositConfiguration getDepositConfiguration() {
return depositConfiguration;
}
public void setDepositConfiguration(DepositConfiguration depositConfiguration) {
this.depositConfiguration = depositConfiguration;
}
}

View File

@ -0,0 +1,36 @@
package eu.eudat.depositinterface.zenodorepository.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import eu.eudat.depositinterface.enums.EnumUtils;
import eu.eudat.depositinterface.enums.EnumValueProvider;
import eu.eudat.depositinterface.enums.FieldType;
import java.util.Map;
public enum ZenodoAccessRight implements EnumValueProvider<String> {
RESTRICTED(Names.Restricted), EMBARGOED(Names.Embargoed), OPEN(Names.Open);
private final String value;
public static class Names {
public static final String Restricted = "restricted";
public static final String Embargoed = "embargoed";
public static final String Open = "open";
}
ZenodoAccessRight(String value) {
this.value = value;
}
@Override
@JsonValue
public String getValue() {
return value;
}
private static final Map<String, ZenodoAccessRight> map = EnumUtils.getEnumValueMap(ZenodoAccessRight.class);
public static ZenodoAccessRight of(String i) {
return map.get(i);
}
}

View File

@ -1,11 +1,11 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoComunity {
public class ZenodoCommunity {
private String identifier;

View File

@ -1,4 +1,4 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -1,4 +1,4 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -1,4 +1,4 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -1,8 +1,9 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import eu.eudat.depositinterface.zenodorepository.enums.ZenodoAccessRight;
import java.util.List;
@ -31,7 +32,7 @@ public class ZenodoDepositMetadata {
private List<String> references;
private List<ZenodoComunity> communities;
private List<ZenodoCommunity> communities;
@JsonProperty("access_right")
private ZenodoAccessRight accessRight;
@ -125,11 +126,11 @@ public class ZenodoDepositMetadata {
this.version = version;
}
public List<ZenodoComunity> getCommunities() {
public List<ZenodoCommunity> getCommunities() {
return communities;
}
public void setCommunities(List<ZenodoComunity> communities) {
public void setCommunities(List<ZenodoCommunity> communities) {
this.communities = communities;
}

View File

@ -1,4 +1,4 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -1,4 +1,4 @@
package eu.eudat.depositinterface.zenodorepository.models;
package eu.eudat.depositinterface.zenodorepository.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -0,0 +1,319 @@
package eu.eudat.depositinterface.zenodorepository.model.builder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.depositinterface.enums.DmpAccessType;
import eu.eudat.depositinterface.enums.DmpUserRole;
import eu.eudat.depositinterface.enums.ReferenceType;
import eu.eudat.depositinterface.models.*;
import eu.eudat.depositinterface.models.reference.FieldDepositModel;
import eu.eudat.depositinterface.zenodorepository.configuration.funder.FunderProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.identifier.IdentifierProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.pid.PidProperties;
import eu.eudat.depositinterface.zenodorepository.configuration.zenodo.ZenodoProperties;
import eu.eudat.depositinterface.zenodorepository.enums.ZenodoAccessRight;
import eu.eudat.depositinterface.zenodorepository.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ZenodoBuilder {
private static final String UPLOAD_TYPE = "publication";
private static final String PUBLICATION_TYPE = "datamanagementplan";
private static final String IS_IDENTICAL_TO = "isIdenticalTo";
private static final String CONTRIBUTOR_TYPE_RESEARCHER = "Researcher";
private static final String CONTRIBUTOR_TYPE_PROJECT_MANAGER = "ProjectMember";
private static final String SOURCE_OPENAIRE = "openaire";
private static final String SOURCE_ORCID = "ORCID";
private static final String PID = "pid";
private final PidProperties pidProperties;
private final IdentifierProperties identifierProperties;
private final FunderProperties funderProperties;
@Autowired
public ZenodoBuilder(PidProperties pidProperties, IdentifierProperties identifierProperties, FunderProperties funderProperties){
this.pidProperties = pidProperties;
this.identifierProperties = identifierProperties;
this.funderProperties = funderProperties;
}
public ZenodoDeposit build(DmpDepositModel dmp, ZenodoProperties zenodoConfig) throws JsonProcessingException {
ZenodoDeposit deposit = new ZenodoDeposit();
this.applyZenodoRelator(dmp, deposit);
deposit.getMetadata().setTitle(dmp.getLabel());
deposit.getMetadata().setUploadType(UPLOAD_TYPE);
deposit.getMetadata().setPublicationType(PUBLICATION_TYPE);
deposit.getMetadata().setDescription((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "<p></p>"));
deposit.getMetadata().setVersion(String.valueOf(dmp.getVersion()));
String zenodoCommunity = zenodoConfig.getCommunity();
if(zenodoCommunity != null && !zenodoCommunity.isEmpty()) {
ZenodoCommunity community = new ZenodoCommunity();
community.setIdentifier(zenodoCommunity);
deposit.getMetadata().getCommunities().add(community);
}
this.applyAccessRight(dmp, deposit);
this.applyIsIdenticalTo(dmp, deposit, zenodoConfig);
this.applyLicenses(dmp, deposit);
this.applyResearchers(dmp, deposit);
this.applyGrants(dmp, deposit);
this.applyContributors(dmp, deposit, zenodoConfig);
this.applyCreators(dmp, deposit, zenodoConfig);
return deposit;
}
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<DescriptionFieldDepositModel> fields, List<String> acceptedPidTypes) throws JsonProcessingException{
ObjectMapper objectMapper = new ObjectMapper();
Set<String> values = new HashSet<>();
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:
case AUTO_COMPLETE:
case WORD_LIST:
values.addAll(value);
break;
case SERVICES:
case EXTERNAL_DATASETS:
case DATA_REPOSITORIES:
case PUB_REPOSITORIES:
case JOURNAL_REPOSITORIES:
case TAXONOMIES:
case PUBLICATIONS:
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)) {
values.add(pid);
}
}
break;
case ORGANIZATIONS:
case RESEARCHERS:
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);
}
}
break;
case DATASET_IDENTIFIER:
for (String s : value) {
Map<String, String> valueMap = objectMapper.readValue(s, new TypeReference<Map<String, String>>() {});
values.add(valueMap.get("identifier"));
}
break;
}
}
}
return values;
}
private List<ReferenceDepositModel> getReferenceDepositModelOfType(DmpDepositModel dmp, ReferenceType referenceType){
if (dmp.getReferences() == null) return new ArrayList<>();
return dmp.getReferences().stream().filter(x -> x.getType().equals(referenceType)).toList();
}
private void applyZenodoRelator(DmpDepositModel dmp, ZenodoDeposit deposit) throws JsonProcessingException {
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<String> acceptedPidTypes = this.pidProperties.getAcceptedTypes();
List<ZenodoRelator> relatedIdentifiers = new ArrayList<>();
for(DescriptionDepositModel descriptionDepositModel: dmp.getDescriptions()){
for(String relatedId: this.identifierProperties.getRelated()){
List<DescriptionFieldDepositModel> fields = findSchematicValues(relatedId, descriptionDepositModel.getFields());
Set<String> values = extractSchematicValues(fields, acceptedPidTypes);
for(String value: values){
ZenodoRelator relator = new ZenodoRelator();
relator.setRelation(relatedId.substring(relatedId.lastIndexOf(".") + 1));
relator.setIdentifier(value);
relatedIdentifiers.add(relator);
}
}
}
deposit.getMetadata().setRelatedIdentifiers(relatedIdentifiers);
}
private void applyAccessRight(DmpDepositModel dmp, ZenodoDeposit deposit){
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
if (dmp.getAccessType() == null) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
} else {
if (dmp.getAccessType().equals(DmpAccessType.Public)) {
Instant publicationDate = dmp.getFinalizedAt();
if (publicationDate == null) publicationDate = Instant.now().minusSeconds(1);
if (publicationDate.isBefore(Instant.now())) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.OPEN);
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.EMBARGOED);
deposit.getMetadata().setEmbargoDate(publicationDate.toString());
}
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
}
}
}
private void applyIsIdenticalTo(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
if (dmp.getAccessType().equals(DmpAccessType.Public)) {
ZenodoRelator relator = new ZenodoRelator();
relator.setIdentifier(zenodoConfig.getDomain() + "/external/zenodo/" + dmp.getId().toString());
relator.setRelation(IS_IDENTICAL_TO);
if (deposit.getMetadata().getRelatedIdentifiers() == null)deposit.getMetadata().setRelatedIdentifiers(new ArrayList<>());
deposit.getMetadata().getRelatedIdentifiers().add(relator);
}
}
private void applyLicenses(DmpDepositModel dmp, ZenodoDeposit deposit){
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<ReferenceDepositModel> dmpLicenses = this.getReferenceDepositModelOfType(dmp, ReferenceType.Licenses);
if (dmpLicenses != null && !dmpLicenses.isEmpty()) {
for (ReferenceDepositModel dmpLicense : dmpLicenses) {
String pid = dmpLicense.getDefinition().getFields().stream().filter(x-> PID.equalsIgnoreCase(x.getCode())).map(FieldDepositModel::getValue).findFirst().orElse(null);
if (pid != null && !pid.isBlank()) {
deposit.getMetadata().setLicense(pid);
break;
}
}
}
}
private void applyResearchers(DmpDepositModel dmp, ZenodoDeposit deposit){
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<ZenodoContributor> researchers = new ArrayList<>();
List<ReferenceDepositModel> dmpResearchers = this.getReferenceDepositModelOfType(dmp, ReferenceType.Researcher);
if (dmpResearchers != null && !dmpResearchers.isEmpty()) {
for (ReferenceDepositModel researcher : dmpResearchers) {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(researcher.getLabel());
contributor.setType(CONTRIBUTOR_TYPE_RESEARCHER);
contributor.setAffiliation(researcher.getSource());
if (researcher.getSource().equalsIgnoreCase(SOURCE_ORCID)) {
contributor.setOrcid(researcher.getReference());
}
researchers.add(contributor);
}
}
if (deposit.getMetadata().getContributors() == null)deposit.getMetadata().setContributors(new ArrayList<>());
deposit.getMetadata().getContributors().addAll(researchers);
}
private void applyGrants(DmpDepositModel dmp, ZenodoDeposit deposit){
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<ReferenceDepositModel> dmpGrants = this.getReferenceDepositModelOfType(dmp, ReferenceType.Grants);
List<ReferenceDepositModel> dmpFunders = this.getReferenceDepositModelOfType(dmp, ReferenceType.Funder);
if (dmpGrants != null && !dmpGrants.isEmpty()) {
ReferenceDepositModel depositGrant = dmpGrants.stream().filter(x-> x.getSource().equals(SOURCE_OPENAIRE)).findFirst().orElse(null);
if (depositGrant != null) {
String grantReferenceTail = depositGrant.getReference().split(":")[2];
List<FunderProperties.DoiFunder> doiFunders = this.funderProperties.getAvailable();
if (dmpFunders != null && !dmpFunders.isEmpty()) {
ReferenceDepositModel depositFunder = dmpFunders.get(0);
FunderProperties.DoiFunder doiFunder = doiFunders.stream()
.filter(doiFunder1 -> depositFunder.getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(depositFunder.getLabel()))
.findFirst().orElse(null);
if (doiFunder != null) {
String finalId = doiFunder.getDoi() + "::" + grantReferenceTail;
ZenodoGrant grant = new ZenodoGrant();
grant.setId(finalId);
if (deposit.getMetadata().getGrants() == null)deposit.getMetadata().setGrants(new ArrayList<>());
deposit.getMetadata().getGrants().add(grant);
}
}
}
}
}
private void applyContributors(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){
if (dmp.getUsers() == null) return;
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<ReferenceDepositModel> dmpOrganizations = this.getReferenceDepositModelOfType(dmp, ReferenceType.Organizations);
String zenodoAffiliation = zenodoConfig.getAffiliation();
List<ZenodoContributor> contributors = new ArrayList<>();
for (DmpUserDepositModel userDMP: dmp.getUsers()) {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(userDMP.getUser().getName());
contributor.setType(CONTRIBUTOR_TYPE_PROJECT_MANAGER);
if (dmpOrganizations != null && !dmpOrganizations.isEmpty()) {
contributor.setAffiliation(dmpOrganizations.stream().map(ReferenceDepositModel::getLabel).collect(Collectors.joining(", ")));
} else {
if(zenodoAffiliation != null && !zenodoAffiliation.isEmpty()) {
contributor.setAffiliation(zenodoAffiliation);
}
}
contributors.add(contributor);
}
if (deposit.getMetadata().getContributors() == null)deposit.getMetadata().setContributors(new ArrayList<>());
deposit.getMetadata().getContributors().addAll(contributors);
}
private void applyCreators(DmpDepositModel dmp, ZenodoDeposit deposit, ZenodoProperties zenodoConfig){
if (dmp.getUsers() == null) return;
if (deposit.getMetadata() == null) deposit.setMetadata(new ZenodoDepositMetadata());
List<ReferenceDepositModel> dmpOrganizations = this.getReferenceDepositModelOfType(dmp, ReferenceType.Organizations);
String zenodoAffiliation = zenodoConfig.getAffiliation();
ZenodoCreator creator = new ZenodoCreator();
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());
if (dmpOrganizations != null && !dmpOrganizations.isEmpty()) {
creator.setAffiliation(dmpOrganizations.stream().map(ReferenceDepositModel::getLabel).collect(Collectors.joining(", ")));
} else {
if(zenodoAffiliation != null && !zenodoAffiliation.isEmpty()) {
creator.setAffiliation(zenodoAffiliation);
}
}
if (deposit.getMetadata().getCreators() == null)deposit.getMetadata().setCreators(new ArrayList<>());
deposit.getMetadata().getCreators().add(creator);
}
}

View File

@ -0,0 +1,14 @@
package eu.eudat.depositinterface.zenodorepository.service;
import eu.eudat.depositinterface.models.DmpDepositModel;
import eu.eudat.depositinterface.repository.DepositConfiguration;
public interface ZenodoDepositService {
String deposit(DmpDepositModel dmpDepositModel, String zenodoToken) throws Exception;
DepositConfiguration getConfiguration();
String authenticate(String code);
String getLogo();
}

View File

@ -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).headers(httpHeaders -> httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM))
.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).headers(httpHeaders -> httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM)).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;
}
}
}

114
pom.xml
View File

@ -5,114 +5,22 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<version>3.1.0</version>
<relativePath/>
</parent>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repositorydepositzenodo</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<artifactId>repository-deposit-parent</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>OpenDMP Repository Deposit Zenodo</name>
<description>OpenDMP Repository Deposit Zenodo</description>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo</url>
<licenses>
<license>
<name>MIT License</name>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo/src/branch/master/LICENSE.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>CITE S.A.</name>
<email>maven-central@cite.gr</email>
<organization>CITE S.A.</organization>
<organizationUrl>https://www.cite.gr</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:git://code-repo.d4science.org</connection>
<developerConnection>scm:git:ssh://code-repo.d4science.org</developerConnection>
<url>https://code-repo.d4science.org/MaDgiK-CITE/repository-deposit-zenodo</url>
</scm>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>core</module>
<module>web</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repositorydepositbase</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>eu.eudat.EuDatApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.json</pattern>
<shadedPattern>zenodorepository.shaded.org.json</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,13 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.config;
import java.io.InputStream;
import java.util.List;
public interface ConfigLoader {
InputStream getStreamFromPath(String filePath);
List<String> getRelatedIdentifiers();
List<String> getAcceptedPidTypes();
PidFieldNames getPidFieldNames();
byte[] getLogo(String repositoryId);
List<ZenodoConfig> getZenodoConfig();
}

View File

@ -1,110 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.config;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service("zenodoConfigLoader")
public class ConfigLoaderImpl implements ConfigLoader{
private static final Logger logger = LoggerFactory.getLogger(ConfigLoaderImpl.class);
private static final ObjectMapper mapper = new ObjectMapper();
private List<String> relatedIdentifiers = new ArrayList<>();
private List<String> acceptedPidTypes = new ArrayList<>();
private PidFieldNames pidFieldNames = new PidFieldNames();
private List<ZenodoConfig> zenodoConfig = new ArrayList<>();
private final Environment environment;
@Autowired
public ConfigLoaderImpl(Environment environment){
this.environment = environment;
}
@Override
public List<String> getRelatedIdentifiers() {
if (relatedIdentifiers == null || relatedIdentifiers.isEmpty()) {
BufferedReader ids = new BufferedReader(new InputStreamReader(getStreamFromPath("relatedIdentifiers.txt")));
relatedIdentifiers = ids.lines().collect(Collectors.toList());
}
return relatedIdentifiers;
}
@Override
public List<String> getAcceptedPidTypes() {
if (acceptedPidTypes == null || acceptedPidTypes.isEmpty()) {
BufferedReader ids = new BufferedReader(new InputStreamReader(getStreamFromPath("acceptedPidTypes.txt")));
acceptedPidTypes = ids.lines().collect(Collectors.toList());
}
return acceptedPidTypes;
}
@Override
public PidFieldNames getPidFieldNames() {
try {
pidFieldNames = mapper.readValue(getStreamFromPath("datasetFieldsPid.json"), PidFieldNames.class);
}
catch (IOException e){
logger.error(e.getLocalizedMessage(), e);
}
return pidFieldNames;
}
@Override
public List<ZenodoConfig> getZenodoConfig() {
if (zenodoConfig == null || zenodoConfig.isEmpty()) {
try {
zenodoConfig = mapper.readValue(getStreamFromPath(environment.getProperty("zenodo_plugin.configuration.zenodo")), new TypeReference<List<ZenodoConfig>>() {});
} catch (IOException e) {
logger.error(e.getLocalizedMessage(), e);
return null;
}
}
return zenodoConfig;
}
@Override
public byte[] getLogo(String repositoryId) {
if (!zenodoConfig.isEmpty()) {
ZenodoConfig zenodoConfig = getZenodoConfig().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
if (zenodoConfig != null) {
String logo = zenodoConfig.getLogo();
InputStream logoStream;
if (logo != null && !logo.isEmpty()) {
logoStream = getStreamFromPath(logo);
}
else {
logoStream = getClass().getClassLoader().getResourceAsStream("zenodo.jpg");
}
try {
return (logoStream != null) ? logoStream.readAllBytes() : null;
}
catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return null;
}
return null;
}
@Override
public InputStream getStreamFromPath(String filePath) {
try {
return new FileInputStream(filePath);
} catch (FileNotFoundException e) {
logger.info("loading from classpath");
return getClass().getClassLoader().getResourceAsStream(filePath);
}
}
}

View File

@ -1,27 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.config;
import com.fasterxml.jackson.annotation.JsonProperty;
public class DOIFunder {
@JsonProperty("Funder")
private String funder;
@JsonProperty("DOI")
private String DOI;
public String getFunder() {
return funder;
}
public void setFunder(String funder) {
this.funder = funder;
}
public String getDOI() {
return DOI;
}
public void setDOI(String DOI) {
this.DOI = DOI;
}
}

View File

@ -1,31 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.config;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PidFieldNames {
@JsonProperty("pidName")
private String pidName;
@JsonProperty("pidTypeName")
private String pidTypeName;
public PidFieldNames() {}
public PidFieldNames(String pidName, String pidTypeName) {
this.pidName = pidName;
this.pidTypeName = pidTypeName;
}
public String getPidName() {
return pidName;
}
public void setPidName(String pidName) {
this.pidName = pidName;
}
public String getPidTypeName() {
return pidTypeName;
}
public void setPidTypeName(String pidTypeName) {
this.pidTypeName = pidTypeName;
}
}

View File

@ -1,195 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.config;
import com.fasterxml.jackson.annotation.JsonProperty;
import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration;
public class ZenodoConfig {
private enum DepositType {
SystemDeposit(0), UserDeposit(1), BothWaysDeposit(2);
private final int value;
DepositType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static DepositType fromInteger(int value) {
switch (value) {
case 0:
return SystemDeposit;
case 1:
return UserDeposit;
case 2:
return BothWaysDeposit;
default:
throw new RuntimeException("Unsupported Deposit Type");
}
}
}
@JsonProperty("depositType")
private int depositType;
@JsonProperty("repositoryId")
private String repositoryId;
@JsonProperty("accessToken")
private String accessToken;
@JsonProperty("repositoryUrl")
private String repositoryUrl;
@JsonProperty("repositoryAuthorizationUrl")
private String repositoryAuthorizationUrl;
@JsonProperty("repositoryRecordUrl")
private String repositoryRecordUrl;
@JsonProperty("repositoryAccessTokenUrl")
private String repositoryAccessTokenUrl;
@JsonProperty("repositoryClientId")
private String repositoryClientId;
@JsonProperty("repositoryClientSecret")
private String repositoryClientSecret;
@JsonProperty("redirectUri")
private String redirectUri;
@JsonProperty("hasLogo")
private boolean hasLogo;
@JsonProperty("logo")
private String logo;
@JsonProperty("doiFunder")
private String doiFunder;
@JsonProperty("community")
private String community;
@JsonProperty("affiliation")
private String affiliation;
@JsonProperty("domain")
private String domain;
public int getDepositType() {
return depositType;
}
public void setDepositType(int depositType) {
this.depositType = depositType;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRepositoryUrl() {
return repositoryUrl;
}
public void setRepositoryUrl(String repositoryUrl) {
this.repositoryUrl = repositoryUrl;
}
public String getRepositoryAuthorizationUrl() {
return repositoryAuthorizationUrl;
}
public void setRepositoryAuthorizationUrl(String repositoryAuthorizationUrl) {
this.repositoryAuthorizationUrl = repositoryAuthorizationUrl;
}
public String getRepositoryRecordUrl() {
return repositoryRecordUrl;
}
public void setRepositoryRecordUrl(String repositoryRecordUrl) {
this.repositoryRecordUrl = repositoryRecordUrl;
}
public String getRepositoryAccessTokenUrl() {
return repositoryAccessTokenUrl;
}
public void setRepositoryAccessTokenUrl(String repositoryAccessTokenUrl) {
this.repositoryAccessTokenUrl = repositoryAccessTokenUrl;
}
public String getRepositoryClientId() {
return repositoryClientId;
}
public void setRepositoryClientId(String repositoryClientId) {
this.repositoryClientId = repositoryClientId;
}
public String getRepositoryClientSecret() {
return repositoryClientSecret;
}
public void setRepositoryClientSecret(String repositoryClientSecret) {
this.repositoryClientSecret = repositoryClientSecret;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public boolean isHasLogo() {
return hasLogo;
}
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;
}
}

View File

@ -1,286 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.interfaces;
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.config.ConfigLoader;
import eu.eudat.depositinterface.zenodorepository.config.ZenodoConfig;
import eu.eudat.depositinterface.zenodorepository.mapper.DMPToZenodoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class ZenodoDeposit implements RepositoryDeposit {
private static final Logger logger = LoggerFactory.getLogger(ZenodoDeposit.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
private final ConfigLoader configLoader;
private final Environment environment;
@Autowired
public ZenodoDeposit(ConfigLoader configLoader, Environment environment){
this.configLoader = configLoader;
this.environment = environment;
}
@Override
public String deposit(String repositoryId, DMPDepositModel dmpDepositModel, String zenodoToken) throws Exception {
RepositoryDepositConfiguration conf = this.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
if(conf != null) {
if (zenodoToken == null) {
zenodoToken = conf.getAccessToken();
}
String zenodoUrl = conf.getRepositoryUrl();
// First step, post call to Zenodo, to create the entry.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
ZenodoConfig zenodoConfig = this.configLoader.getZenodoConfig().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
eu.eudat.depositinterface.zenodorepository.models.ZenodoDeposit deposit = DMPToZenodoMapper.fromDMP(dmpDepositModel, zenodoConfig);
HttpEntity<eu.eudat.depositinterface.zenodorepository.models.ZenodoDeposit> request = new HttpEntity<>(deposit, headers);
Map createResponse;
LinkedHashMap<String, String> links;
String previousDOI = dmpDepositModel.getPreviousDOI();
String unpublishedUrl = null;
String publishUrl;
String finalDoi;
try {
if (previousDOI == null) {
String createUrl = zenodoUrl + "deposit/depositions" + "?access_token=" + zenodoToken;
createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody();
links = (LinkedHashMap<String, String>) createResponse.get("links");
} 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
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
logger.debug("listUrl = " + listUrl);
ResponseEntity<Map[]> listResponses = restTemplate.getForEntity(listUrl, Map[].class);
createResponse = listResponses.getBody()[0];
logger.debug("createResponse-previousDoi:");
logger.debug(objectMapper.writeValueAsString(createResponse));
links = (LinkedHashMap<String, String>) createResponse.get("links");
//Second, make the new version (not in the links?)
String newVersionUrl = links.get("self") + "/actions/newversion" + "?access_token=" + zenodoToken;
logger.debug("new version url: " + newVersionUrl);
createResponse = restTemplate.postForObject(newVersionUrl, null, Map.class);
logger.debug("createResponse-newVersion:");
logger.debug(objectMapper.writeValueAsString(createResponse));
links = (LinkedHashMap<String, String>) createResponse.get("links");
//Third, get the new deposit
String latestDraftUrl = links.get("latest_draft") + "?access_token=" + zenodoToken;
createResponse = restTemplate.getForObject(latestDraftUrl, Map.class);
logger.debug("createResponse-latestDraft:");
logger.debug(objectMapper.writeValueAsString(createResponse));
links = (LinkedHashMap<String, String>) createResponse.get("links");
//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("self") + "?access_token=" + zenodoToken;
restTemplate.put(updateUrl, request);
//And finally remove pre-existing files from it
String fileListUrl = links.get("self") + "/files" + "?access_token=" + zenodoToken;
ResponseEntity<Map[]> fileListResponse = restTemplate.getForEntity(fileListUrl, Map[].class);
for (Map file : fileListResponse.getBody()) {
String fileDeleteUrl = links.get("self") + "/files/" + file.get("id") + "?access_token=" + zenodoToken;
restTemplate.delete(fileDeleteUrl);
}
} 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);
throw e;
}
} else {
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
ResponseEntity<Map[]> listResponses = restTemplate.getForEntity(listUrl, Map[].class);
createResponse = listResponses.getBody()[0];
links = (LinkedHashMap<String, String>) createResponse.get("links");
}
}
if (unpublishedUrl == null) {
// Second step, add the file to the entry.
FileEnvelope pdfEnvelope = dmpDepositModel.getPdfFile();
FileSystemResource fileSystemResource = new FileSystemResource(pdfEnvelope.getFile());
HttpEntity<FileSystemResource> addFileMapRequest = new HttpEntity<>(fileSystemResource, null);
String addFileUrl = links.get("bucket") + "/" + pdfEnvelope.getFilename() + "?access_token=" + zenodoToken;
restTemplate.put(addFileUrl, addFileMapRequest);
FileEnvelope rdaJsonEnvelope = dmpDepositModel.getRdaJsonFile();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentLength(rdaJsonEnvelope.getFile().length());
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
responseHeaders.set("Content-Disposition", "attachment;filename=" + rdaJsonEnvelope.getFilename());
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
byte[] content = Files.readAllBytes(rdaJsonEnvelope.getFile().toPath());
ResponseEntity<byte[]> jsonFile = new ResponseEntity<>(content, responseHeaders, HttpStatus.OK);
UUID jsonFileUUID = UUID.randomUUID();
File tempJsonFile = new File(this.environment.getProperty("zenodo_plugin.storage.temp") + jsonFileUUID + ".json");
try (FileOutputStream jsonFos = new FileOutputStream(tempJsonFile)) {
jsonFos.write(jsonFile.getBody());
jsonFos.flush();
}
fileSystemResource = new FileSystemResource(tempJsonFile);
HttpHeaders jsonHeaders = new HttpHeaders();
jsonHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
addFileMapRequest = new HttpEntity<>(fileSystemResource, jsonHeaders);
String jsonFileName = jsonFile.getHeaders().get("Content-Disposition").get(0).substring(jsonFile.getHeaders().get("Content-Disposition").get(0).lastIndexOf('=') + 1);
addFileUrl = links.get("bucket") + "/" + jsonFileName + "?access_token=" + zenodoToken;
restTemplate.put(addFileUrl, addFileMapRequest);
Files.deleteIfExists(tempJsonFile.toPath());
if (dmpDepositModel.getSupportingFilesZip() != null) {
File supportinFilesZip = dmpDepositModel.getSupportingFilesZip();
String supportinFilesZipName = dmpDepositModel.getSupportingFilesZip().getName();
fileSystemResource = new FileSystemResource(supportinFilesZip);
addFileMapRequest = new HttpEntity<>(fileSystemResource, null);
addFileUrl = links.get("bucket") + "/" + supportinFilesZipName + "?access_token=" + zenodoToken;
restTemplate.put(addFileUrl, addFileMapRequest);
}
// Third post call to Zenodo to publish the entry and return the DOI.
publishUrl = links.get("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(), HashMap.class);
throw new IOException(parsedException.get("message"), ex);
}
}
return null;
}
private String publish(String publishUrl){
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> publishResponce = restTemplate.postForObject(publishUrl, "", Map.class);
return (String) publishResponce.get("conceptdoi");
}
@Override
public List<RepositoryDepositConfiguration> getConfiguration() {
List<ZenodoConfig> zenodoConfigs = this.configLoader.getZenodoConfig();
return (zenodoConfigs != null) ? zenodoConfigs.stream().map(ZenodoConfig::toRepoConfig).collect(Collectors.toList()) : null;
}
@Override
public String authenticate(String repositoryId, String code){
RepositoryDepositConfiguration conf = this.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
if(conf != null) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", conf.getRepositoryClientId());
map.add("client_secret", conf.getRepositoryClientSecret());
map.add("grant_type", "authorization_code");
map.add("code", code);
map.add("redirect_uri", conf.getRedirectUri());
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
try {
Map<String, Object> values = restTemplate.postForObject(conf.getRepositoryAccessTokenUrl(), request, Map.class);
//ZenodoResponseToken zenodoResponseToken = new ZenodoResponseToken();
Map<String, Object> user = (Map<String, Object>) values.get("user");
// zenodoResponseToken.setUserId((String) user.get("id"));
// zenodoResponseToken.setEmail((String) user.get("email"));
// zenodoResponseToken.setExpiresIn((Integer) values.get("expires_in"));
// zenodoResponseToken.setAccessToken((String) values.get("access_token"));
// zenodoResponseToken.setRefreshToken((String) values.get("refresh_token"));
//return zenodoResponseToken;
return (String) values.get("access_token");
} catch (HttpClientErrorException ex) {
logger.error(ex.getResponseBodyAsString(), ex);
}
return null;
}
return null;
}
@Override
public String getLogo(String repositoryId) {
RepositoryDepositConfiguration conf = this.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst().orElse(null);
if(conf != null) {
if(conf.isHasLogo()){
byte[] logo = this.configLoader.getLogo(repositoryId);
return (logo != null && logo.length != 0) ? Base64.getEncoder().encodeToString(logo) : null;
}
}
return null;
}
private String getUnpublishedDOI(String zenodoUrl, String DOI, String token, Integer version) {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
Map createResponse = null;
LinkedHashMap<String, String> links = null;
LinkedHashMap<String, String> metadata = null;
String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + DOI + "\"&access_token=" + token;
ResponseEntity<Map[]> listResponses = restTemplate.getForEntity(listUrl, Map[].class);
createResponse = listResponses.getBody()[0];
metadata = (LinkedHashMap<String, String>) createResponse.get("metadata");
links = (LinkedHashMap<String, String>) createResponse.get("links");
if (metadata.get("version").equals(version.toString())) {
return links.get("publish");
} else {
return null;
}
}catch (Exception e) {
logger.warn(e.getMessage(), e);
return null;
}
}
}

View File

@ -1,279 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.depositinterface.enums.FieldType;
import eu.eudat.depositinterface.models.*;
import eu.eudat.depositinterface.zenodorepository.config.ConfigLoader;
import eu.eudat.depositinterface.zenodorepository.config.DOIFunder;
import eu.eudat.depositinterface.zenodorepository.config.PidFieldNames;
import eu.eudat.depositinterface.zenodorepository.config.ZenodoConfig;
import eu.eudat.depositinterface.zenodorepository.models.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class DMPToZenodoMapper {
private static final Logger logger = LoggerFactory.getLogger(DMPToZenodoMapper.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
private static ConfigLoader configLoader;
private static PidFieldNames pidFieldNames;
@Autowired
public DMPToZenodoMapper(ConfigLoader configL){
configLoader = configL;
pidFieldNames = configLoader.getPidFieldNames();
}
private static List<DatasetFieldsDepositModel> findSchemanticValues(String relatedId, List<DatasetFieldsDepositModel> fields){
return fields.stream().filter(f -> f.getSchematics().contains(relatedId)).collect(Collectors.toList());
}
private static Set<String> extractSchemanticValues(List<DatasetFieldsDepositModel> fields, List<String> acceptedPidTypes) throws JsonProcessingException{
Set<String> values = new HashSet<>();
for(DatasetFieldsDepositModel field: fields){
String value = (String) field.getValue();
if(value != null && !value.isEmpty()) {
switch (FieldType.fromName(field.getRenderStyleType())) {
case FREE_TEXT:
case TEXT_AREA:
case RICH_TEXT_AREA:
case RADIO_BOX:
case DATE_PICKER:
values.add(value);
break;
case COMBO_BOX:
if (field.isMultiple()) {
List<String> selected = objectMapper.readValue(value, new TypeReference<List<String>>() {});
values.addAll(selected);
}
else {
values.add(value);
}
break;
case REGISTRIES:
case SERVICES:
case EXTERNAL_DATASETS:
case DATA_REPOSITORIES:
case PUB_REPOSITORIES:
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(pidFieldNames.getPidName());
String pidType = valueMap.get(pidFieldNames.getPidTypeName());
if (acceptedPidTypes.contains(pidType)) {
values.add(pid);
}
}
}
else {
Map<String, String> valueMap = objectMapper.readValue(value, new TypeReference<Map<String, String>>() {});
String pid = valueMap.get(pidFieldNames.getPidName());
String pidType = valueMap.get(pidFieldNames.getPidTypeName());
if (acceptedPidTypes.contains(pidType)) {
values.add(pid);
}
}
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>>() {});
String pid = valueMap.get("reference");
if(pid != null) {
values.add(pid);
}
}
break;
case DATASET_IDENTIFIER:
Map<String, String> valueMap = objectMapper.readValue(value, new TypeReference<Map<String, String>>() {});
values.add(valueMap.get("identifier"));
break;
}
}
}
return values;
}
public static ZenodoDeposit fromDMP(DMPDepositModel dmp, ZenodoConfig zenodoConfig) throws JsonProcessingException {
Map<String, Object> extraProperties = dmp.getExtraProperties() != null ? new org.json.JSONObject(dmp.getExtraProperties()).toMap() : new HashMap<>();
ZenodoDeposit deposit = new ZenodoDeposit();
Map<String, Object> schematicsMap = new HashMap<>();
List<ZenodoRelator> relatedIdentifiers = new ArrayList<>();
List<ZenodoComunity> communities = new ArrayList<>();
List<ZenodoContributor> contributors = new ArrayList<>();
List<ZenodoCreator> creators = new ArrayList<>();
List<ZenodoGrant> grants = new ArrayList<>();
List<String> keywords = new ArrayList<>();
List<String> references = new ArrayList<>();
List<String> acceptedPidTypes = configLoader.getAcceptedPidTypes();
for(DatasetDepositModel dataset: dmp.getDatasets()){
for(String relatedId: configLoader.getRelatedIdentifiers()){
List<DatasetFieldsDepositModel> fields = findSchemanticValues(relatedId, dataset.getFields());
Set<String> values = extractSchemanticValues(fields, acceptedPidTypes);
for(String value: values){
ZenodoRelator relator = new ZenodoRelator();
relator.setRelation(relatedId.substring(relatedId.lastIndexOf(".") + 1));
relator.setIdentifier(value);
relatedIdentifiers.add(relator);
}
}
}
schematicsMap.put("related_identifiers", relatedIdentifiers);
schematicsMap.put("communities", communities);
schematicsMap.put("contributors", contributors);
schematicsMap.put("creators", creators);
schematicsMap.put("grants", grants);
schematicsMap.put("keywords", keywords);
schematicsMap.put("references", references);
String schematicsString = objectMapper.writeValueAsString(schematicsMap);
objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
ZenodoDepositMetadata metadata = objectMapper.readValue(schematicsString, new TypeReference<ZenodoDepositMetadata>(){});
deposit.setMetadata(metadata);
deposit.getMetadata().setTitle(dmp.getLabel());
deposit.getMetadata().setUploadType("publication");
deposit.getMetadata().setPublicationType("datamanagementplan");
deposit.getMetadata().setDescription((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "<p></p>"));
deposit.getMetadata().setVersion(String.valueOf(dmp.getVersion()));
String zenodoCommunity = zenodoConfig.getCommunity();
if(zenodoCommunity != null && !zenodoCommunity.isEmpty()) {
ZenodoComunity community = new ZenodoComunity();
community.setIdentifier(zenodoCommunity);
deposit.getMetadata().getCommunities().add(community);
}
if (extraProperties.get("visible") == null) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
} else {
if (((Boolean) extraProperties.get("visible"))) {
Instant publicationDate = Instant.parse(extraProperties.get("publicDate").toString());
if (publicationDate.isBefore(Instant.now())) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.OPEN);
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.EMBARGOED);
deposit.getMetadata().setEmbargoDate(publicationDate.toString());
}
if (extraProperties.get("license") != null) {
deposit.getMetadata().setLicense(((Map<?, ?>) extraProperties.get("license")).get("pid").toString());
}
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
}
}
if (dmp.isPublic()) {
ZenodoRelator relator = new ZenodoRelator();
relator.setIdentifier(zenodoConfig.getDomain() + "/external/zenodo/" + dmp.getId().toString());
relator.setRelation("isIdenticalTo");
deposit.getMetadata().getRelatedIdentifiers().add(relator);
}
String zenodoAffiliation = zenodoConfig.getAffiliation();
List<ZenodoContributor> contributors1 = dmp.getUsers().stream().map(userDMP -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(userDMP.getUser().getName());
contributor.setType("ProjectMember");
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
contributor.setAffiliation(dmp.getOrganisations()
.stream().map(OrganisationDepositModel::getLabel).collect(Collectors.joining(", ")));
} else {
if(zenodoAffiliation != null && !zenodoAffiliation.isEmpty()) {
contributor.setAffiliation(zenodoAffiliation);
}
}
return contributor;
}).collect(Collectors.toList());
List<ZenodoContributor> researchers = dmp.getResearchers().stream().map(researcher -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(researcher.getLabel());
contributor.setType("Researcher");
String referenceHead = researcher.getReference().split(":")[0];
String referenceTail = researcher.getReference().replace(referenceHead + ":", "");
contributor.setAffiliation(referenceHead);
if (referenceHead.equalsIgnoreCase("ORCID")) {
contributor.setOrcid(referenceTail);
}
return contributor;
}).collect(Collectors.toList());
deposit.getMetadata().getContributors().addAll(contributors1);
deposit.getMetadata().getContributors().addAll(researchers);
if (dmp.getGrant() != null) {
if (dmp.getGrant().getReference() == null) {
dmp.getGrant().setReference("dmp:" + dmp.getGrant().getId());
}
String grantReferenceHead = dmp.getGrant().getReference().split(":")[0];
if (grantReferenceHead.equals("openaire")) {
String grantReferenceTail = dmp.getGrant().getReference().split(":")[3];
List<DOIFunder> doiFunders = new ArrayList<>();
try {
List<Map<String, Object>> tempdoiFunders = objectMapper.readValue(configLoader.getStreamFromPath(zenodoConfig.getDoiFunder()), List.class);
doiFunders = tempdoiFunders.stream().map(map -> objectMapper.convertValue(map, DOIFunder.class)).collect(Collectors.toList());
} catch (IOException e) {
logger.error(e.getLocalizedMessage(), e);
}
if (dmp.getGrant().getFunder() != null && dmp.getGrant().getFunder().getLabel() != null) {
DOIFunder doiFunder = doiFunders.stream()
.filter(doiFunder1 -> dmp.getGrant().getFunder().getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(dmp.getGrant().getFunder().getLabel()))
.findFirst().orElse(null);
if (doiFunder != null) {
String finalId = doiFunder.getDOI() + "::" + grantReferenceTail;
ZenodoGrant grant = new ZenodoGrant();
grant.setId(finalId);
deposit.getMetadata().getGrants().add(grant);
}
}
}
}
ZenodoCreator creator = new ZenodoCreator();
creator.setName(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMPDepositModel.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName());
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
creator.setAffiliation(dmp.getOrganisations()
.stream().map(OrganisationDepositModel::getLabel).collect(Collectors.joining(", ")));
} else {
if(zenodoAffiliation != null && !zenodoAffiliation.isEmpty()) {
creator.setAffiliation(zenodoAffiliation);
}
}
deposit.getMetadata().getCreators().add(creator);
return deposit;
}
}

View File

@ -1,18 +0,0 @@
package eu.eudat.depositinterface.zenodorepository.models;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ZenodoAccessRight {
RESTRICTED("restricted"), EMBARGOED("embargoed"), OPEN("open");
private final String value;
ZenodoAccessRight(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@ -1,70 +0,0 @@
[
{
"Funder": "Australian Research Council",
"DOI": "10.13039/501100000923"
},
{
"Funder": "Austrian Science Fund",
"DOI": "10.13039/501100002428"
},
{
"Funder": "European Commission",
"DOI": "10.13039/501100000780"
},
{
"Funder": "European Environment Agency",
"DOI": "10.13039/501100000806"
},
{
"Funder": "Academy of Finland",
"DOI": "10.13039/501100002341"
},
{
"Funder": "Hrvatska Zaklada za Znanost",
"DOI": "10.13039/501100004488"
},
{
"Funder": "Fundação para a Ciência e a Tecnologia",
"DOI": "10.13039/501100001871"
},
{
"Funder": "Ministarstvo Prosvete, Nauke i Tehnološkog Razvoja",
"DOI": "10.13039/501100004564"
},
{
"Funder": "Ministarstvo Znanosti, Obrazovanja i Sporta",
"DOI": "10.13039/501100006588"
},
{
"Funder": "National Health and Medical Research Council",
"DOI": "10.13039/501100000925"
},
{
"Funder": "National Institutes of Health",
"DOI": "10.13039/100000002"
},
{
"Funder": "National Science Foundation",
"DOI": "10.13039/100000001"
},
{
"Funder": "Nederlandse Organisatie voor Wetenschappelijk Onderzoek",
"DOI": "10.13039/501100003246"
},
{
"Funder": "Research Councils",
"DOI": "10.13039/501100000690"
},
{
"Funder": "Schweizerischer Nationalfonds zur Förderung der wissenschaftlichen Forschung",
"DOI": "10.13039/501100001711"
},
{
"Funder": "Science Foundation Ireland",
"DOI": "10.13039/501100001602"
},
{
"Funder": "Wellcome Trust",
"DOI": "10.13039/100004440"
}
]

View File

@ -1,43 +0,0 @@
actrn
ark
bibcode
nct
drks
doi
euctr
data.europa.eu
epo_id
GRID
gsk
GeoPass
GBIF
hal
handle
isrctn
ichushi
ISNI
jprn
mag_id
NAID
NCID
oai
orcid_pending
orcid
OrgPeg
PANGAEA
PIC
epo_nr_epodoc
pdb
pmc
pmid
RNSR
ROR
RRID
UNKNOWN
VIAF
who
arXiv
info:eu-repo/dai
orcidworkid
urn
w3id

View File

@ -1,2 +0,0 @@
zenodo_plugin.storage.temp=${STORAGE_TMP_ZENODO}
zenodo_plugin.configuration.zenodo=${CONFIGURATION_ZENODO}

View File

@ -1,4 +0,0 @@
{
"pidName": "pid",
"pidTypeName": "pidTypeField"
}

View File

@ -1,32 +0,0 @@
zenodo.related_identifiers.isCitedBy
zenodo.related_identifiers.cites
zenodo.related_identifiers.isSupplementTo
zenodo.related_identifiers.isSupplementedBy
zenodo.related_identifiers.isContinuedBy
zenodo.related_identifiers.continues
zenodo.related_identifiers.isDescribedBy
zenodo.related_identifiers.describes
zenodo.related_identifiers.hasMetadata
zenodo.related_identifiers.isMetadataFor
zenodo.related_identifiers.isNewVersionOf
zenodo.related_identifiers.isPreviousVersionOf
zenodo.related_identifiers.isPartOf
zenodo.related_identifiers.hasPart
zenodo.related_identifiers.isReferencedBy
zenodo.related_identifiers.references
zenodo.related_identifiers.isDocumentedBy
zenodo.related_identifiers.documents
zenodo.related_identifiers.isCompiledBy
zenodo.related_identifiers.compiles
zenodo.related_identifiers.isVariantFormOf
zenodo.related_identifiers.isOriginalFormof
zenodo.related_identifiers.isIdenticalTo
zenodo.related_identifiers.isAlternateIdentifier
zenodo.related_identifiers.isReviewedBy
zenodo.related_identifiers.reviews
zenodo.related_identifiers.isDerivedFrom
zenodo.related_identifiers.isSourceOf
zenodo.related_identifiers.requires
zenodo.related_identifiers.isRequiredBy
zenodo.related_identifiers.isObsoletedBy
zenodo.related_identifiers.obsoletes

56
web/pom.xml Normal file
View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repository-deposit-parent</artifactId>
<version>${revision}</version>
<relativePath>..</relativePath>
</parent>
<artifactId>repository-deposit-web</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<dependencies>
<dependency>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repositorydepositzenodo</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>oidc-authn</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>cache</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.4</version>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,17 @@
package eu.eudat.deposit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {
"eu.eudat.deposit.*",
"eu.eudat.depositinterface.*",
"gr.cite.tools",
"gr.cite.commons"
})
public class DepositApplication {
public static void main(String[] args) {
SpringApplication.run(DepositApplication.class, args);
}
}

View File

@ -0,0 +1,68 @@
package eu.eudat.deposit.config;
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
import gr.cite.commons.web.oidc.configuration.filter.ApiKeyFilter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import java.util.Set;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
private final WebSecurityProperties webSecurityProperties;
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
@Autowired
public SecurityConfiguration(WebSecurityProperties webSecurityProperties, AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver) {
this.webSecurityProperties = webSecurityProperties;
this.authenticationManagerResolver = authenticationManagerResolver;
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.cors(Customizer.withDefaults())
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
.requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated()
.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous())
.sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER))
.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
return http.build();
}
private String[] buildAntPatterns(Set<String> endpoints) {
if (endpoints == null) {
return new String[0];
}
return endpoints.stream()
.filter(endpoint -> endpoint != null && !endpoint.isBlank())
.map(endpoint -> "/" + stripUnnecessaryCharacters(endpoint) + "/**")
.toArray(String[]::new);
}
private String stripUnnecessaryCharacters(String endpoint) {
endpoint = endpoint.strip();
if (endpoint.startsWith("/")) {
endpoint = endpoint.substring(1);
}
if (endpoint.endsWith("/")) {
endpoint = endpoint.substring(0, endpoint.length() - 1);
}
return endpoint;
}
}

View File

@ -0,0 +1,38 @@
package eu.eudat.deposit.controller;
import eu.eudat.depositinterface.models.DmpDepositModel;
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.*;
import java.util.List;
@RestController
@RequestMapping("/api/deposit")
public class DepositController implements eu.eudat.depositinterface.repository.DepositController {
private final ZenodoDepositService depositClient;
@Autowired
public DepositController(ZenodoDepositService depositClient) {
this.depositClient = depositClient;
}
public String deposit(@RequestBody DmpDepositModel dmpDepositModel, @RequestParam("authToken")String authToken) throws Exception {
return depositClient.deposit(dmpDepositModel, authToken);
}
public String authenticate(@RequestParam("authToken") String code) {
return depositClient.authenticate(code);
}
public DepositConfiguration getConfiguration() {
return depositClient.getConfiguration();
}
public String getLogo() {
return depositClient.getLogo();
}
}

View File

@ -0,0 +1,12 @@
spring:
jackson:
default-property-inclusion: non_null
config:
import: optional:classpath:config/app.env[.properties], optional:file:../config/app.env[.properties],
optional:classpath:config/server.yml[.yml], optional:classpath:config/server-${spring.profiles.active}.yml[.yml], optional:file:../config/server-${spring.profiles.active}.yml[.yml],
optional:classpath:config/zenodo.yml[.yml], optional:classpath:config/zenodo-${spring.profiles.active}.yml[.yml], optional:file:../config/zenodo-${spring.profiles.active}.yml[.yml],
optional:classpath:config/pid.yml[.yml], optional:classpath:config/pid-${spring.profiles.active}.yml[.yml], optional:file:../config/pid-${spring.profiles.active}.yml[.yml],
optional:classpath:config/funder.yml[.yml], optional:classpath:config/funder-${spring.profiles.active}.yml[.yml], optional:file:../config/funder-${spring.profiles.active}.yml[.yml],
optional:classpath:config/identifiers.yml[.yml], optional:classpath:config/identifiers-${spring.profiles.active}.yml[.yml], optional:file:../config/identifiers-${spring.profiles.active}.yml[.yml],
optional:classpath:config/security.yml[.yml], optional:classpath:config/security-${spring.profiles.active}.yml[.yml], optional:file:../config/security-${spring.profiles.active}.yml[.yml],
optional:classpath:config/cache.yml[.yml], optional:classpath:config/cache-${spring.profiles.active}.yml[.yml], optional:file:../config/cache-${spring.profiles.active}.yml[.yml]

View File

@ -0,0 +1,18 @@
cache:
manager:
fallbackToNoOpCache: true
caffeineCaches:
- names: [ "logoByRepository" ]
allowNullValues: true
initialCapacity: 100
maximumSize: 500
enableRecordStats: false
expireAfterWriteMinutes: 10
expireAfterAccessMinutes: 10
refreshAfterWriteMinutes: 10
mapCaches:
logoByRepository:
name: logoByRepository
keyPattern: zenodoplugin_$repo$:v0

View File

@ -0,0 +1,34 @@
funder:
available:
- funder: "Austrian Science Fund"
doi: "10.13039/501100002428"
- funder: "European Commission"
doi: "10.13039/501100000780"
- funder: "European Environment Agency"
doi: "10.13039/501100000806"
- funder: "Academy of Finland"
doi: "10.13039/501100002341"
- funder: "Hrvatska Zaklada za Znanost"
doi: "10.13039/501100004488"
- funder: "Fundação para a Ciência e a Tecnologia"
doi: "10.13039/501100001871"
- funder: "Ministarstvo Prosvete, Nauke i Tehnološkog Razvoja"
doi: "10.13039/501100004564"
- funder: "Ministarstvo Znanosti, Obrazovanja i Sporta"
doi: "10.13039/501100006588"
- funder: "National Health and Medical Research Council"
doi: "10.13039/501100000925"
- funder: "National Institutes of Health"
doi: "10.13039/100000002"
- funder: "National Science Foundation"
doi: "10.13039/100000001"
- funder: "Nederlandse Organisatie voor Wetenschappelijk Onderzoek"
doi: "10.13039/501100003246"
- funder: "Research Councils"
doi: "10.13039/501100000690"
- funder: "Schweizerischer Nationalfonds zur Förderung der wissenschaftlichen Forschung"
doi: "10.13039/501100001711"
- funder: "Science Foundation Ireland"
doi: "10.13039/501100001602"
- funder: "Wellcome Trust"
doi: "10.13039/100004440"

View File

@ -0,0 +1,34 @@
identifiers:
related:
- zenodo.related_identifiers.isCitedBy
- zenodo.related_identifiers.cites
- zenodo.related_identifiers.isSupplementTo
- zenodo.related_identifiers.isSupplementedBy
- zenodo.related_identifiers.isContinuedBy
- zenodo.related_identifiers.continues
- zenodo.related_identifiers.isDescribedBy
- zenodo.related_identifiers.describes
- zenodo.related_identifiers.hasMetadata
- zenodo.related_identifiers.isMetadataFor
- zenodo.related_identifiers.isNewVersionOf
- zenodo.related_identifiers.isPreviousVersionOf
- zenodo.related_identifiers.isPartOf
- zenodo.related_identifiers.hasPart
- zenodo.related_identifiers.isReferencedBy
- zenodo.related_identifiers.references
- zenodo.related_identifiers.isDocumentedBy
- zenodo.related_identifiers.documents
- zenodo.related_identifiers.isCompiledBy
- zenodo.related_identifiers.compiles
- zenodo.related_identifiers.isVariantFormOf
- zenodo.related_identifiers.isOriginalFormof
- zenodo.related_identifiers.isIdenticalTo
- zenodo.related_identifiers.isAlternateIdentifier
- zenodo.related_identifiers.isReviewedBy
- zenodo.related_identifiers.reviews
- zenodo.related_identifiers.isDerivedFrom
- zenodo.related_identifiers.isSourceOf
- zenodo.related_identifiers.requires
- zenodo.related_identifiers.isRequiredBy
- zenodo.related_identifiers.isObsoletedBy
- zenodo.related_identifiers.obsoletes

View File

@ -0,0 +1,48 @@
pid:
fields:
pid-name: pid
pid-type-name: pidTypeField
accepted-types:
- actrn
- ark
- bibcode
- nct
- drks
- doi
- euctr
- data.europa.eu
- epo_id
- GRID
- gsk
- GeoPass
- GBIF
- hal
- handle
- isrctn
- ichushi
- ISNI
- jprn
- mag_id
- NAID
- NCID
- oai
- orcid_pending
- orcid
- OrgPeg
- PANGAEA
- PIC
- epo_nr_epodoc
- pdb
- pmc
- pmid
- RNSR
- ROR
- RRID
- UNKNOWN
- VIAF
- who
- arXiv
- info:eu-repo/dai
- orcidworkid
- urn
- w3id

View File

@ -0,0 +1,7 @@
web:
security:
idp:
resource:
jwt:
audiences: [ "dmp_zenodo_bridge" ]
validIssuer: ${IDP_ISSUER_URI:}

View File

@ -0,0 +1,13 @@
web:
security:
enabled: true
authorized-endpoints: [ api ]
allowed-endpoints: [ health ]
idp:
api-key:
enabled: false
resource:
token-type: JWT #| opaque
jwt:
claims: [ role, x-role ]
issuer-uri: ${IDP_ISSUER_URI:}

View File

@ -0,0 +1,12 @@
server:
port: 8082
tomcat:
threads:
max: 20
max-connections: 10000
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB

View File

@ -0,0 +1,17 @@
zenodo:
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

View File

@ -0,0 +1 @@
zenodo:

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB