Completed working on

[Task #6119] Provide CatalogueResolver: get/resolve a link to a CKAN Entity

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/data-transfer/uri-resolver@139708 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Francesco Mangiacrapa 2016-12-06 10:47:37 +00:00
parent 5a59d6fe3d
commit a3d3a9f709
4 changed files with 119 additions and 41 deletions

View File

@ -4,6 +4,9 @@
<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="gcube-url-shortener-1.1.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/gcube-url-shortener-BRANCH-1.1.0-SNAPSHOT/gcube-url-shortener-BRANCH-1.1.0-SNAPSHOT">
<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

@ -17,20 +17,32 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* The Class UriResolverRewriteFilter. * The Class UriResolverRewriteFilter.
* *
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Apr 5, 2016 * Dec 5, 2016
*/ */
public class UriResolverRewriteFilter implements Filter{ public class UriResolverRewriteFilter implements Filter{
/**
*
*/
public static final String SERVLET_URI_RESOLVER = "/uri-resolver";
private static final String PATH_SEPARATOR = "/";
public static final String SERVLET_GEONETWORK = "/geonetwork"; public static final String SERVLET_GEONETWORK = "/geonetwork";
public static final String PARAMETER_FILTER_PUBLIC_IDS = "filterpublicids"; public static final String PARAMETER_FILTER_PUBLIC_IDS = "filterpublicids";
public static final String PARAMETER_NO_AUTHENTICATION = "noauthentication"; public static final String PARAMETER_NO_AUTHENTICATION = "noauthentication";
public static final String REQUEST_PARAMETER_SEPARATOR = "#"; public static final String REQUEST_PARAMETER_SEPARATOR = "#";
protected static final String SMP_ID = "smp-id";
protected static final String SERVLET_RESOLVER_BY_ID = "id"; public static final String PARAMETER_SMP_ID = "smp-id";
public static final String SERVLET_STORAGE_ID = "id";
public static final String PARAMETER_CATALOGUE_LINK = "cl";
public static final String SERVLET_CATALOGUE = "/catalogue";
protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class); protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class);
private FilterConfig config; private FilterConfig config;
@ -64,20 +76,25 @@ public class UriResolverRewriteFilter implements Filter{
logger.debug("Request URI: " + requestURI + ", QueryString: " +queryString+ ", Servlet path: "+multiReadRequest.getServletPath()); logger.debug("Request URI: " + requestURI + ", QueryString: " +queryString+ ", Servlet path: "+multiReadRequest.getServletPath());
//IS A REQUEST FOR GEONETWORK AUTHENTICATION? (CKAN HARVESTING?) //IS A REQUEST FOR GEONETWORK AUTHENTICATION? (CKAN HARVESTING?)
if(isGeonetworkRequest(multiReadRequest.getServletPath())){ if(multiReadRequest.getServletPath().startsWith(SERVLET_GEONETWORK) || multiReadRequest.getServletPath().startsWith(SERVLET_URI_RESOLVER+SERVLET_GEONETWORK)){
logger.debug("is geonetwork request"); logger.debug("is geonetwork request");
GeonetworkRequestDecoder grd = new GeonetworkRequestDecoder(multiReadRequest.getServletPath(), queryString); GeonetworkRequestDecoder grd = new GeonetworkRequestDecoder(multiReadRequest.getServletPath(), queryString);
logger.debug("forward to: "+grd.getNewURI()); logger.debug("forward to: "+grd.getNewURI());
multiReadRequest.getRequestDispatcher(grd.getNewURI()).forward(multiReadRequest, response); multiReadRequest.getRequestDispatcher(grd.getNewURI()).forward(multiReadRequest, response);
}else if(multiReadRequest.getServletPath().compareTo("/catalogue")==0){ }else if(multiReadRequest.getServletPath().startsWith(SERVLET_CATALOGUE) || multiReadRequest.getServletPath().startsWith(SERVLET_URI_RESOLVER+SERVLET_CATALOGUE)){
logger.debug("is a catalogue request"); logger.debug("is a catalogue request");
chain.doFilter(multiReadRequest, response); int lastSlash = requestURI.lastIndexOf(PATH_SEPARATOR);
String toCatalogueLink = requestURI.substring(lastSlash + 1, requestURI.length());
String newURI = SERVLET_CATALOGUE + "?" + PARAMETER_CATALOGUE_LINK + "=" + toCatalogueLink;
logger.debug("forward to: " + newURI);
multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response);
//chain.doFilter(multiReadRequest, response);
}else{ }else{
//IS WORKSPACE REQUEST? //IS WORKSPACE REQUEST?
if (queryString == null) { // IS A /XXXXX if (queryString == null) { // IS A /XXXXX
logger.debug("QueryString is null, is It a new SMP public uri by ID?"); logger.debug("QueryString is null, is It a new SMP public uri by ID?");
int lastSlash = requestURI.lastIndexOf("/"); int lastSlash = requestURI.lastIndexOf(PATH_SEPARATOR);
if (lastSlash + 1 == requestURI.length()) { if (lastSlash + 1 == requestURI.length()) {
logger.debug("'/' is last index, doFilter Request"); logger.debug("'/' is last index, doFilter Request");
// req.getRequestDispatcher("/").forward(req, res); // req.getRequestDispatcher("/").forward(req, res);
@ -87,7 +104,7 @@ public class UriResolverRewriteFilter implements Filter{
String toStorageID = requestURI.substring(lastSlash + 1, requestURI.length()); String toStorageID = requestURI.substring(lastSlash + 1, requestURI.length());
// String newURI = requestURI.replace(toReplace, // String newURI = requestURI.replace(toReplace,
// SERVLET_RESOLVER_BY_ID+"?"+SMP_ID+"="+toReplace); // SERVLET_RESOLVER_BY_ID+"?"+SMP_ID+"="+toReplace);
String newURI = SERVLET_RESOLVER_BY_ID + "?" + SMP_ID + "=" + toStorageID; String newURI = SERVLET_STORAGE_ID + "?" + PARAMETER_SMP_ID + "=" + toStorageID;
logger.debug("forward to: " + newURI); logger.debug("forward to: " + newURI);
multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response); multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response);
} }
@ -108,17 +125,7 @@ public class UriResolverRewriteFilter implements Filter{
private static String getScope(String scope){ private static String getScope(String scope){
logger.debug("Read scope path: "+scope); logger.debug("Read scope path: "+scope);
// String scope = servletPath.substring(servletPath.indexOf("/"), servletPath.length()); // String scope = servletPath.substring(servletPath.indexOf("/"), servletPath.length());
return "/"+scope.replaceAll("_", "/"); return PATH_SEPARATOR+scope.replaceAll("_", PATH_SEPARATOR);
}
/**
* Checks if is geonetwork request.
*
* @param servletPath the servlet path
* @return true, if is geonetwork request
*/
private boolean isGeonetworkRequest(String servletPath){
return servletPath.startsWith(SERVLET_GEONETWORK);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@ -16,7 +16,7 @@ import java.util.Map;
public class CatalogueEntityRequest { public class CatalogueEntityRequest {
Map<String,String> parameters = new HashMap<String, String>(); private Map<String,String> parameters = new HashMap<String, String>();
/** /**
* Instantiates a new catalogue entity request. * Instantiates a new catalogue entity request.

View File

@ -17,6 +17,7 @@ import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.gcube.common.encryption.StringEncrypter; import org.gcube.common.encryption.StringEncrypter;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.UriResolverRewriteFilter;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -37,7 +38,11 @@ public class CatalogueResolver extends HttpServlet{
private static final String TEXT_PALIN_CHARSET_UTF_8 = "text/plain;charset=UTF-8"; private static final String TEXT_PALIN_CHARSET_UTF_8 = "text/plain;charset=UTF-8";
public static final String UTF_8 = "UTF-8"; public static final String UTF_8 = "UTF-8";
public static final String CATALOGUE_LINK_PARAM = "CL"; //CATALOGUE LINK public static final String CATALOGUE_LINK_PARAM = UriResolverRewriteFilter.PARAMETER_CATALOGUE_LINK;
private static final String PATH_SEPARATOR = "/";
public static final String PARAMETER_PATH = "path";
public static final String ENV_SCOPE = "SCOPE"; //Environment Variable public static final String ENV_SCOPE = "SCOPE"; //Environment Variable
@ -88,40 +93,72 @@ public class CatalogueResolver extends HttpServlet{
logger.info("Trying to decode encoded catalogue query link: "+catalogueQueryLink); logger.info("Trying to decode encoded catalogue query link: "+catalogueQueryLink);
if(catalogueQueryLink==null || catalogueQueryLink.isEmpty()){ if(catalogueQueryLink==null || catalogueQueryLink.isEmpty()){
logger.error(""); logger.error("Data Catalogue Link is malformed, set "+CATALOGUE_LINK_PARAM+" parameter");
sendError(resp, HttpStatus.SC_BAD_REQUEST, "Data Catalogue Link is malformed, set "+CATALOGUE_LINK_PARAM+"parameter"); sendError(resp, HttpStatus.SC_BAD_REQUEST, "Data Catalogue Link is malformed, set "+CATALOGUE_LINK_PARAM+" parameter");
return;
} }
String base64DecodedId = "";
String decryptedDCId = "";
try { try {
String base64DecodedId = base64DecodeString(catalogueQueryLink);
base64DecodedId = base64DecodeString(catalogueQueryLink);
logger.info("Base 64 decoded Data Catalogue Link: "+base64DecodedId +", now decrypting..."); logger.info("Base 64 decoded Data Catalogue Link: "+base64DecodedId +", now decrypting...");
if(scopeToEncDecr==null) if(scopeToEncDecr==null)
initScopeFromEnv(); initScopeFromEnv();
ScopeProvider.instance.set(scopeToEncDecr); ScopeProvider.instance.set(scopeToEncDecr);
String decryptedDCId = StringEncrypter.getEncrypter().decrypt(base64DecodedId); decryptedDCId = StringEncrypter.getEncrypter().decrypt(base64DecodedId);
logger.info("Decrypted Data Catalogue Link: "+decryptedDCId); logger.info("Decrypted Data Catalogue Link: "+decryptedDCId);
}catch (Exception e) { }catch (Exception e) {
logger.error("An error occurred during decrypting data catalogue link: "+base64DecodedId+", using the scope: "+scopeToEncDecr, e);
e.printStackTrace(); sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "The system cannot decrypt the Catalogue Link");
return;
} }
/*String scope = cer.getValueOfParameter(CatalogueRequestParameter.GCUBE_SCOPE.getKey()); CatalogueEntityRequest cer = new CatalogueEntityRequest();
logger.info("Using scope "+scope+ " to search Ckan Portlet URL from IS"); for (CatalogueRequestParameter parameter : CatalogueRequestParameter.values()) {
ScopeProvider.instance.set(scope); String value = getValueOfParameter(parameter.getKey(), decryptedDCId);
String ckanPorltetUrl = CkanPorltetApplicationProfile.getPortletUrlFromInfrastrucure(); cer.addParameterToRequest(parameter.getKey(), value);
if(ckanPorltetUrl == null || ckanPorltetUrl.isEmpty()){ }
sendError(null, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later");
logger.debug("Read parameters: "+cer.toString());
String scope = cer.getValueOfParameter(CatalogueRequestParameter.GCUBE_SCOPE.getKey());
if(scope==null || scope.isEmpty()){
logger.error("An error occurred during resolving data catalogue link: "+base64DecodedId+", the scope to search CKan Portlet is null or empty");
sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "The system cannot resolve the Catalogue Link, the scope is null or empty");
return; return;
}*/ }
resp.getWriter().write("Get AVAILABLE");
String ckanPorltetUrl = "";
try{
logger.info("Using scope "+scope+ " to search Ckan Portlet URL from IS");
ScopeProvider.instance.set(scope);
ckanPorltetUrl = CkanPorltetApplicationProfile.getPortletUrlFromInfrastrucure();
if(ckanPorltetUrl == null || ckanPorltetUrl.isEmpty()){
sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later");
return;
}
}catch(Exception e){
logger.error("An error occurred during discovery Data Catalogue URL: ",e);
sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later");
return;
}
//UrlEncoderUtil.encodeQuery(cer.getParameters());
String buildPath = PARAMETER_PATH +"=";
buildPath+= PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey()) + PATH_SEPARATOR;
buildPath+=cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey());
String finalUrl = ckanPorltetUrl+"?"+buildPath;
logger.info("Builded final URL: "+finalUrl);
resp.sendRedirect(resp.encodeRedirectURL(finalUrl));
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/ */
@ -194,14 +231,18 @@ public class CatalogueResolver extends HttpServlet{
String buildLink = getServerURL(req); String buildLink = getServerURL(req);
buildLink += req.getRequestURI(); buildLink += req.getRequestURI();
String query = UrlEncoderUtil.encodeQuery(cer.getParameters()); //String query = UrlEncoderUtil.encodeQuery(cer.getParameters());
String query = "";
for (String key : cer.getParameters().keySet()) {
query+=key+"="+ cer.getParameters().get(key) +"&";
}
query = UrlEncoderUtil.removeLastChar(query);
logger.info("Builded query string: "+query); logger.info("Builded query string: "+query);
String encriptedQuery = StringEncrypter.getEncrypter().encrypt(query); String encriptedQuery = StringEncrypter.getEncrypter().encrypt(query);
logger.info("Encrypted query: "+encriptedQuery); logger.info("Encrypted query: "+encriptedQuery);
String encodedQuery = base64EncodeStringURLSafe(encriptedQuery); String encodedQuery = base64EncodeStringURLSafe(encriptedQuery);
String catalogueQueryLink = CATALOGUE_LINK_PARAM+"="+encodedQuery; logger.info("Catalogue Query Link: "+encodedQuery);
logger.info("Catalogue Query Link: "+catalogueQueryLink); buildLink+=PATH_SEPARATOR+encodedQuery;
buildLink+="?"+catalogueQueryLink;
logger.info("Writing Catalogue Link: "+buildLink); logger.info("Writing Catalogue Link: "+buildLink);
resp.setContentType(TEXT_PALIN_CHARSET_UTF_8); resp.setContentType(TEXT_PALIN_CHARSET_UTF_8);
@ -281,6 +322,33 @@ public class CatalogueResolver extends HttpServlet{
return uToS; return uToS;
} }
/**
* Gets the value of parameter in the passed query string, null otherwise
*
* @param parameter the parameter
* @param httpQueryString the http query string
* @return the value of parameter if exists, null otherwise
*/
public static String getValueOfParameter(String parameter, String httpQueryString) {
// logger.trace("finding: "+wmsParam +" into "+url);
int index = httpQueryString.toLowerCase().indexOf(parameter.toLowerCase()+"="); //ADDING CHAR "=" IN TAIL TO BE SECURE IT IS A PARAMETER
// logger.trace("start index of "+wmsParam+ " is: "+index);
String value = "";
if(index > -1){
int start = index + parameter.length()+1; //add +1 for char '='
String sub = httpQueryString.substring(start, httpQueryString.length());
int indexOfSeparator = sub.indexOf("&");
int end = indexOfSeparator!=-1?indexOfSeparator:sub.length();
value = sub.substring(0, end);
}else
return null;
// logger.trace("return value: "+value);
return value;
}
/** /**
* Base64 encode string url safe. * Base64 encode string url safe.
* *