Feature #17630 Support parametric Content-Disposition

This commit is contained in:
Francesco Mangiacrapa 2019-09-27 11:56:00 +02:00
parent 2290ae24e2
commit 4b57fae760
8 changed files with 51 additions and 31 deletions

View File

@ -4,9 +4,6 @@
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/> <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="ckan-util-library-2.10.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/ckan-util-library-TRUNK/ckan-util-library-TRUNK">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="uri-resolver"/> <property name="context-root" value="uri-resolver"/>
<property name="java-output-path" value="/uri-resolver/target/classes"/> <property name="java-output-path" value="/uri-resolver/target/classes"/>
</wb-module> </wb-module>

View File

@ -159,4 +159,10 @@
<Change>[Incident #17180] Bug fixes <Change>[Incident #17180] Bug fixes
</Change> </Change>
</Changeset> </Changeset>
<Changeset
component="org.gcube.data-transfer.uri-resolver.2-2-0"
date="${buildDate}">
<Change>[Feature #17630] Support parametric Content-Disposition
</Change>
</Changeset>
</ReleaseNotes> </ReleaseNotes>

View File

@ -9,7 +9,7 @@
</parent> </parent>
<groupId>org.gcube.data.transfer</groupId> <groupId>org.gcube.data.transfer</groupId>
<artifactId>uri-resolver</artifactId> <artifactId>uri-resolver</artifactId>
<version>2.1.1-SNAPSHOT</version> <version>2.2.0-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<description>The URI Resolver is an HTTP URI resolver implemented as an REST service which gives access trough HTTP to different gcube Resolvers and gCube Applications.</description> <description>The URI Resolver is an HTTP URI resolver implemented as an REST service which gives access trough HTTP to different gcube Resolvers and gCube Applications.</description>

View File

@ -12,10 +12,13 @@ package org.gcube.datatransfer.resolver;
public class ConstantsResolver { public class ConstantsResolver {
public static final String CONTENT_DISPOSITION = "Content-Disposition"; public static final String CONTENT_DISPOSITION = "Content-Disposition";
public static final String DEFAULT_CONTENTTYPE_UNKNOWN_UNKNOWN = "unknown/unknown"; public static enum CONTENT_DISPOSITION_VALUE {inline, attachment};
public static final String DEFAULT_FILENAME_FROM_STORAGE_MANAGER = "fromStorageManager";
public static final String CONTENT_LENGTH = "Content-Length"; public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TYPE= "Content-Type"; public static final String CONTENT_TYPE= "Content-Type";
public static final String QUERY_PARAM_CONTENTDISPOSITION = "content-disposition";
public static final String DEFAULT_CONTENTTYPE_UNKNOWN_UNKNOWN = "unknown/unknown";
public static final String DEFAULT_FILENAME_FROM_STORAGE_MANAGER = "fromStorageManager";
public static final String HPC = "hproxycheck"; //for hproxycheck public static final String HPC = "hproxycheck"; //for hproxycheck

View File

@ -147,16 +147,4 @@ public class UpdateApplicationProfileCatalogueResolver {
return document; return document;
} }
// public static void main(String[] args) {
//
// String scope = "/gcube";
// try {
// UpdateApplicationProfileCatalogueResolver.validateEndPoint(
// scope, "gcube", "/gcube/devsec");
// }
// catch (Exception e) {
// e.printStackTrace();
// }
// }
} }

View File

@ -14,6 +14,8 @@ import javax.ws.rs.core.Response.ResponseBuilder;
import org.gcube.common.storagehub.client.StreamDescriptor; import org.gcube.common.storagehub.client.StreamDescriptor;
import org.gcube.common.storagehub.client.plugins.AbstractPlugin; import org.gcube.common.storagehub.client.plugins.AbstractPlugin;
import org.gcube.common.storagehub.client.proxies.ItemManagerClient; import org.gcube.common.storagehub.client.proxies.ItemManagerClient;
import org.gcube.datatransfer.resolver.ConstantsResolver;
import org.gcube.datatransfer.resolver.ConstantsResolver.CONTENT_DISPOSITION_VALUE;
import org.gcube.datatransfer.resolver.services.error.ExceptionManager; import org.gcube.datatransfer.resolver.services.error.ExceptionManager;
import org.gcube.datatransfer.resolver.util.StorageHubMetadataResponseBuilder; import org.gcube.datatransfer.resolver.util.StorageHubMetadataResponseBuilder;
import org.gcube.smartgears.utils.InnerMethodName; import org.gcube.smartgears.utils.InnerMethodName;
@ -68,7 +70,7 @@ public class StorageHubResolver {
ItemManagerClient client = AbstractPlugin.item().build(); ItemManagerClient client = AbstractPlugin.item().build();
StreamDescriptor descriptor = client.resolvePublicLink(id); StreamDescriptor descriptor = client.resolvePublicLink(id);
ResponseBuilder response = Response.noContent(); ResponseBuilder response = Response.noContent();
response = new StorageHubMetadataResponseBuilder(req, response).fillMetadata(descriptor, id); response = new StorageHubMetadataResponseBuilder(req, response).fillMetadata(descriptor, id, CONTENT_DISPOSITION_VALUE.attachment);
return response.build(); return response.build();
}catch(Exception e){ }catch(Exception e){
@ -105,11 +107,27 @@ public class StorageHubResolver {
try{ try{
InnerMethodName.instance.set("resolveStorageHubPublicLink"); InnerMethodName.instance.set("resolveStorageHubPublicLink");
//Checking mandatory parameter id //Checking mandatory parameter "id"
if(id==null || id.isEmpty()){ if(id==null || id.isEmpty()){
logger.error("Path Parameter "+STORAGE_HUB_ID+" not found"); logger.error("Path Parameter "+STORAGE_HUB_ID+" not found");
throw ExceptionManager.badRequestException(req, "Missing mandatory path parameter "+STORAGE_HUB_ID, StorageHubResolver.class, help); throw ExceptionManager.badRequestException(req, "Missing mandatory path parameter "+STORAGE_HUB_ID, StorageHubResolver.class, help);
} }
//Checking the optional parameter "Content-Disposition"
String contDisp = req.getParameter(ConstantsResolver.QUERY_PARAM_CONTENTDISPOSITION);
CONTENT_DISPOSITION_VALUE dispValue = CONTENT_DISPOSITION_VALUE.attachment;
//Validating the Content-Disposition value
if(contDisp!=null && !contDisp.isEmpty()) {
try {
//It must have a value of: "inline" or "attachement"
dispValue = ConstantsResolver.CONTENT_DISPOSITION_VALUE.valueOf(contDisp);
}catch (Exception e) {
String allowedValues = String.format("{%s,%s}", CONTENT_DISPOSITION_VALUE.inline,CONTENT_DISPOSITION_VALUE.attachment);
String errorMsg = "The parameter "+ConstantsResolver.QUERY_PARAM_CONTENTDISPOSITION+" passed in the query string is not a value of "+allowedValues;
logger.error(errorMsg);
throw ExceptionManager.badRequestException(req, errorMsg, StorageHubResolver.class, help);
}
}
try{ try{
@ -117,7 +135,7 @@ public class StorageHubResolver {
StreamDescriptor descriptor = client.resolvePublicLink(id); StreamDescriptor descriptor = client.resolvePublicLink(id);
ResponseBuilder response = Response.ok(descriptor.getStream()); ResponseBuilder response = Response.ok(descriptor.getStream());
response = new StorageHubMetadataResponseBuilder(req, response).fillMetadata(descriptor, id); response = new StorageHubMetadataResponseBuilder(req, response).fillMetadata(descriptor, id, dispValue);
return response.build(); return response.build();
}catch(Exception e){ }catch(Exception e){

View File

@ -282,7 +282,7 @@ public class GetResponseRecordFilter {
Map<String, Boolean> overridingRecordsMap = new HashMap<String, Boolean>(); Map<String, Boolean> overridingRecordsMap = new HashMap<String, Boolean>();
int overrideCount = 0; int overrideCount = 0;
//FOR EACH PUBLIC IDS //FOR EACH PUBLIC IDS
for (String identifier : idsToRemove) { for (String publicIdentifier : idsToRemove) {
//FOR EACH gmd:fileIdentifier RETURNED IN THE GET_RECORDS RESPONSE //FOR EACH gmd:fileIdentifier RETURNED IN THE GET_RECORDS RESPONSE
//CHECKING IF IT IS A PUBLIC ID //CHECKING IF IT IS A PUBLIC ID
@ -292,15 +292,19 @@ public class GetResponseRecordFilter {
// <dc:identifier> // <dc:identifier>
NodeList fileIdentifierLst = mdMetadata.getElementsByTagName("gmd:fileIdentifier"); NodeList fileIdentifierLst = mdMetadata.getElementsByTagName("gmd:fileIdentifier");
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("skipping identifier: " + identifier +" it has not fileidentifier"); logger.info("tagName gmd:fileIdentifier not found, trying to search 'fileIdentifier");
break; fileIdentifierLst = mdMetadata.getElementsByTagName("fileIdentifier");
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("also tagName fileIdentifier not found, skipping matching of public identifier " + publicIdentifier +" current gmd:MD_Metadata has not tagName 'gmd:fileIdentifier' or 'fileIdentifier'");
break;
}
} }
Element id = (Element) fileIdentifierLst.item(0); Element id = (Element) fileIdentifierLst.item(0);
NodeList gcoLst = id.getElementsByTagName("gco:CharacterString"); NodeList gcoLst = id.getElementsByTagName("gco:CharacterString");
if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){ if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){
logger.debug("skipping identifier: " + identifier +" it has not gco:CharacterString"); logger.debug("skipping matching of public identifier: " + publicIdentifier +"current gmd:MD_Metadata has not 'gco:CharacterString'");
break; break;
} }
@ -312,7 +316,7 @@ public class GetResponseRecordFilter {
} }
logger.trace("Summary gmd:fileIdentifier is: " + idValue); logger.trace("Summary gmd:fileIdentifier is: " + idValue);
if (idValue!=null && idValue.compareTo(identifier)==0) { if (idValue!=null && idValue.compareTo(publicIdentifier)==0) {
gco.setTextContent(messageToWrite); gco.setTextContent(messageToWrite);
logger.debug("Overrided child " + idValue); logger.debug("Overrided child " + idValue);
overridingRecordsMap.put(idValue, true); overridingRecordsMap.put(idValue, true);

View File

@ -10,6 +10,7 @@ import org.gcube.common.storagehub.client.StreamDescriptor;
import org.gcube.common.storagehub.client.plugins.AbstractPlugin; import org.gcube.common.storagehub.client.plugins.AbstractPlugin;
import org.gcube.common.storagehub.client.proxies.ItemManagerClient; import org.gcube.common.storagehub.client.proxies.ItemManagerClient;
import org.gcube.datatransfer.resolver.ConstantsResolver; import org.gcube.datatransfer.resolver.ConstantsResolver;
import org.gcube.datatransfer.resolver.ConstantsResolver.CONTENT_DISPOSITION_VALUE;
/** /**
@ -35,18 +36,21 @@ public class StorageHubMetadataResponseBuilder {
this.request = req; this.request = req;
this.responseBuilder = responseBuilder; this.responseBuilder = responseBuilder;
} }
/** /**
* Fill metadata. * Fill metadata.
*
* @param streamDescriptor the stream descriptor * @param streamDescriptor the stream descriptor
* @param entityId the entity id * @param entityId the entity id
* @param contentDispValue the content disp value
* @return the response builder * @return the response builder
*/ */
public ResponseBuilder fillMetadata(StreamDescriptor streamDescriptor, String entityId){ public ResponseBuilder fillMetadata(StreamDescriptor streamDescriptor, String entityId, CONTENT_DISPOSITION_VALUE contentDispValue){
//Adding "Content-Disposition" //Adding "Content-Disposition"
responseBuilder.header(ConstantsResolver.CONTENT_DISPOSITION,"attachment; filename=\""+streamDescriptor.getFileName()+"\""); String headerCD = String.format("%s; filename=\"%s\"", contentDispValue,streamDescriptor.getFileName());
responseBuilder.header(ConstantsResolver.CONTENT_DISPOSITION, headerCD);
//Adding "Content-Location" //Adding "Content-Location"
String contentLocation = String.format("%s/%s/%s", Util.getServerURL(request), "shub", entityId); String contentLocation = String.format("%s/%s/%s", Util.getServerURL(request), "shub", entityId);