Updated in order to manage Geonetwork request for MEF service

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/data-transfer/uri-resolver@128323 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Francesco Mangiacrapa 2016-04-26 15:23:38 +00:00
parent e2db57d9aa
commit 101cc621e0
5 changed files with 513 additions and 79 deletions

View File

@ -0,0 +1,181 @@
/**
*
*/
package org.gcube.datatransfer.resolver;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
/**
* The Class MultiReadHttpServletRequest.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Apr 26, 2016
*/
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedBytes;
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;
/**
* Instantiates a new multi read http servlet request.
*
* @param request the request
*/
public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
}
/**
* Create a new request wrapper that will merge additional parameters into
* the request object without prematurely reading parameters from the
* original request.
*
* @param request
* the request
* @param additionalParams
* the additional params
*/
public MultiReadHttpServletRequest(
final HttpServletRequest request,
final Map<String, String[]> additionalParams) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
}
/* (non-Javadoc)
* @see javax.servlet.ServletRequestWrapper#getInputStream()
*/
@Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null)
cacheInputStream();
return new CachedServletInputStream();
}
/* (non-Javadoc)
* @see javax.servlet.ServletRequestWrapper#getReader()
*/
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* Cache input stream.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
private void cacheInputStream()
throws IOException {
/*
* Cache the inputstream in order to read it multiple times. For
* convenience, I use apache.commons IOUtils
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}
/* An inputstream which reads the cached request body */
/**
* The Class CachedServletInputStream.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Apr 26, 2016
*/
public class CachedServletInputStream extends ServletInputStream {
private ByteArrayInputStream input;
/**
* Instantiates a new cached servlet input stream.
*/
public CachedServletInputStream() {
/* create a new input stream from the cached request body */
input = new ByteArrayInputStream(cachedBytes.toByteArray());
}
/* (non-Javadoc)
* @see java.io.InputStream#read()
*/
@Override
public int read() throws IOException {
return input.read();
}
}
/*
* (non-Javadoc)
* @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String)
*/
@Override
public String getParameter(final String name) {
String[] strings = getParameterMap().get(name);
if (strings != null) {
return strings[0];
}
return super.getParameter(name);
}
/*
* (non-Javadoc)
* @see javax.servlet.ServletRequestWrapper#getParameterMap()
*/
@Override
public Map<String, String[]> getParameterMap() {
if (allParameters == null) {
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
// Return an unmodifiable collection because we need to uphold the
// interface contract.
return Collections.unmodifiableMap(allParameters);
}
/*
* (non-Javadoc)
* @see javax.servlet.ServletRequestWrapper#getParameterNames()
*/
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}
/*
* (non-Javadoc)
* @see
* javax.servlet.ServletRequestWrapper#getParameterValues(java.lang.String)
*/
@Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}
}

View File

