diff --git a/pom.xml b/pom.xml
index c532746..f9a77d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,18 @@
1.3.2
+
+ org.apache.httpcomponents
+ httpclient
+ 4.3.6
+
+
+
+ org.apache.httpcomponents
+ httpmime
+ 4.3.6
+
+
junit
diff --git a/src/main/java/org/gcube/common/deposition/ElaborateDepositionVersion.java b/src/main/java/org/gcube/common/deposition/ElaborateDepositionVersion.java
index 169b047..4e61ccc 100644
--- a/src/main/java/org/gcube/common/deposition/ElaborateDepositionVersion.java
+++ b/src/main/java/org/gcube/common/deposition/ElaborateDepositionVersion.java
@@ -178,22 +178,18 @@ public class ElaborateDepositionVersion {
logger.trace("DepositionVersion to be managed is:{}", objectMapper.writeValueAsString(depositionVersion));
DepositionVersionExecutor dve = DepositionVersionExecutor.getDefaultExecutor();
+ dve.setObjectMapper(objectMapper);
dve.setMetadata(getMetadata());
if(depositionVersion.getDOIURL()!=null) {
- boolean updateEnabled = false;
+ Boolean update = depositionVersion.getUpdate();
- try {
- String updatedDeposit = Config.getProperties().getProperty("update_deposit");
- updateEnabled = Boolean.valueOf(updatedDeposit);
- }catch (Exception e) {
- updateEnabled = false;
+ if(update==null) {
+ update = depositionVersion.getDeposition().getDefaultUpdate();
}
- logger.trace("Deposition update {}", updateEnabled ? "enabled" : "disabled");
-
- if(updateEnabled) {
+ if(update) {
logger.info("Going to update deposition {} {}.",
name , depositionVersion.getVersion());
dve.setDOIURL(depositionVersion.getDOIURL());
diff --git a/src/main/java/org/gcube/common/deposition/executor/DepositionVersionExecutor.java b/src/main/java/org/gcube/common/deposition/executor/DepositionVersionExecutor.java
index 77687e4..c6fe80b 100644
--- a/src/main/java/org/gcube/common/deposition/executor/DepositionVersionExecutor.java
+++ b/src/main/java/org/gcube/common/deposition/executor/DepositionVersionExecutor.java
@@ -4,6 +4,7 @@ import java.net.URL;
import java.util.List;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
+import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.common.deposition.executor.zenodo.ZenodoDepositionVersionExecutor;
import org.gcube.common.deposition.model.DepositionFile;
@@ -16,10 +17,19 @@ public abstract class DepositionVersionExecutor {
return new ZenodoDepositionVersionExecutor();
}
+ protected ObjectMapper objectMapper;
protected JsonNode metadata;
protected URL doiURL;
protected List depositionFiles;
+ public ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ public void setObjectMapper(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
public JsonNode getMetadata() {
return metadata;
}
diff --git a/src/main/java/org/gcube/common/deposition/executor/zenodo/ZenodoDepositionVersionExecutor.java b/src/main/java/org/gcube/common/deposition/executor/zenodo/ZenodoDepositionVersionExecutor.java
index b2524af..e72caac 100644
--- a/src/main/java/org/gcube/common/deposition/executor/zenodo/ZenodoDepositionVersionExecutor.java
+++ b/src/main/java/org/gcube/common/deposition/executor/zenodo/ZenodoDepositionVersionExecutor.java
@@ -1,16 +1,34 @@
package org.gcube.common.deposition.executor.zenodo;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.gcube.com.fasterxml.jackson.databind.JsonNode;
+import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
+import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.common.deposition.config.Config;
import org.gcube.common.deposition.executor.DepositionVersionExecutor;
import org.gcube.common.deposition.model.DepositionFile;
+import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,13 +39,43 @@ public class ZenodoDepositionVersionExecutor extends DepositionVersionExecutor {
private static final Logger logger = LoggerFactory.getLogger(ZenodoDepositionVersionExecutor.class);
+ public static final String GUCBE_ZENODO_SOFTWARE_DEPOSIT = "gCubeSoftwareDeposit";
+
+ public static final String METADATA_FIELD_NAME = "metadata";
+
+ public static final String ZENODO_DOI_URL_BASE_PATH = "https://doi.org/10.5072/zenodo.";
+
+ public static final String DEPOSITIONS_COLLECTION_PATH = "/api/deposit/depositions";
+ public static final String DEPOSITION_PATH = DEPOSITIONS_COLLECTION_PATH + ":id";
+ public static final String DEPOSTION_FILES_PATH = DEPOSITION_PATH + "/files";
+
+ public static final String DEPOSTION_NEW_VERSION_PATH = DEPOSITION_PATH + "/actions/newversion";
+ public static final String DEPOSTION_PUBLISH_PATH = DEPOSITION_PATH + "/actions/publish";
+
+
protected URL zenodoBaseURL;
protected String accessToken;
+ protected String zenodoID;
+ protected JsonNode response;
+
+ protected String getZenodoIDFromDOIURL(URL doiURL) {
+ return doiURL.toString().replace(ZENODO_DOI_URL_BASE_PATH, "");
+ }
+
+ protected Map getAccessTokenQueryParamters() {
+ Map map = new HashMap<>();
+ map.put("access_token", accessToken);
+ return map;
+ }
+
public ZenodoDepositionVersionExecutor() {
try {
this.zenodoBaseURL = new URL(Config.getProperties().getProperty("zenodo_base_url"));
this.accessToken = Config.getProperties().getProperty("zenodo_access_token");
+ if(doiURL!=null) {
+
+ }
}catch (Exception e) {
throw new RuntimeException(e);
}
@@ -52,6 +100,73 @@ public class ZenodoDepositionVersionExecutor extends DepositionVersionExecutor {
return file;
}
+ protected void addFilesToDeposition(List files ) throws Exception {
+ String depositID = getZenodoIDFromDOIURL(doiURL);
+ String newFilePath = DEPOSTION_FILES_PATH.replace(":id", depositID);
+ URL url = new URL(zenodoBaseURL, newFilePath);
+
+ for(File file : files) {
+
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost uploadFile = new HttpPost(url.toURI());
+ uploadFile.addHeader("access_token", accessToken);
+ uploadFile.addHeader("Accept", "application/json");
+ MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+ builder.addTextBody("name", file.getName(), ContentType.TEXT_PLAIN);
+ builder.addBinaryBody("file", new FileInputStream(file),
+ ContentType.APPLICATION_OCTET_STREAM,
+ file.getName()
+ );
+
+ HttpEntity multipart = builder.build();
+ uploadFile.setEntity(multipart);
+
+ CloseableHttpResponse response = httpClient.execute(uploadFile);
+ HttpEntity responseEntity = response.getEntity();
+ StringBuilder result = getStringBuilder(responseEntity.getContent());
+ String res = result.toString();
+ logger.debug("Created file from {} response is {}", file.getAbsolutePath(), res);
+
+ // JsonNode jsonNode = objectMapper.readTree(res);
+
+ }
+ }
+
+ protected void updateMetadata() throws Exception {
+ GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(zenodoBaseURL.toString());
+ gxHTTPStringRequest.from(GUCBE_ZENODO_SOFTWARE_DEPOSIT);
+ gxHTTPStringRequest.queryParams(getAccessTokenQueryParamters());
+ gxHTTPStringRequest.header("Content-Type", "application/json");
+ gxHTTPStringRequest.header("Accept", "application/json");
+
+ String conceptID = getZenodoIDFromDOIURL(doiURL);
+ gxHTTPStringRequest.path(DEPOSITION_PATH.replace(":id", conceptID));
+
+
+ ObjectNode body = objectMapper.createObjectNode();
+ body.set(METADATA_FIELD_NAME, metadata);
+
+ HttpURLConnection httpURLConnection = gxHTTPStringRequest.put(objectMapper.writeValueAsString(body));
+ JsonNode jsonNode = getResponse(httpURLConnection);
+
+
+ }
+
+ protected void publish() throws Exception {
+ GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(zenodoBaseURL.toString());
+ gxHTTPStringRequest.from(GUCBE_ZENODO_SOFTWARE_DEPOSIT);
+ gxHTTPStringRequest.queryParams(getAccessTokenQueryParamters());
+ gxHTTPStringRequest.header("Content-Type", "application/json");
+ gxHTTPStringRequest.header("Accept", "application/json");
+
+ String id = getZenodoIDFromDOIURL(doiURL);
+ gxHTTPStringRequest.path(DEPOSTION_PUBLISH_PATH.replace(":id", id));
+
+ HttpURLConnection httpURLConnection = gxHTTPStringRequest.post();
+ JsonNode jsonNode = getResponse(httpURLConnection);
+
+ }
+
protected void finalize() throws Exception {
List files = new ArrayList<>();
for(DepositionFile df : depositionFiles) {
@@ -61,10 +176,14 @@ public class ZenodoDepositionVersionExecutor extends DepositionVersionExecutor {
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
- // TODO Add depositionFiles
- // TODO Update deposit metadata
+ //Add depositionFiles
+ addFilesToDeposition(files);
- // TODO Publish the version
+ //Update deposit metadata
+ updateMetadata();
+
+ // Publish the version
+ publish();
for(File file : files) {
if(!file.exists()) {
@@ -78,9 +197,79 @@ public class ZenodoDepositionVersionExecutor extends DepositionVersionExecutor {
}
}
+ protected StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
+ StringBuilder result = new StringBuilder();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ result.append(line);
+ }
+ }
+
+ return result;
+ }
+
+ public JsonNode getResponse(HttpURLConnection connection) throws Exception {
+
+ try {
+
+ int responseCode = connection.getResponseCode();
+ String responseMessage = connection.getResponseMessage();
+
+ logger.trace("Response {} {}", responseCode, responseMessage);
+
+ if(connection.getRequestMethod().compareTo("HEAD")==0) {
+ if(responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
+ return null;
+ }
+
+ if(responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
+ throw new RuntimeException(responseCode + " " + responseMessage);
+ }
+ if(responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+ throw new RuntimeException(responseCode + " " + responseMessage);
+ }
+ }
+
+ if(responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
+
+ InputStream inputStream = connection.getErrorStream();
+ StringBuilder result = getStringBuilder(inputStream);
+
+ String res = result.toString();
+
+ throw new RuntimeException(res);
+
+ }
+
+ StringBuilder result = getStringBuilder(connection.getInputStream());
+
+ String res = result.toString();
+ logger.trace("Server returned content : {}", res);
+
+ return objectMapper.readTree(res);
+ } finally {
+ connection.disconnect();
+ }
+ }
+
@Override
public void create() throws Exception {
- // TODO New deposit on Zenodo
+ GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(zenodoBaseURL.toString());
+ gxHTTPStringRequest.from(GUCBE_ZENODO_SOFTWARE_DEPOSIT);
+ gxHTTPStringRequest.queryParams(getAccessTokenQueryParamters());
+ gxHTTPStringRequest.header("Content-Type", "application/json");
+ gxHTTPStringRequest.header("Accept", "application/json");
+ gxHTTPStringRequest.path(DEPOSITIONS_COLLECTION_PATH);
+
+ ObjectNode body = objectMapper.createObjectNode();
+ body.set(METADATA_FIELD_NAME, metadata);
+
+ HttpURLConnection httpURLConnection = gxHTTPStringRequest.post(objectMapper.writeValueAsString(body));
+ response = getResponse(httpURLConnection);
+
+ doiURL = new URL(ZENODO_DOI_URL_BASE_PATH + response.get("conceptrecid").asText());
+
finalize();
}
@@ -89,10 +278,44 @@ public class ZenodoDepositionVersionExecutor extends DepositionVersionExecutor {
// TODO edit a published version
}
+ /**
+ * Remove previous depositionFiles
+ * @throws Exception
+ */
+ protected void deletePreviousFiles() throws Exception {
+ ArrayNode files = (ArrayNode) response.get("files");
+ for(int i=0; i defaultFiles;
@@ -32,34 +35,22 @@ public class Deposition {
return name;
}
- public void setName(String name) {
- this.name = name;
+ public Boolean getDefaultUpdate() {
+ return defaultUpdate;
}
public List getDefaultFiles() {
return defaultFiles;
}
- public void setDefaultFiles(List defaultFiles) {
- this.defaultFiles = defaultFiles;
- }
-
public String getDefaultCodeLocation() {
return defaultCodeLocation;
}
- public void setDefaultCodeLocation(String defaultCodeLocation) {
- this.defaultCodeLocation= defaultCodeLocation;
- }
-
public String getCodeLocationAdditionalDescription() {
return codeLocationAdditionalDescription;
}
- public void setCodeLocationAdditionalDescription(String codeLocationAdditionalDescription) {
- this.codeLocationAdditionalDescription = codeLocationAdditionalDescription;
- }
-
public List getDepositionVersions() {
return depositionVersions;
}
@@ -68,8 +59,4 @@ public class Deposition {
return metadata;
}
- public void setMetadata(JsonNode metadata) {
- this.metadata = metadata;
- }
-
}
diff --git a/src/main/java/org/gcube/common/deposition/model/DepositionVersion.java b/src/main/java/org/gcube/common/deposition/model/DepositionVersion.java
index 10d5488..d7dc255 100644
--- a/src/main/java/org/gcube/common/deposition/model/DepositionVersion.java
+++ b/src/main/java/org/gcube/common/deposition/model/DepositionVersion.java
@@ -59,6 +59,9 @@ public class DepositionVersion {
@JsonProperty(value = "doi_url")
protected URL doiURL;
+
+ @JsonProperty(value = "update")
+ protected Boolean update;
public DepositionVersion() {
this.noCodeLocation = false;
@@ -183,6 +186,14 @@ public class DepositionVersion {
this.doiURL = null;
}
}
+
+ public Boolean getUpdate() {
+ return update;
+ }
+
+ public void setUpdate(Boolean update) {
+ this.update = update;
+ }
diff --git a/src/test/resources/zenodo-deposit.json b/src/test/resources/zenodo-deposit.json
index 4b31347..d59cdfb 100644
--- a/src/test/resources/zenodo-deposit.json
+++ b/src/test/resources/zenodo-deposit.json
@@ -1,5 +1,6 @@
{
"name": "gcat",
+ "default_update": false,
"default_files":
[
{
@@ -31,7 +32,8 @@
"release_ticket": null,
"code_location": null,
"concept_doi_url": "https://doi.org/10.5072/zenodo.1139445",
- "doi_url": "https://doi.org/10.5072/zenodo.1139446"
+ "doi_url": "https://doi.org/10.5072/zenodo.1139446",
+ "update": true
},
{
"version": "1.1.0",