From 101cc621e00825436a44aff23e7c09d64b4a8d1b Mon Sep 17 00:00:00 2001 From: Francesco Mangiacrapa Date: Tue, 26 Apr 2016 15:23:38 +0000 Subject: [PATCH] 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 --- .../resolver/MultiReadHttpServletRequest.java | 181 ++++++++++++++++ .../resolver/UriResolverRewriteFilter.java | 113 ++++++++-- .../gis/GeonetowrkAccessParameter.java | 28 ++- .../gis/geonetwork/GeonetworkResolver.java | 197 +++++++++++++++--- .../gis/geonetwork/HTTPCallsUtils.java | 73 +++++-- 5 files changed, 513 insertions(+), 79 deletions(-) create mode 100644 src/main/java/org/gcube/datatransfer/resolver/MultiReadHttpServletRequest.java diff --git a/src/main/java/org/gcube/datatransfer/resolver/MultiReadHttpServletRequest.java b/src/main/java/org/gcube/datatransfer/resolver/MultiReadHttpServletRequest.java new file mode 100644 index 0000000..1eb0a2a --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/MultiReadHttpServletRequest.java @@ -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 modifiableParameters; + private Map allParameters = null; + + /** + * Instantiates a new multi read http servlet request. + * + * @param request the request + */ + public MultiReadHttpServletRequest(HttpServletRequest request) { + super(request); + modifiableParameters = new TreeMap(); + } + + /** + * 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 additionalParams) { + + super(request); + modifiableParameters = new TreeMap(); + 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 getParameterMap() { + + if (allParameters == null) { + allParameters = new TreeMap(); + 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 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); + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/UriResolverRewriteFilter.java b/src/main/java/org/gcube/datatransfer/resolver/UriResolverRewriteFilter.java index 582132e..00523aa 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/UriResolverRewriteFilter.java +++ b/src/main/java/org/gcube/datatransfer/resolver/UriResolverRewriteFilter.java @@ -31,6 +31,17 @@ public class UriResolverRewriteFilter implements Filter{ protected static final String SERVLET_RESOLVER_BY_ID = "id"; protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class); private FilterConfig config; + + /** + * Gets the config. + * + * @return the config + */ + public FilterConfig getConfig() { + + return config; + } + /* (non-Javadoc) * @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) */ @Override - public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { - - HttpServletRequest request = (HttpServletRequest) req; - String requestURI = request.getRequestURI(); - String queryString = request.getQueryString(); - logger.debug("Request URI: " + requestURI + ", QueryString: " +queryString+ ", Servlet path: "+request.getServletPath()); + public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { + /* wrap the request in order to read the inputstream multiple times */ + MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) req); + String requestURI = multiReadRequest.getRequestURI(); + String queryString = multiReadRequest.getQueryString(); + logger.debug("Request URI: " + requestURI + ", QueryString: " +queryString+ ", Servlet path: "+multiReadRequest.getServletPath()); //IS A REQUEST FOR GEONETWORK AUTHENTICATION? (CKAN HARVESTING?) - if(isGeonetworkRequest(request.getServletPath())){ + if(isGeonetworkRequest(multiReadRequest.getServletPath())){ logger.debug("is geonetwork"); - String path = request.getServletPath(); - String scope = getScope(path); - String newURI = SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + scope; + String path = multiReadRequest.getServletPath(); + String pathWithoutGN = path.substring(SERVLET_GEONETWORK.length()+1, path.length()); + 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()) newURI+="&"+queryString; 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{ //IS WORKSPACE REQUEST? if (queryString == null) { // IS A /XXXXX @@ -69,7 +106,7 @@ public class UriResolverRewriteFilter implements Filter{ if (lastSlash + 1 == requestURI.length()) { logger.debug("'/' is last index, doFilter Request"); // req.getRequestDispatcher("/").forward(req, res); - chain.doFilter(req, res); + chain.doFilter(multiReadRequest, response); } else { String toStorageID = requestURI.substring(lastSlash + 1, requestURI.length()); @@ -77,12 +114,12 @@ public class UriResolverRewriteFilter implements Filter{ // SERVLET_RESOLVER_BY_ID+"?"+SMP_ID+"="+toReplace); String newURI = SERVLET_RESOLVER_BY_ID + "?" + SMP_ID + "=" + toStorageID; logger.debug("forward to: " + newURI); - req.getRequestDispatcher(newURI).forward(req, res); + multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response); } } else { 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. * - * @param servletPath the servlet path + * @param scope the scope * @return the scope */ - private String getScope(String servletPath){ - logger.debug("Read servlet path: "+servletPath); - String scope = servletPath.substring(servletPath.lastIndexOf("/"), servletPath.length()); - return scope.replaceAll("_", "/"); + private static String getScope(String scope){ + logger.debug("Read scope path: "+scope); +// String scope = servletPath.substring(servletPath.indexOf("/"), servletPath.length()); + return "/"+scope.replaceAll("_", "/"); } /** @@ -117,5 +154,43 @@ public class UriResolverRewriteFilter implements Filter{ logger.trace("run init"); 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); + }*/ } diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java index 18cbf0d..a020cce 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java @@ -5,27 +5,23 @@ import org.gcube.datatransfer.resolver.gis.exception.GeonetworkInstanceException import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - - - /** - * + * * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * @Apr 29, 2013 * */ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{ - + protected static Logger logger = LoggerFactory.getLogger(GeonetowrkAccessParameter.class); - + protected GeonetworkInstance geonetworkInstance; - + protected String scope; protected ServerParameters serverParam; - + /** * @param serverParam @@ -34,9 +30,9 @@ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{ this.scope = scope; this.serverParam = serverParam; } - + /** - * @param geonetworkInstance + * @param geonetworkInstance * @return */ public GeonetworkInstance getGeonetworkInstance(boolean authenticate) throws GeonetworkInstanceException { @@ -44,19 +40,19 @@ public class GeonetowrkAccessParameter implements GeonetworkServiceInterface{ } private GeonetworkInstance instanceGeonetwork(boolean authenticate) throws GeonetworkInstanceException{ - + if(scope == null || scope.isEmpty()) throw new GeonetworkInstanceException("Scope is null"); - + if(serverParam.getUrl() == null || serverParam.getUrl().isEmpty()) throw new GeonetworkInstanceException("Geonetwork url is null or empty"); - + if(geonetworkInstance==null) geonetworkInstance = new GeonetworkInstance(scope, serverParam.getUrl(), serverParam.getUser(), serverParam.getPassword(), authenticate); - + return geonetworkInstance; - + } public String getScope() { diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java index 1a6e000..3b03df9 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java @@ -3,10 +3,18 @@ */ package org.gcube.datatransfer.resolver.gis.geonetwork; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; 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.Map; import java.util.Timer; @@ -40,6 +48,14 @@ import org.slf4j.LoggerFactory; */ 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; 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_CACHED_SCOPE = "resetcachedscope"; public static final String CSW_SERVER = "srv/en/csw"; @@ -87,11 +104,13 @@ public class GeonetworkResolver extends HttpServlet{ */ @Override 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 resetScope = req.getParameter(RESET_CACHED_SCOPE); - if (scope == null || scope.equals("")) { + if (scopeValue == null || scopeValue.equals("")) { logger.debug("Scope not found"); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); return; @@ -102,19 +121,23 @@ public class GeonetworkResolver extends HttpServlet{ } 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 { - ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope); + ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scopeValue); HTTPCallsUtils httpUtils = new HTTPCallsUtils(); - boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); - logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); - String newQueryString = purgeScopeFromQueryString(scope, req.getQueryString()); - logger.info("Purged query string: "+newQueryString); - String gnGetlURL = newQueryString==null || newQueryString.isEmpty()? geonetworkParams.getUrl()+"/"+CSW_SERVER : geonetworkParams.getUrl()+"/"+CSW_SERVER+"?"+newQueryString; +// boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); +// logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); + String newQueryString = purgeScopeFromQueryString(scopeValue, req.getQueryString()); + logger.trace("Purged query string from "+scopeValue+" is: "+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); String response = httpUtils.get(gnGetlURL); logger.info("Response return Content-Type: "+httpUtils.getLastContentType()); @@ -138,22 +161,47 @@ public class GeonetworkResolver extends HttpServlet{ } catch (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); 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=0){ 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"); return ""; }else if(end 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()); 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); - 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()); resp.setContentType(httpUtils.getLastContentType()); - InputStream in = IOUtils.toInputStream(response); +// InputStream in = IOUtils.toInputStream(response); 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{ - int bytes = IOUtils.copy(IOUtils.toInputStream(response), out); + int bytes = IOUtils.copy(in, out); if(bytes==0) logger.warn("ResponseBody is empty, returning empty resp"); }catch(Exception e){ @@ -340,13 +439,61 @@ public class GeonetworkResolver extends HttpServlet{ 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 map = new HashMap(); + String[] value = new String[1]; + value[0]=uuid; + map.put(UUID, value); +// data = ""+uuid+""; + 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(); + } + } } diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/HTTPCallsUtils.java b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/HTTPCallsUtils.java index 2b5aa2d..b7e59e5 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/HTTPCallsUtils.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/HTTPCallsUtils.java @@ -4,6 +4,7 @@ package org.gcube.datatransfer.resolver.gis.geonetwork; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -13,12 +14,14 @@ import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.Map; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; 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.StringRequestEntity; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.log4j.Logger; import org.jdom2.Document; 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). * the HTTP response or null on errors. */ - public String putXml(String url, String content) { + public InputStream putXml(String url, String content) { 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). * the HTTP response or null 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)); } @@ -224,7 +228,7 @@ public class HTTPCallsUtils { * @return The HTTP response as a String if the HTTP response code was 200 (OK). * the HTTP response or null on errors. */ - public String put(String url, String content, String contentType) { + public InputStream put(String url, String content, String contentType) { try { return put(url, new StringRequestEntity(content, contentType, null)); } 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). * the HTTP response or null on errors. */ - public String put(String url, RequestEntity requestEntity) { + public InputStream put(String url, RequestEntity 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). * the HTTP response or null on errors. */ - public String postXml(String url, String content) { + public InputStream postXml(String url, String content) { 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). * the HTTP response or null on errors. */ - public String postXml(String url, InputStream content) { + public InputStream postXml(String url, InputStream content) { 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). * the HTTP response or null on errors. */ - public String post(String url, File file, String contentType) { - return post(url, new FileRequestEntity(file, contentType)); + public InputStream post(String url, File file, String 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). * the HTTP response or null on errors. */ - public String post(String url, String content, String contentType) { + public InputStream post(String url, String content, String contentType) { try { - return post(url, new StringRequestEntity(content, contentType, null)); + return post(url, new StringRequestEntity(content, contentType, null), null); } catch (UnsupportedEncodingException ex) { logger.error("Cannot POST " + url, ex); return null; @@ -313,10 +317,25 @@ public class HTTPCallsUtils { * @return The HTTP response as a String if the HTTP response code was 200 (OK). * the HTTP response or null on errors. */ - public String post(String url, InputStream content, String contentType) { - return post(url, new InputStreamRequestEntity(content, contentType)); + public InputStream post(String url, InputStream content, String 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 null on errors. + */ + public InputStream post(String url, InputStream content, String contentType, Map parameterMap) { + return post(url, new InputStreamRequestEntity(content, contentType), parameterMap); + } + + /** * Performs a POST to the given URL. *
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). * the HTTP response or null on errors. */ - public String post(String url, RequestEntity requestEntity) { - return send(new PostMethod(url), url, requestEntity); + public InputStream post(String url, RequestEntity requestEntity, Map parameterMap) { + 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 url the url * @param requestEntity the request entity - * @return the HTTP response or null on errors. + * @return the InputStream body response or null on errors. */ - protected String send(final EntityEnclosingMethod httpMethod, String url, RequestEntity requestEntity) { + protected InputStream send(final EntityEnclosingMethod httpMethod, String url, RequestEntity requestEntity) { try { setAuth(client, url, username, pw); @@ -375,10 +408,12 @@ public class HTTPCallsUtils { if(logger.isDebugEnabled()) logger.debug("HTTP "+ httpMethod.getStatusText() + " <-- " + url); if(ignoreResponseContentOnSuccess) - return ""; - String response = IOUtils.toString(httpMethod.getResponseBodyAsStream()); + return null; + setContentType(httpMethod); - return response; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + IOUtils.copy(httpMethod.getResponseBodyAsStream(), out); + return new ByteArrayInputStream(out.toByteArray()); default: String badresponse = IOUtils.toString(httpMethod.getResponseBodyAsStream()); String message = getGeoNetworkErrorMessage(badresponse);