diff --git a/pom.xml b/pom.xml index ccaec7d..3649229 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.gcube.data.transfer uri-resolver - 1.15.0-SNAPSHOT + 2.0.0-SNAPSHOT war The URI Resolver is an HTTP URI resolver implemented as an HTTP servlet which gives access trough HTTP to different protocols URIs. @@ -25,33 +25,43 @@ + + + + org.gcube.distribution + maven-smartgears-bom + LATEST + pom + import + + + + + + org.gcube.core + common-smartgears + + + + org.gcube.common + common-authorization + + - - junit - junit - 4.8.2 - test - + org.gcube.contentmanagement storage-manager-wrapper [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) - - - org.json - json - 20140107 - compile - - + org.gcube.contentmanagement storage-manager-core @@ -63,6 +73,57 @@ + + + org.gcube.core + common-encryption + compile + + + + org.gcube.resources.discovery + discovery-client + + + + + org.gcube.common + authorization-client + + + + + + javax.ws.rs + javax.ws.rs-api + 2.0 + + + org.glassfish.jersey.containers + jersey-container-servlet + 2.13 + + + org.glassfish.jersey.containers.glassfish + jersey-gf-cdi + 2.13 + + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + org.json + json + 20140107 + compile + + + javax.servlet javax.servlet-api @@ -79,30 +140,12 @@ compile - - org.gcube.core - common-encryption - [1.0.1-SNAPSHOT, 2.0.0-SNAPSHOT) - compile - - - - org.gcube.resources.discovery - discovery-client - [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) - - commons-lang commons-lang 2.6 - - org.gcube.common - authorization-client - [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) - @@ -131,6 +174,14 @@ commons-io 1.2 + + + junit + junit + 4.8.2 + test + + diff --git a/src/main/java/org/gcube/datatransfer/resolver/Constants.java b/src/main/java/org/gcube/datatransfer/resolver/Constants.java new file mode 100644 index 0000000..70d0d29 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/Constants.java @@ -0,0 +1,7 @@ +package org.gcube.datatransfer.resolver; + +public class Constants { + + public static final String SERVLET_GEONETWORK = "geonetwork"; + public static final String SERVLET_CATALOGUE = "catalogue"; +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/ResourceCatalogueCodes.java b/src/main/java/org/gcube/datatransfer/resolver/ResourceCatalogueCodes.java index 1bda1a9..f3e5c9c 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/ResourceCatalogueCodes.java +++ b/src/main/java/org/gcube/datatransfer/resolver/ResourceCatalogueCodes.java @@ -17,8 +17,8 @@ import java.util.List; */ public enum ResourceCatalogueCodes { - CTLG("ctlg","product", "Catalogue Product/Dataset"), - CTLGP("ctlg-p","product", "Catalogue Product"), + CTLG("ctlg","dataset", "Catalogue Product/Dataset"), + CTLGP("ctlg-p","dataset", "Catalogue Product"), CTLGD("ctlg-d","dataset", "Catalogue Dataset"), CTLGO("ctlg-o","organization", "Catalogue Organization"), CTLGG("ctlg-g","group", "Catalogue Group"); diff --git a/src/main/java/org/gcube/datatransfer/resolver/SingleFileStreamingOutput.java b/src/main/java/org/gcube/datatransfer/resolver/SingleFileStreamingOutput.java new file mode 100644 index 0000000..f01e374 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/SingleFileStreamingOutput.java @@ -0,0 +1,46 @@ +package org.gcube.datatransfer.resolver; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SingleFileStreamingOutput implements StreamingOutput { + + private static final Logger log = LoggerFactory.getLogger(SingleFileStreamingOutput.class); + + + InputStream streamToWrite; + + public SingleFileStreamingOutput(InputStream streamToWrite) { + super(); + this.streamToWrite = streamToWrite; + } + + /** + * Overriding the write method to write request data directly to Jersey outputStream . + * @param outputStream + * @throws IOException + * @throws WebApplicationException + */ + @Override + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + log.debug("writing StreamOutput"); + copy(streamToWrite, outputStream); + log.debug("StreamOutput written"); + } + + private void copy(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[2048]; + int readcount = 0; + while ((readcount=in.read(buffer))!=-1) { + out.write(buffer, 0, readcount); + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java b/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java new file mode 100644 index 0000000..5571d8a --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java @@ -0,0 +1,23 @@ +package org.gcube.datatransfer.resolver; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; + +import org.gcube.datatransfer.resolver.services.Catalogue; +import org.gcube.datatransfer.resolver.services.StorageManager; + +@Path("uri-resolver") +public class UriResolver extends Application { + + @Override + public Set> getClasses() { + final Set> classes = new HashSet>(); + // register resources and features + classes.add(StorageManager.class); + classes.add(Catalogue.class); + return classes; + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueRequest.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueRequest.java new file mode 100644 index 0000000..15eb511 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueRequest.java @@ -0,0 +1,20 @@ +package org.gcube.datatransfer.resolver.catalogue; + +public class CatalogueRequest { + + private String gcube_scope; + private String entity_context; + private String entity_name; + + public String getGcube_scope() { + return gcube_scope; + } + public String getEntity_context() { + return entity_context; + } + public String getEntity_name() { + return entity_name; + } + + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/http/StorageIDResolver.java b/src/main/java/org/gcube/datatransfer/resolver/http/StorageIDResolver.java deleted file mode 100644 index 16a61f9..0000000 --- a/src/main/java/org/gcube/datatransfer/resolver/http/StorageIDResolver.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.gcube.datatransfer.resolver.http; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.io.IOUtils; -import org.gcube.contentmanagement.blobstorage.resource.MyFile; -import org.gcube.contentmanagement.blobstorage.service.IClient; -import org.gcube.contentmanagement.blobstorage.service.operation.GetHttpUrl; -import org.gcube.contentmanager.storageclient.model.protocol.smp.Handler; -import org.gcube.contentmanager.storageclient.wrapper.AccessType; -import org.gcube.contentmanager.storageclient.wrapper.MemoryType; -import org.gcube.contentmanager.storageclient.wrapper.StorageClient; -import org.gcube.datatransfer.resolver.MultiReadHttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - - -/** - * The Class StorageIDResolver. - * - * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it - * Jan 19, 2016 - */ -public class StorageIDResolver extends HttpServlet { - - private static final long serialVersionUID = -5208562956923156697L; - - protected static final String SMP_ID = "smp-id"; - protected static final String VALIDATION = "validation"; - protected static final String CONTENT_TYPE = "contentType"; - protected static final String FILE_NAME = "fileName"; - - /** The logger. */ - private static final Logger logger = LoggerFactory.getLogger(StorageIDResolver.class); - - - - /* (non-Javadoc) - * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) - */ - public void init(ServletConfig conf) throws ServletException { - Handler.activateProtocol(); - super.init(conf); - - } - - /* (non-Javadoc) - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - - String smpID =null; - String fileName =null; - String contentType =null; - boolean validatingURI = false; - -// logger.info("The http session id is: " + request.getSession().getId()); - - smpID = request.getParameter(SMP_ID); - - if (smpID == null || smpID.equals("")) { - logger.warn(SMP_ID+" not found"); - response.sendError(404); - return; - } - - fileName = request.getParameter(FILE_NAME); - - - if (fileName == null || fileName.equals("")) { - logger.warn(FILE_NAME+" not found"); - fileName = null; - } - - contentType = request.getParameter(CONTENT_TYPE); - - if (contentType == null || contentType.equals("")) { - logger.warn(CONTENT_TYPE+" not found"); - contentType = null; - } - - String validation = request.getParameter(VALIDATION); - validatingURI = Boolean.parseBoolean(validation); - logger.info("validation? "+validatingURI); - - //we should not unescape the filename with spaces - - logger.info(SMP_ID+" = "+ smpID); - MemoryType memory=null; - if(smpID.endsWith(GetHttpUrl.VOLATILE_URL_IDENTIFICATOR)){ - memory=MemoryType.VOLATILE; - smpID=smpID.replace(GetHttpUrl.VOLATILE_URL_IDENTIFICATOR, ""); - } - InputStream in = null; - String toSEID = null; - - try { - OutputStream out = response.getOutputStream(); - StorageClient client = null; - if(memory==null) - client=new StorageClient(StorageIDResolver.class.getName(), StorageIDResolver.class.getSimpleName(), "storageid-resolver", AccessType.PUBLIC); - else - client=new StorageClient(StorageIDResolver.class.getName(), StorageIDResolver.class.getSimpleName(), "storageid-resolver", AccessType.PUBLIC, memory); - - try{ - IClient icClient = client.getClient(); - toSEID = icClient.getId(smpID); //to Storage Encrypted ID - logger.debug("Decoded ID"+" = "+ toSEID); - - if(toSEID==null){ - String error = "Decrypted id is null, thrown exception!"; - throw new Exception(error); - } - - in=icClient.get().RFileAsInputStream(toSEID); //input stream - - }catch (Exception e) { - response.sendError(404); - logger.error("Storage Client Exception when getting file from storage: ", e); - return; - } - - //CASE InputStream NULL - if(in==null){ - logger.error("Input stream returned from storage is null, sending status error 404"); - sendErrorQuietly(response, 404); - return; - } - - try{ - MyFile file = client.getClient().getMetaFile().RFile(toSEID); - logger.debug("MetaFile retrieved from storage? "+ (file!=null)); - - if(fileName==null || fileName.isEmpty()){ //filename - fileName = file.getName(); - logger.debug("filename read from MetaFile: "+ fileName); - } - - if(contentType==null || contentType.isEmpty()){ //mime type - contentType = file.getMimeType(); - logger.debug("contentType read from MetaFile: "+ contentType); - } - - }catch (Exception e) { - logger.warn("Error when getting file metadata from storage, printing this warning and trying to continue..", e); - } - - //VALIDATING PARAMETERS: FILENAME AND CONTENT TYPE - if(fileName==null || fileName.isEmpty()) - fileName = ConstantsHttpResolver.DEFAULT_FILENAME_FROM_STORAGE_MANAGER; - - if(contentType==null || contentType.isEmpty()) - contentType = ConstantsHttpResolver.DEFAULT_CONTENTTYPE_UNKNOWN_UNKNOWN; - - //The filename should be a quoted string. (According to Section 19.5.1 of RFC 2616) - //http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1 - response.setHeader(ConstantsHttpResolver.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\""); - response.setContentType(contentType); - - //CASE VALIDATION - if(validatingURI){ - byte[] bytes = new byte[1]; //1B - int c = in.read(bytes); - logger.info(c+" byte read from InputStream"); - if(c>0){ - logger.info("at least 1 byte read, returning status 200"); - IOUtils.closeQuietly(in); - response.setStatus(200); - return; - } - } - - try { - - IOUtils.copy(in, out); - - } catch (IOException e){ - logger.warn("IOException class name: "+e.getClass().getSimpleName()); - if (e.getClass().getSimpleName().equals("ClientAbortException")) - logger.warn("Skipping ClientAbortException: "+e.getMessage()); - else - throw e; //Sending Exceptions - - } catch (NullPointerException e) { - logger.warn("NullPointerException during copy, skipping printStrackTrace"); - sendErrorQuietly(response, 404); - - } catch (Exception e) { - logger.error("Exception: ",e); - sendErrorQuietly(response, 404); - - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); - } - - } catch (Exception e) { - logger.error("Exception:", e); - IOUtils.closeQuietly(in); - sendErrorQuietly(response, 404); - return; - } - - } - - /* (non-Javadoc) - * @see javax.servlet.http.HttpServlet#doHead(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - logger.info("doHead working.."); - - String hpc = req.getParameter(ConstantsHttpResolver.HPC); //for HProxy check - try{ - if(hpc==null || Boolean.parseBoolean(hpc)){ - logger.trace("returning status 200 for Hproxy check"); - resp.setStatus(200); - return; - } - }catch (Exception e) { - //silent exception to continue.. - } - - //ADDING PARAMETER TO PERFORM ONLY VALIDATION - Map additionalParams = new HashMap(); - String[] value = new String[1]; - value[0] = "true"; - additionalParams.put(VALIDATION, value); - MultiReadHttpServletRequest request = new MultiReadHttpServletRequest(req, additionalParams); - doGet(request, resp); - } - - /** - * Send error quietly. - * - * @param response the response - * @param code the code - */ - protected void sendErrorQuietly(HttpServletResponse response, int code){ - - if(response!=null){ - try { - response.sendError(code); - logger.info("Response sent error: "+code); - } catch (IOException ioe) { - // ignore - } - } - } - - /* (non-Javadoc) - * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { - doGet(request,response); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/Catalogue.java b/src/main/java/org/gcube/datatransfer/resolver/services/Catalogue.java new file mode 100644 index 0000000..af36581 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/Catalogue.java @@ -0,0 +1,196 @@ +package org.gcube.datatransfer.resolver.services; + +import java.net.URL; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datatransfer.resolver.Constants; +import org.gcube.datatransfer.resolver.ResourceCatalogueCodes; +import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; +import org.gcube.datatransfer.resolver.catalogue.CatalogueRequest; +import org.gcube.datatransfer.resolver.catalogue.CatalogueResolver; +import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver; +import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader; +import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference; +import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver; +import org.gcube.datatransfer.resolver.scope.ScopeUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.trentorise.opendata.jackan.model.CkanDataset; + +@Path(Constants.SERVLET_CATALOGUE) +public class Catalogue { + + private static Logger logger = LoggerFactory.getLogger(Catalogue.class); + + private ApplicationProfileReaderForCatalogueResolver appPrCatResolver; + + public static final String ENV_SCOPE = "SCOPE"; //Environment Variable + + /** The scope to enc decr. */ + private String scopeToEncDecr = null; + + + public void init() throws ServletException { + initScopeFromEnv(); + } + + + /** + * Inits the scope from env. + * + * @return the string + * @throws ServletException the servlet exception + */ + private String initScopeFromEnv() throws ServletException{ + + if(scopeToEncDecr!=null) + return scopeToEncDecr; + + try{ + scopeToEncDecr = ScopeUtil.getScopeFromEnvironment(); + }catch(ServletException e){ + logger.error("I cannot encrypt/descrypt: ", e); + throw new ServletException(CatalogueResolver.class.getName() +" cannot work without set the Environment Variable: "+ENV_SCOPE); + } + + appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(scopeToEncDecr, true); + logger.info("Resource read for CatalogueResolver: "+appPrCatResolver); + return scopeToEncDecr; + } + + + @GET + @Path("{ctlg(-(o|g|p|g))?}/{vreName}/{entityName}") + public Response resolveCatalogue(@PathParam("entityName") String entityName, @PathParam("vreName") String vreName, @PathParam("entityContext") String entityContext) { + + try { + String entityContextValue = ResourceCatalogueCodes.valueOfCodeId(entityContext).getValue(); + + ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(vreName, true); + + String fullScope = appPrCatResolver.getHashVreNameScope().get(vreName); + + ScopeProvider.instance.set(fullScope); + GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); + + logger.debug("Read fullScope: "+fullScope + " for VRE_NAME: "+vreName +" into Application Profile "+ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME); + + //IS THE PRODUCT PLUBLIC OR PRIVATE? + //USING ACCESS TO PUBLIC PORTLET IF THE ITEM IS PUBLIC, OTHERWISE ACCESS TO PRIVATE PORTLET + String ckanPorltetUrl = ckanCatalogueReference.getPrivatePortletURL(); + String datasetName = entityName; + if(ckanCatalogueReference.getCkanURL()!=null){ + try{ + CkanDataset dataset = CkanCatalogueConfigurationsReader.getDataset(datasetName, ckanCatalogueReference.getCkanURL()); + if(dataset!=null){ + ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); + logger.info("The dataset "+datasetName+" is a public item using public access to CKAN portlet: "+ckanPorltetUrl); + } + }catch(Exception e){ + logger.warn("Error on checking if dataset: "+datasetName+" is private or not", e); + ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); + } + } + + + String url = String.format("%s?path=/%s/%s",ckanPorltetUrl,entityContextValue, entityName); + + return Response.seeOther(new URL(url).toURI()).build(); + }catch (Exception e) { + logger.error("error resolving catalogue link",e); + throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR); + } + } + + @POST + @Path("") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.TEXT_PLAIN) + public Response postCatalogue(@Context HttpServletRequest req, CatalogueRequest jsonRequest) { + //final CatalogueEntityRequest cer = new CatalogueEntityRequest(); + + //CHECK IF INPUT SCOPE IS VALID + String scope = jsonRequest.getGcube_scope(); + if(!scope.startsWith("/")){ + logger.info("Scope not start with char '/' adding it"); + scope+="/"+scope; + } + + String serverUrl = getServerURL(req); + + final String vreName = scope.substring(scope.lastIndexOf("/")+1, scope.length()); + + ResourceCatalogueCodes rc = ResourceCatalogueCodes.valueOfCodeValue(jsonRequest.getEntity_context()); + if(rc==null){ + logger.error("Entity context is null/malformed"); + throw new WebApplicationException("Entity context is null/malformed", Status.BAD_REQUEST); + } + + + String linkURL = String.format("%s/%s/%s/%s", serverUrl, rc.getId(), vreName, jsonRequest.getEntity_name()); + + logger.info("Writing Decoded Catalogue Link: "+linkURL); + + //IT'S GOING TO UPDATE THE GENERIC RESOURCE IF IS NEEDED + final String fullscope = scope; + new Thread(){ + public void run() { + try { + boolean endPointUpdated = UpdateApplicationProfileCatalogueResolver.validateEndPoint(scopeToEncDecr, vreName, fullscope); + if(endPointUpdated) + appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(fullscope, true); + } + catch (ApplicationProfileNotFoundException e) { + logger.error("Error during validating Application Profile", e); + } + }; + }.start(); + + + return Response.ok(linkURL).build(); + } + + /** + * Gets the server url. + * + * @param req the req + * @return the server url + */ + private String getServerURL(HttpServletRequest req) { + + String scheme = req.getScheme(); // http + String serverName = req.getServerName(); // hostname.com + int serverPort = req.getServerPort(); // 80 + //String contextPath = req.getContextPath(); // /mywebapp + + // Reconstruct original requesting URL + StringBuffer url = new StringBuffer(); + url.append(scheme).append("://").append(serverName); + + if (serverPort != 80 && serverPort != 443) + url.append(":").append(serverPort); + + // if(contextPath!=null) + // url.append(":").append(contextPath); + + String uToS = url.toString(); + logger.debug("returning servlet context URL: "+uToS); + return uToS; + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/GeoServer.java b/src/main/java/org/gcube/datatransfer/resolver/services/GeoServer.java new file mode 100644 index 0000000..716a378 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/GeoServer.java @@ -0,0 +1,14 @@ +package org.gcube.datatransfer.resolver.services; + +import javax.ws.rs.Path; + +import org.gcube.datatransfer.resolver.Constants; + +@Path(Constants.SERVLET_GEONETWORK) +public class GeoServer { + + public void resolveGeoserver() { + + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/StorageManager.java b/src/main/java/org/gcube/datatransfer/resolver/services/StorageManager.java new file mode 100644 index 0000000..dfeab9e --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/StorageManager.java @@ -0,0 +1,67 @@ +package org.gcube.datatransfer.resolver.services; + +import java.io.InputStream; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.StreamingOutput; + +import org.gcube.contentmanagement.blobstorage.resource.MyFile; +import org.gcube.contentmanagement.blobstorage.service.IClient; +import org.gcube.contentmanager.storageclient.wrapper.AccessType; +import org.gcube.contentmanager.storageclient.wrapper.StorageClient; +import org.gcube.datatransfer.resolver.SingleFileStreamingOutput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("") +public class StorageManager { + + private static Logger logger = LoggerFactory.getLogger(StorageManager.class); + + @Path("{smpId}") + @Produces() + public Response getFile(@PathParam("smpId") String smpId) { + StorageClient client = new StorageClient("DataTransfer", "UriResolver", "storageid-resolver", AccessType.PUBLIC); + IClient iClient = client.getClient(); + String toSEID = iClient.getId(smpId); //to Storage Encrypted ID + logger.debug("Decoded ID"+" = "+ toSEID); + + if(toSEID==null){ + String error = "Decrypted id is null, thrown exception!"; + throw new WebApplicationException(error, Status.BAD_REQUEST); + } + + long size = iClient.getSize().RFileById(toSEID); + String fileName="download"; + String contentType=null; + try{ + MyFile file = client.getClient().getMetaFile().RFile(toSEID); + logger.debug("MetaFile retrieved from storage? "+ (file!=null)); + + fileName= file.getName(); + contentType = file.getMimeType(); + + }catch (Exception e) { + logger.warn("Error when getting file metadata from storage, printing this warning and trying to continue..", e); + } + + + InputStream streamToWrite=iClient.get().RFileAsInputStream(toSEID); //input stream + + StreamingOutput so = new SingleFileStreamingOutput(streamToWrite); + + ResponseBuilder response = Response + .ok(so) + .header("content-disposition","attachment; filename = "+fileName) + .header("Content-Length", size); + if (contentType!= null) response.header("Content-Type",contentType); + return response.build(); + } + +} diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml new file mode 100644 index 0000000..b6455fc --- /dev/null +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -0,0 +1,7 @@ + + URIResolver + DataTransfer + 1.0.0-SNAPSHOT + Storage Hub webapp + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 6aaf420..be5ca7e 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,7 +1,7 @@ - + + + + + + + org.gcube.data.access.storagehub.StorageHub + + + + org.gcube.data.access.storagehub.StorageHub + /workspace/*