package org.gcube.datatransfer.resolver.services; import java.net.URL; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.ResourceCatalogueCodes; import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; import org.gcube.datatransfer.resolver.catalogue.CatalogueRequest; import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver; import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader; import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference; import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.trentorise.opendata.jackan.model.CkanDataset; @Path("/") public class Catalogue { private static Logger logger = LoggerFactory.getLogger(Catalogue.class); public static final String ENV_SCOPE = "SCOPE"; //Environment Variable /** The scope to enc decr. */ private String scopeToEncDecr = null; ApplicationProfileReaderForCatalogueResolver appPrCatResolver; @GET @Path("{entityContext:ctlg(-(o|g|p|d)?}/{vreName}/{entityName}") public Response resolveCatalogue(@PathParam("entityName") String entityName, @PathParam("vreName") String vreName, @PathParam("entityContext") String entityContext) { try { String entityContextValue = ResourceCatalogueCodes.valueOfCodeId(entityContext).getValue(); ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(vreName, true); String fullScope = appPrCatResolver.getHashVreNameScope().get(vreName); ScopeProvider.instance.set(fullScope); GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); logger.debug("Read fullScope: "+fullScope + " for VRE_NAME: "+vreName +" into Application Profile "+ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME); //IS THE PRODUCT PLUBLIC OR PRIVATE? //USING ACCESS TO PUBLIC PORTLET IF THE ITEM IS PUBLIC, OTHERWISE ACCESS TO PRIVATE PORTLET String ckanPorltetUrl = ckanCatalogueReference.getPrivatePortletURL(); String datasetName = entityName; if(ckanCatalogueReference.getCkanURL()!=null){ try{ CkanDataset dataset = CkanCatalogueConfigurationsReader.getDataset(datasetName, ckanCatalogueReference.getCkanURL()); if(dataset!=null){ ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); logger.info("The dataset "+datasetName+" is a public item using public access to CKAN portlet: "+ckanPorltetUrl); } }catch(Exception e){ logger.warn("Error on checking if dataset: "+datasetName+" is private or not", e); ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); } } String url = String.format("%s?path=/%s/%s",ckanPorltetUrl,entityContextValue, entityName); return Response.seeOther(new URL(url).toURI()).build(); }catch (Exception e) { logger.error("error resolving catalogue link",e); throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR); } } @POST @Path("catalogue") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public Response postCatalogue(@Context HttpServletRequest req, CatalogueRequest jsonRequest) { //final CatalogueEntityRequest cer = new CatalogueEntityRequest(); //CHECK IF INPUT SCOPE IS VALID String scope = jsonRequest.getGcube_scope(); if(!scope.startsWith("/")){ logger.info("Scope not start with char '/' adding it"); scope+="/"+scope; } String serverUrl = getServerURL(req); final String vreName = scope.substring(scope.lastIndexOf("/")+1, scope.length()); ResourceCatalogueCodes rc = ResourceCatalogueCodes.valueOfCodeValue(jsonRequest.getEntity_context()); if(rc==null){ logger.error("Entity context is null/malformed"); throw new WebApplicationException("Entity context is null/malformed", Status.BAD_REQUEST); } String linkURL = String.format("%s/%s/%s/%s", serverUrl, rc.getId(), vreName, jsonRequest.getEntity_name()); logger.info("Writing Decoded Catalogue Link: "+linkURL); //IT'S GOING TO UPDATE THE GENERIC RESOURCE IF IS NEEDED final String fullscope = scope; new Thread(){ public void run() { try { boolean endPointUpdated = UpdateApplicationProfileCatalogueResolver.validateEndPoint(scopeToEncDecr, vreName, fullscope); if(endPointUpdated) appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(fullscope, true); } catch (ApplicationProfileNotFoundException e) { logger.error("Error during validating Application Profile", e); } }; }.start(); return Response.ok(linkURL).build(); } /** * Gets the server url. * * @param req the req * @return the server url */ private String getServerURL(HttpServletRequest req) { String scheme = req.getScheme(); // http String serverName = req.getServerName(); // hostname.com int serverPort = req.getServerPort(); // 80 //String contextPath = req.getContextPath(); // /mywebapp // Reconstruct original requesting URL StringBuffer url = new StringBuffer(); url.append(scheme).append("://").append(serverName); if (serverPort != 80 && serverPort != 443) url.append(":").append(serverPort); // if(contextPath!=null) // url.append(":").append(contextPath); String uToS = url.toString(); logger.debug("returning servlet context URL: "+uToS); return uToS; } }