diff --git a/dmp-backend/dataverseRepository/pom.xml b/dmp-backend/dataverseRepository/pom.xml index 1772a86c1..329ee14f7 100644 --- a/dmp-backend/dataverseRepository/pom.xml +++ b/dmp-backend/dataverseRepository/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.4 + 2.5.2 eu.eudat.depositinterface @@ -43,4 +43,30 @@ + + + + maven-assembly-plugin + + + package + + single + + + + + + + eu.eudat.EuDatApplication + + + + jar-with-dependencies + + + + + + diff --git a/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoader.java b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoader.java new file mode 100644 index 000000000..5c8b82008 --- /dev/null +++ b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoader.java @@ -0,0 +1,5 @@ +package eu.eudat.depositinterface.dataverserepository.config; + +public interface ConfigLoader { + DataverseConfig getDataverseConfig(); +} diff --git a/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoaderImpl.java b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoaderImpl.java new file mode 100644 index 000000000..109bd7d1d --- /dev/null +++ b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/ConfigLoaderImpl.java @@ -0,0 +1,45 @@ +package eu.eudat.depositinterface.dataverserepository.config; + +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.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +@Service("dataverseConfigLoader") +public class ConfigLoaderImpl implements ConfigLoader{ + private static final Logger logger = LoggerFactory.getLogger(ConfigLoaderImpl.class); + private static final ObjectMapper mapper = new ObjectMapper(); + + private DataverseConfig dataverseConfig; + + @Autowired + private Environment environment; + + @Override + public DataverseConfig getDataverseConfig() { + if(dataverseConfig == null){ + try{ + dataverseConfig = mapper.readValue(getStreamFromPath(environment.getProperty("configuration.dataverse")), DataverseConfig.class); + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + } + return dataverseConfig; + } + + private InputStream getStreamFromPath(String filePath) { + try { + return new FileInputStream(filePath); + } catch (FileNotFoundException e) { + logger.info("loading from classpath"); + return getClass().getClassLoader().getResourceAsStream(filePath); + } + } +} diff --git a/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/DataverseConfig.java b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/DataverseConfig.java new file mode 100644 index 000000000..90b21c58d --- /dev/null +++ b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/config/DataverseConfig.java @@ -0,0 +1,88 @@ +package eu.eudat.depositinterface.dataverserepository.config; + +import com.fasterxml.jackson.annotation.JsonProperty; +import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; + +public class DataverseConfig { + 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("apiToken") + private String apiToken; + @JsonProperty("repositoryUrl") + private String repositoryUrl; + @JsonProperty("repositoryRecordUrl") + private String repositoryRecordUrl; + + 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 getApiToken() { + return apiToken; + } + public void setApiToken(String apiToken) { + this.apiToken = apiToken; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } + public void setRepositoryUrl(String repositoryUrl) { + this.repositoryUrl = repositoryUrl; + } + + public String getRepositoryRecordUrl() { + return repositoryRecordUrl; + } + public void setRepositoryRecordUrl(String repositoryRecordUrl) { + this.repositoryRecordUrl = repositoryRecordUrl; + } + + public RepositoryDepositConfiguration toRepoConfig() { + RepositoryDepositConfiguration config = new RepositoryDepositConfiguration(); + config.setDepositType(this.depositType); + config.setRepositoryId(this.repositoryId); + config.setRepositoryUrl(this.repositoryUrl); + config.setRepositoryRecordUrl(this.repositoryRecordUrl); + return config; + } +} diff --git a/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/interfaces/DataverseDeposit.java b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/interfaces/DataverseDeposit.java index 9a63460c5..552efb52c 100644 --- a/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/interfaces/DataverseDeposit.java +++ b/dmp-backend/dataverseRepository/src/main/java/eu/eudat/depositinterface/dataverserepository/interfaces/DataverseDeposit.java @@ -9,6 +9,7 @@ import com.researchspace.dataverse.entities.facade.DatasetContact; import com.researchspace.dataverse.entities.facade.DatasetDescription; import com.researchspace.dataverse.entities.facade.DatasetFacade; import com.researchspace.dataverse.http.DataverseAPIImpl; +import eu.eudat.depositinterface.dataverserepository.config.ConfigLoader; import eu.eudat.depositinterface.models.DMPDepositModel; import eu.eudat.depositinterface.repository.RepositoryDeposit; import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; @@ -29,13 +30,11 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; -import static eu.eudat.depositinterface.repository.RepositoryDepositConfiguration.DepositAccountStatus.SystemDeposit; +import static com.researchspace.dataverse.entities.Version.MAJOR; +import static com.researchspace.dataverse.entities.Version.MINOR; @Component public class DataverseDeposit implements RepositoryDeposit { @@ -50,10 +49,12 @@ public class DataverseDeposit implements RepositoryDeposit { private DataverseAPI api; private boolean isApiSet; + private ConfigLoader configLoader; private Environment environment; @Autowired - public DataverseDeposit(Environment environment){ + public DataverseDeposit(ConfigLoader configLoader, Environment environment){ + this.configLoader = configLoader; this.environment = environment; this.isApiSet = false; } @@ -73,18 +74,7 @@ public class DataverseDeposit implements RepositoryDeposit { if(!this.isApiSet) this.setDataverseApi(); - String alias = dmpDepositModel.getLabel().replace(" ", "_"); - DataverseGet dataverse = this.api.getDataverseOperations().getDataverseById(alias); - if(dataverse == null) { - DataversePost entity = new DataversePost(); - entity.setName(dmpDepositModel.getLabel()); - entity.setAlias(alias); - entity.setDescription(dmpDepositModel.getDescription()); - entity.setCreationDate(new Date()); - entity.setDataverseContacts(Collections.singletonList(new DataverseContacts(SYSTEM_EMAIL))); - DataverseResponse response = this.api.getDataverseOperations().createNewDataverse(SYSTEM_PARENT_DATAVERSE_ALIAS, entity); - } - + String doi; DatasetFacade dataset = DatasetFacade.builder() .title(dmpDepositModel.getLabel()) .authors(dmpDepositModel.getUsers().stream().map(x -> DatasetAuthor.builder().authorName(x.getUser().getName()).build()).collect(Collectors.toList())) @@ -94,10 +84,34 @@ public class DataverseDeposit implements RepositoryDeposit { .languages(new ArrayList<>()) .depositor("") .build(); - Identifier id = this.api.getDataverseOperations().createDataset(dataset, alias); - String doi = this.api.getDatasetOperations().getDataset(id).getDoiId().orElse(null); + if(dmpDepositModel.getPreviousDOI() == null || dmpDepositModel.getPreviousDOI().isEmpty()){ + Identifier id = this.api.getDataverseOperations().createDataset(dataset, SYSTEM_PARENT_DATAVERSE_ALIAS); + doi = this.api.getDatasetOperations().getDataset(id).getDoiId().orElse(null); + + this.uploadFiles(dmpDepositModel, doi); + + this.api.getDatasetOperations().publishDataset(id, MAJOR); + } + else{ + Map datasetJson = this.getDatasetIdentifier(dmpDepositModel.getPreviousDOI()); + Identifier id = new Identifier(); + id.setId(((Integer) datasetJson.get("id")).longValue()); + + this.uploadFiles(dmpDepositModel, dmpDepositModel.getPreviousDOI()); + + this.api.getDatasetOperations().updateDataset(dataset, id); + DataverseResponse publishedDataset = this.api.getDatasetOperations().publishDataset(id, MAJOR); + doi = publishedDataset.getData().getAuthority() + "/" + publishedDataset.getData().getIdentifier(); + } + + + return doi; + + } + + private void uploadFiles(DMPDepositModel dmpDepositModel, String doi) throws IOException { this.uploadFile(dmpDepositModel.getPdfFileName(), dmpDepositModel.getPdfFile(), doi); String contentDisposition = dmpDepositModel.getRdaJson().getHeaders().get("Content-Disposition").get(0); @@ -113,9 +127,14 @@ public class DataverseDeposit implements RepositoryDeposit { } this.uploadFile(jsonFileName, rdaJson, doi); Files.deleteIfExists(rdaJson.toPath()); + } - return doi; - + private Map getDatasetIdentifier(String previousDOI) { + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Dataverse-key", API_TOKEN); + String serverUrl = SERVER + "/api/datasets/:persistentId?persistentId=doi:" + previousDOI; + RestTemplate restTemplate = new RestTemplate(); + return (Map) restTemplate.exchange(serverUrl, HttpMethod.GET, new HttpEntity<>(headers), Map.class).getBody().get("data"); } private void uploadFile(String filename, File file, String doi) throws IOException { @@ -132,7 +151,7 @@ public class DataverseDeposit implements RepositoryDeposit { HttpEntity fileEntity = new HttpEntity<>(Files.readAllBytes(file.toPath()), fileMap); MultiValueMap body = new LinkedMultiValueMap<>(); body.add("file", fileEntity); - body.add("jsonData", "{\"restrict\":\"true\", \"tabIngest\":\"false\"}"); + body.add("jsonData", "{\"restrict\":\"false\", \"tabIngest\":\"false\"}"); HttpEntity> requestEntity = new HttpEntity<>(body, headers); @@ -144,13 +163,8 @@ public class DataverseDeposit implements RepositoryDeposit { @Override public RepositoryDepositConfiguration getConfiguration() { - RepositoryDepositConfiguration conf = new RepositoryDepositConfiguration(); - conf.setRepositoryId("Dataverse"); - conf.setDepositAccountStatus(SystemDeposit.getValue()); - conf.setAccessToken(API_TOKEN); - conf.setRepositoryUrl(SERVER + "/api/"); - conf.setRepositoryRecordUrl(SERVER + "/dataset.xhtml?persistentId=doi:"); - return conf; + eu.eudat.depositinterface.dataverserepository.config.DataverseConfig dataverseConfig = this.configLoader.getDataverseConfig(); + return dataverseConfig.toRepoConfig(); } @Override diff --git a/dmp-backend/dataverseRepository/src/main/resources/application.properties b/dmp-backend/dataverseRepository/src/main/resources/application.properties index 0ef26534a..2545c8f21 100644 --- a/dmp-backend/dataverseRepository/src/main/resources/application.properties +++ b/dmp-backend/dataverseRepository/src/main/resources/application.properties @@ -1 +1,2 @@ storage.temp= +configuration.dataverse=dataverse.json \ No newline at end of file diff --git a/dmp-backend/dataverseRepository/src/main/resources/dataverse.json b/dmp-backend/dataverseRepository/src/main/resources/dataverse.json new file mode 100644 index 000000000..6ef4f472f --- /dev/null +++ b/dmp-backend/dataverseRepository/src/main/resources/dataverse.json @@ -0,0 +1,7 @@ +{ + "depositType": 0, + "repositoryId": "Dataverse", + "apiToken": "", + "repositoryUrl": "", + "repositoryRecordUrl": "" +} \ No newline at end of file diff --git a/dmp-backend/depositinterface/src/main/java/eu/eudat/depositinterface/repository/RepositoryDepositConfiguration.java b/dmp-backend/depositinterface/src/main/java/eu/eudat/depositinterface/repository/RepositoryDepositConfiguration.java index 937e5182a..883f95d74 100644 --- a/dmp-backend/depositinterface/src/main/java/eu/eudat/depositinterface/repository/RepositoryDepositConfiguration.java +++ b/dmp-backend/depositinterface/src/main/java/eu/eudat/depositinterface/repository/RepositoryDepositConfiguration.java @@ -2,12 +2,12 @@ package eu.eudat.depositinterface.repository; public class RepositoryDepositConfiguration { - public enum DepositAccountStatus { + public enum DepositType { SystemDeposit(0), UserDeposit(1), BothWaysDeposit(2); private int value; - DepositAccountStatus(int value) { + DepositType(int value) { this.value = value; } @@ -15,7 +15,7 @@ public class RepositoryDepositConfiguration { return value; } - public static DepositAccountStatus fromInteger(int value) { + public static DepositType fromInteger(int value) { switch (value) { case 0: return SystemDeposit; @@ -24,27 +24,27 @@ public class RepositoryDepositConfiguration { case 2: return BothWaysDeposit; default: - throw new RuntimeException("Unsupported Deposit Account Status"); + throw new RuntimeException("Unsupported Deposit Account Type"); } } } - private int depositAccountStatus; + private int depositType; private String repositoryId; private String accessToken; private String repositoryUrl; private String repositoryAuthorizationUrl; private String repositoryRecordUrl; - private String repositoryLoginAccessTokenUrl; - private String repositoryLoginClientId; - private String repositoryLoginClientSecret; - private String repositoryLoginRedirectUri; + private String repositoryAccessTokenUrl; + private String repositoryClientId; + private String repositoryClientSecret; + private String redirectUri; - public int getDepositAccountStatus() { - return depositAccountStatus; + public int getDepositType() { + return depositType; } - public void setDepositAccountStatus(int depositAccountStatus) { - this.depositAccountStatus = depositAccountStatus; + public void setDepositType(int depositType) { + this.depositType = depositType; } public String getRepositoryId() { @@ -82,31 +82,31 @@ public class RepositoryDepositConfiguration { this.repositoryRecordUrl = repositoryRecordUrl; } - public String getRepositoryLoginAccessTokenUrl() { - return repositoryLoginAccessTokenUrl; + public String getRepositoryAccessTokenUrl() { + return repositoryAccessTokenUrl; } - public void setRepositoryLoginAccessTokenUrl(String repositoryLoginAccessTokenUrl) { - this.repositoryLoginAccessTokenUrl = repositoryLoginAccessTokenUrl; + public void setRepositoryAccessTokenUrl(String repositoryAccessTokenUrl) { + this.repositoryAccessTokenUrl = repositoryAccessTokenUrl; } - public String getRepositoryLoginClientId() { - return repositoryLoginClientId; + public String getRepositoryClientId() { + return repositoryClientId; } - public void setRepositoryLoginClientId(String repositoryLoginClientId) { - this.repositoryLoginClientId = repositoryLoginClientId; + public void setRepositoryClientId(String repositoryClientId) { + this.repositoryClientId = repositoryClientId; } - public String getRepositoryLoginClientSecret() { - return repositoryLoginClientSecret; + public String getRepositoryClientSecret() { + return repositoryClientSecret; } - public void setRepositoryLoginClientSecret(String repositoryLoginClientSecret) { - this.repositoryLoginClientSecret = repositoryLoginClientSecret; + public void setRepositoryClientSecret(String repositoryClientSecret) { + this.repositoryClientSecret = repositoryClientSecret; } - public String getRepositoryLoginRedirectUri() { - return repositoryLoginRedirectUri; + public String getRedirectUri() { + return redirectUri; } - public void setRepositoryLoginRedirectUri(String repositoryLoginRedirectUri) { - this.repositoryLoginRedirectUri = repositoryLoginRedirectUri; + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; } } diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index 4295c6b12..7b0ddcedb 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -222,14 +222,37 @@ org.springframework.boot spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 - ZIP + + + true + eu.eudat.EuDatApplication + dependency-jars/ + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.5.1 + copy-dependencies + package - repackage + copy-dependencies + + + ${project.build.directory}/dependency-jars/ + + diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java index f579394d8..863f79a96 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java @@ -1,12 +1,12 @@ package eu.eudat.controllers; -import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; import eu.eudat.logic.managers.DepositManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.doi.DepositCode; import eu.eudat.models.data.doi.DepositRequest; import eu.eudat.models.data.doi.Doi; +import eu.eudat.models.data.doi.RepositoryConfig; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; @@ -36,9 +36,9 @@ public class DepositController extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/repos"}) public @ResponseBody - ResponseEntity>> getAvailableRepos(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { - List ids = this.depositManager.getAvailableRepos(); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(ids)); + ResponseEntity>> getAvailableRepos(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { + List ids = this.depositManager.getAvailableRepos(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(ids)); } @RequestMapping(method = RequestMethod.POST, value = {"/getAccessToken"}) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 825592d16..d5bafb1ec 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -1062,9 +1062,9 @@ public class DataManagementPlanManager { }); UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); sendNotification(dmp, user, NotificationType.DMP_PUBLISH); - if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) { - this.createZenodoDoi(dmp.getId(), principal, true); - } +// if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { +// this.createZenodoDoi(dmp.getId(), principal, true); +// } } @Transactional @@ -2011,23 +2011,28 @@ public class DataManagementPlanManager { * DOI Generation * */ - private String getPreviousDOI(UUID groupId, UUID selfId) { + private String getPreviousDOI(UUID groupId, UUID selfId, String repositoryId) { DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); List groupIds = new ArrayList<>(); groupIds.add(groupId); criteria.setGroupIds(groupIds); criteria.setAllVersions(true); List dmps = this.databaseRepository.getDmpDao().getWithCriteria(criteria).toList(); - String doi = null; + dmps.sort((DMP d1, DMP d2) -> d2.getVersion() - d1.getVersion()); for (DMP dmp: dmps) { if (!dmp.getId().equals(selfId)) { - if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) { - doi = dmp.getDoi(); + if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { + for (Iterator it = dmp.getDois().iterator(); it.hasNext(); ) { + EntityDoi entityDoi = it.next(); + if(entityDoi.getRepositoryId().equals(repositoryId)){ + return entityDoi.getDoi(); + } + } } } } - return doi; + return null; } private String getUnpublishedDOI(String DOI, String token, Integer version) { @@ -2079,7 +2084,7 @@ public class DataManagementPlanManager { } catch (Exception e) { throw e; } - String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId()); + String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), "Zenodo"); DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, previousDOI); @@ -2094,10 +2099,23 @@ public class DataManagementPlanManager { String finalDoi = null; for(RepositoryDeposit repo: this.repositoriesDeposit) { //temp - finalDoi = repo.deposit(dmpDepositModel, update, zenodoToken); - if (finalDoi != null) { - dmp.setDoi(finalDoi); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + if(repo.getConfiguration().getRepositoryId().equals("Zenodo")) { + finalDoi = repo.deposit(dmpDepositModel, update, zenodoToken); + if (finalDoi != null) { + EntityDoi doiEntity = new EntityDoi(); + doiEntity.setId(UUID.randomUUID()); + doiEntity.setEntityType(EntityDoi.EntityType.DMP); + doiEntity.setDoi(finalDoi); + doiEntity.setRepositoryId("Zenodo"); + Date now = new Date(); + doiEntity.setCreatedAt(now); + doiEntity.setUpdatedAt(now); + doiEntity.setEntityId(dmp); + apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity); + + dmp.getDois().add(doiEntity); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + } } } Files.deleteIfExists(file.getFile().toPath()); @@ -2124,7 +2142,7 @@ public class DataManagementPlanManager { } catch (Exception e) { throw e; } - String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId()); + String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), depositRequest.getRepositoryId()); DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, previousDOI); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java index d5ec7ff88..a5e05da30 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java @@ -10,6 +10,7 @@ import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.pdf.PDFUtils; import eu.eudat.models.data.doi.DepositRequest; import eu.eudat.models.data.doi.Doi; +import eu.eudat.models.data.doi.RepositoryConfig; import eu.eudat.models.data.security.Principal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,12 +37,13 @@ public class DepositManager { this.dataManagementPlanManager = dataManagementPlanManager; } - public List getAvailableRepos() { - List repos = new ArrayList<>(); + public List getAvailableRepos() { + List reposConfigModel = new ArrayList<>(); for (RepositoryDeposit r: this.repositories) { - repos.add(r.getConfiguration()); + RepositoryConfig repoModel = new RepositoryConfig(); + reposConfigModel.add(repoModel.toModel(r.getConfiguration())); } - return repos; + return reposConfigModel; } public String authenticate(String id, String code) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java new file mode 100644 index 000000000..67eaab098 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java @@ -0,0 +1,65 @@ +package eu.eudat.models.data.doi; + +import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; + +public class RepositoryConfig { + + private int depositType; + private String repositoryId; + private String repositoryAuthorizationUrl; + private String repositoryRecordUrl; + private String repositoryClientId; + private String redirectUri; + + 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 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 getRepositoryClientId() { + return repositoryClientId; + } + public void setRepositoryClientId(String repositoryClientId) { + this.repositoryClientId = repositoryClientId; + } + + public String getRedirectUri() { + return redirectUri; + } + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + + public RepositoryConfig toModel(RepositoryDepositConfiguration r){ + this.setDepositType(r.getDepositType()); + this.setRepositoryId(r.getRepositoryId()); + this.setRepositoryAuthorizationUrl(r.getRepositoryAuthorizationUrl()); + this.setRepositoryRecordUrl(r.getRepositoryRecordUrl()); + this.setRepositoryClientId(r.getRepositoryClientId()); + this.setRedirectUri(r.getRedirectUri()); + return this; + } +} diff --git a/dmp-backend/zenodoRepository/pom.xml b/dmp-backend/zenodoRepository/pom.xml index 9acabc826..afdd03335 100644 --- a/dmp-backend/zenodoRepository/pom.xml +++ b/dmp-backend/zenodoRepository/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.4 + 2.5.2 eu.eudat.depositinterface diff --git a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoader.java b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoader.java index 100f94d06..72873bf9f 100644 --- a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoader.java +++ b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoader.java @@ -4,4 +4,5 @@ import java.util.List; public interface ConfigLoader { List getDOIFunders(); + ZenodoConfig getZenodoConfig(); } diff --git a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoaderImpl.java b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoaderImpl.java index 52514bda2..d43b9dbee 100644 --- a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoaderImpl.java +++ b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ConfigLoaderImpl.java @@ -7,10 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -22,6 +19,7 @@ public class ConfigLoaderImpl implements ConfigLoader{ private static final ObjectMapper mapper = new ObjectMapper(); private List doiFunders = new ArrayList<>(); + private ZenodoConfig zenodoConfig; @Autowired private Environment environment; @@ -39,6 +37,18 @@ public class ConfigLoaderImpl implements ConfigLoader{ return doiFunders; } + @Override + public ZenodoConfig getZenodoConfig() { + if (zenodoConfig == null) { + try { + zenodoConfig = mapper.readValue(getStreamFromPath("zenodo.json"), ZenodoConfig.class); + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + } + return zenodoConfig; + } + private InputStream getStreamFromPath(String filePath) { try { return new FileInputStream(filePath); diff --git a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ZenodoConfig.java b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ZenodoConfig.java new file mode 100644 index 000000000..763981ed5 --- /dev/null +++ b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/config/ZenodoConfig.java @@ -0,0 +1,140 @@ +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; + + 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 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); + return config; + } +} diff --git a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/interfaces/ZenodoDeposit.java b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/interfaces/ZenodoDeposit.java index 012076af7..b73fae54d 100644 --- a/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/interfaces/ZenodoDeposit.java +++ b/dmp-backend/zenodoRepository/src/main/java/eu/eudat/depositinterface/zenodorepository/interfaces/ZenodoDeposit.java @@ -5,6 +5,7 @@ import eu.eudat.depositinterface.models.DMPDepositModel; 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; @@ -27,8 +28,6 @@ import java.io.IOException; import java.nio.file.Files; import java.util.*; -import static eu.eudat.depositinterface.repository.RepositoryDepositConfiguration.DepositAccountStatus.*; - @Component public class ZenodoDeposit implements RepositoryDeposit { private static final Logger logger = LoggerFactory.getLogger(ZenodoDeposit.class); @@ -73,7 +72,8 @@ public class ZenodoDeposit implements RepositoryDeposit { createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody(); links = (LinkedHashMap) createResponse.get("links"); finalDoi = (String) createResponse.get("conceptdoi"); - } else { + } + else { unpublishedUrl = this.getUnpublishedDOI(zenodoUrl, previousDOI, zenodoToken, dmpDepositModel.getVersion()); if (unpublishedUrl == null) { //It requires more than one step to create a new version @@ -121,8 +121,7 @@ public class ZenodoDeposit implements RepositoryDeposit { if (unpublishedUrl == null) { // Second step, add the file to the entry. File pdfFile = dmpDepositModel.getPdfFile(); - String name = dmpDepositModel.getPdfFileName(); - String fileName = name + ".pdf"; + String fileName = dmpDepositModel.getPdfFileName(); FileSystemResource fileSystemResource = new FileSystemResource(pdfFile); HttpEntity addFileMapRequest = new HttpEntity<>(fileSystemResource, null); @@ -148,18 +147,15 @@ public class ZenodoDeposit implements RepositoryDeposit { // Third post call to Zenodo to publish the entry and return the DOI. publishUrl = links.get("publish") + "?access_token=" + zenodoToken; - } else { + } + else { publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; } -// if (dmp.isPublic()) { - Map publishResponce = restTemplate.postForObject(publishUrl, "", Map.class); - finalDoi = (String) publishResponce.get("conceptdoi"); -// } + finalDoi = this.publish(publishUrl); } else { Map editResponce = restTemplate.postForObject(links.get("edit") + "?access_token=" + zenodoToken, "", Map.class); restTemplate.put(links.get("self") + "?access_token=" + zenodoToken, request); - Map publishResponce = restTemplate.postForObject(links.get("publish") + "?access_token=" + zenodoToken, "", Map.class); - finalDoi = (String) publishResponce.get("conceptdoi"); + finalDoi = this.publish(links.get("publish") + "?access_token=" + zenodoToken); } return finalDoi; @@ -170,20 +166,35 @@ public class ZenodoDeposit implements RepositoryDeposit { } + private String publish(String publishUrl){ + RestTemplate restTemplate = new RestTemplate(); + Map publishResponce = restTemplate.postForObject(publishUrl, "", Map.class); + return (String) publishResponce.get("conceptdoi"); + } + + private void publishIfNot(String zenodoUrl, String doi, String zenodoToken, DMPDepositModel dmpDepositModel){ + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + headers.setContentType(MediaType.APPLICATION_JSON); + + eu.eudat.depositinterface.zenodorepository.models.ZenodoDeposit deposit = DMPToZenodoMapper.fromDMP(dmpDepositModel, "argos", "ARGOS", "https://argos.openaire.eu/", this.configLoader.getDOIFunders()); + HttpEntity request = new HttpEntity<>(deposit, headers); + + String listUrl = zenodoUrl + "deposit/depositions" + "?q=conceptdoi:\"" + doi + "\"&access_token=" + zenodoToken; + ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); + Map createResponse = listResponses.getBody()[0]; + LinkedHashMap links = (LinkedHashMap) createResponse.get("links"); + Map editResponce = restTemplate.postForObject(links.get("edit") + "?access_token=" + zenodoToken, "", Map.class); + + restTemplate.put(links.get("self") + "?access_token=" + zenodoToken, request); + this.publish(links.get("publish") + "?access_token=" + zenodoToken); + } + @Override public RepositoryDepositConfiguration getConfiguration() { - RepositoryDepositConfiguration conf = new RepositoryDepositConfiguration(); - conf.setDepositAccountStatus(BothWaysDeposit.getValue()); - conf.setRepositoryId("Zenodo"); - conf.setAccessToken("pcqw4LGLrhp17FF5GoXNCXakkEi82ThchZw7Tk4qh74VrDE3EmliG3UlhYtd"); - conf.setRepositoryUrl("https://sandbox.zenodo.org/api/"); - conf.setRepositoryAuthorizationUrl("https://sandbox.zenodo.org/oauth/authorize"); - conf.setRepositoryRecordUrl("https://sandbox.zenodo.org/record/"); - conf.setRepositoryLoginAccessTokenUrl("https://sandbox.zenodo.org/oauth/token"); - conf.setRepositoryLoginClientId("hEmVRNc1OzRmWyi2GDR3XVKbhG3OtfJXLXkkOGXx"); - conf.setRepositoryLoginClientSecret("7VSU0NjiAg0P3mv14wemMYy2XhvlmV6F7xoszxPH4ZDx98v8FdMpBbxlncqr"); - conf.setRepositoryLoginRedirectUri("http://localhost:4200/login/external/zenodo"); - return conf; + ZenodoConfig zenodoConfig = this.configLoader.getZenodoConfig(); + return zenodoConfig.toRepoConfig(); } @Override @@ -197,15 +208,15 @@ public class ZenodoDeposit implements RepositoryDeposit { headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("client_id", conf.getRepositoryLoginClientId()); - map.add("client_secret", conf.getRepositoryLoginClientSecret()); + 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.getRepositoryLoginRedirectUri()); + map.add("redirect_uri", conf.getRedirectUri()); HttpEntity> request = new HttpEntity<>(map, headers); try { - Map values = restTemplate.postForObject(conf.getRepositoryLoginAccessTokenUrl(), request, Map.class); + Map values = restTemplate.postForObject(conf.getRepositoryAccessTokenUrl(), request, Map.class); //ZenodoResponseToken zenodoResponseToken = new ZenodoResponseToken(); Map user = (Map) values.get("user"); // zenodoResponseToken.setUserId((String) user.get("id")); diff --git a/dmp-backend/zenodoRepository/src/main/resources/application.properties b/dmp-backend/zenodoRepository/src/main/resources/application.properties index 51594e272..4ce4e4ac6 100644 --- a/dmp-backend/zenodoRepository/src/main/resources/application.properties +++ b/dmp-backend/zenodoRepository/src/main/resources/application.properties @@ -1 +1,2 @@ configuration.doi_funder=DOI_Funder.json +configuration.zenodo=zenodo.json diff --git a/dmp-backend/zenodoRepository/src/main/resources/zenodo.json b/dmp-backend/zenodoRepository/src/main/resources/zenodo.json new file mode 100644 index 000000000..2dd32fd6b --- /dev/null +++ b/dmp-backend/zenodoRepository/src/main/resources/zenodo.json @@ -0,0 +1,12 @@ +{ + "depositType": 2, + "repositoryId": "Zenodo", + "accessToken": "", + "repositoryUrl": "https://sandbox.zenodo.org/api/", + "repositoryAuthorizationUrl": "https://sandbox.zenodo.org/oauth/authorize", + "repositoryRecordUrl": "https://sandbox.zenodo.org/record/", + "repositoryAccessTokenUrl": "https://sandbox.zenodo.org/oauth/token", + "repositoryClientId": "", + "repositoryClientSecret": "", + "redirectUri": "http://localhost:4200/login/external/zenodo" +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts b/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts index 97840d578..bfcc105c6 100644 --- a/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts +++ b/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts @@ -1,14 +1,10 @@ import { DepositConfigurationStatus } from "@app/core/common/enum/deposit-configuration-status"; export class DepositConfigurationModel { - depositAccountStatus: DepositConfigurationStatus; + depositType: DepositConfigurationStatus; repositoryId: string; - accessToken: string; - repositoryUrl: string; repositoryAuthorizationUrl: string; repositoryRecordUrl: string; - repositoryLoginAccessTokenUrl: string; - repositoryLoginClientId: string; - repositoryLoginClientSecret: string; - repositoryLoginRedirectUri: string; + repositoryClientId: string; + redirectUri: string; } diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dialog/dmp-deposit-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dialog/dmp-deposit-dialog.component.ts index 005eba99d..cf0ddf001 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dialog/dmp-deposit-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dialog/dmp-deposit-dialog.component.ts @@ -60,7 +60,7 @@ export class DmpDepositDialogComponent extends BaseComponent implements OnInit { deposit(repo: DepositConfigurationModel) { - if(repo.depositAccountStatus == DepositConfigurationStatus.BothSystemAndUser){ + if(repo.depositType == DepositConfigurationStatus.BothSystemAndUser){ const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, { maxWidth: '600px', @@ -73,9 +73,9 @@ export class DmpDepositDialogComponent extends BaseComponent implements OnInit { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { switch (result) { case 0: - this.showOauth2Dialog(repo.repositoryAuthorizationUrl + '?client_id=' + repo.repositoryLoginClientId + this.showOauth2Dialog(repo.repositoryAuthorizationUrl + '?client_id=' + repo.repositoryClientId + '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri=' - + repo.repositoryLoginRedirectUri, repo, this.dmp); + + repo.redirectUri, repo, this.dmp); break; case 1: this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null) @@ -93,7 +93,7 @@ export class DmpDepositDialogComponent extends BaseComponent implements OnInit { }); } - else if(repo.depositAccountStatus == DepositConfigurationStatus.System){ + else if(repo.depositType == DepositConfigurationStatus.System){ this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null) .pipe(takeUntil(this._destroyed)) .subscribe(doi =>{