@ -31,6 +31,17 @@ public class UriResolverRewriteFilter implements Filter{
protected static final String SERVLET_RESOLVER_BY_ID = "id"; protected static final String SERVLET_RESOLVER_BY_ID = "id";
protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class); protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class);
private FilterConfig config; private FilterConfig config;
/**
* Gets the config.
*
* @return the config
*/
public FilterConfig getConfig() {
return config;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see javax.servlet.Filter#destroy() * @see javax.servlet.Filter#destroy()
*/ */
@ -43,24 +54,50 @@ public class UriResolverRewriteFilter implements Filter{
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/ */
@Override @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/* wrap the request in order to read the inputstream multiple times */
HttpServletRequest request = (HttpServletRequest) req; MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) req);
String requestURI = request.getRequestURI(); String requestURI = multiReadRequest.getRequestURI();
String queryString = request.getQueryString(); String queryString = multiReadRequest.getQueryString();
logger.debug("Request URI: " + requestURI + ", QueryString: " +queryString+ ", Servlet path: "+request.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(request.getServletPath())){ if(isGeonetworkRequest(multiReadRequest.getServletPath())){
logger.debug("is geonetwork"); logger.debug("is geonetwork");
String path = request.getServletPath(); String path = multiReadRequest.getServletPath();
String scope = getScope(path); String pathWithoutGN = path.substring(SERVLET_GEONETWORK.length()+1, path.length());
String newURI = SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + scope; logger.debug("servlet path without "+SERVLET_GEONETWORK + " is:" +pathWithoutGN);
String[] params = pathWithoutGN.split("/");
if(params[0]==null || params[0].isEmpty()){
logger.error("Scope is null or empty, you must set a valid scope /geonetwork/root_vo_vre");
throw new ServletException("Scope is null or empty, you must set a valid scope /geonetwork/root_vo_vre");
}
String scopeValue = getScope(params[0]);
logger.debug("scope value is: "+scopeValue);
String newURI = SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + scopeValue;
if(params.length>1){
String remainPath = "";
// newURI +="&remainPath=";
for (int i = 1; i < params.length; i++) {
String httpGetParam = params[i];
if(httpGetParam!=null && !httpGetParam.isEmpty())
remainPath+="/"+httpGetParam;
}
newURI +="&"+GeonetworkResolver.REMAIN_PATH+"="+remainPath;
}
if(queryString!=null && !queryString.isEmpty()) if(queryString!=null && !queryString.isEmpty())
newURI+="&"+queryString; newURI+="&"+queryString;
logger.debug("forward "+newURI); logger.debug("forward "+newURI);
req.getRequestDispatcher(newURI).forward(req, res); //BODY DEBUG
/*
String readBody = IOUtils.toString(multiReadRequest.getReader());
logger.debug("Read body request: "+readBody);
*/
multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response);
}else{ }else{
//IS WORKSPACE REQUEST? //IS WORKSPACE REQUEST?
if (queryString == null) { // IS A /XXXXX if (queryString == null) { // IS A /XXXXX
@ -69,7 +106,7 @@ public class UriResolverRewriteFilter implements Filter{
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);
chain.doFilter(req, res); chain.doFilter(multiReadRequest, response);
} }
else { else {
String toStorageID = requestURI.substring(lastSlash + 1, requestURI.length()); String toStorageID = requestURI.substring(lastSlash + 1, requestURI.length());
@ -77,12 +114,12 @@ public class UriResolverRewriteFilter implements Filter{
// 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_RESOLVER_BY_ID + "?" + SMP_ID + "=" + toStorageID;
logger.debug("forward to: " + newURI); logger.debug("forward to: " + newURI);
req.getRequestDispatcher(newURI).forward(req, res); multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response);
} }
} }
else { else {
logger.debug("is NOT a SMP public uri by ID, doFilter Request"); logger.debug("is NOT a SMP public uri by ID, doFilter Request");
chain.doFilter(req, res); chain.doFilter(multiReadRequest, response);
} }
} }
} }
@ -90,13 +127,13 @@ public class UriResolverRewriteFilter implements Filter{
/** /**
* Gets the scope. * Gets the scope.
* *
* @param servletPath the servlet path * @param scope the scope
* @return the scope * @return the scope
*/ */
private String getScope(String servletPath){ private static String getScope(String scope){
logger.debug("Read servlet path: "+servletPath); logger.debug("Read scope path: "+scope);
String scope = servletPath.substring(servletPath.lastIndexOf("/"), servletPath.length()); // String scope = servletPath.substring(servletPath.indexOf("/"), servletPath.length());
return scope.replaceAll("_", "/"); return "/"+scope.replaceAll("_", "/");
} }
/** /**
@ -117,5 +154,43 @@ public class UriResolverRewriteFilter implements Filter{
logger.trace("run init"); logger.trace("run init");
this.config = config; this.config = config;
} }
/*
public static void main(String[] args) throws ServletException {
String path = "/geonetwork/gcube_devsec_devVRE/srv/en/mef.export";
String queryString = "p1=1&p2=2";
String pathWithoutGN = path.substring(SERVLET_GEONETWORK.length()+1, path.length());
logger.debug("servlet path without "+SERVLET_GEONETWORK + " is:" +pathWithoutGN);
String[] params = pathWithoutGN.split("/");
System.out.println(Arrays.asList(params));
if(params[0]==null || params[0].isEmpty()){
logger.error("Scope is null or empty, you must set a valid scope /geonetwork/root_vo_vre");
throw new ServletException("Scope is null or empty, you must set a valid scope /geonetwork/root_vo_vre");
}
String scopeValue = getScope(params[0]);
logger.debug("scope value is: "+scopeValue);
String newURI = SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + scopeValue;
if(params.length>1){
String remainPath = "";
// newURI +="&remainPath=";
for (int i = 1; i < params.length; i++) {
String httpGetParam = params[i];
if(httpGetParam!=null && !httpGetParam.isEmpty())
remainPath+="/"+httpGetParam;
}
newURI +="&"+GeonetworkResolver.REMAIN_PATH+"="+remainPath;
}
if(queryString!=null && !queryString.isEmpty())
newURI+="&"+queryString;
logger.debug("forward "+newURI);
}*/
} }

