289 lines
10 KiB
Java
289 lines
10 KiB
Java
package org.gcube.data.publishing.ckan2zenodo.clients;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.net.URL;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.StandardCopyOption;
|
|
import java.util.List;
|
|
import java.util.concurrent.Callable;
|
|
import java.util.concurrent.Future;
|
|
|
|
import javax.ws.rs.client.Client;
|
|
import javax.ws.rs.client.ClientBuilder;
|
|
import javax.ws.rs.client.Entity;
|
|
import javax.ws.rs.core.MediaType;
|
|
import javax.ws.rs.core.Response;
|
|
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
|
import org.gcube.data.publishing.ckan2zenodo.Fixer;
|
|
import org.gcube.data.publishing.ckan2zenodo.LocalConfiguration;
|
|
import org.gcube.data.publishing.ckan2zenodo.LocalConfiguration.Configuration;
|
|
import org.gcube.data.publishing.ckan2zenodo.commons.IS;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.ZenodoCredentials;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.faults.ConfigurationException;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.faults.ZenodoException;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.DepositionMetadata;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.FileDeposition;
|
|
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.ZenodoDeposition;
|
|
import org.glassfish.jersey.client.ClientProperties;
|
|
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
|
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
|
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
import lombok.NonNull;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class Zenodo {
|
|
|
|
private static final String CONTENT_TYPE="application/json";
|
|
|
|
private static final String DEPOSITION_BASE_URL="deposit/depositions";
|
|
|
|
|
|
private static final String PUBLISH_URL_POST="actions/publish";
|
|
private static final String NEW_VERSION_URL_POST="actions/newversion";
|
|
|
|
|
|
private static final String UNLOCK_URL_POST="actions/edit";
|
|
|
|
|
|
|
|
private static final String ACCESS_TOKEN="access_token";
|
|
|
|
private static ObjectMapper mapper = new ObjectMapper();
|
|
|
|
static {
|
|
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
|
|
mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
|
|
mapper.setSerializationInclusion(Include.NON_NULL);
|
|
// mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
|
}
|
|
|
|
|
|
public static final Zenodo get() throws ConfigurationException {
|
|
String eprCategory=LocalConfiguration.getProperty(Configuration.ZENODO_ENDPOINT_CATEGORY);
|
|
String eprPlatform=LocalConfiguration.getProperty(Configuration.ZENODO_ENDPOINT_PLATFORM);
|
|
List<ServiceEndpoint> eps=IS.queryForServiceEndpoints(eprCategory,eprPlatform);
|
|
|
|
if(eps.isEmpty()) throw new ConfigurationException("No Zenodo Credentials found ("+eprCategory+" : "+eprPlatform+")");
|
|
if(eps.size()>1) throw new ConfigurationException("Multiple ["+eps.size()+"] Zenodo Credentials found ("+eprCategory+" : "+eprPlatform+")");
|
|
AccessPoint se=eps.get(0).profile().accessPoints().iterator().next();
|
|
ZenodoCredentials toSet=new ZenodoCredentials(IS.decryptString(se.password()), se.address());
|
|
return new Zenodo(toSet);
|
|
}
|
|
|
|
|
|
@NonNull
|
|
private ZenodoCredentials credentials;
|
|
|
|
Client client;
|
|
|
|
private synchronized Client getWebClient() {
|
|
if(client==null) {
|
|
client = ClientBuilder.newClient()
|
|
.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
|
|
client.register(MultiPartFeature.class);
|
|
}
|
|
return client;
|
|
}
|
|
|
|
public ZenodoDeposition readDeposition(Integer id) throws ZenodoException {
|
|
Response resp= getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).path(id+"").
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.get();
|
|
return check(resp,ZenodoDeposition.class);
|
|
}
|
|
|
|
|
|
private static <T> T check(Response resp, Class<T> clazz) throws ZenodoException{
|
|
if(resp.getStatus()<200||resp.getStatus()>=300) {
|
|
String remoteMessage=resp.readEntity(String.class);
|
|
Integer httpCode=resp.getStatus();
|
|
ZenodoException e=new ZenodoException("RESP STATUS IS "+httpCode+". Message : "+remoteMessage);
|
|
e.setRemoteMessage(remoteMessage);
|
|
e.setResponseHTTPCode(httpCode);
|
|
throw e;
|
|
}else {
|
|
if(clazz==null) return null;
|
|
String respString=resp.readEntity(String.class);
|
|
try {
|
|
return mapper.readValue(Fixer.fixIncoming(respString), clazz);
|
|
} catch (IOException e) {
|
|
throw new ZenodoException("Unable to parse response from Zenodo. Content was : \n "+respString,e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public ZenodoDeposition updateMetadata(ZenodoDeposition dep) throws ZenodoException {
|
|
return updateMetadata(dep.getId(), dep.getMetadata());
|
|
}
|
|
|
|
public FileDeposition uploadFile(ZenodoDeposition deposition, String toUploadName,File toUpload) throws ZenodoException {
|
|
final ZenodoDeposition dep=(deposition.getSubmitted())?newVersion(deposition.getId()):deposition;
|
|
|
|
|
|
Callable<Response> call=new Callable<Response>() {
|
|
@Override
|
|
public Response call() throws Exception {
|
|
try {
|
|
|
|
//upload
|
|
FormDataMultiPart multi=new FormDataMultiPart();
|
|
FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file",
|
|
toUpload,MediaType.APPLICATION_OCTET_STREAM_TYPE);
|
|
multi.field("name", toUploadName);
|
|
multi.bodyPart(fileDataBodyPart);
|
|
|
|
log.debug("Starting transfer of "+toUploadName+" into "+dep.getId());
|
|
Response toReturn=getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).path(dep.getId()+"").path("files").
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.post(Entity.entity(multi,multi.getMediaType()));
|
|
|
|
log.debug("DONE.");
|
|
return toReturn;
|
|
|
|
}catch(Throwable e) {
|
|
throw new ZenodoException("Unable to transfer file "+toUploadName,e);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
log.debug("Submitting request to upload "+toUploadName+" to Manager");
|
|
Future<Response> resp=FileUploaderManager.submitForResponse(call);
|
|
|
|
try {
|
|
return check(resp.get(),FileDeposition.class);
|
|
}catch(ZenodoException z) {
|
|
throw z;
|
|
}catch(Throwable t) {
|
|
throw new ZenodoException(t.getMessage(),t);
|
|
}
|
|
|
|
//return
|
|
|
|
}
|
|
|
|
|
|
public void deleteFile(ZenodoDeposition dep,FileDeposition toDelete) throws ZenodoException {
|
|
if(dep.getSubmitted())
|
|
dep=newVersion(dep.getId());
|
|
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).
|
|
path(dep.getId()+"").
|
|
path("files").
|
|
path(toDelete.getId()).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.delete();
|
|
try {
|
|
check(resp,null);
|
|
}catch(ZenodoException z) {
|
|
throw z;
|
|
}catch(Throwable t) {
|
|
throw new ZenodoException(t.getMessage(),t);
|
|
}
|
|
}
|
|
|
|
|
|
public ZenodoDeposition newVersion(Integer originalId) throws ZenodoException {
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).
|
|
path(originalId+"").
|
|
path(NEW_VERSION_URL_POST).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.post(Entity.json("{}"));
|
|
ZenodoDeposition d=check(resp,ZenodoDeposition.class);
|
|
|
|
|
|
//GET LATEST DRAFT
|
|
resp=getWebClient().target(d.getLinks().getLatest_draft()).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE).get();
|
|
|
|
|
|
try {
|
|
return check(resp,ZenodoDeposition.class);
|
|
}catch(ZenodoException z) {
|
|
throw z;
|
|
}catch(Throwable t) {
|
|
throw new ZenodoException(t.getMessage(),t);
|
|
}
|
|
}
|
|
|
|
private ZenodoDeposition updateMetadata(Integer depositionId,DepositionMetadata meta) throws ZenodoException {
|
|
try{
|
|
String serialized="{\"metadata\":"+Fixer.fixIncoming(mapper.writeValueAsString(meta))+"}";
|
|
try {
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).path(depositionId+"").
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.put(Entity.json(serialized));
|
|
return check(resp,ZenodoDeposition.class);
|
|
}catch(Throwable t) {
|
|
log.debug("Error while tryin to update "+serialized);
|
|
throw t;
|
|
}
|
|
}catch(JsonProcessingException e) {
|
|
log.debug("Error while parsing "+meta,e);
|
|
throw new ZenodoException("Internal error.",e);
|
|
}
|
|
}
|
|
|
|
public ZenodoDeposition unlockPublished(Integer depositionId) throws ZenodoException {
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).
|
|
path(depositionId+"").
|
|
path(UNLOCK_URL_POST).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.post(Entity.json("{}"));
|
|
return check(resp,ZenodoDeposition.class);
|
|
}
|
|
|
|
public void deleteDeposition(Integer depositionId) throws ZenodoException {
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).path(depositionId+"").
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.delete();
|
|
check(resp,null);
|
|
}
|
|
|
|
public ZenodoDeposition createNew() throws ZenodoException {
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.post(Entity.json("{}"));
|
|
return check(resp,ZenodoDeposition.class);
|
|
}
|
|
|
|
public ZenodoDeposition publish(ZenodoDeposition dep) throws ZenodoException{
|
|
return publish(dep.getId());
|
|
}
|
|
|
|
private ZenodoDeposition publish(Integer depositionId) throws ZenodoException{
|
|
Response resp = getWebClient().target(credentials.getBaseUrl()).
|
|
path(DEPOSITION_BASE_URL).
|
|
path(depositionId+"").
|
|
path(PUBLISH_URL_POST).
|
|
queryParam(ACCESS_TOKEN, credentials.getKey()).request(CONTENT_TYPE)
|
|
.post(Entity.json("{}"));
|
|
return check(resp,ZenodoDeposition.class);
|
|
}
|
|
|
|
|
|
|
|
}
|