/** * */ package org.gcube.datatransfer.resolver.gis.geonetwork; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader; import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader.GEO_SERVICE; import org.gcube.datatransfer.resolver.gis.GeonetowrkAccessParameter; import org.gcube.datatransfer.resolver.gis.GeonetworkServiceInterface; import org.gcube.datatransfer.resolver.gis.MetadataConverter; import org.gcube.datatransfer.resolver.gis.entity.ServerParameters; import org.gcube.datatransfer.resolver.gis.exception.GeonetworkInstanceException; import org.gcube.datatransfer.resolver.gis.exception.IllegalArgumentException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The Class GeonetworkResolver. * * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * Apr 4, 2016 * * This class authenticate all query on Geonetwork */ public class GeonetworkResolver extends HttpServlet{ /** * */ private static final long serialVersionUID = -61097584153314181L; public static final String SCOPE = "scope"; public static final String CSW_SERVER = "srv/en/csw"; /** The logger. */ private static final Logger logger = LoggerFactory.getLogger(GeonetworkResolver.class); protected Map cacheGNServerParams; //A cache: scope - geonetwork parameters private Timer timer; //THIRTY MINUTES public static final long CACHE_RESET_TIME = 30*60*1000; //TEN MINUTES public static final long CACHE_RESET_DELAY = 10*1000; /* (non-Javadoc) * @see javax.servlet.GenericServlet#init() */ @Override public void init() throws ServletException { super.init(); timer = new Timer(true); timer.schedule(new TimerTask() { @Override public void run() { logger.info("Resetting Geonetwork configuratios cache..."); reseCacheServerParameters(); } }, CACHE_RESET_DELAY, CACHE_RESET_TIME); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String scope = req.getParameter(SCOPE); if (scope == null || scope.equals("")) { logger.debug("Scope not found"); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); return; } logger.info("SCOPE is: " + scope); try { ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope); HTTPCallsUtils httpUtils = new HTTPCallsUtils(); boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); String gnGetlURL = geonetworkParams.getUrl()+"/"+CSW_SERVER+"?"+req.getQueryString(); logger.info("Sending get request to URL: "+gnGetlURL); String response = httpUtils.get(geonetworkParams.getUrl()+CSW_SERVER+"?"+req.getQueryString()); InputStream in = IOUtils.toInputStream(response); OutputStream out = resp.getOutputStream(); try{ int bytes = IOUtils.copy(in, out); if(bytes==0) logger.warn("ResponseBody is empty, returning empty resp"); }catch(Exception e){ logger.error("Error on copy response:", e); }finally{ IOUtils.closeQuietly(in); } } catch (IllegalArgumentException e){ logger.error("IllegalArgumentException:", e); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!"); return; } catch (Exception e) { logger.error("Exception:", e); String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!"; sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); return; } } private String getScope(String servletPath){ String path = servletPath; logger.debug("Read servlet context: "+path); String scope = path.substring(path.lastIndexOf("/")+1, path.length()); return scope.replaceAll("_", "/"); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { String scope = req.getParameter(SCOPE); if (scope == null || scope.equals("")) { logger.debug("Scope not found"); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); return; } logger.info("SCOPE is: " + scope); try { ServerParameters geonetworkParams = getGeonetworkCachedServerParameters(scope); HTTPCallsUtils httpUtils = new HTTPCallsUtils(); boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword()); logger.trace("Authorized on "+geonetworkParams +" ? "+authorized); String gnCSWlURL = geonetworkParams.getUrl()+"/"+CSW_SERVER; logger.info("Sending CSW request to URL: "+gnCSWlURL); String response = httpUtils.post(gnCSWlURL, req.getInputStream(), req.getContentType()); InputStream in = IOUtils.toInputStream(response); OutputStream out = resp.getOutputStream(); try{ int bytes = IOUtils.copy(IOUtils.toInputStream(response), out); if(bytes==0) logger.warn("ResponseBody is empty, returning empty resp"); }catch(Exception e){ logger.error("Error on copy response:", e); }finally{ IOUtils.closeQuietly(in); } } catch (IllegalArgumentException e){ logger.error("IllegalArgumentException:", e); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!"); return; } catch (Exception e) { logger.error("Exception:", e); String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!"; sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); return; } } /** * Gets the geonetwork cached server parameters. * * @param scope the scope * @return the geonetwork cached server parameters * @throws Exception the exception */ protected ServerParameters getGeonetworkCachedServerParameters(String scope) throws Exception{ if(cacheGNServerParams==null) reseCacheServerParameters(); logger.info("Tentative for recovering geonetwork server parameters from cache with scope: "+scope); ServerParameters serverParam = cacheGNServerParams.get(scope); if(serverParam==null){ logger.info("Cache having null Geonetwork server parameters, reading from IS.."); GeoRuntimeReader reader = new GeoRuntimeReader(); try { serverParam = reader.retrieveGisParameters(scope, GEO_SERVICE.GEONETWORK); cacheGNServerParams.put(scope, serverParam); logger.info("Updated Cache for Geonetwork server parameters! Scope "+scope+" linking "+serverParam); } catch (Exception e) { logger.error("An error occurred on reading application profile to "+GEO_SERVICE.GEONETWORK, e); throw new Exception("Sorry, An error occurred on reading configuration to "+GEO_SERVICE.GEONETWORK); } }else logger.info("Cache gis server param is not null using it"); logger.info("returning geonetworkParams "+serverParam); return serverParam; } /** * Rese cache server parameters. */ private void reseCacheServerParameters(){ cacheGNServerParams = new HashMap(); logger.info("Cache Geonetwork server params reset!"); } /** * Gets the layer wms request. * * @param scope the scope * @param gisUUID the gis uuid * @param geonetworkParams the geonetwork params * @return the layer wms request * @throws Exception the exception */ protected String getLayerWmsRequest(String scope, String gisUUID, ServerParameters geonetworkParams) throws Exception{ try { GeonetworkServiceInterface gntwAccess = new GeonetowrkAccessParameter(scope, geonetworkParams); return MetadataConverter.getWMSOnLineResource(gntwAccess.getGeonetworkInstance(true), gisUUID); }catch (GeonetworkInstanceException e){ logger.error("An error occurred when instancing geonetowrk gis layer with UUID "+gisUUID, e); throw new IllegalArgumentException("Sorry, An error occurred when instancing geonetwork with UUID: "+gisUUID); } catch (Exception e) { logger.error("An error occurred when retrieving gis layer with UUID "+gisUUID, e); throw new IllegalArgumentException("Sorry, An error occurred when retrieving gis layer with UUID "+gisUUID); } } /** * Send error. * * @param response the response * @param status the status * @param message the message * @throws IOException Signals that an I/O exception has occurred. */ protected void sendError(HttpServletResponse response, int status, String message) throws IOException { // response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.setStatus(status); logger.info("error message: "+message); logger.info("writing response..."); StringReader sr = new StringReader(message); IOUtils.copy(sr, response.getOutputStream()); // response.getWriter().write(resultMessage.toString()); logger.info("response writed"); response.flushBuffer(); } /** * Url redirect. * * @param req the req * @param response the response * @param redirectTo the redirect to * @throws IOException Signals that an I/O exception has occurred. */ protected void urlRedirect(HttpServletRequest req, HttpServletResponse response, String redirectTo) throws IOException { response.sendRedirect(response.encodeRedirectURL(redirectTo)); return; } /** * Gets the request url. * * @param req the req * @return the request url */ public static String getRequestURL(HttpServletRequest req) { String scheme = req.getScheme(); // http String serverName = req.getServerName(); // hostname.com int serverPort = req.getServerPort(); // 80 String contextPath = req.getContextPath(); // /mywebapp // String servletPath = req.getServletPath(); // /servlet/MyServlet // String pathInfo = req.getPathInfo(); // /a/b;c=123 // String queryString = req.getQueryString(); // d=789 // Reconstruct original requesting URL StringBuffer url = new StringBuffer(); url.append(scheme).append("://").append(serverName); if (serverPort != 80 && serverPort != 443) { url.append(":").append(serverPort); } logger.trace("server: "+url); logger.trace("omitted contextPath: "+contextPath); return url.toString(); } /* public static void main(String[] args) { GisResolver gisResolver = new GisResolver(); String scope = "/gcube/devsec/devVRE"; String UUID = "177e1c3c-4a22-4ad9-b015-bfc443d16cb8"; try { ServerParameters geonetworkParams = gisResolver.getCachedServerParameters(scope); String wmsRequest = gisResolver.getLayerWmsRequest(scope, UUID, geonetworkParams); logger.info("Final url is: " + wmsRequest); wmsRequest = URLEncoder.encode(wmsRequest, UTF_8); logger.info("Encoded WMS request is: " + wmsRequest); String gisPortletUrl = gisResolver.getGisViewerApplicationURL(scope); logger.info("Gis Viewer Application url is: " + gisPortletUrl); // logger.info("WmsRequest is: " + wmsRequest); // wmsRequest = encodeURLWithParamDelimiter(wmsRequest); // logger.info("Encoded url is: " + wmsRequest); // wmsRequest = appendParamReplacement(wmsRequest); gisPortletUrl+="?wmsrequest="+wmsRequest; System.out.println(gisPortletUrl); // urlRedirect(req, resp, gisPortletUrl); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }*/ }