/** * */ package org.gcube.datatransfer.resolver.services; import java.net.URI; import java.net.URLEncoder; import java.util.Random; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.caches.LoadingGeoExplorerApplicationURLCache; import org.gcube.datatransfer.resolver.caches.LoadingGeonetworkInstanceCache; import org.gcube.datatransfer.resolver.caches.LoadingGisViewerApplicationURLCache; import org.gcube.datatransfer.resolver.gis.GeonetworkInstance; import org.gcube.datatransfer.resolver.gis.MetadataConverter; import org.gcube.datatransfer.resolver.gis.entity.GisLayerItem; import org.gcube.datatransfer.resolver.gis.exception.GeonetworkInstanceException; import org.gcube.datatransfer.resolver.init.UriResolverSmartGearManagerInit; import org.gcube.datatransfer.resolver.services.error.ExceptionManager; import org.gcube.spatial.data.geonetwork.LoginLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.cache.CacheLoader.InvalidCacheLoadException; /** * The Class GisResolver. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * Dec 14, 2018 */ @Path("gis") public class GisResolver { private static Logger logger = LoggerFactory.getLogger(GisResolver.class); public static String help = "https://wiki.gcube-system.org/gcube/URI_Resolver#GIS_Resolver"; public static final String UTF_8 = "UTF-8"; public static final String GIS_UUID = "gis-UUID"; public static final String SCOPE = "scope"; public static final String GEO_EXPLORER_LAYER_UUID = "geo-exp"; /** * Submit get. * * @param req the req * @param scope the scope * @param gisUUID the gis uuid * @param geoExplorerUUID the geo explorer uuid * @return the response * @throws WebApplicationException the web application exception */ @GET @Path("") public Response submitGet(@Context HttpServletRequest req, @QueryParam(SCOPE) String scope, @QueryParam(GIS_UUID) String gisUUID, @QueryParam(GEO_EXPLORER_LAYER_UUID) String geoExplorerUUID) throws WebApplicationException { logger.info(this.getClass().getSimpleName() + " GET starts..."); try { boolean isGisLink = false; boolean isGeoExplorerLink = false; if (scope == null || scope.isEmpty()) { logger.error("Query Parameter 'scope' not found"); throw ExceptionManager.badRequestException(req, "Missing mandatory query parameter 'scope'", this.getClass(), help); } if (gisUUID == null || gisUUID.isEmpty()) { logger.error("Path Parameter 'gis-UUID' not found"); throw ExceptionManager.badRequestException(req, "Missing mandatory query parameter 'gis-UUID'", this.getClass(), help); } else isGisLink = true; logger.info(SCOPE + " is: " + scope); logger.info(GIS_UUID + " is: " + gisUUID); if (geoExplorerUUID == null || geoExplorerUUID.isEmpty()) { logger.debug(GEO_EXPLORER_LAYER_UUID + " not found"); } else isGeoExplorerLink = true; logger.info(GEO_EXPLORER_LAYER_UUID + " is: " + geoExplorerUUID); if (!isGisLink && !isGeoExplorerLink) { String err = GIS_UUID + " or " + GEO_EXPLORER_LAYER_UUID + " not found or empty in the query string"; logger.error(err); throw ExceptionManager.badRequestException(req, err, this.getClass(), help); } if (isGisLink) { ScopeProvider.instance.set(scope); // ServerParameters geonetworkParams = getCachedServerParameters(scope); GisLayerItem gisLayerItem = getGisLayerForLayerUUID(req, scope, gisUUID); logger.info("wms url is: " + gisLayerItem.getFullWmsUrlRequest()); String wmsRequest = URLEncoder.encode(gisLayerItem.getFullWmsUrlRequest(), UTF_8); logger.info("encoded WMS url is: " + wmsRequest); String layerTitle = null; if (gisLayerItem.getCitationTitle() != null && !gisLayerItem.getCitationTitle().isEmpty()) layerTitle = URLEncoder.encode(gisLayerItem.getCitationTitle(), UTF_8); logger.info("layer Title encoded is: " + layerTitle); String gisViewerPortletUrl = null; try { gisViewerPortletUrl = LoadingGisViewerApplicationURLCache.get(scope); } catch (ExecutionException | InvalidCacheLoadException e) { logger.error("Error on getting the GisViewer Applicaton URL from cache for scope " + scope, e); throw ExceptionManager.wrongParameterException(req, "Error on getting the GisViewer Applicaton URL from cache for scope " + scope + ".\nIs the Application Profile with APPID " + UriResolverSmartGearManagerInit.getGisViewerProfile().getAppId() + " registered for this scope: " + scope + "?", this.getClass(), help); } // CHECKING IF THE GisViewer Portlet URL is valid if (gisViewerPortletUrl == null || gisViewerPortletUrl.isEmpty()) throw ExceptionManager.notFoundException(req, "GisViewer Portlet URL not found in the scope: " + scope + ". Please contact the support", this.getClass(), help); logger.info("Gis Viewer Application url is: " + gisViewerPortletUrl); gisViewerPortletUrl += "?rid=" + new Random().nextLong() + "&wmsrequest=" + wmsRequest + "&uuid=" + URLEncoder.encode(gisUUID, UTF_8); if (layerTitle != null) gisViewerPortletUrl += "&layertitle=" + layerTitle; logger.info("Redirecting to: " + gisViewerPortletUrl); return Response.seeOther(new URI(gisViewerPortletUrl)).build(); } if (isGeoExplorerLink) { ScopeProvider.instance.set(scope); String geoExplorerPortletUrl = null; try { geoExplorerPortletUrl = LoadingGeoExplorerApplicationURLCache.get(scope); } catch (ExecutionException e) { logger.error("Error on getting the GeoExplorer Applicaton URL from cache for scope " + scope, e); throw ExceptionManager.wrongParameterException(req, "Error on getting the GeoExplorer Applicaton URL from cache for scope " + scope + ".\nIs the Application Profile with APPID " + UriResolverSmartGearManagerInit.getGeoExplorerProfile().getAppId() + " registered for this scope: " + scope + "?", this.getClass(), help); } // CHECKING IF THE GeoExplorer Portlet URL is valid if (geoExplorerPortletUrl == null || geoExplorerPortletUrl.isEmpty()) throw ExceptionManager.notFoundException(req, "GeoExplorer Portlet URL not found in the scope: " + scope + ". Please contact the support", this.getClass(), help); logger.info("GeoExplorer Application url is: " + geoExplorerPortletUrl); geoExplorerPortletUrl += "?rid=" + new Random().nextLong() + "&luuid=" + URLEncoder.encode(geoExplorerUUID, UTF_8); // urlRedirect(req, resp, geoExplorerPortletUrl); return Response.seeOther(new URI(geoExplorerPortletUrl)).build(); } throw ExceptionManager.badRequestException(req, GIS_UUID + " or " + GEO_EXPLORER_LAYER_UUID + " not found or empty in the query string", this.getClass(), help); } catch (Exception e) { if (!(e instanceof WebApplicationException)) { // UNEXPECTED EXCEPTION managing it as WebApplicationException String error = "Sorry, an error occurred on resolving request with UUID " + gisUUID + " and scope " + scope + ". Please, contact support!"; if (e.getCause() != null) error += "\n\nCaused: " + e.getCause().getMessage(); throw ExceptionManager.internalErrorException(req, error, this.getClass(), help); } // ALREADY MANAGED AS WebApplicationException logger.error("Exception:", e); throw (WebApplicationException) e; } } /** * Gets the gis layer for layer uuid. * * @param req the req * @param scope the scope * @param gisUUID the gis uuid * @return the gis layer for layer uuid * @throws Exception the exception */ public GisLayerItem getGisLayerForLayerUUID(HttpServletRequest req, String scope, String gisUUID) throws Exception { try { GeonetworkInstance gi = null; try { gi = LoadingGeonetworkInstanceCache.get(scope); } catch (ExecutionException | InvalidCacheLoadException e) { logger.error("Error on getting the Geonetwork Instance from cache for scope " + scope, e); throw ExceptionManager.wrongParameterException(req, "Error on getting the Geonetwork Instance from cache for scope " + scope + ". Is it registered for this scope: " + scope + "?", this.getClass(), help); } if (gi == null) throw new Exception("GeonetworkInstance not instanciable in the scope: " + scope); LoginLevel toLoginLevel = LoginLevel.SCOPE; logger.info( "Performing authentication on GN with " + LoginLevel.class.getSimpleName() + " " + toLoginLevel); gi.getGeonetworkPublisher().login(toLoginLevel); GisLayerItem gisLayerItem = MetadataConverter.getWMSOnLineResource(gi, gisUUID); return gisLayerItem; // TODO CREATE A BEAN ADDING WMS REQUEST AND LAYER TITLE MetadataConverter. } 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); } } }