ckan2zenodo-publisher-widget/src/main/java/org/gcube/portlets/widgets/ckan2zenodopublisher/server/CkanToZenodoPublisherServic...

305 lines
12 KiB
Java

package org.gcube.portlets.widgets.ckan2zenodopublisher.server;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.gcube.data.publishing.ckan2zenodo.Ckan2Zenodo;
import org.gcube.data.publishing.ckan2zenodo.Ckan2ZenodoImpl;
import org.gcube.data.publishing.ckan2zenodo.model.CkanItemDescriptor;
import org.gcube.data.publishing.ckan2zenodo.model.CkanResource;
import org.gcube.data.publishing.ckan2zenodo.model.faults.ConfigurationException;
import org.gcube.data.publishing.ckan2zenodo.model.faults.GcatException;
import org.gcube.data.publishing.ckan2zenodo.model.faults.TransformationException;
import org.gcube.data.publishing.ckan2zenodo.model.faults.ZenodoException;
import org.gcube.data.publishing.ckan2zenodo.model.report.EnvironmentReport;
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.DepositionMetadata;
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.ZenodoDeposition;
import org.gcube.portlets.widgets.ckan2zenodopublisher.client.CkanToZenodoPublisherService;
import org.gcube.portlets.widgets.ckan2zenodopublisher.server.configuration.ZenodoFieldsDescriptionsReader;
import org.gcube.portlets.widgets.ckan2zenodopublisher.server.converter.ItemToZenodoConverter;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.CatalogueItem;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.ItemTranslateError;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.ItemTranslateError.ERROR_TYPE;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.ZenodoError;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.wrapped.ZenodoFile;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.wrapped.ZenodoItem;
import org.gcube.portlets.widgets.ckan2zenodopublisher.shared.wrapped.ZenodoMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.liferay.portal.service.UserLocalServiceUtil;
/**
* The server side implementation of the RPC service.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Jan 15, 2020
*/
@SuppressWarnings("serial")
public class CkanToZenodoPublisherServiceImpl extends RemoteServiceServlet implements CkanToZenodoPublisherService {
private static Logger LOG = LoggerFactory.getLogger(CkanToZenodoPublisherServiceImpl.class);
/* (non-Javadoc)
* @see org.gcube.portlets.widgets.ckan2zenodopublisher.client.CkanToZenodoPublisherService#publishOnZenodo(org.gcube.portlets.widgets.ckan2zenodopublisher.shared.wrapped.ZenodoItem)
*/
@Override
public String publishOnZenodo(ZenodoItem zenodoItem) throws Exception {
LOG.info("publishOnZenodo called");
try {
if(isOutFromPortal()) {
PortalUtils.getCurrentContext(this.getThreadLocalRequest(), true);
PortalUtils.getCurrentToken(this.getThreadLocalRequest(), true);
}
Ckan2Zenodo client = new Ckan2ZenodoImpl();
// Get the item representation
CkanItemDescriptor itemDescr = client.read(zenodoItem.getName());
// Get a preview of the deposition to be published
ZenodoDeposition zenodoDepositionPreview = null;
try {
zenodoDepositionPreview = client.translate(itemDescr);
} catch (ConfigurationException e) {
LOG.info("Using forceTranslation for: " + itemDescr.getItemUrl());
zenodoDepositionPreview = client.forceTranslation(itemDescr);
}
//(EVENTUALLY) UPDATING BASIC INFO CHANGED BY FORM ON CLIENT-SIDE
//Basic info
zenodoDepositionPreview.setTitle(zenodoItem.getTitle());
//Updating Deposition Metadata potentially changed on client-side
ZenodoMetadata metadata = zenodoItem.getMetadata();
DepositionMetadata depositionMetadata = zenodoDepositionPreview.getMetadata();
depositionMetadata = ItemToZenodoConverter.updateMetadataInfoOfDepositionMetadata(metadata, depositionMetadata);
zenodoDepositionPreview.setMetadata(depositionMetadata);
//Loading Filtered resources according to VRE policies
List<CkanResource> filteredResources = loadFilterResources(zenodoItem.getName());
HashSet<CkanResource> toUpload = new HashSet<CkanResource>();
//Adding for publishing only the resources selected on clien-side
if(zenodoItem.getFiles()!=null) {
for (ZenodoFile zf : zenodoItem.getFiles()) {
for (CkanResource ckanResource : filteredResources) {
if(zf.getId().compareTo(ckanResource.getId())==0 && zf.getIsAlreadyPublished()==false) {
if(CkanToZenodoUtil.isNotEmpty(zf.getFilename())) {
ckanResource.setName(zf.getFilename()); //only the filename can be changed on clien-side
toUpload.add(ckanResource);
}
}
}
}
}
//Actually publish to zenodo :
// Step 1 : metadata
client= new Ckan2ZenodoImpl();
LOG.debug("Calling updatedMetadata for: "+zenodoDepositionPreview);
zenodoDepositionPreview = client.updatedMetadata(zenodoDepositionPreview);
//Step 2 : publish Resources
if(toUpload.size()>0) {
LOG.debug("Trying to publish the set of CKAN resources: "+toUpload.toString());
Future<ZenodoDeposition> future_Dep=client.uploadFiles(toUpload, zenodoDepositionPreview);
while(!future_Dep.isDone()) {
LOG.debug("Waiting for completed future computation (publishing of resources on Zenodo)...");
Thread.sleep(2000);
}
zenodoDepositionPreview = future_Dep.get(600,TimeUnit.SECONDS);
}
// Get the item representation
CkanItemDescriptor item=client.read(zenodoItem.getName());
//Finalize
LOG.debug("Calling publish on Zenodo for: "+zenodoDepositionPreview);
zenodoDepositionPreview = client.publish(zenodoDepositionPreview, item);
return zenodoDepositionPreview.getDoi();
//throw new ZenodoException();
}catch (TimeoutException e) {
String error = "I'm waiting too time to upload the files to Zenodo. Check by yourself the result later";
LOG.error(error, e);
String clientError = String.format("%s", error);
throw new Exception(clientError);
} catch (ZenodoException e) {
String error = ZenodoException.class.getName()+" during upload to Zenodo the catalogue item: "+zenodoItem.getName();
LOG.error(error, e);
//String clientError = String.format("%s", e.getRemoteMessage());
ZenodoError zenodoError = new ZenodoError(e);
zenodoError.setRemoteMessage(e.getRemoteMessage());
zenodoError.setResponseHTTPCode(e.getResponseHTTPCode());
throw zenodoError;
} catch (Exception e) {
String error = "Error during upload to Zenodo the catalogue item: "+zenodoItem.getName();
LOG.error(error, e);
String clientError = String.format("%s. %s", error, e.getMessage());
throw new Exception(clientError);
}
}
/* (non-Javadoc)
* @see org.gcube.portlets.widgets.ckan2zenodopublisher.client.CkanToZenodoPublisherService#convertToZenodoItem(org.gcube.portlets.widgets.ckan2zenodopublisher.shared.CatalogueItem)
*/
@Override
public ZenodoItem convertToZenodoItem(CatalogueItem item) throws Exception {
LOG.info("convertToZenodoItem called");
try {
if(isOutFromPortal()) {
PortalUtils.getCurrentContext(this.getThreadLocalRequest(), true);
PortalUtils.getCurrentToken(this.getThreadLocalRequest(), true);
}
Ckan2Zenodo client = new Ckan2ZenodoImpl();
// Get the item representation
CkanItemDescriptor itemDescr = client.read(item.getItemId());
// Get a preview of the deposition to be published
ZenodoDeposition zdDeposition = null;
ItemTranslateError itemTrError = null;
try {
zdDeposition = client.translate(itemDescr);
} catch (ConfigurationException e) {
LOG.info(ConfigurationException.class.getSimpleName() + " thrown, trying to use forceTranslation for: "
+ itemDescr.getName());
itemTrError = new ItemTranslateError(e.getMessage(), ERROR_TYPE.INFO);
zdDeposition = client.forceTranslation(itemDescr);
}
//Loading Filtered resources according to VRE policies
List<CkanResource> filteredResources = loadFilterResources(item.getItemId());
LOG.debug("Loaded filtered resources: "+filteredResources);
//Converting ZenodoDeposition to ZenodoItem
ZenodoItem zenodoItem = ItemToZenodoConverter.toZenodoItem(zdDeposition);
//Adding ItemTranslateError eventually occurred by calling client.translate
zenodoItem.setTranslateError(itemTrError);
//Adding the filtered resources
List<ZenodoFile> resources = ItemToZenodoConverter.toZenodoFiles(filteredResources, false);
zenodoItem.addFiles(resources);
//I'M SETTING THE ID BECAUSE THE NAME IS NULL INTO BEAN PASSED FROM PORTLET SIDE
//TODO I'M WAITING FOR itemName retrieved from ckan2zenodo library
zenodoItem.setName(item.getItemId());
LOG.debug("Returning item: "+zenodoItem);
return zenodoItem;
} catch (ZenodoException e) {
String error = ZenodoException.class.getName()+" on converting the catalogue item with id: "+item.getItemId();
LOG.error(error, e);
//String clientError = String.format("%s. %s", error, e.getRemoteMessage());
ZenodoError zenodoError = new ZenodoError(e);
zenodoError.setRemoteMessage(e.getRemoteMessage());
zenodoError.setResponseHTTPCode(e.getResponseHTTPCode());
throw zenodoError;
} catch (Exception e) {
String error = "Error on converting the catalogue item with id: "+item.getItemId();
LOG.error(error, e);
String clientError = String.format("%s. %s", error, e.getMessage());
throw new Exception(clientError);
}
}
/* (non-Javadoc)
* @see org.gcube.portlets.widgets.ckan2zenodopublisher.client.CkanToZenodoPublisherService#convertToZenodoItem(org.gcube.portlets.widgets.ckan2zenodopublisher.shared.CatalogueItem)
*/
@Override
public Map<String, String> readFieldsDescriptions() throws Exception {
LOG.info("readFieldsDescriptions called");
try {
if(isOutFromPortal()) {
PortalUtils.getCurrentContext(this.getThreadLocalRequest(), true);
PortalUtils.getCurrentToken(this.getThreadLocalRequest(), true);
}
return ZenodoFieldsDescriptionsReader.readProperties();
} catch (Exception e) {
String error = "Unable to read the file of properties with the fields desciptions";
LOG.error(error, e);
String clientError = String.format("%s. %s", error, e.getMessage());
throw new Exception(clientError);
}
}
@Override
public Boolean checkZenodoEnvironment() {
LOG.info("checkZenodoEnvironment called");
boolean isZenodoConfigured = false;
try {
if(isOutFromPortal()) {
PortalUtils.getCurrentContext(this.getThreadLocalRequest(), true);
PortalUtils.getCurrentToken(this.getThreadLocalRequest(), true);
}
LOG.info("readFieldsDescriptions called");
Ckan2Zenodo client = new Ckan2ZenodoImpl();
EnvironmentReport report = client.checkEnvironment();
LOG.info("EnvironmentReport returned: "+report);
isZenodoConfigured = report.isok();
} catch (Exception e) {
LOG.error("Error occurred during checkEnvironment: ", e);
}
LOG.info("Is Zenodo Environment configured? " + isZenodoConfigured);
return isZenodoConfigured;
}
/**
* Load filter resources.
*
* @param itemName the item name
* @return the list
* @throws GcatException the gcat exception
* @throws ConfigurationException the configuration exception
* @throws TransformationException the transformation exception
*/
private List<CkanResource> loadFilterResources(String itemName) throws GcatException, ConfigurationException, TransformationException {
Ckan2Zenodo client = new Ckan2ZenodoImpl();
// Get the item representation
CkanItemDescriptor itemDescr=client.read(itemName);
//Filter resources according to VRE policies
return client.filterResources(itemDescr);
}
/**
* Online or in development mode?.
*
* @return true if you're running into the portal, false if in development
*/
private boolean isOutFromPortal() {
try {
UserLocalServiceUtil.getService();
return false;
}
catch (com.liferay.portal.kernel.bean.BeanLocatorException ex) {
LOG.debug("Development Mode ON");
return true;
}
}
}