diff --git a/pom.xml b/pom.xml index 3804d4f..f76f2f5 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.gcube.data.transfer uri-resolver - 1.1.0-SNAPSHOT + 1.2.0-SNAPSHOT war @@ -45,6 +45,48 @@ provided + + + + org.gcube.spatial.data + geonetwork + [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) + compile + + + + javax.servlet + javax.servlet-api + 3.0.1 + compile + + + + org.gcube.core + common-encryption + [1.0.1-SNAPSHOT, 2.0.0-SNAPSHOT) + compile + + + + org.gcube.resources.discovery + discovery-client + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + + + + org.w3c + dom + 2.3.0-jaxb-1.0.6 + compile + + + + + + + log4j log4j diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GeoProfileReader.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GeoProfileReader.java new file mode 100644 index 0000000..6f21edb --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GeoProfileReader.java @@ -0,0 +1,116 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.util.Iterator; +import java.util.List; + +import org.gcube.common.encryption.StringEncrypter; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.common.resources.gcore.utils.Group; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datatransfer.resolver.gis.entity.ServerParameters; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public class GeoProfileReader { + + public static final String GEOSERVER_RESOURCE_NAME = "GeoServer"; + public static final String GEONETWORK_RESOURCE_NAME = "GeoNetwork"; + public static final String WORKSPACES_PROPERTY_NAME = "workspaces"; + + public static enum GEO_SERVICE{GEOSERVER, GEONETWORK}; + + public static final Logger logger = LoggerFactory.getLogger(GisResolver.class); + + private ServerParameters getParameters(String scope, GEO_SERVICE geoservice) throws Exception + { + + ServerParameters parameters = new ServerParameters(); + + try{ + + boolean isGeoserver = geoservice.equals(GEO_SERVICE.GEOSERVER); + + String resourceName = (isGeoserver ? GEOSERVER_RESOURCE_NAME : GEONETWORK_RESOURCE_NAME); + + ScopeProvider.instance.set(scope); + + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/string() eq '"+resourceName+"'"); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + + List r = client.submit(query); + if (r == null || r.isEmpty()) throw new Exception("Cannot retrieve the runtime resource: "+resourceName); + + ServiceEndpoint se = r.get(0); + if(se.profile()==null) + throw new Exception("IS profile is null for resource: "+resourceName); + + Group accessPoints = se.profile().accessPoints(); + if(accessPoints.size()==0) throw new Exception("Accesspoint in resource "+resourceName+" not found"); + + AccessPoint ap = accessPoints.iterator().next(); + parameters.setUrl(ap.address()); + parameters.setUser(ap.username()); //username + + String decryptedPassword = StringEncrypter.getEncrypter().decrypt(ap.password()); + + parameters.setPassword(decryptedPassword); //password + + if (isGeoserver){ + Group properties = ap.properties(); + + if(properties.size()==0) throw new Exception("Properties in resource "+resourceName+" not found"); + + Iterator iter = properties.iterator(); + + while (iter.hasNext()) { + + Property prop = iter.next(); + + if(prop.name().compareTo(WORKSPACES_PROPERTY_NAME)==0){ +// logger.trace("Property "+WORKSPACES_PROPERTY_NAME+" found, setting value: "+prop.value()); +// parameters.setWorkspaces(prop.value()); +// break; + } + } + } + + }catch (Exception e) { + logger.error("Sorry, an error occurred on reading parameters in Runtime Reosurces",e); + e.printStackTrace(); + } + + return parameters; + } + + public ServerParameters retrieveGisParameters(String scope, GEO_SERVICE geoservice) throws Exception + { + if(geoservice==null) + return null; + + try { + return getParameters(scope, geoservice); + + } catch (Exception e){ + logger.error("Error retrieving the "+geoservice+" parameters", e); + throw new Exception("Error retrieving the "+geoservice+" parameters", e); + } + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java new file mode 100644 index 0000000..6a96529 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetowrkAccessParameter.java @@ -0,0 +1,64 @@ +package org.gcube.datatransfer.resolver.gis; + +import org.gcube.datatransfer.resolver.gis.entity.ServerParameters; +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 + */ + public GeonetowrkAccessParameter(String scope, ServerParameters serverParam) { + this.scope = scope; + this.serverParam = serverParam; + } + + /** + * @param geonetworkInstance + * @return + */ + public GeonetworkInstance getGeonetworkInstance(boolean authenticate) throws Exception { + return instanceGeonetwork(authenticate); + } + + private GeonetworkInstance instanceGeonetwork(boolean authenticate) throws Exception{ + + if(scope == null || scope.isEmpty()) + throw new Exception("Scope is null"); + + if(serverParam.getUrl() == null || serverParam.getUrl().isEmpty()) + throw new Exception("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() { + return scope; + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkInstance.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkInstance.java new file mode 100644 index 0000000..ad766b0 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkInstance.java @@ -0,0 +1,195 @@ +package org.gcube.datatransfer.resolver.gis; + +import java.util.HashMap; +import java.util.Map; + +import org.gcube.spatial.data.geonetwork.GeoNetwork; +import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; +import org.gcube.spatial.data.geonetwork.LoginLevel; +import org.gcube.spatial.data.geonetwork.configuration.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public class GeonetworkInstance { + + private GeoNetworkPublisher geonetworkPublisher = null; + private String geoNetworkUrl; + private String geoNetworkUser = ""; + private String geoNetworkPwd = ""; + + private String scope = "noscope"; + + public GeonetworkInstance(){} //FOR SERIALIZATION + + private Logger logger = LoggerFactory.getLogger(GeonetworkInstance.class); + + /** + * + * @param scope + */ + public GeonetworkInstance(String scope){ + this.scope = scope; + } + + + /** + * Creates a new configuration for Gis publisher with parameters passed in input. By default executes the login as user passed in input on geonetwork instance + * @param scope + * @param geoNetworkUrl + * @param user + * @param pwd + * @param geoserverUrl + * @param geoserverUser + * @param geoserverPwd + * @param httpSession + * @throws Exception + */ + public GeonetworkInstance(String scope, String geoNetworkUrl, String user, String pwd, boolean authenticate) throws Exception { + logger.trace("Instancing GeonetworkInstance with specific parameters"); + this.geoNetworkUser = user; + this.geoNetworkPwd = pwd; + this.geoNetworkUrl = geoNetworkUrl; + this.scope = scope; + try { + createInstance(authenticate); + } catch (Exception e) { + String message = "Sorry, an error occurred in instancing geonetwork"; + logger.warn(message, e); + throw new Exception(message); + } + } + + /** + * + * @param authenticate + * @throws Exception + */ + private void createInstance(boolean authenticate) throws Exception { + this.geonetworkPublisher = GeoNetwork.get(new GeonetworkConfiguration()); + authenticateOnGeoenetwork(authenticate); + } + + /** + * + * @param authenticate + * @throws Exception + */ + public void authenticateOnGeoenetwork(boolean authenticate) throws Exception { + + logger.trace("authenticating.. geonetworkPublisher is null? "+(this.geonetworkPublisher==null)); + if(geonetworkPublisher==null){ + logger.trace("skipping authentication.. please createInstace"); + return; + } + + if (authenticate){ + this.geonetworkPublisher.login(LoginLevel.DEFAULT); + logger.trace("authentication on geonetwork completed"); + } + } + + + /** + * Creates a new configuration for Gis publisher with parameter passed in input. Executes the login on geonetwork instance if authenticate param is true, no otherwise + * + * @param geoNetworkUrl + * @param user + * @param pwd + * @throws Exception + */ + public GeonetworkInstance(String geoNetworkUrl, String user, String pwd, boolean authenticate) throws Exception { + try { + this.geoNetworkUrl = geoNetworkUrl; + this.geoNetworkUser = user; + this.geoNetworkPwd = pwd; + + createInstance(authenticate); + + } catch (Exception e) { + logger.error("Sorry, an error occurred in getting geonetwork instance",e); + throw new Exception("Sorry, an error occurred in getting geonetwork instance",e); + } + } + + + public class GeonetworkConfiguration implements Configuration { + + public Map pwds=new HashMap(); + public Map usrs=new HashMap(); + + @Override + public String getGeoNetworkEndpoint() { + logger.trace("geoNetworkUrl is: "+geoNetworkUrl); + return geoNetworkUrl; + } + + @Override + public Map getGeoNetworkPasswords() { + pwds.put(LoginLevel.DEFAULT, geoNetworkPwd); + logger.trace("geoNetworkPwd is: "+geoNetworkPwd); + return pwds; + } + + @Override + public Map getGeoNetworkUsers() { + usrs.put(LoginLevel.DEFAULT, geoNetworkUser); + logger.trace("geoNetworkUser is: "+geoNetworkUser); + return usrs; + } + + @Override + public int getScopeGroup() { + return 2; + } + } + + public GeoNetworkPublisher getGeonetworkPublisher() { + return geonetworkPublisher; + } + + public String getGeoNetworkUrl() { + return geoNetworkUrl; + } + + public String getGeoNetworkUser() { + return geoNetworkUser; + } + + public String getGeoNetworkPwd() { + return geoNetworkPwd; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("GeonetworkInstance [geonetworkPublisher="); + builder.append(geonetworkPublisher); + builder.append(", geoNetworkUrl="); + builder.append(geoNetworkUrl); + builder.append(", geoNetworkUser="); + builder.append(geoNetworkUser); + builder.append(", geoNetworkPwd="); + builder.append(geoNetworkPwd); + builder.append(", scope="); + builder.append(scope); + builder.append(", logger="); + builder.append(logger); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkServiceInterface.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkServiceInterface.java new file mode 100644 index 0000000..621d543 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GeonetworkServiceInterface.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public interface GeonetworkServiceInterface { + + /** + * @param scope + * @param geonetworkInstance + * @return + */ + public GeonetworkInstance getGeonetworkInstance(boolean authenticate) throws Exception; + + public String getScope(); + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/GisResolver.java b/src/main/java/org/gcube/datatransfer/resolver/gis/GisResolver.java new file mode 100644 index 0000000..7966df3 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/GisResolver.java @@ -0,0 +1,281 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis; + +import java.io.IOException; +import java.io.StringReader; +import java.net.URLEncoder; +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.GeoProfileReader.GEO_SERVICE; +import org.gcube.datatransfer.resolver.gis.entity.ServerParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public class GisResolver extends HttpServlet{ + + /** + * + */ + public static final String PARAM_SEPARATOR_REPLACEMENT_VALUE = "%%"; + public static final String PARAM_SEPARATOR_REPLACEMENT_KEY = "separtor"; + + /** + * + */ + private static final long serialVersionUID = 5605107730993617579L; + + public static final String GIS_UUID = "gis-UUID"; + public static final String SCOPE = "scope"; + + /** The logger. */ + private static final Logger logger = LoggerFactory.getLogger(GisResolver.class); + + protected Map cachedServerParams; + + private Timer timer; + + //FIVE MINUTES + public static final long CACHE_RESET_TIME = 5*60*1000; + + @Override + public void init() throws ServletException { + super.init(); + timer = new Timer(true); + timer.schedule(new TimerTask() { + @Override + public void run() { + logger.info("Timer resetting cache.."); + reseCacheServerParameters(); + } + }, 0, CACHE_RESET_TIME); + } + + protected ServerParameters getCachedServerParameters(String scope) throws Exception{ + + if(cachedServerParams==null){ + reseCacheServerParameters(); + } + + logger.info("Tentative to recovering gis server param from cache to scope "+scope); + ServerParameters serverParam = cachedServerParams.get(scope); + + if(serverParam==null){ + logger.info("Gis server param is null, reading from application profile.."); + GeoProfileReader reader = new GeoProfileReader(); + try { + serverParam = reader.retrieveGisParameters(scope, GEO_SERVICE.GEONETWORK); + cachedServerParams.put(scope, serverParam); + logger.info("Updated cache! 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; + } + + private void reseCacheServerParameters(){ + cachedServerParams = new HashMap(); + logger.info("Cache server params reset!"); + } + + /* (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 { + logger.info("The http session id is: " + req.getSession().getId()); + + String gisUUID = req.getParameter(GIS_UUID); + + if (gisUUID == null || gisUUID.equals("")) { + logger.debug("GIS UUID not found"); + sendError(resp, HttpServletResponse.SC_BAD_REQUEST, GIS_UUID+" not found or empty"); + return; + } + + logger.info("GIS UUID is: " + gisUUID); + + 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: " + gisUUID); + + try { + + ServerParameters geonetworkParams = getCachedServerParameters(scope); + String wmsRequest = getLayerWmsRequest(scope, gisUUID, geonetworkParams); + +// logger.info("WmsRequest is: " + wmsRequest); +// wmsRequest = encodeURLWithParamDelimiter(wmsRequest); +// logger.info("Encoded url is: " + wmsRequest); +// wmsRequest = appendParamReplacement(wmsRequest); + logger.info("wms url is: " + wmsRequest); + wmsRequest = URLEncoder.encode(wmsRequest, "UTF-8"); + logger.info("encoded WMS url is: " + wmsRequest); + String gisPortletUrl = "http://127.0.0.1:8080/gis-viewer-app-1.0.0-SNAPSHOT/?"; + gisPortletUrl+="wmsrequest="+wmsRequest; + urlRedirect(req, resp, gisPortletUrl); + } catch (Exception e) { + logger.error("Exception:", e); + String error = "Sorry, an error occurred on resolving request with UUID "+gisUUID+" and scope "+scope+". Please, contact support!"; + sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); + return; + } + + } + + /** + * + * @param wmsRequest + * @return + */ + private String encodeURLWithParamDelimiter(String wmsRequest){ + return wmsRequest.replaceAll("&", PARAM_SEPARATOR_REPLACEMENT_VALUE); + } + + /** + * + * @param wmsRequest + * @return + */ + private String decodeURLWithParamDelimiter(String wmsRequest){ + return wmsRequest.replaceAll(PARAM_SEPARATOR_REPLACEMENT_VALUE, "&"); + } + + /** + * + * @param wmsRequest + * @return + */ + private String appendParamReplacement(String wmsRequest){ + return wmsRequest+"&"+PARAM_SEPARATOR_REPLACEMENT_KEY+"="+PARAM_SEPARATOR_REPLACEMENT_VALUE; + } + + /** + * + * @param scope + * @param gisUUID + * @param geonetworkParams + * @return + * @throws 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 (Exception e) { + logger.error("An error occurred when retrieving gis layer with UUID "+gisUUID, e); + throw new Exception("Sorry, An error occurred when retrieving gis layer with UUID "+gisUUID); + } + } + + /* (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 { + this.doGet(req, resp); + } + + /** + * + * @param response + * @param status + * @param message + * @throws IOException + */ + 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(); + } + + protected void urlRedirect(HttpServletRequest req, HttpServletResponse response, String redirectTo) throws IOException { + response.sendRedirect(response.encodeRedirectURL(redirectTo)); + return; + } + + 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 = "http://127.0.0.1:8080/gis-viewer-app-1.0.0-SNAPSHOT/?"; + gisPortletUrl+="wmsrequest="+wmsRequest; + + logger.info("gisPortletUrl: " + gisPortletUrl); +// urlRedirect(req, resp, gisPortletUrl); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + + + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/MetadataConverter.java b/src/main/java/org/gcube/datatransfer/resolver/gis/MetadataConverter.java new file mode 100644 index 0000000..f5a9ab4 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/MetadataConverter.java @@ -0,0 +1,189 @@ +package org.gcube.datatransfer.resolver.gis; + +import java.util.Collection; + +import org.gcube.datatransfer.resolver.gis.entity.GeoserverBaseUri; +import org.gcube.datatransfer.resolver.gis.util.HttpRequestUtil; +import org.opengis.metadata.Metadata; +import org.opengis.metadata.citation.OnlineResource; +import org.opengis.metadata.distribution.DigitalTransferOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Apr 26, 2013 + * + */ +public class MetadataConverter { + + private static final String GEOSERVER = "/geoserver"; + protected static final String SERVICE_WMS = "service=wms"; + protected static Logger logger = LoggerFactory.getLogger(MetadataConverter.class); + public static final String NOT_FOUND = ""; + + /** + * + * @param uri + * @return the input uri without the parameters, (the uri substring from start to index of '?' char (if exists)) if geoserver base url not found, + * geoserver url otherwise + */ + public static GeoserverBaseUri getGeoserverBaseUri(String uri){ + + GeoserverBaseUri geoserverBaseUri = new GeoserverBaseUri(); + + if(uri==null) + return geoserverBaseUri; //uri is empty + +// Remove each string after "?" + int end = uri.toLowerCase().lastIndexOf("?"); + + if(end==-1){ + logger.trace("char ? not found in geoserver uri, return: "+uri); + return geoserverBaseUri; //uri is empty + } + + String geoserverUrl = uri.substring(0, uri.toLowerCase().lastIndexOf("?")); + + int index = geoserverUrl.lastIndexOf(GEOSERVER); + + if(index>-1){ //FOUND the string GEOSERVER into URL + logger.trace("found geoserver string: "+GEOSERVER+" in "+geoserverUrl); + + //THERE IS SCOPE? + int lastSlash = geoserverUrl.lastIndexOf("/"); + int includeGeoserverString = index+GEOSERVER.length(); + int endUrl = lastSlash>includeGeoserverString?lastSlash:includeGeoserverString; + + logger.trace("indexs - lastSlash: ["+lastSlash+"], includeGeoserverString: ["+includeGeoserverString+"], endUrl: ["+endUrl+"]"); + + int startScope = includeGeoserverString+1 onlineResources = item.getOnLines(); + + for (OnlineResource onlineResource : onlineResources) { + String geoserverUrl = onlineResource.getLinkage()!=null? onlineResource.getLinkage().toString():""; + + //FIND ONLINE RESOURCES WITH GEOSERVER WMS PROTOCOL + if(!geoserverUrl.isEmpty()){ + + int indexServiceWMS = geoserverUrl.toLowerCase().lastIndexOf(SERVICE_WMS); + fullWmsPath = geoserverUrl; + + + //IS OWS OR WMS? + if(indexServiceWMS>-1){ + logger.info("found "+SERVICE_WMS+" url "+geoserverUrl); + isOwsService = geoserverUrl.contains("ows"); + + tempBaseUri = getGeoserverBaseUri(geoserverUrl); + + if(!geoserverUrl.contains("layers") && !geoserverUrl.contains("LAYERS")){ + logger.info("geoserverUrl does not contain 'layers' param, reading"); + layerName= onlineResource.getName()!=null? onlineResource.getName():""; + logger.info("found layer name: " +layerName); + if(!layerName.isEmpty()){ + logger.info("added layers = "+layerName); + fullWmsPath+="&layers="+layerName; + } + } + + break; + } + + if(!foundGeoserverUrl) + logger.trace(SERVICE_WMS+" not found for "+uuid); + } + } + + } + } + + } + + }catch(Exception e){ + logger.error("getWMSOnLineResource with UUID "+uuid + " has throw exception: ",e); + throw new Exception("An error occurred when converting layer with UUID "+uuid); + } + logger.trace("returning: "+fullWmsPath); + return fullWmsPath; + } + + public static void main(String[] args) throws Exception { + +// String geoserver = "http://www.fao.org/figis/a/wms/?service=WMS&version=1.1.0&request=GetMap&layers=area:FAO_AREAS&styles=Species_prob, puppa&bbox=-180.0,-88.0,180.0,90.0000000694&width=667&height=330&srs=EPSG:4326&format=image%2Fpng"; +// +// System.out.println(MetadataConverter.getGeoserverBaseUri(geoserver)); + + String user ="admin"; + String pwd = "admin"; + boolean authenticate = true; +// String uuid ="177e1c3c-4a22-4ad9-b015-bfc443d16cb8"; + String uuid ="fao-species-map-bep"; +// String uuid ="fao-species-map-bon"; //FAO + String geoNetworkUrl ="http://geoserver-dev2.d4science-ii.research-infrastructures.eu/geonetwork"; + GeonetworkInstance geonetowrkInstance = new GeonetworkInstance(geoNetworkUrl, user, pwd, authenticate); + String onLineResource = getWMSOnLineResource(geonetowrkInstance, uuid); + System.out.println(onLineResource); + + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GeoserverBaseUri.java b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GeoserverBaseUri.java new file mode 100644 index 0000000..34826d2 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GeoserverBaseUri.java @@ -0,0 +1,64 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis.entity; + +import java.io.Serializable; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @May 21, 2013 + * + */ +public class GeoserverBaseUri implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = -3321571622161066198L; + private String baseUrl = ""; + private String scope = ""; + + /** + * + */ + public GeoserverBaseUri() { + } + + /** + * @param baseUrl + * @param scope + */ + public GeoserverBaseUri(String baseUrl, String scope) { + this.baseUrl = baseUrl; + this.scope = scope; + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("GeoserverBaseUri [baseUrl="); + builder.append(baseUrl); + builder.append(", scope="); + builder.append(scope); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GisLayerItem.java b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GisLayerItem.java new file mode 100644 index 0000000..5dd45f7 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/GisLayerItem.java @@ -0,0 +1,226 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis.entity; + +import java.util.Date; +import java.util.List; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public class GisLayerItem { + + private String uuid; + private String citationTitle; + private String layerName; + private String topicCategory; + private Date publicationDate; + private String scopeCode; + private String geoserverBaseUrlOnLineResource; + private String baseWmsServiceUrl; + private String fullWmsUrlRequest; + private List styles; + private String metaAbstract; + private List listKeywords; + private String versionWMS; + private String setCrsWMS; + + /** + * @param uuid + * @param citationTitle + * @param layerName + * @param topicCategory + * @param publicationDate + * @param scopeCode + * @param geoserverBaseUrlOnlineResource + * @param baseWmsServiceUrl + * @param fullWmsUrlRequest + * @param b + * @param styles + * @param metaAbstract + * @param listKeywords + */ + public GisLayerItem(String uuid, String citationTitle, String layerName, + String topicCategory, Date publicationDate, String scopeCode, + String geoserverBaseUrlOnlineResource, String baseWmsServiceUrl, + String fullWmsUrlRequest, List styles, + String metaAbstract, List listKeywords) { + this.uuid = uuid; + this.citationTitle = citationTitle; + this.layerName = layerName; + this.topicCategory = topicCategory; + this.publicationDate = publicationDate; + this.scopeCode = scopeCode; + this.geoserverBaseUrlOnLineResource = geoserverBaseUrlOnlineResource; + this.baseWmsServiceUrl = baseWmsServiceUrl; + this.fullWmsUrlRequest = fullWmsUrlRequest; + this.styles = styles; + this.metaAbstract = metaAbstract; + this.listKeywords = listKeywords; + } + + /** + * @param versionWms + */ + public void setVersionWMS(String versionWms) { + this.versionWMS = versionWms; + + } + + /** + * @param crs + */ + public void setCrsWMS(String crs) { + this.setCrsWMS =crs; + } + + public String getUuid() { + return uuid; + } + + public String getCitationTitle() { + return citationTitle; + } + + public String getLayerName() { + return layerName; + } + + public String getTopicCategory() { + return topicCategory; + } + + public Date getPublicationDate() { + return publicationDate; + } + + public String getScopeCode() { + return scopeCode; + } + + public String getGeoserverBaseUrlOnLineResource() { + return geoserverBaseUrlOnLineResource; + } + + public String getBaseWmsServiceUrl() { + return baseWmsServiceUrl; + } + + public String getFullWmsUrlRequest() { + return fullWmsUrlRequest; + } + + public List getStyles() { + return styles; + } + + public String getMetaAbstract() { + return metaAbstract; + } + + public List getListKeywords() { + return listKeywords; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setCitationTitle(String citationTitle) { + this.citationTitle = citationTitle; + } + + public void setLayerName(String layerName) { + this.layerName = layerName; + } + + public void setTopicCategory(String topicCategory) { + this.topicCategory = topicCategory; + } + + public void setPublicationDate(Date publicationDate) { + this.publicationDate = publicationDate; + } + + public void setScopeCode(String scopeCode) { + this.scopeCode = scopeCode; + } + + public void setGeoserverBaseUrlOnLineResource( + String geoserverBaseUrlOnLineResource) { + this.geoserverBaseUrlOnLineResource = geoserverBaseUrlOnLineResource; + } + + public void setBaseWmsServiceUrl(String baseWmsServiceUrl) { + this.baseWmsServiceUrl = baseWmsServiceUrl; + } + + public void setFullWmsUrlRequest(String fullWmsUrlRequest) { + this.fullWmsUrlRequest = fullWmsUrlRequest; + } + + public void setStyles(List styles) { + this.styles = styles; + } + + public void setMetaAbstract(String metaAbstract) { + this.metaAbstract = metaAbstract; + } + + public void setListKeywords(List listKeywords) { + this.listKeywords = listKeywords; + } + + public String getVersionWMS() { + return versionWMS; + } + + public String getSetCrsWMS() { + return setCrsWMS; + } + + public void setSetCrsWMS(String setCrsWMS) { + this.setCrsWMS = setCrsWMS; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("LayerItem [uuid="); + builder.append(uuid); + builder.append(", citationTitle="); + builder.append(citationTitle); + builder.append(", layerName="); + builder.append(layerName); + builder.append(", topicCategory="); + builder.append(topicCategory); + builder.append(", publicationDate="); + builder.append(publicationDate); + builder.append(", scopeCode="); + builder.append(scopeCode); + builder.append(", geoserverBaseUrlOnLineResource="); + builder.append(geoserverBaseUrlOnLineResource); + builder.append(", baseWmsServiceUrl="); + builder.append(baseWmsServiceUrl); + builder.append(", fullWmsUrlRequest="); + builder.append(fullWmsUrlRequest); + builder.append(", styles="); + builder.append(styles); + builder.append(", metaAbstract="); + builder.append(metaAbstract); + builder.append(", listKeywords="); + builder.append(listKeywords); + builder.append(", versionWMS="); + builder.append(versionWMS); + builder.append(", setCrsWMS="); + builder.append(setCrsWMS); + builder.append("]"); + return builder.toString(); + } + + + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/entity/ServerParameters.java b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/ServerParameters.java new file mode 100644 index 0000000..c448e3f --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/entity/ServerParameters.java @@ -0,0 +1,89 @@ +package org.gcube.datatransfer.resolver.gis.entity; + +import java.io.Serializable; + +/** + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Oct 7, 2014 + * + */ +public class ServerParameters implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 2459971193655529274L; + + protected String url; + protected String user; + protected String password; + + public ServerParameters(){} + + /** + * @param url + * @param user + * @param password + */ + public ServerParameters(String url, String user, String password) { + this.url = url; + this.user = user; + this.password = password; + } + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @param url the url to set + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @return the user + */ + public String getUser() { + return user; + } + + /** + * @param user the user to set + */ + public void setUser(String user) { + this.user = user; + } + + /** + * @return the password + */ + public String getPassword() { + return password; + } + + /** + * @param password the password to set + */ + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ServerParameters [url="); + builder.append(url); + builder.append(", user="); + builder.append(user); + builder.append(", password="); + builder.append(password); + builder.append("]"); + return builder.toString(); + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/util/HttpRequestUtil.java b/src/main/java/org/gcube/datatransfer/resolver/gis/util/HttpRequestUtil.java new file mode 100644 index 0000000..8e495cc --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/util/HttpRequestUtil.java @@ -0,0 +1,110 @@ +package org.gcube.datatransfer.resolver.gis.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @Apr 26, 2013 + * + */ +public class HttpRequestUtil { + + private static final String SERVICE_EXCEPTION_REPORT = "ServiceExceptionReport"; //WMS Exception + private static final String OWS_EXCEPTION_REPORT = "ows:ExceptionReport"; //OWS Exception + private static final int CONNECTION_TIMEOUT = 1000; + public static Logger logger = LoggerFactory.getLogger(HttpRequestUtil.class); + + public static boolean urlExists(String urlConn, boolean verifyIsWmsGeoserver) throws Exception { + + URL url; + try { + url = new URL(urlConn); + + URLConnection connection = url.openConnection(); + connection.setConnectTimeout(CONNECTION_TIMEOUT); + connection.setReadTimeout(CONNECTION_TIMEOUT+CONNECTION_TIMEOUT); + + logger.trace("open connection on: " + url); + + // Cast to a HttpURLConnection + if (connection instanceof HttpURLConnection) { + HttpURLConnection httpConnection = (HttpURLConnection) connection; + + httpConnection.setRequestMethod("GET"); + + int code = httpConnection.getResponseCode(); + + if(verifyIsWmsGeoserver) + return isGeoserver(httpConnection); + + httpConnection.disconnect(); + + if (code == 200) { + return true; + } + +// logger.trace("result: "+result); + + } else { + logger.error("error - not a http request!"); + } + + return false; + + } catch (SocketTimeoutException e) { + logger.error("Error SocketTimeoutException with url " +urlConn); + throw new Exception("Error SocketTimeoutException"); + } catch (MalformedURLException e) { + logger.error("Error MalformedURLException with url " +urlConn); + throw new Exception("Error MalformedURLException"); + } catch (IOException e) { + logger.error("Error IOException with url " +urlConn); + throw new Exception("Error IOException"); + }catch (Exception e) { + logger.error("Error Exception with url " +urlConn); + throw new Exception("Error Exception"); + } + } + + + private static boolean isGeoserver(HttpURLConnection httpConnection) throws IOException{ + + BufferedReader rd = new BufferedReader(new InputStreamReader(httpConnection.getInputStream())); + String line; + String result = ""; + + int code = httpConnection.getResponseCode(); + + if (code == 200) { + while ((line = rd.readLine()) != null) { + result += line; + } + } + else{ + rd.close(); + return false; + } + if(result.contains(OWS_EXCEPTION_REPORT) || result.contains(SERVICE_EXCEPTION_REPORT)){ + rd.close(); + return true; + } + rd.close(); + return false; + + } + + public static void main(String[] args) throws Exception { + System.out.println(HttpRequestUtil.urlExists("http://geoserver2.d4science.research-infrastructures.eu/geoserver/wms", true)); + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/http/HttpResolver.java b/src/main/java/org/gcube/datatransfer/resolver/http/HttpResolver.java index ba697c8..aa49430 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/http/HttpResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/http/HttpResolver.java @@ -7,7 +7,6 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; - import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index 74ea2d7..0a48f18 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -8,5 +8,6 @@ log4j.appender.A0.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %c{2} [%t,%M:%L log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern= %d{HH:mm:ss,SSS} %-5p %c{2} [%t,%M:%L] %m%n +#log4j.category.org.gcube=TRACE,A1 log4j.category.org.gcube=DEBUG,A1 log4j.additivity.org.gcube=false \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 34bcc4e..15679f5 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -2,7 +2,7 @@ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > -http resolver + http resolver smp @@ -10,9 +10,23 @@ org.gcube.datatransfer.resolver.http.HttpResolver true - + + + gisResolver + gisResolver + org.gcube.datatransfer.resolver.gis.GisResolver + true + + + smp /smp + + gisResolver + /gis + + + diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 06abbbe..7c2e970 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -1,5 +1,6 @@

The SM URI resolver

+

See: URI Resolver gCube Wiki