View File

@ -5,27 +5,23 @@ import org.gcube.datatransfer.resolver.gis.exception.GeonetworkInstanceException
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* @Apr 29, 2013 * @Apr 29, 2013
* *
*/ */
public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{
protected static Logger logger = LoggerFactory.getLogger(GeonetowrkAccessParameter.class); protected static Logger logger = LoggerFactory.getLogger(GeonetowrkAccessParameter.class);
protected GeonetworkInstance geonetworkInstance; protected GeonetworkInstance geonetworkInstance;
protected String scope; protected String scope;
protected ServerParameters serverParam; protected ServerParameters serverParam;
/** /**
* @param serverParam * @param serverParam
@ -34,9 +30,9 @@ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{
this.scope = scope; this.scope = scope;
this.serverParam = serverParam; this.serverParam = serverParam;
} }
/** /**
* @param geonetworkInstance * @param geonetworkInstance
* @return * @return
*/ */
public GeonetworkInstance getGeonetworkInstance(boolean authenticate) throws GeonetworkInstanceException { public GeonetworkInstance getGeonetworkInstance(boolean authenticate) throws GeonetworkInstanceException {
@ -44,19 +40,19 @@ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{
} }
private GeonetworkInstance instanceGeonetwork(boolean authenticate) throws GeonetworkInstanceException{ private GeonetworkInstance instanceGeonetwork(boolean authenticate) throws GeonetworkInstanceException{
if(scope == null || scope.isEmpty()) if(scope == null || scope.isEmpty())
throw new GeonetworkInstanceException("Scope is null"); throw new GeonetworkInstanceException("Scope is null");
if(serverParam.getUrl() == null || serverParam.getUrl().isEmpty()) if(serverParam.getUrl() == null || serverParam.getUrl().isEmpty())
throw new GeonetworkInstanceException("Geonetwork url is null or empty"); throw new GeonetworkInstanceException("Geonetwork url is null or empty");
if(geonetworkInstance==null) if(geonetworkInstance==null)
geonetworkInstance = new GeonetworkInstance(scope, serverParam.getUrl(), serverParam.getUser(), serverParam.getPassword(), authenticate); geonetworkInstance = new GeonetworkInstance(scope, serverParam.getUrl(), serverParam.getUser(), serverParam.getPassword(), authenticate);
return geonetworkInstance; return geonetworkInstance;
} }
public String getScope() { public String getScope() {

View File

@ -3,10 +3,18 @@
*/ */
package org.gcube.datatransfer.resolver.gis.geonetwork; package org.gcube.datatransfer.resolver.gis.geonetwork;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.StringReader; import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
@ -40,6 +48,14 @@ import org.slf4j.LoggerFactory;
*/ */
public class GeonetworkResolver extends HttpServlet{ public class GeonetworkResolver extends HttpServlet{
/**
*
*/
public static final String SRV_EN_MEF_EXPORT = "/srv/en/mef.export"; //MEF Geonetwork service
/**
*
*/
public static final String UUID = "uuid";
/** /**
* *
*/ */
@ -49,6 +65,7 @@ public class GeonetworkResolver extends HttpServlet{
*/ */
private static final long serialVersionUID = -61097584153314181L; private static final long serialVersionUID = -61097584153314181L;
public static final String SCOPE = "scope"; public static final String SCOPE = "scope";
public static final String REMAIN_PATH = "remainPath";
public static final String RESET_CACHE = "resetcache"; public static final String RESET_CACHE = "resetcache";
public static final String RESET_CACHED_SCOPE = "resetcachedscope"; public static final String RESET_CACHED_SCOPE = "resetcachedscope";
public static final String CSW_SERVER = "srv/en/csw"; public static final String CSW_SERVER = "srv/en/csw";
@ -87,11 +104,13 @@ public class GeonetworkResolver extends HttpServlet{
*/ */
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String scope = req.getParameter(SCOPE); logger.info("doGET running...");
String scopeValue = req.getParameter(SCOPE);
String remainValue = req.getParameter(REMAIN_PATH);
String resetCache = req.getParameter(RESET_CACHE); String resetCache = req.getParameter(RESET_CACHE);
String resetScope = req.getParameter(RESET_CACHED_SCOPE); String resetScope = req.getParameter(RESET_CACHED_SCOPE);
if (scope == null || scope.equals("")) { if (scopeValue == null || scopeValue.equals("")) {
logger.debug("Scope not found"); logger.debug("Scope not found");
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty");
return; return;
@ -102,19 +121,23 @@ public class GeonetworkResolver extends HttpServlet{
} }
if(resetScope!=null && Boolean.parseBoolean(resetScope)){ if(resetScope!=null && Boolean.parseBoolean(resetScope)){
resetCacheServerParameterForScope(scope); resetCacheServerParameterForScope(scopeValue);
} }
logger.info("SCOPE: " + scope +", Query String: " + req.getQueryString()); logger.info("SCOPE: " + scopeValue +", Query String: " + req.getQueryString());
try { try {
ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope); ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scopeValue);
HTTPCallsUtils httpUtils = new HTTPCallsUtils(); HTTPCallsUtils httpUtils = new HTTPCallsUtils();
boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); // boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword());
logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); // logger.trace("Authorized on "+geonetworkParams +" ? "+authorized);
String newQueryString = purgeScopeFromQueryString(scope, req.getQueryString()); String newQueryString = purgeScopeFromQueryString(scopeValue, req.getQueryString());
logger.info("Purged query string: "+newQueryString); logger.trace("Purged query string from "+scopeValue+" is: "+newQueryString);
String gnGetlURL = newQueryString==null || newQueryString.isEmpty()? geonetworkParams.getUrl()+"/"+CSW_SERVER : geonetworkParams.getUrl()+"/"+CSW_SERVER+"?"+newQueryString; String baseURL = remainValue==null ||remainValue.isEmpty()?geonetworkParams.getUrl()+"/"+CSW_SERVER:geonetworkParams.getUrl()+"/"+CSW_SERVER+remainValue;
logger.trace("New base URL "+baseURL);
newQueryString = purgeRemainFromQueryString(remainValue, newQueryString);
logger.trace("Purged query string from "+remainValue+" is: "+newQueryString);
String gnGetlURL = newQueryString==null || newQueryString.isEmpty()? baseURL : baseURL+"?"+newQueryString;
logger.info("Sending get request to URL: "+gnGetlURL); logger.info("Sending get request to URL: "+gnGetlURL);
String response = httpUtils.get(gnGetlURL); String response = httpUtils.get(gnGetlURL);
logger.info("Response return Content-Type: "+httpUtils.getLastContentType()); logger.info("Response return Content-Type: "+httpUtils.getLastContentType());
@ -138,22 +161,47 @@ public class GeonetworkResolver extends HttpServlet{
} catch (Exception e) { } catch (Exception e) {
logger.error("Exception:", e); logger.error("Exception:", e);
String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!"; String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scopeValue+". Please, contact support!";
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
return; return;
} }
} }
/**
* Purge remain from query string.
*
* @param remain_value the scope
* @param queryString the query string
* @return the string
*/
private static String purgeRemainFromQueryString(String remain_value, String queryString){
// SCOPE is: /gcube/devsec/devVRE
// [INFO ] 2016-04-05 15:01:42,808 org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver -
// Query String is: scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW
int start = queryString.indexOf(REMAIN_PATH+"=");
if(start>=0){
int end = queryString.indexOf("&", start);
if(end==-1 && queryString.length()==(REMAIN_PATH+"="+remain_value).length()){ //SCOPE IS THE UNIQUE PARAMETER INTO QUETY STRING
logger.debug("Scope is the unique parameter, returning empty query string");
return "";
}else if(end<queryString.length())
return queryString.substring(end+1, queryString.length());
}
return queryString;
}
/** /**
* Purge scope from query string. * Purge scope from query string.
* *
* @param scope the scope * @param scope_value the scope
* @param queryString the query string * @param queryString the query string
* @return the string * @return the string
*/ */
private static String purgeScopeFromQueryString(String scope, String queryString){ private static String purgeScopeFromQueryString(String scope_value, String queryString){
// SCOPE is: /gcube/devsec/devVRE // SCOPE is: /gcube/devsec/devVRE
// [INFO ] 2016-04-05 15:01:42,808 org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver - // [INFO ] 2016-04-05 15:01:42,808 org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver -
// Query String is: scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW // Query String is: scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW
@ -162,7 +210,7 @@ public class GeonetworkResolver extends HttpServlet{
if(start>=0){ if(start>=0){
int end = queryString.indexOf("&", start); int end = queryString.indexOf("&", start);
if(end==-1 && queryString.length()==(SCOPE+"="+scope).length()){ //SCOPE IS THE UNIQUE PARAMETER INTO QUETY STRING if(end==-1 && queryString.length()==(SCOPE+"="+scope_value).length()){ //SCOPE IS THE UNIQUE PARAMETER INTO QUETY STRING
logger.debug("Scope is the unique parameter, returning empty query string"); logger.debug("Scope is the unique parameter, returning empty query string");
return ""; return "";
}else if(end<queryString.length()) }else if(end<queryString.length())
@ -178,7 +226,13 @@ public class GeonetworkResolver extends HttpServlet{
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
/*MultiReadHttpServletRequest req2;
if(req instanceof MultiReadHttpServletRequest)
req2 = (MultiReadHttpServletRequest) req;*/
logger.info("doPost running...");
String scope = req.getParameter(SCOPE); String scope = req.getParameter(SCOPE);
String remainValue = req.getParameter(REMAIN_PATH);
if (scope == null || scope.equals("")) { if (scope == null || scope.equals("")) {
logger.debug("Scope not found"); logger.debug("Scope not found");
@ -192,17 +246,62 @@ public class GeonetworkResolver extends HttpServlet{
ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope); ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope);
HTTPCallsUtils httpUtils = new HTTPCallsUtils(); HTTPCallsUtils httpUtils = new HTTPCallsUtils();
logger.info("Parameters..");
for (Enumeration<String> e = req.getParameterNames(); e.hasMoreElements();){
String p = e.nextElement();
logger.debug("param "+p + " value "+Arrays.toString(req.getParameterValues(p)));
}
// String readBody = IOUtils.toString(req.getReader());
// logger.debug("doPost read body request: "+readBody);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword());
logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); logger.trace("Authorized on "+geonetworkParams +" ? "+authorized);
String gnCSWlURL = geonetworkParams.getUrl()+"/"+CSW_SERVER;
// SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export
String gnCSWlURL;
if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){
logger.info("In case of mef.export, perfoming a custom handler");
gnCSWlURL = geonetworkParams.getUrl() + SRV_EN_MEF_EXPORT;
String[] uuidValues = req.getParameterValues(UUID);
if(uuidValues!=null){
String data = null;
for (String uuid : uuidValues) {
data = UUID+"="+uuid;
}
if(data!=null){
logger.debug("Writing "+data +" to byte array");
byteArray.write(data.getBytes());
}else
IOUtils.copy(req.getReader(), byteArray);
}else
IOUtils.copy(req.getReader(), byteArray);
}else{
gnCSWlURL = remainValue==null ||remainValue.isEmpty()?geonetworkParams.getUrl()+"/"+CSW_SERVER:geonetworkParams.getUrl()+"/"+CSW_SERVER+remainValue;
IOUtils.copy(req.getReader(), byteArray);
}
// String gnCSWlURL = geonetworkParams.getUrl()+"/"+CSW_SERVER;
logger.info("Sending CSW POST request to URL: "+gnCSWlURL); logger.info("Sending CSW POST request to URL: "+gnCSWlURL);
String response = httpUtils.post(gnCSWlURL, req.getInputStream(), req.getContentType()); logger.info("Content-Type: "+req.getContentType());
//DEBUG
logger.debug("POST - BODY : "+byteArray.toString());
InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap());
//END DEBUG
// String response = httpUtils.post(gnCSWlURL, req.getInputStream(), req.getContentType());
logger.info("Response return Content-Type: "+httpUtils.getLastContentType()); logger.info("Response return Content-Type: "+httpUtils.getLastContentType());
resp.setContentType(httpUtils.getLastContentType()); resp.setContentType(httpUtils.getLastContentType());
InputStream in = IOUtils.toInputStream(response); // InputStream in = IOUtils.toInputStream(response);
OutputStream out = resp.getOutputStream(); OutputStream out = resp.getOutputStream();
if(in==null){
logger.warn("Input stream returned is null, sending "+HttpServletResponse.SC_NOT_FOUND);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
try{ try{
int bytes = IOUtils.copy(IOUtils.toInputStream(response), out); int bytes = IOUtils.copy(in, out);
if(bytes==0) if(bytes==0)
logger.warn("ResponseBody is empty, returning empty resp"); logger.warn("ResponseBody is empty, returning empty resp");
}catch(Exception e){ }catch(Exception e){
@ -340,13 +439,61 @@ public class GeonetworkResolver extends HttpServlet{
return; return;
} }
/**
* The main method.
*
* @param args the arguments
*/
public static void main(String[] args) {
System.out.println(purgeScopeFromQueryString("/gcube/devsec/devVRE", "scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW")); public static void main(String[] args) throws UnsupportedEncodingException {
/*String scopeValue ="/gcube/devsec/devVRE";
String remainValue = "/srv/en/mef.export";
String queryString = "scope=/gcube/devsec/devVRE&remainPath=/srv/en/mef.export&version=2.0.2&request=GetCapabilities&service=CSW";
ServerParameters geonetworkParams = new ServerParameters("http://geoserver-dev2.d4science-ii.research-infrastructures.eu/geonetwork", "", "");
String newQueryString = purgeScopeFromQueryString(scopeValue, queryString);
logger.info("Purged query string from "+scopeValue+" is: "+newQueryString);
String baseURL = remainValue==null ||remainValue.isEmpty()?geonetworkParams.getUrl()+"/"+CSW_SERVER:geonetworkParams.getUrl()+"/"+CSW_SERVER+remainValue;
logger.info("New base URL "+baseURL);
newQueryString = purgeRemainFromQueryString(remainValue, newQueryString);
logger.info("Purged query string from "+remainValue+" is: "+newQueryString);
String gnGetlURL = newQueryString==null || newQueryString.isEmpty()? baseURL : baseURL+"?"+newQueryString;
logger.info("Sending get request to URL: "+gnGetlURL);*/
HTTPCallsUtils httpUtils = new HTTPCallsUtils();
String data ="";
String contentType = "application/x-www-form-urlencoded";
String uuid = "fao-fsa-map-27.7.j";
String gnCSWlURL = "http://geoserver-dev2.d4science-ii.research-infrastructures.eu/geonetwork/srv/en//srv/en/mef.export";
try {
/*File file = File.createTempFile(uuid, ".xml");
InputStream response = httpUtils.post(gnCSWlURL, file, contentType);*/
//MAP
Map<String, String[]> map = new HashMap<String, String[]>();
String[] value = new String[1];
value[0]=uuid;
map.put(UUID, value);
// data = "<request><uuid>"+uuid+"</uuid></request>";
data = "uuid="+uuid;
byte[] byteArray = data.getBytes();
InputStream response = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray), contentType, map);
if(response!=null){
try {
final Path destination = Paths.get("test");
Files.copy(response, destination);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} }
} }

View File

@ -4,6 +4,7 @@
package org.gcube.datatransfer.resolver.gis.geonetwork; package org.gcube.datatransfer.resolver.gis.geonetwork;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -13,12 +14,14 @@ import java.net.ConnectException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Map;
import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.DeleteMethod; import org.apache.commons.httpclient.methods.DeleteMethod;
@ -31,6 +34,7 @@ import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
@ -198,7 +202,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String putXml(String url, String content) { public InputStream putXml(String url, String content) {
return put(url, content, xmlContentType); return put(url, content, xmlContentType);
} }
@ -211,7 +215,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String put(String url, File file, String contentType) { public InputStream put(String url, File file, String contentType) {
return put(url, new FileRequestEntity(file, contentType)); return put(url, new FileRequestEntity(file, contentType));
} }
@ -224,7 +228,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String put(String url, String content, String contentType) { public InputStream put(String url, String content, String contentType) {
try { try {
return put(url, new StringRequestEntity(content, contentType, null)); return put(url, new StringRequestEntity(content, contentType, null));
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
@ -241,7 +245,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String put(String url, RequestEntity requestEntity) { public InputStream put(String url, RequestEntity requestEntity) {
return send(new PutMethod(url), url, requestEntity); return send(new PutMethod(url), url, requestEntity);
} }
@ -257,7 +261,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String postXml(String url, String content) { public InputStream postXml(String url, String content) {
return post(url, content, xmlContentType); return post(url, content, xmlContentType);
} }
@ -269,7 +273,7 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String postXml(String url, InputStream content) { public InputStream postXml(String url, InputStream content) {
return post(url, content, xmlContentType); return post(url, content, xmlContentType);
} }
@ -282,8 +286,8 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String post(String url, File file, String contentType) { public InputStream post(String url, File file, String contentType) {
return post(url, new FileRequestEntity(file, contentType)); return post(url, new FileRequestEntity(file, contentType), null);
} }
/** /**
@ -295,9 +299,9 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String post(String url, String content, String contentType) { public InputStream post(String url, String content, String contentType) {
try { try {
return post(url, new StringRequestEntity(content, contentType, null)); return post(url, new StringRequestEntity(content, contentType, null), null);
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
logger.error("Cannot POST " + url, ex); logger.error("Cannot POST " + url, ex);
return null; return null;
@ -313,10 +317,25 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String post(String url, InputStream content, String contentType) { public InputStream post(String url, InputStream content, String contentType) {
return post(url, new InputStreamRequestEntity(content, contentType)); return post(url, new InputStreamRequestEntity(content, contentType), null);
} }
/**
* POSTs a Stream content to the given URL.
*
* @param url the url
* @param content The content to be sent as an InputStream.
* @param contentType The content-type to advert in the POST.
* @param parameterMap the parameter map
* @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors.
*/
public InputStream post(String url, InputStream content, String contentType, Map<String, String[]> parameterMap) {
return post(url, new InputStreamRequestEntity(content, contentType), parameterMap);
}
/** /**
* Performs a POST to the given URL. * Performs a POST to the given URL.
* <BR>Basic auth is used if both username and pw are not null. * <BR>Basic auth is used if both username and pw are not null.
@ -326,8 +345,22 @@ public class HTTPCallsUtils {
* @return The HTTP response as a String if the HTTP response code was 200 (OK). * @return The HTTP response as a String if the HTTP response code was 200 (OK).
* the HTTP response or <TT>null</TT> on errors. * the HTTP response or <TT>null</TT> on errors.
*/ */
public String post(String url, RequestEntity requestEntity) { public InputStream post(String url, RequestEntity requestEntity, Map<String, String[]> parameterMap) {
return send(new PostMethod(url), url, requestEntity); PostMethod postMethod = new PostMethod(url);
if(parameterMap!=null){
for(String stringParameterName : parameterMap.keySet()) {
// Iterate the values for each parameter name
String[] stringArrayParameterValues = parameterMap.get(stringParameterName);
for(String stringParamterValue : stringArrayParameterValues) {
// Create a NameValuePair and store in list
NameValuePair nameValuePair = new NameValuePair(stringParameterName, stringParamterValue);
logger.debug("Adding parameter: "+nameValuePair.toString());
postMethod.addParameter(nameValuePair);
}
}
}
return send(postMethod, url, requestEntity);
} }
//========================================================================== //==========================================================================
@ -347,9 +380,9 @@ public class HTTPCallsUtils {
* @param httpMethod the http method * @param httpMethod the http method
* @param url the url * @param url the url
* @param requestEntity the request entity * @param requestEntity the request entity
* @return the HTTP response or <TT>null</TT> on errors. * @return the InputStream body response or <TT>null</TT> on errors.
*/ */
protected String send(final EntityEnclosingMethod httpMethod, String url, RequestEntity requestEntity) { protected InputStream send(final EntityEnclosingMethod httpMethod, String url, RequestEntity requestEntity) {
try { try {
setAuth(client, url, username, pw); setAuth(client, url, username, pw);
@ -375,10 +408,12 @@ public class HTTPCallsUtils {
if(logger.isDebugEnabled()) if(logger.isDebugEnabled())
logger.debug("HTTP "+ httpMethod.getStatusText() + " <-- " + url); logger.debug("HTTP "+ httpMethod.getStatusText() + " <-- " + url);
if(ignoreResponseContentOnSuccess) if(ignoreResponseContentOnSuccess)
return ""; return null;
String response = IOUtils.toString(httpMethod.getResponseBodyAsStream());
setContentType(httpMethod); setContentType(httpMethod);
return response; ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(httpMethod.getResponseBodyAsStream(), out);
return new ByteArrayInputStream(out.toByteArray());
default: default:
String badresponse = IOUtils.toString(httpMethod.getResponseBodyAsStream()); String badresponse = IOUtils.toString(httpMethod.getResponseBodyAsStream());
String message = getGeoNetworkErrorMessage(badresponse); String message = getGeoNetworkErrorMessage(badresponse);