diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 18a79e2..7098efc 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,5 +1,5 @@ - + @@ -15,8 +15,58 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33,7 +83,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -50,7 +125,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -67,7 +167,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -84,7 +209,38 @@ - + + uses + + + uses + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -101,7 +257,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118,7 +299,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -135,7 +341,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 99a117b..476a997 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.10.0-SNAPSHOT] + +- GeoPortal-Resolver enhancement: implemented share link towards Geoportal Data-Entry facility [#27135] +- Added Geoportal Exporter as PDF [#27274] +- Migrated to `catalogue-util-library` [#27423] + ## [v2.9.0] - GeoPortal-Resolver implemented [#24792] diff --git a/README.md b/README.md index fa871ef..e98a7cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # gCube URI Resolver -The URI Resolver is a RESTful service which gives access via HTTP(s) to different gCube Resolver services and gCube Applications +The URI Resolver is a RESTful service which gives access via HTTP(s) to different gCube Resolver services and gCube Applications. + +The URI Resolver production service is available at [D4Science URI Resolver](https://data.d4science.org/) ## Built With @@ -11,7 +13,7 @@ The URI Resolver is a RESTful service which gives access via HTTP(s) to differen You can find the URI Resolver documentation at [URI Resolver Wiki Page](https://wiki.gcube-system.org/gcube/URI_Resolver) -The API documentation accessible by [links](https://wiki.gcube-system.org/gcube/URI_Resolver#Instances) is provided by [Enunciate](https://github.com/stoicflame/enunciate/) +The API documentation accessible by this [link](https://wiki.gcube-system.org/gcube/URI_Resolver#Instances) is provided by [Enunciate](https://github.com/stoicflame/enunciate/) ## Change log diff --git a/pom.xml b/pom.xml index 374ecd4..9b448cf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,11 +5,11 @@ maven-parent org.gcube.tools - 1.1.0 + 1.2.0 org.gcube.data.transfer uri-resolver - 2.9.0 + 2.10.0-SNAPSHOT war The URI Resolver is an HTTP URI resolver implemented as a REST service which gives access trough HTTP to different gcube Resolvers and gCube Applications. @@ -19,8 +19,43 @@ https://code-repo.d4science.org/gCubeSystem/${project.artifactId} + + + + + uri-resolver-release-profile + + + Release + + + + + 2.5.0 + [2.0.0, 3.0.0-SNAPSHOT) + + + + + uri-resolver-snapshot-profile + + + !Release + + + + + 2.5.0 + [2.0.0, 3.0.0-SNAPSHOT) + + + + + - 2.24.1 + 2.25.1 + + 2.8.4 1.8 1.8 2.14.0 @@ -28,16 +63,24 @@ + + + + + + + org.gcube.distribution gcube-smartgears-bom - 2.4.0 + ${gcube-smartgears-bom-version} pom import + @@ -76,7 +119,7 @@ org.gcube.data-publishing storagehub-application-persistence - [1.0.0, 2.0.0-SNAPSHOT) + [1.0.0, 3.0.0-SNAPSHOT) org.gcube.common @@ -98,6 +141,12 @@ [1.0.0,2.0.0-SNAPSHOT) + + org.gcube.common + authorization-utils + ${authorization-utils-range} + + com.google.guava guava @@ -123,7 +172,6 @@ org.gcube.common storagehub-client-library - [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) @@ -132,7 +180,6 @@ ${jersey.version} compile - org.glassfish.jersey.core jersey-server @@ -140,6 +187,25 @@ compile + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + net.bull.javamelody @@ -187,17 +253,11 @@ compile - - org.projectlombok - lombok - 1.14.8 - - javax.xml.bind jaxb-api - 2.3.0 + provided @@ -205,7 +265,7 @@ org.projectlombok lombok - 1.18.4 + provided @@ -242,14 +302,33 @@ - org.gcube.data-catalogue - ckan-util-library - [2.0.0, 3.0.0-SNAPSHOT) + org.gcube.datacatalogue + catalogue-util-library + [1.0.0, 2.0.0-SNAPSHOT) compile + + org.gcube.application + geoportal-data-mapper + [1.0.0, 2.0.0-SNAPSHOT) + + + + org.gcube.contentmanagement + storage-manager-wrapper + + + org.gcube.contentmanagement + storage-manager-core + + + compile + + org.slf4j slf4j-api diff --git a/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java b/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java index 8cc867c..0ed52fa 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/UriResolver.java @@ -14,10 +14,12 @@ import org.glassfish.jersey.server.ResourceConfig; @ManagedBy(UriResolverSmartGearManagerInit.class) public class UriResolver extends ResourceConfig { - public UriResolver() { - // Register all resources present under the package. - packages(CatalogueResolver.class.getPackage().getName(), RequestHandler.class.getPackage().getName(), BackCatalogueResolver.class.getPackage().getName()); - packages(DataMinerInvocation.class.getPackage().getName()); - } + public UriResolver() { + // Register all resources present under the package. + packages(CatalogueResolver.class.getPackage().getName(), RequestHandler.class.getPackage().getName(), BackCatalogueResolver.class.getPackage().getName()); + packages(DataMinerInvocation.class.getPackage().getName()); +// +// register(JspMvcFeature.class); +// property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/img"); + } } - diff --git a/src/main/java/org/gcube/datatransfer/resolver/UriResolverServices.java b/src/main/java/org/gcube/datatransfer/resolver/UriResolverServices.java index a4f8051..6ee7764 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/UriResolverServices.java +++ b/src/main/java/org/gcube/datatransfer/resolver/UriResolverServices.java @@ -11,14 +11,15 @@ import java.util.Set; import javax.ws.rs.Path; +import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; +import org.gcube.com.fasterxml.jackson.databind.node.JsonNodeFactory; +import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.glassfish.jersey.server.model.Resource; import org.glassfish.jersey.server.model.ResourceMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; + /** @@ -192,8 +193,9 @@ public class UriResolverServices { if(listResourcePath.isEmpty()){ log.info("Reference to the List of Resources/Services is empty, creating it..."); readResources(applicationClasses); - log.info("Hard-Coding the resource/s: "+ConstantsResolver.resourcesHardCoded); - listResourcePath.addAll(Arrays.asList(ConstantsResolver.resourcesHardCoded)); + List listHardCodedResources = Arrays.asList(ConstantsResolver.resourcesHardCoded); + log.info("Hard-Coding the resource/s: "+listHardCodedResources); + listResourcePath.addAll(listHardCodedResources); } return listResourcePath; diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java index 9b81eb2..759cbef 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java @@ -12,7 +12,7 @@ import java.util.Map; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueImpl; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueImpl; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.slf4j.Logger; diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java index eed1d99..f6930f3 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java @@ -18,8 +18,11 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.gcube.common.resources.gcore.utils.XPathHelper; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueImpl; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.jackan.CkanClient; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueImpl; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.exceptions.CkanException; import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; import org.gcube.datatransfer.resolver.catalogue.endpoint.CatalogueServiceEndpointReader; import org.gcube.resources.discovery.client.api.DiscoveryClient; @@ -30,10 +33,6 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.xml.sax.InputSource; -import eu.trentorise.opendata.jackan.CkanClient; -import eu.trentorise.opendata.jackan.exceptions.CkanException; -import eu.trentorise.opendata.jackan.model.CkanDataset; - /** * The Class CkanCatalogueConfigurationsReader. diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java index 8bc4e8d..37f647a 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java @@ -7,7 +7,7 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalCommonConstants.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalCommonConstants.java index b2ff4d5..5ebabce 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalCommonConstants.java +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalCommonConstants.java @@ -12,6 +12,8 @@ public class GeoportalCommonConstants { public static final String GET_GEONA_ITEM_TYPE = "git"; public static final String GET_GEONA_ITEM_ID = "gid"; - public static final String GEOPORTAL_DATA_VIEWER_APP = "geoportal-data-viewer-app"; + public static final String GEOPORTAL_DATA_VIEWER_APP_ID = "geoportal-data-viewer-app"; + + public static final String GEOPORTAL_DATA_ENTRY_APP_ID = "geoportal-data-entry-app"; } diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfile.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfile.java similarity index 77% rename from src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfile.java rename to src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfile.java index b3c0c73..7496439 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfile.java +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfile.java @@ -3,25 +3,25 @@ package org.gcube.datatransfer.resolver.geoportal; import java.io.Serializable; /** - * The Class GeoportalDataViewerConfigProfile. + * The Class GeoportalConfigApplicationProfile. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * - * Dec 21, 2021 + * Apr 3, 2024 */ -public class GeoportalDataViewerConfigProfile implements Serializable { +public class GeoportalConfigApplicationProfile implements Serializable { /** * */ - private static final long serialVersionUID = 2968334957258327191L; + private static final long serialVersionUID = 8340275391003882511L; private String restrictedPortletURL; private String openPortletURL; /** * Instantiates a new geo na data viewer profile. */ - public GeoportalDataViewerConfigProfile() { + public GeoportalConfigApplicationProfile() { } @@ -61,15 +61,20 @@ public class GeoportalDataViewerConfigProfile implements Serializable { this.openPortletURL = openPortletURL; } + /** + * To string. + * + * @return the string + */ @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("GeoportalDataViewerConfigProfile [restrictedPortletURL="); + builder.append("GeoportalConfigApplicationProfile [restrictedPortletURL="); builder.append(restrictedPortletURL); builder.append(", openPortletURL="); builder.append(openPortletURL); builder.append("]"); return builder.toString(); } - + } diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfileReader.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfileReader.java similarity index 77% rename from src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfileReader.java rename to src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfileReader.java index 5b8fb8b..5642fa9 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalDataViewerConfigProfileReader.java +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalConfigApplicationProfileReader.java @@ -20,36 +20,35 @@ import org.w3c.dom.Document; import org.xml.sax.InputSource; /** - * The Class GeoportalDataViewerConfigProfileReader. + * The Class GeoportalConfigApplicationProfileReader. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * - * Mar 23, 2023 + * Apr 3, 2024 */ -public class GeoportalDataViewerConfigProfileReader { +public class GeoportalConfigApplicationProfileReader { + private static Logger LOG = LoggerFactory.getLogger(GeoportalConfigApplicationProfileReader.class); private static final String RESOURCE_PROFILE_BODY = "/Resource/Profile/Body"; public static final String SECONDARY_TYPE = "ApplicationProfile"; - public static final String GENERIC_RESOURCE_NAME = "Geoportal-DataViewer-Configs"; - private static Logger LOG = LoggerFactory.getLogger(GeoportalDataViewerConfigProfileReader.class); private String secondaryType; private String scope; private String appID; - private GeoportalDataViewerConfigProfile geoportalDataViewerConfigProfile; + private GeoportalConfigApplicationProfile geoportalConfigAppProfile; /** - * Instantiates a new geoportal data viewer config profile reader. + * Instantiates a new geoportal config application profile reader. * * @param appID the app ID * @throws Exception the exception */ - public GeoportalDataViewerConfigProfileReader(String appID) throws Exception { + public GeoportalConfigApplicationProfileReader(String appID) throws Exception { this.appID = appID; this.secondaryType = SECONDARY_TYPE; this.scope = ScopeProvider.instance.get(); - this.geoportalDataViewerConfigProfile = readProfileFromInfrastructure(); + this.geoportalConfigAppProfile = readProfileFromInfrastructure(); } /** @@ -58,7 +57,7 @@ public class GeoportalDataViewerConfigProfileReader { * @return the map * @throws Exception the exception */ - private GeoportalDataViewerConfigProfile readProfileFromInfrastructure() throws Exception { + private GeoportalConfigApplicationProfile readProfileFromInfrastructure() throws Exception { String queryString = getGcubeGenericQueryString(secondaryType, appID); LOG.info("Scope " + scope + ", trying to perform query: " + queryString); @@ -68,7 +67,7 @@ public class GeoportalDataViewerConfigProfileReader { if (scope == null) throw new Exception("Scope is null, set scope into ScopeProvider"); - GeoportalDataViewerConfigProfile profile = new GeoportalDataViewerConfigProfile(); + GeoportalConfigApplicationProfile profile = new GeoportalConfigApplicationProfile(); LOG.info("Trying to fetch ApplicationProfile in the scope: " + scope + ", SecondaryType: " + secondaryType + ", AppId: " + appID); @@ -107,8 +106,8 @@ public class GeoportalDataViewerConfigProfileReader { } } catch (Exception e) { - LOG.error("Error while trying to read the " + SECONDARY_TYPE + " with SecondaryType " - + GENERIC_RESOURCE_NAME + " from scope " + scope, e); + LOG.error("Error while trying to read the SecondaryType " + SECONDARY_TYPE + " with appID " + appID + + " from scope " + scope, e); return null; } finally { @@ -116,8 +115,13 @@ public class GeoportalDataViewerConfigProfileReader { } - public GeoportalDataViewerConfigProfile getGeoportalDataViewerConfigProfile() { - return geoportalDataViewerConfigProfile; + /** + * Gets the geoportal config app profile. + * + * @return the geoportal config app profile + */ + public GeoportalConfigApplicationProfile getGeoportalConfigAppProfile() { + return geoportalConfigAppProfile; } /** @@ -152,17 +156,22 @@ public class GeoportalDataViewerConfigProfileReader { return scope; } + /** + * To string. + * + * @return the string + */ @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("GeoportalDataViewerConfigProfileReader [secondaryType="); + builder.append("GeoportalConfigApplicationProfileReader [secondaryType="); builder.append(secondaryType); builder.append(", scope="); builder.append(scope); builder.append(", appID="); builder.append(appID); - builder.append(", geoportalDataViewerConfigProfile="); - builder.append(geoportalDataViewerConfigProfile); + builder.append(", geoportalConfigAppProfile="); + builder.append(geoportalConfigAppProfile); builder.append("]"); return builder.toString(); } diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalRequest.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalRequest.java index 3bf4206..ed91528 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalRequest.java +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/GeoportalRequest.java @@ -1,5 +1,6 @@ package org.gcube.datatransfer.resolver.geoportal; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @@ -15,11 +16,13 @@ import lombok.extern.slf4j.Slf4j; */ @Slf4j @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class GeoportalRequest { public static final String P_GCUBE_SCOPE = "gcube_scope"; public static final String P_ITEM_TYPE = "item_type"; public static final String P_ITEM_ID = "item_id"; + public static final String P_RESOLVES_AS = "res"; public static final String P_QUERY_STRING = "query_string"; @JsonProperty(P_GCUBE_SCOPE) @@ -34,7 +37,11 @@ public class GeoportalRequest { */ @JsonProperty(P_ITEM_ID) private String itemID; + @JsonProperty(P_QUERY_STRING) private String queryString; + + @JsonProperty(P_RESOLVES_AS) + private String res; } diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/FetchPDF.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/FetchPDF.java new file mode 100644 index 0000000..3d08199 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/FetchPDF.java @@ -0,0 +1,66 @@ +package org.gcube.datatransfer.resolver.geoportal.exporter; + +import org.gcube.application.geoportaldatamapper.shared.FileReference; + +public class FetchPDF { + + private final int MAX_RETRY = 60; + private FileReference fileRef; + private String code; + + private int attempt = 0; + + public FetchPDF() { + + } + + public FetchPDF(FileReference fileRef, String code, int attempt) { + super(); + this.fileRef = fileRef; + this.code = code; + this.attempt = attempt; + } + + public int getMAX_RETRY() { + return MAX_RETRY; + } + + public FileReference getFileRef() { + return fileRef; + } + + public String getCode() { + return code; + } + + public int getAttempt() { + return attempt; + } + + public void setFileRef(FileReference fileRef) { + this.fileRef = fileRef; + } + + public synchronized int incrementAttempt() { + attempt++; + return attempt; + } + + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("FetchPDF [MAX_RETRY="); + builder.append(MAX_RETRY); + builder.append(", fileRef="); + builder.append(fileRef); + builder.append(", code="); + builder.append(code); + builder.append(", attempt="); + builder.append(attempt); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/GeoportalJsonResponse.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/GeoportalJsonResponse.java new file mode 100644 index 0000000..ff65c5f --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/GeoportalJsonResponse.java @@ -0,0 +1,12 @@ +package org.gcube.datatransfer.resolver.geoportal.exporter; + +import lombok.Data; + +@Data +public class GeoportalJsonResponse { + + //State can be "OK" or "ERROR" + String state; + String url; + String message; +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/Geoportal_HTML_Page.java b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/Geoportal_HTML_Page.java new file mode 100644 index 0000000..909d38f --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/geoportal/exporter/Geoportal_HTML_Page.java @@ -0,0 +1,171 @@ +package org.gcube.datatransfer.resolver.geoportal.exporter; + +public class Geoportal_HTML_Page { + + /** + * Sets the HTML message. + * + * @param action the action + * @param message the message + * @param waiting the waiting + * @return the string + */ + public static String entityHTMLMessage(String action, String message, boolean waiting, String viewPdfURL) { + + //NB the images are located at https://data.d4science.net/qLix + String newHTML = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " D4Science Geoportal - Action\n" + + " \n" + + "\n" + + " "; + + newHTML += "\"D4Science
"; + + newHTML += "
"; + newHTML += "

Geoportal


"; + newHTML += "
"; + newHTML += "

" + action + "

"; + + if (waiting) { + newHTML += "\"D4Science
"; + } + + newHTML += "

" + message + "

"; + newHTML += "
"; + + return newHTML; + } + + + /** + * Sets the HTML message. + * + * @param action the action + * @param message the message + * @param waiting the waiting + * @return the string + */ + public static String getErrorPage(String action, String message) { + + String newHTML = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + ""; + + newHTML += "\"D4Science
"; + + newHTML += "
"; + newHTML += "

Geoportal Exporter


"; + newHTML += "

" + action + "

"; + newHTML += "

" + message + "

"; + newHTML += "
"; + + return newHTML; + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/requesthandler/RequestHandler.java b/src/main/java/org/gcube/datatransfer/resolver/requesthandler/RequestHandler.java index 98e3935..df8aabf 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/requesthandler/RequestHandler.java +++ b/src/main/java/org/gcube/datatransfer/resolver/requesthandler/RequestHandler.java @@ -19,20 +19,25 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.ext.Provider; +import org.gcube.common.authorization.library.provider.AccessTokenProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.authorization.utils.secret.GCubeSecret; +import org.gcube.common.authorization.utils.secret.JWTSecret; +import org.gcube.common.authorization.utils.secret.Secret; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.ConstantsResolver; import org.gcube.datatransfer.resolver.UriResolverServices; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * The Class RequestHandler. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * - * Mar 15, 2019 + * Mar 15, 2019 */ @Provider @PreMatching @@ -44,7 +49,8 @@ public class RequestHandler implements ContainerRequestFilter, ContainerResponse private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); - @Context ServletContext context; + @Context + ServletContext context; @Context HttpServletRequest webRequest; @@ -55,127 +61,195 @@ public class RequestHandler implements ContainerRequestFilter, ContainerResponse @Context ResourceContext resourceContext; - /* (non-Javadoc) - * @see javax.ws.rs.container.ContainerRequestFilter#filter(javax.ws.rs.container.ContainerRequestContext) - */ - @Override - public void filter(ContainerRequestContext reqContext) throws IOException { - log.info(RequestHandler.class.getSimpleName() +" Request called"); - - if(SecurityTokenProvider.instance.get()==null) - SecurityTokenProvider.instance.set(context.getInitParameter(ROOT_APP_TOKEN)); + /** + * Filter. + * + * @param reqContext the req context + * @throws IOException Signals that an I/O exception has occurred. + */ + /* + * (non-Javadoc) + * + * @see + * javax.ws.rs.container.ContainerRequestFilter#filter(javax.ws.rs.container. + * ContainerRequestContext) + */ + @Override + public void filter(ContainerRequestContext reqContext) throws IOException { + log.debug(RequestHandler.class.getSimpleName() + " Request called"); + setSecretManager(reqContext); - if(ScopeProvider.instance.get()==null) - ScopeProvider.instance.set(context.getInitParameter(ROOT_SCOPE)); - - log.info("Token and Scope Provider set called"); + if (SecurityTokenProvider.instance.get() == null) + SecurityTokenProvider.instance.set(context.getInitParameter(ROOT_APP_TOKEN)); + + if (ScopeProvider.instance.get() == null) + ScopeProvider.instance.set(context.getInitParameter(ROOT_SCOPE)); + + log.debug("Token and Scope Provider set called"); List listOfPath = UriResolverServices.getInstance().getListOfResourcePath(application.getClasses()); - log.debug("The resources are: {}", listOfPath); + log.debug("The resources are: {}", listOfPath); - String path = reqContext.getUriInfo().getPath(); - log.debug("The path is: {}", path); - - //HOW TO READ THE QUERY STRING - /*MultivaluedMap queryParameters = reqContext.getUriInfo().getQueryParameters(); - String queryString = ""; - try { - queryString = Util.toQueryString(queryParameters); - }catch (Exception e) { - //silent - log.warn("Error on reading the query string, trying to continue..."); + String path = reqContext.getUriInfo().getPath(); + log.debug("The path is: {}", path); + + // HOW TO READ THE QUERY STRING + /* + * MultivaluedMap queryParameters = + * reqContext.getUriInfo().getQueryParameters(); String queryString = ""; try { + * queryString = Util.toQueryString(queryParameters); }catch (Exception e) { + * //silent + * log.warn("Error on reading the query string, trying to continue..."); } + * log.debug("The query string is: {}", queryString); + */ + + if (path == null || path.isEmpty()) { + log.debug("The path is null or empty, redirecting to /index"); + URI newRequestURI = reqContext.getUriInfo().getBaseUriBuilder().path("/index").build(); + reqContext.setRequestUri(newRequestURI); + return; } - log.debug("The query string is: {}", queryString); - */ - if(path==null || path.isEmpty()) { - log.debug("The path is null or empty, redirecting to /index"); - URI newRequestURI = reqContext.getUriInfo().getBaseUriBuilder().path("/index").build(); - reqContext.setRequestUri(newRequestURI); - return; - } - - String[] splittePath = null; - boolean resourceToRedirectFound = false; - String candidateResource = ""; - try { - splittePath = path.split("/"); - if(splittePath!=null && splittePath.length>0) { - String requestedResourceName = splittePath[0]; - log.debug("The resource requested is: {}",requestedResourceName); - - if(requestedResourceName!=null && !requestedResourceName.isEmpty()) { - for (String resource : listOfPath) { - log.trace("Is resource '{}' starting with '{}' ?",resource,requestedResourceName); - if(resource.startsWith(requestedResourceName)) { + String[] splittePath = null; + boolean resourceToRedirectFound = false; + String candidateResource = ""; + try { + splittePath = path.split("/"); + if (splittePath != null && splittePath.length > 0) { + String requestedResourceName = splittePath[0]; + log.debug("The resource requested is: {}", requestedResourceName); + + if (requestedResourceName != null && !requestedResourceName.isEmpty()) { + for (String resource : listOfPath) { + log.trace("Is resource '{}' starting with '{}' ?", resource, requestedResourceName); + if (resource.startsWith(requestedResourceName)) { log.trace("Yes it starts!"); candidateResource = requestedResourceName; - log.info("The candidate resource to manage the request is: {}",candidateResource); + log.info("The candidate resource to manage the request is: {}", candidateResource); resourceToRedirectFound = true; break; } } - - //Try to manage as Catalogue Request ctlg, ctlg-p, etc. - if(!resourceToRedirectFound) { - log.info("Trying to manage as hard-coded case among cases: {}", Arrays.asList(ConstantsResolver.resourcesHardCoded).toString()); - String[] hardCode = ConstantsResolver.resourcesHardCoded; - - for (String resource : hardCode) { - log.trace("Is requested resource '{}' starting with hard-coded resource '{}'?",requestedResourceName,resource); - if(requestedResourceName.startsWith(resource)) { + + // Try to manage as Catalogue Request ctlg, ctlg-p, etc. + if (!resourceToRedirectFound) { + log.info("Trying to manage as hard-coded case among cases: {}", + Arrays.asList(ConstantsResolver.resourcesHardCoded).toString()); + String[] hardCode = ConstantsResolver.resourcesHardCoded; + + for (String resource : hardCode) { + log.trace("Is requested resource '{}' starting with hard-coded resource '{}'?", + requestedResourceName, resource); + if (requestedResourceName.startsWith(resource)) { log.trace("Yes it starts!"); candidateResource = resource; - log.info("The candidate resource to manage the request is the hard-coded resource: {}",candidateResource); + log.info("The candidate resource to manage the request is the hard-coded resource: {}", + candidateResource); resourceToRedirectFound = true; break; } } - - } - - }else - log.warn("It was not possible to get the resource name from the splitted path {}. No action performed", path); - }else { - log.warn("It was not possible to split the path {}. No action performed", path); - } - }catch (Exception e) { + + } + + } else + log.warn( + "It was not possible to get the resource name from the splitted path {}. No action performed", + path); + } else { + log.warn("It was not possible to split the path {}. No action performed", path); + } + } catch (Exception e) { log.error("Error trying to retrieve the service able to manage the request. No action performed", e); } - - if(resourceToRedirectFound) { - log.debug("The input request '{}' can be managed by the service '{}'. No redirect performed", path, candidateResource); - }else { - log.info("No resource/service found to manage the input request '{}'", path); - String newPath = String.format("/%s/%s", ConstantsResolver.defaultServiceToRedirect,path); - //log.debug("The path to redirect is '{}'", newPath); - //URI newRequestURI = reqContext.getUriInfo().getBaseUriBuilder().path(newPath).build(); - UriBuilder uriBuilder = reqContext.getUriInfo().getBaseUriBuilder(); - //ADDING THE INPUT QUERY STRING - MultivaluedMap queryParameters = reqContext.getUriInfo().getQueryParameters(); - for (String param : queryParameters.keySet()) { - List values = queryParameters.get(param); - if(values!=null && !values.isEmpty()) - uriBuilder.queryParam(param,values.toArray()); - } - - URI newRequestURI = uriBuilder.path(newPath).build(); - log.info("Redirect to URI path '{}'", newRequestURI.toString()); - reqContext.setRequestUri(newRequestURI); - } - } - /* (non-Javadoc) - * @see javax.ws.rs.container.ContainerResponseFilter#filter(javax.ws.rs.container.ContainerRequestContext, javax.ws.rs.container.ContainerResponseContext) + if (resourceToRedirectFound) { + log.debug("The input request '{}' can be managed by the service '{}'. No redirect performed", path, + candidateResource); + } else { + log.info("No resource/service found to manage the input request '{}'", path); + String newPath = String.format("/%s/%s", ConstantsResolver.defaultServiceToRedirect, path); + // log.debug("The path to redirect is '{}'", newPath); + // URI newRequestURI = + // reqContext.getUriInfo().getBaseUriBuilder().path(newPath).build(); + UriBuilder uriBuilder = reqContext.getUriInfo().getBaseUriBuilder(); + // ADDING THE INPUT QUERY STRING + MultivaluedMap queryParameters = reqContext.getUriInfo().getQueryParameters(); + for (String param : queryParameters.keySet()) { + List values = queryParameters.get(param); + if (values != null && !values.isEmpty()) + uriBuilder.queryParam(param, values.toArray()); + } + + URI newRequestURI = uriBuilder.path(newPath).build(); + log.info("Redirect to URI path '{}'", newRequestURI.toString()); + reqContext.setRequestUri(newRequestURI); + } + } + + /** + * Filter. + * + * @param requestContext the request context + * @param responseContext the response context + * @throws IOException Signals that an I/O exception has occurred. + */ + /* + * (non-Javadoc) + * + * @see + * javax.ws.rs.container.ContainerResponseFilter#filter(javax.ws.rs.container. + * ContainerRequestContext, javax.ws.rs.container.ContainerResponseContext) */ @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { - log.info(RequestHandler.class.getSimpleName() +" Response called"); + log.debug(RequestHandler.class.getSimpleName() + " Response called"); SecurityTokenProvider.instance.reset(); ScopeProvider.instance.reset(); - log.info("Token and Scope Provider reset called"); + log.debug("Token and Scope Provider reset called"); + resetScretManager(requestContext, responseContext); } + /** + * Reset scret manager. + * + * @param requestContext the request context + * @param responseContext the response context + * @throws IOException Signals that an I/O exception has occurred. + */ + private void resetScretManager(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + log.debug("SecreteManager instance remove"); + SecretManagerProvider.instance.remove(); + } + + /** + * Sets the secret manager. + * + * @param requestContext the new secret manager + * @throws IOException Signals that an I/O exception has occurred. + */ + private void setSecretManager(ContainerRequestContext requestContext) throws IOException { + log.debug("setSecretManager called"); + + SecretManagerProvider.instance.remove(); + SecretManager secretManager = new SecretManager(); + + String token = AccessTokenProvider.instance.get(); + if (token != null) { + Secret secret = new JWTSecret(token); + secretManager.addSecret(secret); + } + + token = SecurityTokenProvider.instance.get(); + if (token != null) { + Secret secret = new GCubeSecret(token); + secretManager.addSecret(secret); + } + + SecretManagerProvider.instance.set(secretManager); + } + } \ No newline at end of file diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java index 06baae6..e676900 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java @@ -22,7 +22,8 @@ import org.apache.commons.codec.binary.Base64; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset; import org.gcube.datatransfer.resolver.ConstantsResolver; import org.gcube.datatransfer.resolver.caches.LoadingMapOfDetachedVRE; import org.gcube.datatransfer.resolver.caches.LoadingMapOfScopeCache; @@ -42,8 +43,6 @@ import org.slf4j.LoggerFactory; import com.google.common.cache.CacheLoader.InvalidCacheLoadException; -import eu.trentorise.opendata.jackan.model.CkanDataset; - /** * The CatalogueResolver is able to get/resolve a link to a "Catalogue Entity" * stored in one of the D4Science Catalogue's instances. A Catalogue Entity is @@ -247,7 +246,7 @@ public class CatalogueResolver { scopeBean = LoadingMapOfScopeCache.get(scopeName); } catch (ExecutionException | InvalidCacheLoadException e) { logger.error( - "Error on getting the fullscope from cache for scopeName {}. Tryng to load it from DetachedRE", + "Error on getting the fullscope from cache for scopeName {}. Trying to load it from DetachedRE", scopeName); boolean isScopeDetached = false; diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java index 6b75e52..8de2991 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java @@ -408,7 +408,7 @@ public class GeonetworkResolver { // SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export if (remainPath != null && remainPath.compareTo(SRV_EN_MEF_EXPORT) == 0) { - logger.info("In case of mef.export, perfoming a custom handler"); + logger.info("In case of mef.export, performing a custom handler"); gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT; String[] uuidValues = req.getParameterValues(UUID); if (uuidValues != null) { diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalExporter.java b/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalExporter.java new file mode 100644 index 0000000..f29227c --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalExporter.java @@ -0,0 +1,502 @@ +package org.gcube.datatransfer.resolver.services; + +import java.io.InputStream; +import java.util.LinkedHashMap; + +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +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 javax.ws.rs.core.StreamingOutput; + +import org.gcube.application.geoportalcommon.GeoportalCommon; +import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences; +import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences.SHARE_LINK_TO; +import org.gcube.application.geoportaldatamapper.exporter.Geoportal_PDF_Exporter; +import org.gcube.application.geoportaldatamapper.shared.ExporterProjectSource; +import org.gcube.application.geoportaldatamapper.shared.FileReference; +import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; +import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; +import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.authorization.utils.user.User; +import org.gcube.datatransfer.resolver.ConstantsResolver; +import org.gcube.datatransfer.resolver.geoportal.exporter.FetchPDF; +import org.gcube.datatransfer.resolver.geoportal.exporter.GeoportalJsonResponse; +import org.gcube.datatransfer.resolver.geoportal.exporter.Geoportal_HTML_Page; +import org.gcube.datatransfer.resolver.services.error.ExceptionManager; +import org.gcube.datatransfer.resolver.services.exceptions.BadRequestException; +import org.gcube.datatransfer.resolver.util.SingleFileStreamingOutput; +import org.gcube.datatransfer.resolver.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class GeoportalExporter. + * + * The Geoportal Exporter provides the facilities to export GIS projects stored in + * the Geoportal system provided via D4Science VREs. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Apr 16, 2024 + */ +@Path("geoportal") +public class GeoportalExporter { + + private static final String JOB_CODE = "jobCode"; + + public static final String EXPORT_TYPE = "type"; + + public static final String PATH_PROJECT_ID = GeoportalResolver.PATH_PROJECT_ID; + public static final String PATH_USECASE_ID = GeoportalResolver.PATH_USECASE_ID; + public static final String PATH_VRE_NAME = GeoportalResolver.PATH_VRE_NAME; + + public static final String QUERY_PARAMETER_AS_URL = "as-url"; + + private static final Logger LOG = LoggerFactory.getLogger(GeoportalExporter.class); + private static String helpURI = "https://wiki.gcube-system.org/gcube/URI_Resolver#Geoportal_Resolver"; + + private static LinkedHashMap map = new LinkedHashMap(); + + /** + * The Enum ACCEPTED_EXPORT_TYPE. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Apr 22, 2024 + */ + public enum ACCEPTED_EXPORT_TYPE { + pdf + } + + /** + * Export. + * + * @param req the req + * @param export_type the export type. Must be a value of the enum + * {#ACCEPTED_EXPORT_TYPE} + * @param ucdID the ucd ID + * @param projectID the project ID + * @param asURL the as URL. If true returns the project exported as an URL + * in the response + * @return the response. Can be an URL or a Stream of the project exported. + * @throws WebApplicationException the web application exception + */ + @GET + @Path("/export/{type}/{usecase_id}/{project_id}") + @Produces({ MediaType.TEXT_HTML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_OCTET_STREAM }) + public Response export(@Context HttpServletRequest req, @PathParam(EXPORT_TYPE) String export_type, + @PathParam(PATH_USECASE_ID) String ucdID, @PathParam(PATH_PROJECT_ID) String projectID, + @QueryParam(QUERY_PARAMETER_AS_URL) @Nullable String asURL) throws WebApplicationException { + + String userAgentName = req.getHeader("User-Agent"); + + LOG.info(this.getClass().getSimpleName() + " export - GET starts..."); + LOG.info("Params: [" + EXPORT_TYPE + ": {}, " + PATH_USECASE_ID + ": {}, " + PATH_PROJECT_ID + ": {}, " + + QUERY_PARAMETER_AS_URL + ": {}]", export_type, ucdID, projectID, asURL); + + checkPathParameterNotNull(req, EXPORT_TYPE, export_type); + checkPathParameterNotNull(req, PATH_USECASE_ID, ucdID); + checkPathParameterNotNull(req, PATH_PROJECT_ID, projectID); + + boolean getAsURL = false; + try { + getAsURL = Boolean.parseBoolean(asURL); + } catch (Exception e) { + } + + LOG.info("getAsURL is: {}", getAsURL); + + checkExportType(req, export_type); + + boolean checked = false; + + SecretManager secreteManager = SecretManagerProvider.instance.get(); + final String context = secreteManager.getContext(); + if (context == null) { + throw ExceptionManager.forbiddenException(req, "Cannot determine context (the scope)", this.getClass(), + helpURI); + } + + final org.gcube.common.authorization.utils.user.User user = secreteManager.getUser(); + if (user == null) { + throw ExceptionManager.forbiddenException(req, "Cannot determine user", this.getClass(), helpURI); + } + + LOG.info("Identified caller {} in context {}", user.getUsername(), context); + + try { + Geoportal_PDF_Exporter pdfExporter = new Geoportal_PDF_Exporter(); + checked = pdfExporter.checkConfig(); + } catch (Exception e) { + LOG.error("Error on performing export", e); + throw ExceptionManager + .internalErrorException(req, + "Error the " + Geoportal_PDF_Exporter.class.getSimpleName() + + " seems to be not configured in the context: " + context, + this.getClass(), helpURI); + } + // if the configuration exists in the context + if (checked) { + if (getAsURL) { + try { + LOG.info("Serving request as getAsURL..."); + FileReference pdfRef = exportAsPDF(req, ucdID, projectID, null, context, user); + String theURL = pdfRef.getStorageVolatileURL().toString(); + LOG.info("returning URL {}", theURL); + return Response.ok(theURL).build(); + } catch (Exception e) { + LOG.error("Error on performing export by url", e); + throw ExceptionManager.internalErrorException(req, + "Sorry, error occurred when generating the project URL. Error is: " + e.getMessage(), + this.getClass(), helpURI); + } + } + + try { + if (userAgentName != null) { + LOG.info("Serving request as User-Agent {}", userAgentName); + final String jobCode = ucdID + "_" + projectID + "_" + System.currentTimeMillis(); + final FetchPDF fetchPDF = new FetchPDF(null, jobCode, 0); + map.put(jobCode, fetchPDF); + try { + Thread t = new Thread() { + @Override + public void run() { + LOG.info("exportAsPDF called in thread..."); + FileReference pdfRef = exportAsPDF(req, ucdID, projectID, null, context, user); + LOG.info("exportAsPDF setFileRef in thread for code: " + jobCode); + fetchPDF.setFileRef(pdfRef); + map.put(jobCode, fetchPDF); + } + + }; + t.start(); + } catch (Exception e) { + LOG.error("Error on performing export in thread", e); + throw e; + } + + String serviceViewPDF_URL = String.format("%s/%s/view/%s", Util.getServerURL(req), "geoportal", + jobCode); + + String entity = Geoportal_HTML_Page.entityHTMLMessage("Exporting as PDF...", + "The project with id: " + projectID, true, serviceViewPDF_URL); + + LOG.info("returning waiting HTML page"); + return Response.ok(entity).encoding("UTF-8").header(ConstantsResolver.CONTENT_TYPE, "text/html") + .build(); + } else { + LOG.info("Serving request as client..."); + FileReference pdfRef = exportAsPDF(req, ucdID, projectID, null, context, user); + // returning as stream + InputStream input = pdfRef.getStorageVolatileURL().openStream(); + StreamingOutput so = new SingleFileStreamingOutput(input); + LOG.info("returning project streaming..."); + return Response.ok(so) + .header(ConstantsResolver.CONTENT_DISPOSITION, + "inline; filename=\"" + pdfRef.getFileName() + "\"") + .header("Content-Type", pdfRef.getContentType()).build(); + + } + } catch (Exception e) { + LOG.error("Error on performing export", e); + throw ExceptionManager.internalErrorException(req, "Sorry, error occurred when exporting the project", + this.getClass(), helpURI); + } + } else { + return Response + .status(Status.NOT_FOUND).entity(GeoportalExporter.class.getSimpleName() + + "seems to be not configured in the context: " + context) + .type(MediaType.TEXT_PLAIN).build(); + } + + } + + /** + * Healthcheck. Checks if the export facility is configured in the context (i.e. + * the scope read from input token). + * + * @param req the req + * @param export_type the export type + * @return an object of type {#GeoportalJsonResponse) that contains the response + * @throws WebApplicationException the web application exception + */ + @GET + @Path("/export/{type}/healthcheck") + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML }) + public Response healthcheck(@Context HttpServletRequest req, @PathParam(EXPORT_TYPE) String export_type) + throws WebApplicationException { + + LOG.info(this.getClass().getSimpleName() + " healthcheck - GET starts..."); + LOG.debug("param is: exportType: {}", export_type); + + checkPathParameterNotNull(req, EXPORT_TYPE, export_type); + + checkExportType(req, export_type); + + try { + + SecretManager cm = SecretManagerProvider.instance.get(); + String context = cm.getContext(); + if (context == null) { + throw ExceptionManager.forbiddenException(req, "Cannot determine context (the scope)", this.getClass(), + helpURI); + } + org.gcube.common.authorization.utils.user.User user = cm.getUser(); + LOG.info("Identified caller {} in context {}", user.getUsername(), context); + + Geoportal_PDF_Exporter pdfExporter = new Geoportal_PDF_Exporter(); + boolean checked = pdfExporter.checkConfig(); + GeoportalJsonResponse theJson = new GeoportalJsonResponse(); + if (checked) { + theJson.setState("OK"); + theJson.setMessage(GeoportalExporter.class.getSimpleName() + " Config OK in the context: " + context); + String jsonResponse = responseToString(theJson); + return Response.ok(jsonResponse).build(); + } else { + theJson.setState("KO"); + theJson.setMessage(GeoportalExporter.class.getSimpleName() + " Config " + + Status.NOT_FOUND.getReasonPhrase() + " in the context: " + context); + String jsonResponse = responseToString(theJson); + return Response.status(Status.NOT_FOUND).entity(jsonResponse).build(); + } + + } catch (Exception e) { + LOG.error("Error on performing healthcheck", e); + throw ExceptionManager.internalErrorException(req, + "Error when performing " + GeoportalExporter.class.getSimpleName() + " healthcheck", + this.getClass(), helpURI); + } + } + + /** + * View job. Check the job export status. + * + * @param req the req + * @param jobCode the job code. The job ID assigned by export facility that + * returns a waiting HTML page + * @return the response. It is a {#GeoportalJsonResponse} with the status of the + * job. An export job completed contains the URL of the project + * exported. + * @throws WebApplicationException the web application exception + */ + @GET + @Path("/view/{jobCode}") + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.TEXT_PLAIN }) + public Response viewJob(@Context HttpServletRequest req, @PathParam(JOB_CODE) String jobCode) + throws WebApplicationException { + + LOG.info(this.getClass().getSimpleName() + " viewPDF - GET starts..."); + LOG.info("viewJob param " + JOB_CODE + ": {}", jobCode); + + FetchPDF fetchedPDF = map.get(jobCode); + LOG.info("viewJob FileReference at code {} is {}", jobCode, fetchedPDF); + + String theURL = null; + String messagge = null; + String state = null; + + GeoportalJsonResponse theJson = new GeoportalJsonResponse(); + theJson.setState(state); + theJson.setUrl(theURL); + theJson.setMessage(messagge); + + String jsonReponse = null; + + if (fetchedPDF == null) { + theJson.setState(Status.NOT_FOUND.getReasonPhrase()); + theJson.setMessage("No job found with id: " + jobCode); + try { + jsonReponse = responseToString(theJson); + LOG.info("viewJob returning not found: " + jsonReponse); + return Response.status(Status.NOT_FOUND).entity(jsonReponse).build(); + } catch (JsonProcessingException e) { + throw ExceptionManager.internalErrorException(req, "Error when returning " + + GeoportalExporter.class.getSimpleName() + " not found job for " + jobCode, this.getClass(), + helpURI); + } + + } + + try { + // File PDF is not available + if (fetchedPDF.getFileRef() == null) { + int attempt = fetchedPDF.incrementAttempt(); + if (fetchedPDF.getAttempt() < fetchedPDF.getMAX_RETRY()) { + state = "OK"; + messagge = "Attempt #" + attempt; + } else { + state = "ERROR"; + messagge = "Sorry, an error occurred trying to create the PDF. Max retries reached"; + theJson.setState(state); + } + // updating map status + map.put(jobCode, fetchedPDF); + } else { + // File PDF is available + state = "OK"; + theURL = fetchedPDF.getFileRef().getStorageVolatileURL().toString(); + messagge = "PDF created correclty"; + // removing from map + map.put(jobCode, null); + } + + theJson.setState(state); + theJson.setUrl(theURL); + theJson.setMessage(messagge); + try { + jsonReponse = responseToString(theJson); + LOG.info("viewJob returning OK: " + jsonReponse); + return Response.ok(jsonReponse).build(); + } catch (JsonProcessingException e) { + throw ExceptionManager.internalErrorException(req, + "Error when returning " + GeoportalExporter.class.getSimpleName() + " response for " + jobCode, + this.getClass(), helpURI); + } + + } catch (Exception e) { + LOG.error("Error on checking job", e); + throw ExceptionManager.internalErrorException(req, + "Error when checking " + GeoportalExporter.class.getSimpleName() + " job view for " + jobCode, + this.getClass(), helpURI); + } + + } + + public String responseToString(GeoportalJsonResponse jsonResponse) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(jsonResponse); + } + + /** + * Check path parameter not null. + * + * @param req the req + * @param parameter the parameter + * @param value the value + * @throws BadRequestException the bad request exception + */ + public void checkPathParameterNotNull(HttpServletRequest req, String parameter, String value) + throws BadRequestException { + if (value == null || value.isEmpty()) { + LOG.error("The path parameter {} not found or empty in the path", parameter); + throw ExceptionManager.badRequestException(req, + "Mandatory path parameter " + parameter + " not found or empty", this.getClass(), helpURI); + } + } + + /** + * Check export type. + * + * @param req the req + * @param export_type the export type + * @return the accepted export type + * @throws BadRequestException the bad request exception + */ + public ACCEPTED_EXPORT_TYPE checkExportType(HttpServletRequest req, String export_type) throws BadRequestException { + ACCEPTED_EXPORT_TYPE exportType; + try { + exportType = ACCEPTED_EXPORT_TYPE.valueOf(export_type); + } catch (Exception e) { + throw ExceptionManager + .wrongParameterException(req, + "The path parameter " + EXPORT_TYPE + " has a bad value: " + export_type + + ". It must be value of " + ACCEPTED_EXPORT_TYPE.values(), + this.getClass(), helpURI); + } + + return exportType; + } + + /** + * Export as PDF. + * + * @param req the req + * @param profileID the profile ID + * @param projectID the project ID + * @param profileTitle the profile title + * @param context the context + * @param user the user + * @return the file reference + * @throws WebApplicationException the web application exception + */ + public FileReference exportAsPDF(HttpServletRequest req, String profileID, String projectID, String profileTitle, + String context, User user) throws WebApplicationException { + LOG.info("exportAsPDF for profileID: " + profileID + ", projectID: " + projectID + "called"); + LOG.info("exportAsPDF context is {}, user is {}", context, user); + + FileReference pdfRef = null; + try { + + Geoportal_PDF_Exporter gpdfe = new Geoportal_PDF_Exporter(); + ExporterProjectSource exportSource = new ExporterProjectSource(); + exportSource.setProfileID(profileID); + exportSource.setProfileTitle(profileTitle); + exportSource.setProjectID(projectID); + exportSource.setScope(context); + + GeoportalItemReferences geoportalItemReferences = new GeoportalItemReferences(projectID, profileID, + SHARE_LINK_TO.DATA_VIEWER); + GeoportalItemReferences gir = getPublicLinksFor(geoportalItemReferences, context); + + if (user.isApplication()) { + exportSource.setGisLink(gir.getOpenLink().getShortURL()); + exportSource.setAccountname(null); + } else { + exportSource.setGisLink(gir.getRestrictedLink().getShortURL()); + exportSource.setAccountname(user.getUsername()); + } + + pdfRef = gpdfe.createPDFFile(exportSource); + + } catch (Exception e1) { + LOG.error("Error occurred when exporting the project", e1); + throw ExceptionManager.internalErrorException(req, "Sorry, an error occurred when exporting the project", + this.getClass(), helpURI); + } + return pdfRef; + } + + /** + * Gets the public links for. + * + * @param item the item + * @param context the context + * @return the public links for + * @throws Exception the exception + */ + public GeoportalItemReferences getPublicLinksFor(GeoportalItemReferences item, String context) throws Exception { + LOG.info("getPublicLinksFor called for: " + item); + + try { + + if (item == null) + throw new Exception("Bad request, the item is null"); + + if (item.getProjectID() == null) + throw new Exception("Bad request, the projectID is null"); + + if (item.getProfileID() == null) + throw new Exception("Bad request, the profileID is null"); + + GeoportalCommon gc = new GeoportalCommon(); + return gc.getPublicLinksFor(context, item, true); + + } catch (Exception e) { + LOG.error("Error on getPublicLinksFor for: " + item, e); + throw new Exception("Share link not available for this item. Try later or contact the support. Error: " + + e.getMessage()); + } + } + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalResolver.java index eab1704..33d9dd0 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/GeoportalResolver.java @@ -24,8 +24,8 @@ import org.gcube.common.scope.impl.ScopeBean; import org.gcube.datatransfer.resolver.ConstantsResolver; import org.gcube.datatransfer.resolver.caches.LoadingMapOfScopeCache; import org.gcube.datatransfer.resolver.geoportal.GeoportalCommonConstants; -import org.gcube.datatransfer.resolver.geoportal.GeoportalDataViewerConfigProfile; -import org.gcube.datatransfer.resolver.geoportal.GeoportalDataViewerConfigProfileReader; +import org.gcube.datatransfer.resolver.geoportal.GeoportalConfigApplicationProfile; +import org.gcube.datatransfer.resolver.geoportal.GeoportalConfigApplicationProfileReader; import org.gcube.datatransfer.resolver.geoportal.GeoportalRequest; import org.gcube.datatransfer.resolver.geoportal.TargetAppGeoportalCodes; import org.gcube.datatransfer.resolver.services.error.ExceptionManager; @@ -45,20 +45,20 @@ import com.google.common.cache.CacheLoader.InvalidCacheLoadException; * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * - * Mar 23, 2023 + * Apr 03, 2024 */ -@Path("/geo") +@Path("geo") public class GeoportalResolver { public static final String GEO_DE = "de"; // data-entry public static final String GEO = "geo"; // geoportal public static final String GEO_DV = "dv"; // data-viewer - private static final String QP_RESOLVE_AS = "res"; - private static final String PATH_PROJECT_ID = "project_id"; - private static final String PATH_USECASE_ID = "usecase_id"; - private static final String PATH_VRE_NAME = "vre_name"; - private static final String PATH_TARGET_APP = "targetAppId"; + public static final String QP_RESOLVE_AS = "res"; + public static final String PATH_PROJECT_ID = "project_id"; + public static final String PATH_USECASE_ID = "usecase_id"; + public static final String PATH_VRE_NAME = "vre_name"; + public static final String PATH_TARGET_APP = "targetAppId"; private static final Logger LOG = LoggerFactory.getLogger(GeoportalResolver.class); private static String helpURI = "https://wiki.gcube-system.org/gcube/URI_Resolver#Geoportal_Resolver"; @@ -70,7 +70,7 @@ public class GeoportalResolver { * * Mar 24, 2023 */ - private static enum RESOLVE_AS { + public static enum RESOLVE_AS { PUBLIC, PRIVATE } @@ -141,8 +141,7 @@ public class GeoportalResolver { public Response resolveDataViewerLink(@Context HttpServletRequest req, @QueryParam(GeoportalRequest.P_GCUBE_SCOPE) String gcubeScope, @QueryParam(GeoportalRequest.P_ITEM_ID) String itemId, - @QueryParam(GeoportalRequest.P_ITEM_TYPE) String itemType, - @QueryParam(QP_RESOLVE_AS) String resolveAs) + @QueryParam(GeoportalRequest.P_ITEM_TYPE) String itemType, @QueryParam(QP_RESOLVE_AS) String resolveAs) throws WebApplicationException { LOG.info(this.getClass().getSimpleName() + " resolveDataViewerLink - GET starts..."); @@ -231,8 +230,10 @@ public class GeoportalResolver { LOG.error("Target application parameter is malformed"); List targetApps = Arrays.asList(TargetAppGeoportalCodes.values()).stream() .map(TargetAppGeoportalCodes::getTarget_app).collect(Collectors.toList()); + List targetPaths = Arrays.asList(TargetAppGeoportalCodes.values()).stream() + .map(TargetAppGeoportalCodes::getId).collect(Collectors.toList()); throw ExceptionManager.badRequestException(req, - "Target application is wrong. It must be one value of: " + targetApps, this.getClass(), + "Target application is wrong. Add a target path as /"+targetPaths+" to resolve towards the applications: " + targetApps, this.getClass(), helpURI); } } @@ -321,21 +322,35 @@ public class GeoportalResolver { LOG.info("Found RESOLVE_AS_PARAMETER: " + resolveAs); String originalScope = ScopeProvider.instance.get(); - GeoportalDataViewerConfigProfileReader reader; + GeoportalConfigApplicationProfileReader reader; + String itemLink = null; + String appID = null; + + // Resolving towards Data-Viewer or Data-Entry Application + switch (resoruceGeoportalCodes) { + case GEO_DE: { + appID = org.gcube.datatransfer.resolver.geoportal.GeoportalCommonConstants.GEOPORTAL_DATA_ENTRY_APP_ID; + break; + } + case GEO_DV: + default: { + appID = org.gcube.datatransfer.resolver.geoportal.GeoportalCommonConstants.GEOPORTAL_DATA_VIEWER_APP_ID; + break; + } + } + try { String theScope = fullScopeBean.toString(); LOG.info("Full scope is: " + theScope); ScopeProvider.instance.set(theScope); - reader = new GeoportalDataViewerConfigProfileReader( - org.gcube.datatransfer.resolver.geoportal.GeoportalCommonConstants.GEOPORTAL_DATA_VIEWER_APP); + reader = new GeoportalConfigApplicationProfileReader(appID); } catch (Exception e) { - LOG.error("Error on reading the " + GeoportalDataViewerConfigProfileReader.SECONDARY_TYPE - + " with generic resource name: " - + GeoportalDataViewerConfigProfileReader.GENERIC_RESOURCE_NAME, e); - throw ExceptionManager.internalErrorException(req, - "Error on reading the " + GeoportalDataViewerConfigProfileReader.SECONDARY_TYPE + " for name " - + GeoportalDataViewerConfigProfileReader.GENERIC_RESOURCE_NAME - + ". Please contact the support", + String error = "Error on reading the generic resource with SecondaryType: " + + GeoportalConfigApplicationProfileReader.SECONDARY_TYPE + " and APP ID: " + appID + + " in the scope: " + appID; + LOG.error(error, e); + + throw ExceptionManager.internalErrorException(req, error + ". Please contact the support", this.getClass(), helpURI); } finally { if (originalScope != null && !originalScope.isEmpty()) { @@ -347,51 +362,33 @@ public class GeoportalResolver { } } - // Resolving towards Data-Viewer or Data-Entry Application - String itemLink = null; + GeoportalConfigApplicationProfile geonaDataProfile = reader.getGeoportalConfigAppProfile(); - switch (resoruceGeoportalCodes) { - case GEO_DV: { + switch (resolveTO) { + case PUBLIC: { + // Open Link + itemLink = String.format("%s?%s=%s&%s=%s", geonaDataProfile.getOpenPortletURL(), + GeoportalCommonConstants.GET_GEONA_ITEM_ID, projectID, + GeoportalCommonConstants.GET_GEONA_ITEM_TYPE, ucdID); + break; + } + case PRIVATE: { - GeoportalDataViewerConfigProfile geonaDataProfile = reader.getGeoportalDataViewerConfigProfile(); - - switch (resolveTO) { - case PUBLIC: - // Open Link - itemLink = String.format("%s?%s=%s&%s=%s", geonaDataProfile.getOpenPortletURL(), - GeoportalCommonConstants.GET_GEONA_ITEM_ID, projectID, - GeoportalCommonConstants.GET_GEONA_ITEM_TYPE, ucdID); - break; - case PRIVATE: - - // Restricted Link - itemLink = String.format("%s?%s=%s&%s=%s", geonaDataProfile.getRestrictedPortletURL(), - GeoportalCommonConstants.GET_GEONA_ITEM_ID, projectID, - GeoportalCommonConstants.GET_GEONA_ITEM_TYPE, ucdID); - - break; - - default: - break; - } + // Restricted Link + itemLink = String.format("%s?%s=%s&%s=%s", geonaDataProfile.getRestrictedPortletURL(), + GeoportalCommonConstants.GET_GEONA_ITEM_ID, projectID, + GeoportalCommonConstants.GET_GEONA_ITEM_TYPE, ucdID); break; } - case GEO_DE: { - - LOG.error("The Resolver towards '" + resoruceGeoportalCodes + "' not implemented yet"); - throw ExceptionManager.internalErrorException(req, - "The Resolver towards '" + resoruceGeoportalCodes + "' not implemented yet", this.getClass(), - helpURI); - - } default: break; } LOG.info("Returning link: " + itemLink); return Response.seeOther(new URL(itemLink).toURI()).build(); + } catch (Exception e) { if (!(e instanceof WebApplicationException)) { diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/StaticImageController.java b/src/main/java/org/gcube/datatransfer/resolver/services/StaticImageController.java new file mode 100644 index 0000000..9418993 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/StaticImageController.java @@ -0,0 +1,119 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.services; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.commons.io.IOUtils; +import org.gcube.datatransfer.resolver.services.error.ExceptionManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class StaticImageController. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * May 2, 2024 + */ +@Path("img") +public class StaticImageController { + + private static Logger logger = LoggerFactory.getLogger(StaticImageController.class); + +// /** +// * To doc. +// * +// * @param req the req +// * @return the input stream +// * @throws WebApplicationException the web application exception +// */ +// @GET +// @Path("/{any: .*}") +// @Produces({ "image/png", "image/jpg", "image/gif" }) +// public InputStream toFile(@Context HttpServletRequest req) throws WebApplicationException { +// logger.info(StaticImageController.class.getSimpleName() + " toFile called"); +// +// String pathInfo = req.getPathInfo(); +// logger.debug("pathInfo {}", pathInfo); +// try { +// +// logger.info("going to {}", pathInfo); +// +// String realPath = req.getServletContext().getRealPath(pathInfo); +// return new FileInputStream(new File(realPath)); +// +// } catch (Exception e) { +// +// if (!(e instanceof WebApplicationException)) { +// // UNEXPECTED EXCEPTION managing it as WebApplicationException +// String error = pathInfo + " not found. Please, contact the support!"; +// throw ExceptionManager.internalErrorException(req, error, this.getClass(), null); +// } +// // ALREADY MANAGED AS WebApplicationException +// logger.error("Exception:", e); +// throw (WebApplicationException) e; +// } +// } +// + + /** + * To file out. + * + * @param req the req + * @return the streaming output + * @throws WebApplicationException the web application exception + */ + @GET + @Path("/{any: .*}") + @Produces({ "image/png", "image/jpg", "image/gif" }) + public StreamingOutput toFileOut(@Context HttpServletRequest req) throws WebApplicationException { + logger.info(StaticImageController.class.getSimpleName() + " toFileOut called"); + String pathInfo = req.getPathInfo(); + logger.debug("pathInfo {}", pathInfo); + try { + final String realPath = req.getServletContext().getRealPath(pathInfo); + logger.info("going to {}", pathInfo); + return new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + FileInputStream fileIS = null; + try { + fileIS = new FileInputStream(new File(realPath)); + IOUtils.copy(fileIS, os); + } catch (Exception e) { + try { + if(fileIS!=null) + fileIS.close(); + } catch (Exception e2) { + + } + } + } + }; + + } catch (Exception e) { + + if (!(e instanceof WebApplicationException)) { + // UNEXPECTED EXCEPTION managing it as WebApplicationException + String error = pathInfo + " not found. Please, contact the support!"; + throw ExceptionManager.internalErrorException(req, error, this.getClass(), null); + } + // ALREADY MANAGED AS WebApplicationException + logger.error("Exception:", e); + throw (WebApplicationException) e; + } + } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/StorageIDResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/StorageIDResolver.java index edc1fae..2b57600 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/StorageIDResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/StorageIDResolver.java @@ -14,10 +14,10 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.StreamingOutput; import org.apache.commons.io.IOUtils; -import org.apache.http.HttpStatus; import org.gcube.contentmanagement.blobstorage.resource.MyFile; import org.gcube.contentmanagement.blobstorage.service.IClient; import org.gcube.contentmanager.storageclient.wrapper.AccessType; @@ -222,7 +222,7 @@ public class StorageIDResolver { //THIS IS FOR HPROXY CHECK if(hproxycheck){ LOG.trace("returning status 200 for Hproxy check"); - ResponseBuilder response = Response.status(HttpStatus.SC_OK); + ResponseBuilder response = Response.status(Status.OK); return response.build(); } @@ -313,7 +313,7 @@ public class StorageIDResolver { if(c>0){ LOG.info("at least 1 byte read, returning status 200"); IOUtils.closeQuietly(streamToWrite); - response = Response.status(HttpStatus.SC_OK); + response = Response.status(Status.OK); }else throw ExceptionManager.notFoundException(httpRequest, "The file with id: "+storageId+" is missing in the storage", StorageIDResolver.class, help); } diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverIndex.java b/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverIndex.java index 286bf1a..1d91b9b 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverIndex.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverIndex.java @@ -46,7 +46,7 @@ public class UriResolverIndex { String indexFile = "/WEB-INF/jsp/index.jsp"; try { - logger.info(UriResolverIndex.class.getSimpleName() + " called"); + logger.debug(UriResolverIndex.class.getSimpleName() + " called"); String realPath = req.getServletContext().getRealPath(indexFile); return new FileInputStream(new File(realPath)); } catch (Exception e) { diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverResources.java b/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverResources.java index 8513ae2..c7749ea 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverResources.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/UriResolverResources.java @@ -14,11 +14,12 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.datatransfer.resolver.UriResolverServices; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; + /** * The UriResolverResources. Show the resources as a JSON diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml index fe2bdfd..a8d3fb2 100644 --- a/src/main/webapp/WEB-INF/gcube-app.xml +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -7,4 +7,5 @@ /knime/create/* /wekeo/gettoken/* /oat/get/* + /geoportal/export/* \ No newline at end of file diff --git a/src/main/webapp/img/icon-globe.gif b/src/main/webapp/img/icon-globe.gif new file mode 100644 index 0000000..db68dbf Binary files /dev/null and b/src/main/webapp/img/icon-globe.gif differ diff --git a/src/main/webapp/img/loading-gears.gif b/src/main/webapp/img/loading-gears.gif new file mode 100644 index 0000000..682a20d Binary files /dev/null and b/src/main/webapp/img/loading-gears.gif differ diff --git a/src/test/java/gis/GeonetworkQueryTest.java b/src/test/java/gis/GeonetworkQueryTest.java index 08d3dda..6ed577f 100644 --- a/src/test/java/gis/GeonetworkQueryTest.java +++ b/src/test/java/gis/GeonetworkQueryTest.java @@ -12,7 +12,6 @@ import org.gcube.spatial.data.geonetwork.LoginLevel; import org.gcube.spatial.data.geonetwork.configuration.Configuration; import org.gcube.spatial.data.geonetwork.model.Account; import org.gcube.spatial.data.geonetwork.model.Account.Type; -import org.junit.Test; import it.geosolutions.geonetwork.util.GNSearchRequest; import it.geosolutions.geonetwork.util.GNSearchResponse; diff --git a/src/test/java/gis/LayersMatchingGN_CKAN.java b/src/test/java/gis/LayersMatchingGN_CKAN.java index 29b57c3..d97b17b 100644 --- a/src/test/java/gis/LayersMatchingGN_CKAN.java +++ b/src/test/java/gis/LayersMatchingGN_CKAN.java @@ -3,10 +3,6 @@ */ package gis; -import it.geosolutions.geonetwork.util.GNSearchRequest; -import it.geosolutions.geonetwork.util.GNSearchResponse; -import resources.GetAllInfrastructureScopes; - import java.io.BufferedWriter; import java.io.FileWriter; import java.io.PrintWriter; @@ -18,7 +14,10 @@ import org.gcube.common.scope.api.ScopeProvider; import org.gcube.spatial.data.geonetwork.GeoNetwork; import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; import org.gcube.spatial.data.geonetwork.LoginLevel; -import org.junit.Test; + +import it.geosolutions.geonetwork.util.GNSearchRequest; +import it.geosolutions.geonetwork.util.GNSearchResponse; +import resources.GetAllInfrastructureScopes; /** diff --git a/src/test/java/gis/RuntimeResourceReader.java b/src/test/java/gis/RuntimeResourceReader.java index 7896431..acdc935 100644 --- a/src/test/java/gis/RuntimeResourceReader.java +++ b/src/test/java/gis/RuntimeResourceReader.java @@ -7,9 +7,9 @@ import java.util.ArrayList; import java.util.List; import org.gcube.common.encryption.StringEncrypter; -import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.scope.api.ScopeProvider; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.slf4j.Logger; @@ -95,8 +95,6 @@ public class RuntimeResourceReader { System.err.println("Error on reading Access point not found"); } - System.out.println("sono qui"); - seb.setListAP(listAp); listSE.add(seb); } @@ -127,13 +125,32 @@ public class RuntimeResourceReader { */ public static void main(String[] args) { +// String scope = "/pred4s/preprod/preVRE"; +// String scope = "/d4science.research-infrastructures.eu/D4OS/GNA"; String scope = "/gcube/devsec/devVRE"; - //String platformName = "GeoServer"; - - String platformName = "postgis"; - String category = "Database"; + //String scope = "/d4science.research-infrastructures.eu/gCubeApps/Esquiline"; +// String scope = "/d4science.research-infrastructures.eu/D4OS/ARIADNEplus_Project"; - //scope = "/pred4s/preprod/preVRE"; +// String platformName = "geonetwork"; +// String category = "Gis"; + +// String platformName = "GeoServer"; +// String category = "Gis"; + +// String platformName = "postgis"; +// String category = "Database"; + + String platformName = "postgres"; + String category = "Database"; + +// String platformName = "mongodb"; +// String category = "Database"; + + // scope = "/pred4s/preprod/preVRE"; + +// scope = "/d4science.research-infrastructures.eu/D4OS/Blue-Cloud2026Project"; +// platformName = "Zenodo"; +// category = "Repository"; RuntimeResourceReader reader; try { @@ -148,14 +165,13 @@ public class RuntimeResourceReader { for (AccessPoint ap : listAp) { System.out.println("username: " + ap.username()); System.out.println("password: " + ap.password()); - try{ + try { String decryptedPassword = StringEncrypter.getEncrypter().decrypt(ap.password()); - System.out.println("Decrypted Password: "+decryptedPassword); - }catch(Exception e){ + System.out.println("Decrypted Password: " + decryptedPassword); + } catch (Exception e) { System.out.println("ignoring exception during pwd decrypting"); } - } } diff --git a/src/test/java/gis/SE_Harvester_from_IS.java b/src/test/java/gis/SE_Harvester_from_IS.java index b6eec61..99d5476 100644 --- a/src/test/java/gis/SE_Harvester_from_IS.java +++ b/src/test/java/gis/SE_Harvester_from_IS.java @@ -3,10 +3,6 @@ */ package gis; -import it.geosolutions.geonetwork.util.GNSearchRequest; -import it.geosolutions.geonetwork.util.GNSearchResponse; -import resources.GetAllInfrastructureScopes; - import java.io.BufferedWriter; import java.io.FileWriter; import java.io.PrintWriter; @@ -16,13 +12,9 @@ import java.util.List; import java.util.Map; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.spatial.data.geonetwork.GeoNetwork; -import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; import org.gcube.spatial.data.geonetwork.LoginLevel; -import org.junit.Test; -import com.itextpdf.text.log.SysoCounter; +import resources.GetAllInfrastructureScopes; /** * diff --git a/src/test/java/rest/TestResolvers.java b/src/test/java/rest/TestResolvers.java index f5a4ac5..77387f9 100644 --- a/src/test/java/rest/TestResolvers.java +++ b/src/test/java/rest/TestResolvers.java @@ -15,11 +15,13 @@ import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Map; +import javax.ws.rs.core.Response.Status; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; -import org.apache.http.HttpStatus; import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileReader; import org.gcube.datatransfer.resolver.util.HTTPCallsUtils; +import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +61,7 @@ public class TestResolvers { System.out.println("header fields: "+con.getHeaderFields()); String fileName = getFilename(con.getHeaderFields()); System.out.println("Response status is: "+status); - if(status==HttpStatus.SC_OK){ + if(status==Status.OK.getStatusCode()){ Path target = Files.createTempFile(FilenameUtils.getBaseName(fileName), "."+FilenameUtils.getExtension(fileName)); try (InputStream in = con.getInputStream()) { Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); @@ -103,7 +105,7 @@ public class TestResolvers { //printHeaders(con.getHeaderFields()); String fileName = getFilename(con.getHeaderFields()); System.out.println("Response status is: "+status); - if(status==HttpStatus.SC_OK){ + if(status==Status.OK.getStatusCode()){ Path target = Files.createTempFile(FilenameUtils.getBaseName(fileName), "."+FilenameUtils.getExtension(fileName)); try (InputStream in = con.getInputStream()) { Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); @@ -146,7 +148,7 @@ public class TestResolvers { status = con.getResponseCode(); //printHeaders(con.getHeaderFields()); System.out.println("Response status is: "+status); - if(status==HttpStatus.SC_OK){ + if(status==Status.OK.getStatusCode()){ System.out.println("\nFile to URL: "+url +" is reachable via doHEAD"); System.out.println(IOUtils.toString(con.getInputStream())); }else{ @@ -187,7 +189,7 @@ public class TestResolvers { con.connect(); status = con.getResponseCode(); System.out.println("Response status is: "+status); - if(status==HttpStatus.SC_OK){ + if(status==Status.OK.getStatusCode()){ System.out.println("Response: \n"+getContentReponse(con.getInputStream())); }else{ System.out.println("\nError on resolving the Catalogue URL: "+toURL); @@ -323,7 +325,7 @@ public class TestResolvers { status = con.getResponseCode(); //printHeaders(con.getHeaderFields()); System.out.println("Response status is: "+status); - if(status==HttpStatus.SC_SEE_OTHER){ + if(status==Status.SEE_OTHER.getStatusCode()){ System.out.println("\nResponse to URL: "+url); System.out.println(IOUtils.toString(con.getInputStream())); }else{