From aa401e40cd3da6c061dbfdd041ae978b8c462669 Mon Sep 17 00:00:00 2001 From: Fabio Sinibaldi Date: Fri, 18 May 2018 15:50:51 +0000 Subject: [PATCH] git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/spatial-data/sdi-service@167625 82a268e6-3cf1-43bd-a215-b396298e98cf --- distro/changelog.xml | 7 + pom.xml | 49 ++- .../spatial/data/sdi/LocalConfiguration.java | 66 +++- .../org/gcube/spatial/data/sdi/NetUtils.java | 94 ++++++ .../gcube/spatial/data/sdi/SDIService.java | 5 +- .../gcube/spatial/data/sdi/ScopeUtils.java | 70 ++++ .../spatial/data/sdi/engine/GISManager.java | 14 +- .../data/sdi/engine/GeoNetworkManager.java | 14 +- .../data/sdi/engine/GeoNetworkProvider.java | 10 - .../data/sdi/engine/GeoServiceManager.java | 19 ++ .../spatial/data/sdi/engine/RoleManager.java | 14 + .../spatial/data/sdi/engine/SDIManager.java | 6 + ...plateManager.java => TemplateManager.java} | 10 +- .../data/sdi/engine/ThreddsManager.java | 17 +- .../data/sdi/engine/impl/AbstractManager.java | 51 +++ .../data/sdi/engine/impl/GISManagerImpl.java | 45 +-- .../engine/impl/GeoNetworkManagerImpl.java | 66 ++-- .../engine/impl/GeoNetworkProviderImpl.java | 26 -- .../data/sdi/engine/impl/NetUtils.java | 36 -- .../data/sdi/engine/impl/RoleManagerImpl.java | 56 ++++ .../data/sdi/engine/impl/SDIManagerImpl.java | 44 ++- .../engine/impl/TemporaryPersistenceImpl.java | 2 +- .../sdi/engine/impl/ThreddsManagerImpl.java | 80 +++-- .../engine/impl/cache/AbstractISModule.java | 156 --------- .../data/sdi/engine/impl/cache/Cache.java | 53 --- .../impl/cache/GeoServerClusterRetriever.java | 186 ----------- .../data/sdi/engine/impl/cache/ISUtils.java | 90 ----- .../engine/impl/cluster/AbstractCluster.java | 100 ++++++ .../impl/cluster/GeoNetworkCluster.java | 51 +++ .../impl/cluster/GeoNetworkController.java | 285 ++++++++++++++++ .../engine/impl/cluster/GeoServerCluster.java | 55 ++++ .../impl/cluster/GeoServerController.java | 244 ++++++++++++++ .../impl/cluster/GeoServiceController.java | 99 ++++++ .../engine/impl/cluster/ThreddsCluster.java | 28 ++ .../impl/cluster/ThreddsController.java | 136 ++++++++ .../InvalidServiceEndpointException.java | 38 +++ .../OutdatedServiceEndpointException.java | 38 +++ .../faults/ServiceInteractionException.java | 35 ++ .../impl/faults/ThreddsOperationFault.java | 35 ++ .../impl/faults/gn/MetadataException.java | 37 +++ .../faults/gn/MetadataNotFoundException.java | 38 +++ .../impl/gn/extension/GN26Extension.java | 16 + .../impl/gn/extension/GN3Extension.java | 17 + .../impl/gn/extension/GNClientExtension.java | 177 ++++++++++ .../extension/GNMetadataAdminExtension.java | 309 ++++++++++++++++++ .../impl/gn/extension/GeoNetworkClient.java | 179 ++++++++++ .../impl/gn/extension/GeoNetworkUtils.java | 87 +++++ .../gn/extension/HttpUtilsExtensions.java | 281 ++++++++++++++++ .../impl/gn/extension/ServerAccess.java | 34 ++ .../sdi/engine/impl/is/AbstractISModule.java | 259 +++++++++++++++ .../impl/{cache => is}/CachedObject.java | 2 +- .../{cache => is}/GeoNetworkRetriever.java | 106 +++--- .../impl/is/GeoServerClusterRetriever.java | 125 +++++++ .../engine/impl/{cache => is}/ISModule.java | 10 +- .../data/sdi/engine/impl/is/ISUtils.java | 213 ++++++++++++ .../impl/{cache => is}/ThreddsRetriever.java | 135 ++++---- .../impl/metadata/GenericTemplates.java | 15 + .../engine/impl/metadata/MetadataHandler.java | 2 +- .../metadata/MetadataTemplateManagerImpl.java | 86 ++--- ...ate.java => AbstractMetadataTemplate.java} | 20 +- .../templates/ThreddsOnlineTemplate.java | 13 +- ...figuration.java => CatalogDescriptor.java} | 13 +- .../data/sdi/model/ScopeConfiguration.java | 14 +- .../sdi/model/credentials/AccessType.java | 6 +- ...uration.java => GeoNetworkDescriptor.java} | 25 +- ...guration.java => GeoServerDescriptor.java} | 7 +- ...Service.java => GeoServiceDescriptor.java} | 7 +- ...figuration.java => ThreddsDescriptor.java} | 4 +- .../spatial/data/sdi/rest/GeoNetwork.java | 173 +++++----- .../spatial/data/sdi/rest/GeoServer.java | 58 ++-- .../gcube/spatial/data/sdi/rest/Metadata.java | 45 ++- .../org/gcube/spatial/data/sdi/rest/SDI.java | 2 + .../gcube/spatial/data/sdi/rest/Thredds.java | 78 +++++ src/main/webapp/WEB-INF/config.properties | 53 ++- .../ThreddsOnlineResources.ftlx | 14 +- .../WEB-INF/xmlTemplates/thredds_catalog.ftlx | 63 ++++ .../data/sdi/test/ConfigurationTest.java | 3 +- .../gcube/spatial/data/sdi/test/MainTest.java | 26 +- .../sdi/test/MetadataApplicationTest.java | 6 +- .../gcube/spatial/data/sdi/test/NetTests.java | 14 + .../data/sdi/test/RoleManagerTests.java | 33 ++ .../gcube/spatial/data/sdi/test/TestIS.java | 26 ++ .../sdi/test/factories/GISManagerFactory.java | 18 +- .../factories/GeoNetworkManagerFactory.java | 18 +- .../factories/GeoNetworkProviderFactory.java | 38 --- .../MetadataTemplateManagerFactory.java | 10 +- .../test/factories/RoleManagerFactory.java | 19 ++ .../test/factories/ThreddsManagerFactory.java | 16 +- 88 files changed, 4284 insertions(+), 1096 deletions(-) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/NetUtils.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/ScopeUtils.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkProvider.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/GeoServiceManager.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/RoleManager.java rename src/main/java/org/gcube/spatial/data/sdi/engine/{MetadataTemplateManager.java => TemplateManager.java} (51%) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/AbstractManager.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkProviderImpl.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/NetUtils.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/RoleManagerImpl.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/AbstractISModule.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/Cache.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoServerClusterRetriever.java delete mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISUtils.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/AbstractCluster.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkCluster.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkController.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerCluster.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerController.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServiceController.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsCluster.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsController.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/InvalidServiceEndpointException.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/OutdatedServiceEndpointException.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ServiceInteractionException.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ThreddsOperationFault.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataException.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataNotFoundException.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN26Extension.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN3Extension.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNClientExtension.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNMetadataAdminExtension.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkClient.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkUtils.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/HttpUtilsExtensions.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/ServerAccess.java create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/AbstractISModule.java rename src/main/java/org/gcube/spatial/data/sdi/engine/impl/{cache => is}/CachedObject.java (88%) rename src/main/java/org/gcube/spatial/data/sdi/engine/impl/{cache => is}/GeoNetworkRetriever.java (64%) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/GeoServerClusterRetriever.java rename src/main/java/org/gcube/spatial/data/sdi/engine/impl/{cache => is}/ISModule.java (56%) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISUtils.java rename src/main/java/org/gcube/spatial/data/sdi/engine/impl/{cache => is}/ThreddsRetriever.java (59%) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/GenericTemplates.java rename src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/{AbstractTemplate.java => AbstractMetadataTemplate.java} (58%) rename src/main/java/org/gcube/spatial/data/sdi/model/{service/GeoServerClusterConfiguration.java => CatalogDescriptor.java} (66%) rename src/main/java/org/gcube/spatial/data/sdi/model/service/{GeoNetworkConfiguration.java => GeoNetworkDescriptor.java} (52%) rename src/main/java/org/gcube/spatial/data/sdi/model/service/{GeoServerConfiguration.java => GeoServerDescriptor.java} (83%) rename src/main/java/org/gcube/spatial/data/sdi/model/service/{GeoService.java => GeoServiceDescriptor.java} (74%) rename src/main/java/org/gcube/spatial/data/sdi/model/service/{ThreddsConfiguration.java => ThreddsDescriptor.java} (78%) create mode 100644 src/main/java/org/gcube/spatial/data/sdi/rest/Thredds.java rename src/main/webapp/WEB-INF/{metadataTemplates => xmlTemplates}/ThreddsOnlineResources.ftlx (89%) create mode 100644 src/main/webapp/WEB-INF/xmlTemplates/thredds_catalog.ftlx create mode 100644 src/test/java/org/gcube/spatial/data/sdi/test/NetTests.java create mode 100644 src/test/java/org/gcube/spatial/data/sdi/test/RoleManagerTests.java create mode 100644 src/test/java/org/gcube/spatial/data/sdi/test/TestIS.java delete mode 100644 src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkProviderFactory.java create mode 100644 src/test/java/org/gcube/spatial/data/sdi/test/factories/RoleManagerFactory.java diff --git a/distro/changelog.xml b/distro/changelog.xml index 14e216e..6a80387 100644 --- a/distro/changelog.xml +++ b/distro/changelog.xml @@ -6,4 +6,11 @@ Added GeoServer interface Added Metadata interface + + Added Health interface + Added GeoNetwork interface + + + Added Thredds interface + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 16b27fb..6b1e5ae 100644 --- a/pom.xml +++ b/pom.xml @@ -8,14 +8,14 @@ org.gcube.spatial.data sdi-service - 1.1.0-SNAPSHOT + 1.3.0-SNAPSHOT SDI Service REST Interface towards SDI facilities war ${project.basedir}/src/main/webapp/WEB-INF ${project.basedir}/distro - 2.22 + 2.14 2.14 2.2.4.Final @@ -59,12 +59,23 @@ data-transfer-library [1.2.0-SNAPSHOT,2.0.0-SNAPSHOT) + + + + + + + org.gcube.resources - registry-publisher + registry-publisher - + + org.gcube.resourcemanagement + resourcemanager-client + [1.0.0-SNAPSHOT,2.0.0-SNAPSHOT) + org.gcube.core @@ -98,6 +109,7 @@ ${jersey-cdi-version} + javax.transaction javax.transaction-api @@ -168,11 +180,11 @@ - - org.glassfish.jersey.media - jersey-media-moxy - 2.26-b08 - + + + + + @@ -237,9 +249,26 @@ - GeoSolutions + GeoSolutions-snap http://maven.research-infrastructures.eu/nexus/content/repositories/geo-solutions-snapshots/ + + true + + + false + + + GeoSolutions-rels + http://maven.research-infrastructures.eu:8081/nexus/content/repositories/geo-solutions/ + + false + + + true + + + GeoToolkit http://maven.research-infrastructures.eu:8081/nexus/content/repositories/geotoolkit/ diff --git a/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java index 082a194..4fbd52a 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java +++ b/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java @@ -3,15 +3,13 @@ package org.gcube.spatial.data.sdi; import java.net.URL; import java.util.Properties; -import javax.servlet.ServletContext; - import lombok.Synchronized; import lombok.extern.slf4j.Slf4j; @Slf4j public class LocalConfiguration { - + //GN final static public String GEONETWORK_CACHE_TTL="gn.cache.TTL"; final static public String GEONETWORK_SE_CATEGORY="gn.se.category"; final static public String GEONETWORK_SE_PLATFORM="gn.se.platform"; @@ -20,7 +18,30 @@ public class LocalConfiguration { final static public String GEONETWORK_GE_SERVICE_CLASS="gn.ge.serviceClass"; final static public String GEONETWORK_GE_SERVICE_NAME="gn.ge.serviceName"; + final static public String GEONETWORK_UPDATE_TIMEOUT="gn.update.timeout"; + final static public String GEONETWORK_UPDATE_WAIT="gn.update.wait"; + final static public String GEONETWORK_MAIL="gn.contact.mail"; + final static public String GEONETWORK_PASSWORD_LENGTH="gn.password.length"; + final static public String GEONETWORK_SE_SUFFIXES="gn.se.suffixes"; + final static public String GEONETWORK_SE_ASSIGNED_SCOPE_PREFIX="gn.se.assigned.scope.prefix"; + final static public String GEONETWORK_SE_SCOPE_USER_PREFIX="gn.se.scope.user.prefix"; + final static public String GEONETWORK_SE_SCOPE_PASSWORD_PREFIX="gn.se.scope.password.prefix"; + final static public String GEONETWORK_SE_CKAN_USER_PREFIX="gn.se.ckan.user.prefix"; + final static public String GEONETWORK_SE_CKAN_PASSWORD_PREFIX="gn.se.ckan.password.prefix"; + final static public String GEONETWORK_SE_MANAGER_USER_PREFIX="gn.se.manager.user.prefix"; + final static public String GEONETWORK_SE_MANAGER_PASSWORD_PREFIX="gn.se.manager.password.prefix"; + final static public String GEONETWORK_SE_DEFAULT_GROUP_PREFIX="gn.se.default.group.prefix"; + final static public String GEONETWORK_SE_SHARED_GROUP_PREFIX="gn.se.shared.group.prefix"; + final static public String GEONETWORK_SE_CONFIDENTIAL_GROUP_PREFIX="gn.se.confidential.group.prefix"; + final static public String GEONETWORK_SE_CONTEXT_GROUP_PREFIX="gn.se.context.group.prefix"; + final static public String GEONETWORK_GROUP_ALL="gn.groups.all"; + + + final static public String GEONETWORK_MANDATORY_SG="gn.mandatorySG"; + + + //GS final static public String GEOSERVER_CACHE_TTL="gs.cache.TTL"; final static public String GEOSERVER_GE_SERVICE_CLASS="gs.ge.serviceClass"; final static public String GEOSERVER_GE_SERVICE_NAME="gs.ge.serviceName"; @@ -28,7 +49,15 @@ public class LocalConfiguration { final static public String GEOSERVER_SE_PLATFORM="gs.se.platform"; final static public String GEOSERVER_SE_ENDPOINT_NAME="gs.se.endpointName"; + public static final String GEOSERVER_HOSTED_LAYERS_TTL="gs.cache.hostedLayers.TTL"; + public static final String GEOSERVER_STYLES_TTL="gs.cache.hostedLayers.TTL"; + public static final String GEOSERVER_WORKSPACE_TTL="gs.cache.hostedLayers.TTL"; + public static final String GEOSERVER_DATASTORE_TTL="gs.cache.hostedLayers.TTL"; + final static public String GEOSERVER_MANDATORY_SG="gs.mandatorySG"; + + + //TH final static public String THREDDS_CACHE_TTL="th.cache.TTL"; final static public String THREDDS_SE_CATEGORY="th.se.category"; final static public String THREDDS_SE_PLATFORM="th.se.platform"; @@ -36,7 +65,11 @@ public class LocalConfiguration { final static public String THREDDS_GE_SERVICE_NAME="th.ge.serviceName"; final static public String THREDDS_SE_ENDPOINT_NAME="th.se.endpointName"; - final static public String METADATA_TEMPLATE_FOLDER="meta.tpl.folder"; + final static public String THREDDS_MANDATORY_SG="th.mandatorySG"; + final static public String THREDDS_SE_REMOTE_MANAGEMENT_ACCESS="th.se.remoteManagement.access"; + + //META + final static public String TEMPLATE_FOLDER="tpl.folder"; final static public String TEMPORARY_PERSISTENCE_TTL="temp.ttl"; @@ -45,10 +78,6 @@ public class LocalConfiguration { static LocalConfiguration instance=null; - public static synchronized LocalConfiguration get(){ - return instance; - } - @Synchronized public static LocalConfiguration init(URL propertiesURL){ if(instance==null) @@ -67,17 +96,24 @@ public class LocalConfiguration { } } - public String getProperty(String property){ - return props.getProperty(property); + public static String getProperty(String property){ + return instance.props.getProperty(property); } - public String getProperty(String property,String defaultValue){ - return props.getProperty(property, defaultValue); + public static String getProperty(String property,String defaultValue){ + return instance.props.getProperty(property, defaultValue); } + public static Long getTTL(String property) { + return Long.parseLong(getProperty(property)); + } - private Object templateConfiguration=null; + public static boolean getFlag(String property) { + return Boolean.parseBoolean(property); + } - public Object getTemplateConfigurationObject() {return templateConfiguration;} - public void setTemplateConfigurationObject(Object obj) {this.templateConfiguration=obj;} + private static Object templateConfiguration=null; + + public static Object getTemplateConfigurationObject() {return templateConfiguration;} + public static void setTemplateConfigurationObject(Object obj) {templateConfiguration=obj;} } diff --git a/src/main/java/org/gcube/spatial/data/sdi/NetUtils.java b/src/main/java/org/gcube/spatial/data/sdi/NetUtils.java new file mode 100644 index 0000000..2add166 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/NetUtils.java @@ -0,0 +1,94 @@ +package org.gcube.spatial.data.sdi; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.util.Base64; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NetUtils { + + public static boolean isSameHost(String toTestHost,String toLookForHost) throws UnknownHostException { + log.debug("Checking same hosts {},{}",toTestHost,toLookForHost); + if(toTestHost.equalsIgnoreCase(toLookForHost)) return true; + else { + InetAddress[] toTestHostIPs=InetAddress.getAllByName(toTestHost); + InetAddress[] toLookForHostIPs=InetAddress.getAllByName(toLookForHost); + log.debug("Checking IPs. ToTestIPs {}, ToLookForIPs {} ",toTestHostIPs,toLookForHostIPs); + for(InetAddress toTestIP:toTestHostIPs) { + for(InetAddress toLookForIP:toLookForHostIPs) + if(toTestIP.equals(toLookForIP)) return true; + } + } + log.debug("HOSTS are different."); + return false; + } + + public static String getHostByURL(String url){ + try{ + return new URL(url).getHost(); + }catch(MalformedURLException e) { + log.debug("Passed url {} is invalid. Assuming it's an hostname."); + return url; + } + } + + public static final String getHost(String endpoint) throws MalformedURLException{ + log.debug("Get host from endpoint {} ",endpoint); + if(endpoint.startsWith("http")){ + log.debug("Endpoint seems url.."); + return getHostByURL(endpoint); + } + return endpoint; + } + + + public static boolean isUp(String url) throws IOException { + String finalUrl=resolveRedirects(url); + log.debug("Checking {} availability .. ",finalUrl); + URL urlObj=new URL(finalUrl); + HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection(); + int status=connection.getResponseCode(); + log.trace("HTTP Status response code for {} is {} ",finalUrl,status); + return status>=200&&status<300; + } + + + public static String resolveRedirects(String url) throws IOException{ + log.debug("Resolving redirect for url {} ",url); + URL urlObj=new URL(url); + HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection(); + int status=connection.getResponseCode(); + if(status>=300&&status<400){ + String newUrl=connection.getHeaderField("Location"); + log.debug("Following redirect from {} to {} ",url,newUrl); + return resolveRedirects(newUrl); + }else return url; + } + + + public static void makeAuthorizedCall(String host,String path,String user,String password) throws IOException { + String urlString=String.format("https://%s/%s", host,path); + makeAuthorizedCall(urlString, user, password); + } + + public static void makeAuthorizedCall(String urlString,String user,String password) throws IOException { + log.debug("Connecting to {} ",urlString); + URL url = new URL(urlString); + URLConnection uc = url.openConnection(); + String userpass = user + ":" + password; + String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes())); + uc.setRequestProperty ("Authorization", basicAuth); + uc.setRequestProperty("gcube-token", SecurityTokenProvider.instance.get()); + InputStream in = uc.getInputStream(); + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/SDIService.java b/src/main/java/org/gcube/spatial/data/sdi/SDIService.java index f7efd7f..e05398d 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/SDIService.java +++ b/src/main/java/org/gcube/spatial/data/sdi/SDIService.java @@ -10,7 +10,6 @@ import org.gcube.smartgears.context.application.ApplicationContext; import org.gcube.spatial.data.sdi.model.ServiceConstants; import org.gcube.spatial.data.sdi.rest.GeoNetwork; import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.glassfish.jersey.moxy.xml.MoxyXmlFeature; import org.glassfish.jersey.server.ResourceConfig; import io.swagger.jaxrs.config.BeanConfig; @@ -27,11 +26,11 @@ public class SDIService extends ResourceConfig{ public SDIService() { super(); packages("org.gcube.spatial.data"); - packages("org.gcube.spatial.data.sdi.model"); +// packages("org.gcube.spatial.data.sdi.model"); register(io.swagger.jaxrs.listing.ApiListingResource.class); register(io.swagger.jaxrs.listing.SwaggerSerializers.class); register(MultiPartFeature.class); - register(MoxyXmlFeature.class); +// register(MoxyXmlFeature.class); ApplicationContext context=ContextProvider.get(); ContainerConfiguration configuration=context.container().configuration(); diff --git a/src/main/java/org/gcube/spatial/data/sdi/ScopeUtils.java b/src/main/java/org/gcube/spatial/data/sdi/ScopeUtils.java new file mode 100644 index 0000000..4edce5a --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/ScopeUtils.java @@ -0,0 +1,70 @@ +package org.gcube.spatial.data.sdi; + +import static org.gcube.common.authorization.client.Constants.authorizationService; + +import java.util.ArrayList; + +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ScopeUtils { + + public static String getCurrentScope(){ + // try{ + // String token=SecurityTokenProvider.instance.get(); + // log.debug("Token is : "+token); + // if(token==null) throw new Exception("Security Token is null"); + // AuthorizationEntry entry = authorizationService().get(token); + // return entry.getContext(); + // }catch(Exception e ){ + // log.debug("Unable to resolve token, checking scope provider..",e); + // return ScopeProvider.instance.get(); + // } + + String scope=ScopeProvider.instance.get(); + if(scope!=null) { + log.debug("Found scope provider {}, skipping token",scope); + return scope; + }else{ + try{ + log.debug("Scope provider not set, reverting to token"); + String token=SecurityTokenProvider.instance.get(); + log.debug("Token is : "+token); + if(token==null) throw new Exception("Security Token is null"); + AuthorizationEntry entry = authorizationService().get(token); + return entry.getContext(); + }catch(Exception e){ + throw new RuntimeException("Unable to evaluate scope ",e); + } + } + + + } + + public static String getCurrentScopeName(){ + return getScopeName(getCurrentScope()); + } + + public static String getScopeName(String scope) { + return scope.substring(scope.lastIndexOf('/')+1); + } + + + public static ArrayList getParentScopes(String scope){ + String[] splitted=scope.substring(1).split("/"); + ArrayList toReturn=new ArrayList(); + for(int i=0;i{ - public GeoServerClusterConfiguration getConfiguration() throws ConfigurationNotFoundException; - public ServiceHealthReport getHealthReport(); - public String registerService(GeoServerDefinition definition)throws ServiceRegistrationException; +// public List getConfiguration() throws ConfigurationNotFoundException; +// public ServiceHealthReport getHealthReport(); +// public String registerService(GeoServerDefinition definition)throws ServiceRegistrationException; +// String importHostFromToken(String sourceToken, String hostname) throws ServiceRegistrationException; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkManager.java index 477d433..508c857 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkManager.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkManager.java @@ -1,15 +1,15 @@ package org.gcube.spatial.data.sdi.engine; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkClient; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; import org.gcube.spatial.data.sdi.model.services.GeoNetworkServiceDefinition; -public interface GeoNetworkManager { +public interface GeoNetworkManager extends GeoServiceManager{ - public GeoNetworkConfiguration getConfiguration() throws ConfigurationNotFoundException; - public ServiceHealthReport getHealthReport(); - public String registerService(GeoNetworkServiceDefinition definition)throws ServiceRegistrationException; + + public GeoNetworkClient getClient() throws ConfigurationNotFoundException; + public GeoNetworkClient getClient(GeoNetworkDescriptor descriptor); + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkProvider.java b/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkProvider.java deleted file mode 100644 index 33260ce..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/GeoNetworkProvider.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.gcube.spatial.data.sdi.engine; - -import org.gcube.spatial.data.geonetwork.GeoNetworkAdministration; -import org.gcube.spatial.data.sdi.engine.impl.faults.ClientInitializationException; - -public interface GeoNetworkProvider { - - public GeoNetworkAdministration getGeoNetwork() throws ClientInitializationException; - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/GeoServiceManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/GeoServiceManager.java new file mode 100644 index 0000000..7465838 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/GeoServiceManager.java @@ -0,0 +1,19 @@ +package org.gcube.spatial.data.sdi.engine; + +import java.util.List; + +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; +import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; +import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; + +public interface GeoServiceManager { + + public T getDescriptorByHostname(String hostname) throws ConfigurationNotFoundException; + public List getAvailableInstances() throws ConfigurationNotFoundException; + public List getSuggestedInstances() throws ConfigurationNotFoundException; + public String registerService(E toRegister) throws ServiceRegistrationException; + public String importHostFromToken(String sourceToken, String hostname) throws ServiceRegistrationException; + public ServiceHealthReport getHealthReport(); +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/RoleManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/RoleManager.java new file mode 100644 index 0000000..ef1a3a6 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/RoleManager.java @@ -0,0 +1,14 @@ +package org.gcube.spatial.data.sdi.engine; + +import java.util.List; + +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; + +public interface RoleManager { + + public Credentials getMostAccessible(List toFilter,boolean considerAdmin); + + public List filterByRole(List toFilter, boolean considerAdmin); + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/SDIManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/SDIManager.java index 836c565..57fa104 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/SDIManager.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/SDIManager.java @@ -12,4 +12,10 @@ public interface SDIManager { public HealthReport getHealthReport(); public String registerService(ServiceDefinition definition) throws ServiceRegistrationException; + + public String importService(String sourceToken,String host,ServiceDefinition.Type expectedType)throws ServiceRegistrationException; + + public GeoNetworkManager getGeoNetworkManager(); + public ThreddsManager getThreddsManager(); + public GISManager getGeoServerManager(); } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/TemplateManager.java similarity index 51% rename from src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/TemplateManager.java index c25cd49..168cfdd 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/TemplateManager.java @@ -2,6 +2,7 @@ package org.gcube.spatial.data.sdi.engine; import java.io.File; import java.io.IOException; +import java.util.Map; import java.util.Set; import javax.xml.transform.TransformerException; @@ -10,10 +11,13 @@ import org.gcube.spatial.data.sdi.engine.impl.metadata.TemplateApplicationReport import org.gcube.spatial.data.sdi.model.metadata.TemplateCollection; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation; -public interface MetadataTemplateManager { +public interface TemplateManager { - public TemplateCollection getAvailableTemplates(); - public TemplateApplicationReport applyTemplates(File original,Set invocations) throws IOException, TransformerException; + public TemplateCollection getAvailableMetadataTemplates(); + public TemplateApplicationReport applyMetadataTemplates(File original,Set invocations) throws IOException, TransformerException; + public File generateFromTemplate(Map parameters, String templateID) throws Exception; + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/ThreddsManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/ThreddsManager.java index eea3e15..fd1e3b7 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/ThreddsManager.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/ThreddsManager.java @@ -1,14 +1,17 @@ package org.gcube.spatial.data.sdi.engine; +import java.io.File; + +import org.gcube.data.transfer.model.plugins.thredds.ThreddsCatalog; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.faults.ThreddsOperationFault; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; import org.gcube.spatial.data.sdi.model.services.ThreddsDefinition; -public interface ThreddsManager { +public interface ThreddsManager extends GeoServiceManager{ - public ThreddsConfiguration getConfiguration() throws ConfigurationNotFoundException; - public ServiceHealthReport getHealthReport(); - public String registerService(ThreddsDefinition definition)throws ServiceRegistrationException; + public ThreddsCatalog publishCatalog(File catalogFile,String catalogReference) throws ConfigurationNotFoundException, ThreddsOperationFault; + + public ThreddsCatalog createCatalogFromTemplate(String authorityUrl,String catalogPath, + String datasetScanId,String datasetScanName, String subFolder, String catalogReference)throws Exception; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/AbstractManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/AbstractManager.java new file mode 100644 index 0000000..1157af6 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/AbstractManager.java @@ -0,0 +1,51 @@ +package org.gcube.spatial.data.sdi.engine.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.gcube.spatial.data.sdi.engine.GeoServiceManager; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoServiceController; +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; +import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; + +public abstract class AbstractManager> implements GeoServiceManager{ + + + protected abstract ISModule getRetriever(); + protected abstract AbstractCluster getCluster(); + + @Override + public T getDescriptorByHostname(String hostname) throws ConfigurationNotFoundException { + return getCluster().getControllerByHostName(hostname).getDescriptor(); + } + + @Override + public List getAvailableInstances() throws ConfigurationNotFoundException { + ArrayList toReturn=new ArrayList<>(); + for(L controller :getCluster().getActualCluster()) + toReturn.add(controller.getDescriptor()); + return toReturn; + } + + + @Override + public String registerService(E toRegister) throws ServiceRegistrationException { + return getRetriever().registerService(toRegister); + } + + @Override + public String importHostFromToken(String sourceToken, String hostname) throws ServiceRegistrationException { + return getRetriever().importHostFromToken(sourceToken, hostname); + } + + @Override + public ServiceHealthReport getHealthReport() { + return getRetriever().getHealthReport(); + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GISManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GISManagerImpl.java index 95c01de..bef3690 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GISManagerImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GISManagerImpl.java @@ -1,43 +1,44 @@ package org.gcube.spatial.data.sdi.engine.impl; +import java.util.List; + import javax.inject.Singleton; import org.gcube.spatial.data.sdi.LocalConfiguration; import org.gcube.spatial.data.sdi.engine.GISManager; -import org.gcube.spatial.data.sdi.engine.impl.cache.Cache; -import org.gcube.spatial.data.sdi.engine.impl.cache.GeoServerClusterRetriever; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoServerCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoServerController; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.GeoServerClusterConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.is.GeoServerClusterRetriever; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; import org.gcube.spatial.data.sdi.model.services.GeoServerDefinition; @Singleton -public class GISManagerImpl implements GISManager { +public class GISManagerImpl extends AbstractManager implements GISManager{ - private Cache theCache=null; private GeoServerClusterRetriever retriever=null; - + private GeoServerCluster cluster=null; public GISManagerImpl() { retriever=new GeoServerClusterRetriever(); - theCache=Cache.getCache(retriever, Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_CACHE_TTL)), "GeoCluster - cache"); + cluster=new GeoServerCluster(LocalConfiguration.getTTL(LocalConfiguration.GEOSERVER_CACHE_TTL), retriever, "GeoServer - cache"); } - @Override - public GeoServerClusterConfiguration getConfiguration() throws ConfigurationNotFoundException { - return theCache.get(); + protected AbstractCluster getCluster() { + return cluster; } + + @Override + protected ISModule getRetriever() { + return retriever; + } + @Override + public List getSuggestedInstances() throws ConfigurationNotFoundException { + return getAvailableInstances(); + } + - - @Override - public ServiceHealthReport getHealthReport() { - return retriever.getHealthReport(); - } - - @Override - public String registerService(GeoServerDefinition definition) throws ServiceRegistrationException { - return retriever.registerService(definition); - } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkManagerImpl.java index 7c52360..0a03f11 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkManagerImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkManagerImpl.java @@ -1,45 +1,69 @@ package org.gcube.spatial.data.sdi.engine.impl; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; import javax.inject.Singleton; import org.gcube.spatial.data.sdi.LocalConfiguration; import org.gcube.spatial.data.sdi.engine.GeoNetworkManager; -import org.gcube.spatial.data.sdi.engine.impl.cache.Cache; -import org.gcube.spatial.data.sdi.engine.impl.cache.GeoNetworkRetriever; +import org.gcube.spatial.data.sdi.engine.RoleManager; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoNetworkCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoNetworkController; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkClient; +import org.gcube.spatial.data.sdi.engine.impl.is.GeoNetworkRetriever; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; import org.gcube.spatial.data.sdi.model.services.GeoNetworkServiceDefinition; +import lombok.extern.slf4j.Slf4j; + +@Slf4j @Singleton -public class GeoNetworkManagerImpl implements GeoNetworkManager { +public class GeoNetworkManagerImpl extends AbstractManager implements GeoNetworkManager { - private Cache cache=null; + RoleManager roleManager; + + private GeoNetworkRetriever retriever=null; - - public GeoNetworkManagerImpl() { + private GeoNetworkCluster cluster=null; + + @Inject + public GeoNetworkManagerImpl(RoleManager roleManager) { + this.roleManager=roleManager; retriever=new GeoNetworkRetriever(); - cache=Cache.getCache(retriever, - Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_CACHE_TTL)),"GeoNetwork - cache"); + cluster=new GeoNetworkCluster(LocalConfiguration.getTTL(LocalConfiguration.GEONETWORK_CACHE_TTL), retriever, "GeoNEtwork - cache"); + } + + + @Override + protected AbstractCluster getCluster() { + return cluster; + } + + @Override + protected ISModule getRetriever() { + return retriever; } - @Override - public GeoNetworkConfiguration getConfiguration() throws ConfigurationNotFoundException { - return cache.get(); + public List getSuggestedInstances() throws ConfigurationNotFoundException { + return Collections.singletonList(getCluster().getDefaultController().getDescriptor()); } @Override - public ServiceHealthReport getHealthReport() { - return retriever.getHealthReport(); + public GeoNetworkClient getClient() throws ConfigurationNotFoundException { + return getClient(getCluster().getDefaultController().getDescriptor()); } @Override - public String registerService(GeoNetworkServiceDefinition definition) throws ServiceRegistrationException { - return retriever.registerService(definition); - + public GeoNetworkClient getClient(GeoNetworkDescriptor descriptor) { + Credentials selected=roleManager.getMostAccessible(descriptor.getAccessibleCredentials(), false); + log.info("Logging in {} using {} ",descriptor,selected); + return new GeoNetworkClient(descriptor.getBaseEndpoint(), descriptor.getVersion(), selected.getPassword(), selected.getUsername(),descriptor); } - - } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkProviderImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkProviderImpl.java deleted file mode 100644 index f79399d..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/GeoNetworkProviderImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl; - -import javax.inject.Singleton; - -import org.gcube.spatial.data.geonetwork.GeoNetwork; -import org.gcube.spatial.data.geonetwork.GeoNetworkAdministration; -import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider; -import org.gcube.spatial.data.sdi.engine.impl.faults.ClientInitializationException; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Singleton -public class GeoNetworkProviderImpl implements GeoNetworkProvider { - - @Override - public GeoNetworkAdministration getGeoNetwork() throws ClientInitializationException{ - log.debug("Getting GeoNetwork .. "); - try{ - return GeoNetwork.get(); - }catch(Exception e){ - throw new ClientInitializationException(e); - } - } - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/NetUtils.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/NetUtils.java deleted file mode 100644 index 06d04a8..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/NetUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class NetUtils { - - public static boolean isUp(String url) throws IOException { - String finalUrl=resolveRedirects(url); - log.debug("Checking {} availability .. ",finalUrl); - URL urlObj=new URL(finalUrl); - HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection(); - int status=connection.getResponseCode(); - log.trace("HTTP Status response code for {} is {} ",finalUrl,status); - return status>=200&&status<300; - } - - - public static String resolveRedirects(String url) throws IOException{ - log.debug("Resolving redirect for url {} ",url); - URL urlObj=new URL(url); - HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection(); - int status=connection.getResponseCode(); - if(status>=300&&status<400){ - String newUrl=connection.getHeaderField("Location"); - log.debug("Following redirect from {} to {} ",url,newUrl); - return resolveRedirects(newUrl); - }else return url; - } - - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/RoleManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/RoleManagerImpl.java new file mode 100644 index 0000000..1d8d89b --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/RoleManagerImpl.java @@ -0,0 +1,56 @@ +package org.gcube.spatial.data.sdi.engine.impl; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Singleton; +import javax.validation.metadata.ConstraintDescriptor; + +import org.gcube.spatial.data.sdi.engine.RoleManager; +import org.gcube.spatial.data.sdi.model.credentials.AccessType; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Singleton +public class RoleManagerImpl implements RoleManager { + + public RoleManagerImpl() { + // TODO Auto-generated constructor stub + } + + @Override + public Credentials getMostAccessible(List toFilter, boolean considerAdmin) { + + //need to check roles by contacting social + AccessType maxLevel=getMaxLevel(considerAdmin); + + Credentials toReturn=null; + for(Credentials cred: toFilter) { + if(cred.getAccessType().compareTo(maxLevel)>=0) { // cred level + if(toReturn==null || cred.getAccessType().compareTo(toReturn.getAccessType())<0) + toReturn = cred; + } + } + return toReturn; + } + + @Override + public List filterByRole(List toFilter, boolean considerAdmin) { + ArrayList toReturn=new ArrayList(); + AccessType maxLevel=getMaxLevel(considerAdmin); + for(T descriptor:toFilter) { + + } + return toReturn; + } + + + private AccessType getMaxLevel(boolean considerAdmin) { + //TOD ask to social manager + return considerAdmin?AccessType.ADMIN:AccessType.CONTEXT_MANAGER; + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/SDIManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/SDIManagerImpl.java index 0ea47c4..5c1eef3 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/SDIManagerImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/SDIManagerImpl.java @@ -8,7 +8,6 @@ import org.gcube.spatial.data.sdi.engine.GISManager; import org.gcube.spatial.data.sdi.engine.GeoNetworkManager; import org.gcube.spatial.data.sdi.engine.SDIManager; import org.gcube.spatial.data.sdi.engine.ThreddsManager; -import org.gcube.spatial.data.sdi.engine.impl.cache.ISUtils; import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; import org.gcube.spatial.data.sdi.model.ScopeConfiguration; @@ -27,16 +26,11 @@ import lombok.extern.slf4j.Slf4j; @Singleton public class SDIManagerImpl implements SDIManager { - // @Inject GeoNetworkManager geonetworkManager; - // @Inject ThreddsManager threddsManager; - // @Inject GISManager gisManager; - - @Inject public SDIManagerImpl(GeoNetworkManager geonetworkManager, ThreddsManager threddsManager, GISManager gisManager) { super(); @@ -57,19 +51,19 @@ public class SDIManagerImpl implements SDIManager { ScopeConfiguration toReturn=new ScopeConfiguration(); toReturn.setContextName(ScopeUtils.getCurrentScopeName()); try{ - toReturn.setGeonetworkConfiguration(geonetworkManager.getConfiguration()); + toReturn.setGeonetworkConfiguration(geonetworkManager.getSuggestedInstances()); }catch(Exception e){ log.warn("Scope is not well configured. Missing GeoNetwork. ",e); } try{ - toReturn.setThreddsConfiguration(threddsManager.getConfiguration()); + toReturn.setThreddsConfiguration(threddsManager.getSuggestedInstances()); }catch(Exception e){ log.warn("THREDDS not found in current scope {} ",ScopeUtils.getCurrentScope()); } try{ - toReturn.setGeoserverClusterConfiguration(gisManager.getConfiguration()); + toReturn.setGeoserverClusterConfiguration(gisManager.getSuggestedInstances()); }catch(Exception e){ log.warn("GeoServer not found in current scope {} ",ScopeUtils.getCurrentScope()); } @@ -129,4 +123,36 @@ public class SDIManagerImpl implements SDIManager { throw new InvalidServiceDefinitionException("Unable to register. Incoherent service type. Definition was "+definition); } } + + @Override + public String importService(String sourceToken, String host, ServiceDefinition.Type expectedType) throws ServiceRegistrationException { + switch(expectedType) { + case GEONETWORK : + return geonetworkManager.importHostFromToken(sourceToken, host); + + case GEOSERVER : + return gisManager.importHostFromToken(sourceToken, host); + + case THREDDS : + return threddsManager.importHostFromToken(sourceToken, host); + + default : throw new InvalidServiceDefinitionException("Unable to register. Invalid service type "+expectedType); + } + } + + + @Override + public GeoNetworkManager getGeoNetworkManager() { + return geonetworkManager; + } + + @Override + public GISManager getGeoServerManager() { + return gisManager; + } + + @Override + public ThreddsManager getThreddsManager() { + return threddsManager; + } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/TemporaryPersistenceImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/TemporaryPersistenceImpl.java index 9cf8fe9..4dbf28c 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/TemporaryPersistenceImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/TemporaryPersistenceImpl.java @@ -94,7 +94,7 @@ public class TemporaryPersistenceImpl implements TemporaryPersistence { service = new ScheduledThreadPoolExecutor (1); - long TTL=Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.TEMPORARY_PERSISTENCE_TTL, "120000")); + long TTL=Long.parseLong(LocalConfiguration.getProperty(LocalConfiguration.TEMPORARY_PERSISTENCE_TTL, "120000")); log.debug("Temp TTL is {} ",TTL); long delay=TTL/4; diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/ThreddsManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/ThreddsManagerImpl.java index 2aaf0b0..8832f8f 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/ThreddsManagerImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/ThreddsManagerImpl.java @@ -1,43 +1,85 @@ package org.gcube.spatial.data.sdi.engine.impl; +import java.io.File; +import java.util.HashMap; +import java.util.List; + +import javax.inject.Inject; import javax.inject.Singleton; +import org.gcube.data.transfer.model.plugins.thredds.ThreddsCatalog; +import org.gcube.data.transfer.model.plugins.thredds.ThreddsInfo; import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.engine.TemplateManager; import org.gcube.spatial.data.sdi.engine.ThreddsManager; -import org.gcube.spatial.data.sdi.engine.impl.cache.Cache; -import org.gcube.spatial.data.sdi.engine.impl.cache.ThreddsRetriever; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.ThreddsCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.ThreddsController; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.faults.ThreddsOperationFault; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.engine.impl.is.ThreddsRetriever; +import org.gcube.spatial.data.sdi.engine.impl.metadata.GenericTemplates; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; import org.gcube.spatial.data.sdi.model.services.ThreddsDefinition; -@Singleton -public class ThreddsManagerImpl implements ThreddsManager { +import lombok.extern.slf4j.Slf4j; - private Cache cache=null; +@Singleton +@Slf4j +public class ThreddsManagerImpl extends AbstractManager implements ThreddsManager { + + private ThreddsCluster cluster=null; private ThreddsRetriever retriever=null; + @Inject + TemplateManager templateManager; + public ThreddsManagerImpl() { retriever=new ThreddsRetriever(); - cache=Cache.getCache(retriever, - Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_CACHE_TTL)), "THREDDS - CACHE"); + cluster=new ThreddsCluster(LocalConfiguration.getTTL(LocalConfiguration.THREDDS_CACHE_TTL),retriever,"Thredds Cache"); } @Override - public ThreddsConfiguration getConfiguration() throws ConfigurationNotFoundException { - return cache.get(); - } - - @Override - public ServiceHealthReport getHealthReport() { - return retriever.getHealthReport(); + protected AbstractCluster getCluster() { + return cluster; } @Override - public String registerService(ThreddsDefinition definition) throws ServiceRegistrationException { - return retriever.registerService(definition); + protected ISModule getRetriever() { + return retriever; + } + @Override + public List getSuggestedInstances() throws ConfigurationNotFoundException { + return getAvailableInstances(); } + + @Override + public ThreddsCatalog publishCatalog(File catalogFile, String catalogReference) throws ConfigurationNotFoundException, ThreddsOperationFault { + return getCluster().getDefaultController().publishCatalog(catalogFile, catalogReference); + } + + @Override + public ThreddsCatalog createCatalogFromTemplate(String authorityUrl, String catalogPath, String datasetScanId, + String datasetScanName, String subFolder, String catalogReference) throws Exception { + ThreddsController controller=getCluster().getDefaultController(); + ThreddsInfo info=controller.getThreddsInfo(); + + + log.info("Going to create catalog for authorityURL {}, path {}, subFolder {} ",authorityUrl,catalogPath,subFolder); + + HashMap parameters=new HashMap(); + parameters.put(GenericTemplates.ThreddsCatalogTemplate.AUTHORITY_URL, authorityUrl); + parameters.put(GenericTemplates.ThreddsCatalogTemplate.CATALOG_PATH, catalogPath); + parameters.put(GenericTemplates.ThreddsCatalogTemplate.DATASET_SCAN_ID, datasetScanId); + parameters.put(GenericTemplates.ThreddsCatalogTemplate.DATASET_SCAN_NAME, datasetScanName); + parameters.put(GenericTemplates.ThreddsCatalogTemplate.LOCATION, info.getLocalBasePath()+"/"+subFolder); + + File catalog= + templateManager.generateFromTemplate(parameters, GenericTemplates.ThreddsCatalogTemplate.FILENAME); + + return controller.publishCatalog(catalog, catalogReference); + } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/AbstractISModule.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/AbstractISModule.java deleted file mode 100644 index e97698a..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/AbstractISModule.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; - -import java.util.ArrayList; -import java.util.List; - -import org.gcube.common.resources.gcore.GCoreEndpoint; -import org.gcube.common.resources.gcore.ServiceEndpoint; -import org.gcube.common.resources.gcore.ServiceEndpoint.Profile; -import org.gcube.common.resources.gcore.common.Platform; -import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; -import org.gcube.spatial.data.sdi.LocalConfiguration; -import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; -import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; -import org.gcube.spatial.data.sdi.model.health.Level; -import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.health.Status; -import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; - -import lombok.Synchronized; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public abstract class AbstractISModule implements ISModule { - - protected abstract String getGCoreEndpointServiceClass(); - protected abstract String getGCoreEndpointServiceName(); - protected abstract String getServiceEndpointAccessPointName(); - protected abstract String getServiceEndpointCategory(); - protected abstract String getServiceEndpointPlatformName(); - - protected abstract String getManagedServiceType(); - - - @Override - public ServiceHealthReport getHealthReport() { - List checkStatuses=new ArrayList<>(); - try { - - log.trace("Checking {} heatlh under context {} ",getManagedServiceType(),ScopeUtils.getCurrentScope()); - //Check if existing - List gCoreEndpoints=getGcoreEndpoints(); - List serviceEndpoints=getServiceEndpoints(); - log.debug("Found {} GC Endpoints and {} SE Endpoints",gCoreEndpoints.size(),serviceEndpoints.size()); - - if(serviceEndpoints.isEmpty()) - if(gCoreEndpoints.isEmpty())checkStatuses.add(new Status("No "+getManagedServiceType()+" found in context "+ScopeUtils.getCurrentScope(),Level.ERROR)); - else checkStatuses.add(new Status("Unregistered "+getManagedServiceType()+" instances found. Check following messages",Level.ERROR)); - - //For each GC check for missing SE - for(GCoreEndpoint gc:gCoreEndpoints) { - String hostname= gc.profile().endpoints().iterator().next().uri().getHost(); - if(ISUtils.getGCEByHostname(hostname, serviceEndpoints)==null) { - String msg="Found unregistered "+getManagedServiceType()+" hosted on "+hostname; - log.debug(msg); - checkStatuses.add(new Status(msg,Level.WARNING)); - } - } - - - for(ServiceEndpoint se : serviceEndpoints) { - checkStatuses.addAll(performInstanceCheck(se)); - } - - }catch(Throwable t) { - log.error("Unable to perform checks", t); - checkStatuses.add(new Status("Internal error while checking "+getManagedServiceType()+" Status.",Level.ERROR)); - } - return new ServiceHealthReport(checkStatuses); - } - - protected abstract List performInstanceCheck(ServiceEndpoint se); - - - protected List getGcoreEndpoints(){ - String geClass=getGCoreEndpointServiceClass(); - String geName=getGCoreEndpointServiceName(); - return ISUtils.queryForGCoreEndpoint(geClass, geName); - } - - - protected List getServiceEndpoints(){ - String seCategory=getServiceEndpointCategory(); - String sePlatform=getServiceEndpointPlatformName(); - return ISUtils.queryForServiceEndpoints(seCategory, sePlatform); - } - - @Override - @Synchronized - public String registerService(ServiceDefinition definition) throws ServiceRegistrationException { - log.info("Registering {} ",definition); - log.debug("Checking definition type.."); - checkDefinitionType(definition); - log.debug("Checking IS .."); - checkDefinition(definition); - log.debug("Performing type specific checks.."); - checkDefinitionForServiceType(definition); - log.debug("Preparing ServiceEndpoint.. "); - ServiceEndpoint ep=prepareEndpoint(definition); - log.debug("Publishing resource.."); - String id=ISUtils.registerService(ep); - - List registered=null; - long registrationTime=System.currentTimeMillis(); - long timeout=Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.IS_REGISTRATION_TIMEOUT)); - do{ - log.debug("Waiting for IS to update. Passed {} ms.",(System.currentTimeMillis()-registrationTime)); - try{Thread.sleep(500); - }catch(Exception e) {} - - registered=ISUtils.queryById(id); - }while(registered.isEmpty()&&((System.currentTimeMillis()-registrationTime)<=timeout)); - if(registered.isEmpty()) { - log.warn("Registered resource [ID :{}] was not found before Timeout of {} ms. Returning id. ",id,timeout); - return id; - }else return registered.get(0); - } - - - protected abstract void checkDefinitionForServiceType(ServiceDefinition definition) throws InvalidServiceDefinitionException; - protected abstract void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException; - - protected void checkDefinition(ServiceDefinition definition) throws ServiceRegistrationException { - String hostname=definition.getHostname(); - List serviceEndpoints=getServiceEndpoints(); - ServiceEndpoint existing=ISUtils.getGCEByHostname(hostname, serviceEndpoints); - if(existing!=null) { - throw new ServiceRegistrationException("Service is already registered"); - } - List gCoreNodes=getGcoreEndpoints(); - GCoreEndpoint running=ISUtils.getGCEByHostname(hostname, gCoreNodes); - if(running==null) throw new ServiceRegistrationException("No GCoreEndpoint found for "+definition); - } - - protected ServiceEndpoint prepareEndpoint(ServiceDefinition definition) { - ServiceEndpoint toCreate=new ServiceEndpoint(); - Profile profile=toCreate.newProfile(); - profile.category(getServiceEndpointCategory()); - profile.description(definition.getDescription()); - Platform platform=profile.newPlatform(); - platform.name(getServiceEndpointPlatformName()). - version(definition.getMajorVersion()). - minorVersion(definition.getMinorVersion()). - revisionVersion(definition.getReleaseVersion()); - - org.gcube.common.resources.gcore.ServiceEndpoint.Runtime runtime=profile.newRuntime(); - runtime.hostedOn(definition.getHostname()); - - GCoreEndpoint relatedGHN=ISUtils.getGCEByHostname(definition.getHostname(), getGcoreEndpoints()); - - runtime.ghnId(relatedGHN.id()); - runtime.status("READY"); - - return toCreate; - } - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/Cache.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/Cache.java deleted file mode 100644 index e0838d4..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/Cache.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; - -import java.util.concurrent.ConcurrentHashMap; - -import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; -import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.model.service.GeoService; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class Cache { - - private long objectsTTL; - private ConcurrentHashMap> theCache; - private ISModule retriever; - private String cacheName; - - - - - private Cache(long objectsTTL, ISModule retriever, String cacheName) { - super(); - this.objectsTTL = objectsTTL; - this.retriever = retriever; - this.cacheName=cacheName; - theCache=new ConcurrentHashMap<>(); - - } - - public synchronized T get() throws ConfigurationNotFoundException{ - String key=ScopeUtils.getCurrentScope(); - log.info("Getting object from cache{} , key is {} ",cacheName,key); - if((!theCache.containsKey(key))||(!theCache.get(key).isValid(objectsTTL))) - theCache.put(key, new CachedObject(retriever.getObject())); - return theCache.get(key).getTheObject(); - } - - public void invalidate(){ - String key=ScopeUtils.getCurrentScope(); - log.info("Invalidating cache {} under scope {} ",cacheName,key); - if(theCache.containsKey(key))theCache.get(key).invalidate(); - } - - public void invalidateAll(){ - for(CachedObject obj:theCache.values())obj.invalidate(); - } - - public static Cache getCache(ISModule retriever, long objectsTTL,String cacheName){ - return new Cache(objectsTTL,retriever,cacheName); - } - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoServerClusterRetriever.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoServerClusterRetriever.java deleted file mode 100644 index 91deb8b..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoServerClusterRetriever.java +++ /dev/null @@ -1,186 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.gcube.common.resources.gcore.ServiceEndpoint; -import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; -import org.gcube.common.resources.gcore.ServiceEndpoint.Profile; -import org.gcube.common.resources.gcore.ServiceEndpoint.Property; -import org.gcube.common.resources.gcore.common.Platform; -import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; -import org.gcube.spatial.data.gis.GISInterface; -import org.gcube.spatial.data.gis.is.AbstractGeoServerDescriptor; -import org.gcube.spatial.data.sdi.LocalConfiguration; -import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; -import org.gcube.spatial.data.sdi.model.credentials.AccessType; -import org.gcube.spatial.data.sdi.model.credentials.Credentials; -import org.gcube.spatial.data.sdi.model.health.Status; -import org.gcube.spatial.data.sdi.model.service.GeoServerClusterConfiguration; -import org.gcube.spatial.data.sdi.model.service.GeoServerConfiguration; -import org.gcube.spatial.data.sdi.model.service.Version; -import org.gcube.spatial.data.sdi.model.services.GeoServerDefinition; -import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; -import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class GeoServerClusterRetriever extends AbstractISModule{ - - - @Override - public GeoServerClusterConfiguration getObject() throws ConfigurationNotFoundException { - //TODO skip library - //TODO use both GCoreEndpoints and ServiceEndpoint - try { - ArrayList availableInstances=new ArrayList<>(); - for(ServiceEndpoint ep: getServiceEndpoints()) { - try{ - availableInstances.add(translate(ep)); - }catch(Throwable t) { - log.warn("Unable to translate ServiceEndpoint [ID : {}].",ep.id(),t); - } - } - }catch(Throwable e){ - log.warn("Unable to gather geoserver cluster configuration on scope "+ScopeUtils.getCurrentScope(),e); - throw new ConfigurationNotFoundException("Unable to gather geoserver cluster configuration. Please ontact administrator.",e); - } - - - - - log.info("Retrieving GeoServer cluster configuration under scope {}",ScopeUtils.getCurrentScope()); - try{ - GISInterface gis=GISInterface.get(); - ArrayList availableInstances=new ArrayList<>(); - for(AbstractGeoServerDescriptor desc: gis.getCurrentCacheElements(true)){ - try{ - availableInstances.add(translate(desc)); - }catch(Throwable t){ - log.warn("Unable to translate descriptor for endpoint"+desc.getUrl(),t); - } - } - - return new GeoServerClusterConfiguration(availableInstances); - }catch(Exception e){ - log.warn("Unable to gather geoserver cluster configuration on scope "+ScopeUtils.getCurrentScope(),e); - throw new ConfigurationNotFoundException("Unable to gather geoserver cluster configuration. Please ontact administrator.",e); - } - } - - private final GeoServerConfiguration translate(ServiceEndpoint ep) { - GeoServerConfiguration toReturn=new GeoServerConfiguration(); - - Profile profile=ep.profile(); - AccessPoint point=null; - for(AccessPoint declaredPoint:profile.accessPoints().asCollection()) { - if(declaredPoint.name().equals(getServiceEndpointAccessPointName())) { - point=declaredPoint; - break; - } - } - toReturn.setBaseEndpoint(point.address()); - - - - - String scopeName=ScopeUtils.getCurrentScopeName(); - - //Getting Scope credentials - List accessibleCredentials=toReturn.getAccessibleCredentials(); - //Admin credentials - accessibleCredentials.add(new Credentials(point.username(),ISUtils.decryptString(point.password()),AccessType.ADMIN)); - - Map pointProperties=point.propertyMap(); - for(AccessType toLookForType:AccessType.values()) { - String userNameProperty=toLookForType+"_u_"+scopeName; - String passwordProperty=toLookForType+"_u_"+scopeName; - if(pointProperties.containsKey(userNameProperty)) { - String user=pointProperties.get(userNameProperty).value(); - String password=ISUtils.decryptString(pointProperties.get(passwordProperty).value()); - accessibleCredentials.add(new Credentials(user,password,toLookForType)); - } - } - - //Getting scope data spaces - String confidentialProperty="confidential_"+scopeName; - if(pointProperties.containsKey(confidentialProperty)) - toReturn.setConfidentialWorkspace(pointProperties.get(confidentialProperty).value()); - String contextProperty="context_"+scopeName; - if(pointProperties.containsKey(contextProperty)) - toReturn.setContextVisibilityWorkspace(pointProperties.get(contextProperty).value()); - String sharedProperty="shared_"+scopeName; - if(pointProperties.containsKey(sharedProperty)) - toReturn.setSharedWorkspace(pointProperties.get(sharedProperty).value()); - String publicProperty="public_"+scopeName; - if(pointProperties.containsKey(publicProperty)) - toReturn.setPublicWorkspace(pointProperties.get(publicProperty).value()); - - // Getting version - Platform platform=profile.platform(); - toReturn.setVersion(new Version(platform.version(),platform.minorVersion(),platform.revisionVersion())); - return toReturn; - - } - - private static final GeoServerConfiguration translate(AbstractGeoServerDescriptor desc){ - Version version=new Version(2,1,2); - String baseEndpoint=desc.getUrl(); - List accessibleCredentials=Collections.singletonList(new Credentials(desc.getUser(), desc.getPassword(), AccessType.ADMIN)); - String confidentialWorkspace=null; - String contextVisibilityWorkspace=null; - String sharedWorkspace=null; - String publicWorkspace=null; - return new GeoServerConfiguration(version, baseEndpoint, accessibleCredentials, confidentialWorkspace, contextVisibilityWorkspace, sharedWorkspace, publicWorkspace); - } - - @Override - protected String getGCoreEndpointServiceClass() { - return LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_GE_SERVICE_CLASS); - } - @Override - protected String getGCoreEndpointServiceName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_GE_SERVICE_NAME); - } - @Override - protected String getManagedServiceType() { - return "GeoServer"; - } - - @Override - protected String getServiceEndpointAccessPointName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_SE_ENDPOINT_NAME); - } - - @Override - protected String getServiceEndpointCategory() { - return LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_SE_CATEGORY); - } - @Override - protected String getServiceEndpointPlatformName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_SE_PLATFORM); - } - @Override - protected List performInstanceCheck(ServiceEndpoint se) { - // TODO Auto-generated method stub - return null; - } - - @Override - protected void checkDefinitionForServiceType(ServiceDefinition definition) - throws InvalidServiceDefinitionException { - // Contact GN - // try to login with credentials - } - @Override - protected void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException { - if(!definition.getType().equals(Type.GEOSERVER)||!(definition instanceof GeoServerDefinition)) - throw new InvalidServiceDefinitionException("Invalid service type [expected "+Type.GEOSERVER+"]. Definition was "+definition); - } - - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISUtils.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISUtils.java deleted file mode 100644 index 25ddc99..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISUtils.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; - -import static org.gcube.resources.discovery.icclient.ICFactory.client; -import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; -import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; - -import java.util.Collection; -import java.util.List; - -import org.gcube.common.encryption.StringEncrypter; -import org.gcube.common.resources.gcore.GCoreEndpoint; -import org.gcube.common.resources.gcore.Resource; -import org.gcube.common.resources.gcore.ServiceEndpoint; -import org.gcube.informationsystem.publisher.RegistryPublisher; -import org.gcube.informationsystem.publisher.RegistryPublisherFactory; -import org.gcube.resources.discovery.client.api.DiscoveryClient; -import org.gcube.resources.discovery.client.queries.api.SimpleQuery; -import org.gcube.resources.discovery.client.queries.impl.QueryBox; -import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ISUtils { - - static List queryForServiceEndpoints(String category, String platformName){ - log.debug("Querying for Service Endpoints [category : {} , platformName : {}, currentScope : {} ]",category,platformName,ScopeUtils.getCurrentScope()); - - SimpleQuery query = queryFor(ServiceEndpoint.class); - - query.addCondition("$resource/Profile/Category/text() eq '"+category+"'") - .addCondition("$resource/Profile/Platform/Name/text() eq '"+platformName+"'"); - // .setResult("$resource/Profile/AccessPoint"); - - DiscoveryClient client = clientFor(ServiceEndpoint.class); - - return client.submit(query); - } - - static List queryForGCoreEndpoint(String serviceClass,String serviceName){ - log.debug("Querying for GCore Endpoints [ServiceClass : {} , ServiceName : {}, currentScope : {} ]",serviceClass,serviceName,ScopeUtils.getCurrentScope()); - - - SimpleQuery query =queryFor(GCoreEndpoint.class); - query.addCondition("$resource/Profile/ServiceClass/text() eq '"+serviceClass+"'") - .addCondition("$resource/Profile/ServiceName/text() eq '"+serviceName+"'"); - // .setResult("$resource/Profile/AccessPoint"); - - DiscoveryClient client = clientFor(GCoreEndpoint.class); - - return client.submit(query); - } - - - static T getGCEByHostname(String hostname, Collection toCheckList) { - for(T gc:toCheckList) - if(gc instanceof GCoreEndpoint) { - if(((GCoreEndpoint)gc).profile().endpoints().iterator().next().uri().getHost().equals(hostname)) return gc;} - else if(((ServiceEndpoint)gc).profile().runtime().hostedOn().equals(hostname)) return gc; - - return null; - } - - - static List queryById(String id) { - DiscoveryClient client = client(); - String queryString ="declare namespace ic = 'http://gcube-system.org/namespaces/informationsystem/registry'; "+ - "for $profiles in collection('/db/Profiles')//Document/Data/ic:Profile/Resource "+ - "where $profiles/ID/text() eq '"+id+"'"+ - " return $profiles"; - return client.submit(new QueryBox(queryString)); - - } - - - static String registerService(ServiceEndpoint toRegister) { - RegistryPublisher rp=RegistryPublisherFactory.create(); - Resource r=rp.create(toRegister); - return r.id(); - } - - static String decryptString(String toDecrypt){ - try{ - return StringEncrypter.getEncrypter().decrypt(toDecrypt); - }catch(Exception e) { - throw new RuntimeException("Unable to decrypt.",e); - } - } - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/AbstractCluster.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/AbstractCluster.java new file mode 100644 index 0000000..0f5e33c --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/AbstractCluster.java @@ -0,0 +1,100 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.concurrent.ConcurrentHashMap; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; +import org.gcube.spatial.data.sdi.NetUtils; +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.is.CachedObject; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractCluster> { + + private long objectsTTL; + private ConcurrentHashMap>> scopedCache; + private ISModule retriever; + private String cacheName; + + + public synchronized ArrayList getActualCluster() throws ConfigurationNotFoundException{ + String key=ScopeUtils.getCurrentScope(); + log.info("Getting object from cache{} , key is {} ",cacheName,key); + if((!scopedCache.containsKey(key))||(!scopedCache.get(key).isValid(objectsTTL))) + scopedCache.put(key, new CachedObject>(getLiveControllerCollection())); + return scopedCache.get(key).getTheObject(); + } + + + protected ArrayList getLiveControllerCollection() throws ConfigurationNotFoundException{ + ArrayList toReturn=new ArrayList(); + for(ServiceEndpoint endpoint : retriever.getISInformation()) + try { + toReturn.add(translate(endpoint)); + }catch(Throwable t) { + log.warn("Unable to handle ServiceEndpoint [name {} , ID {}]",endpoint.profile().name(),endpoint.id(),t); + } + Comparator comp=getComparator(); + if(comp!=null)Collections.sort(toReturn, getComparator()); + return toReturn; + } + + protected abstract E translate(ServiceEndpoint e) throws InvalidServiceEndpointException; + + + + + public void invalidate(){ + String key=ScopeUtils.getCurrentScope(); + log.info("Invalidating cache {} under scope {} ",cacheName,key); + if(scopedCache.containsKey(key))scopedCache.get(key).invalidate(); + } + + public void invalidateAll(){ + for(CachedObject obj:scopedCache.values())obj.invalidate(); + } + + + public E getDefaultController() throws ConfigurationNotFoundException { + return getActualCluster().get(0); + } + + protected abstract Comparator getComparator(); + + + public E getControllerByHostName(String hostname) throws ConfigurationNotFoundException { + ArrayList controllerCluster=getLiveControllerCollection(); + log.debug("Looking for {} inside cluster [size = {}]",hostname,controllerCluster.size()); + for(E toCheck:controllerCluster) { + String toCheckHostname=NetUtils.getHostByURL(toCheck.getDescriptor().getBaseEndpoint()); + try { + if(NetUtils.isSameHost(toCheckHostname, hostname)) + return toCheck; + } catch (UnknownHostException e) { + log.warn("Unable to check equality between {} and {} hosts.",toCheckHostname,hostname,e); + } + } + return null; + } + + public AbstractCluster(long objectsTTL, ISModule retriever, String cacheName) { + super(); + this.objectsTTL = objectsTTL; + this.retriever = retriever; + this.cacheName=cacheName; + scopedCache=new ConcurrentHashMap<>(); + } + + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkCluster.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkCluster.java new file mode 100644 index 0000000..f59ea85 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkCluster.java @@ -0,0 +1,51 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.util.ArrayList; +import java.util.Comparator; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceInteractionException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GeoNetworkCluster extends AbstractCluster{ + + private static final Comparator comparator=new Comparator() { + @Override + public int compare(GeoNetworkController o1, GeoNetworkController o2) { + return o1.getDescriptor().getPriority().compareTo(o2.getDescriptor().getPriority()); + } + }; + + + public GeoNetworkCluster(long objectsTTL, ISModule retriever, String cacheName) { + super(objectsTTL, retriever, cacheName); + // TODO Auto-generated constructor stub + } + + @Override + protected Comparator getComparator() { + return comparator; + } + + @Override + protected GeoNetworkController translate(ServiceEndpoint e) throws InvalidServiceEndpointException { + return new GeoNetworkController(e); + } + + @Override + protected ArrayList getLiveControllerCollection() throws ConfigurationNotFoundException { + ArrayList toReturn= super.getLiveControllerCollection(); + try{ + toReturn.get(0).configure(); + }catch(ServiceInteractionException e) { + log.warn("Unexpected exception while configuring GeoNetwork SE [ID : "+toReturn.get(0).getServiceEndpoint().id()+"]",e); + } + return toReturn; + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkController.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkController.java new file mode 100644 index 0000000..537f332 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoNetworkController.java @@ -0,0 +1,285 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.spatial.data.geonetwork.model.Group; +import org.gcube.spatial.data.geonetwork.model.User; +import org.gcube.spatial.data.geonetwork.utils.UserUtils; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.ScopeUtils; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.OutdatedServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceInteractionException; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkClient; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkUtils; +import org.gcube.spatial.data.sdi.engine.impl.is.ISUtils; +import org.gcube.spatial.data.sdi.model.credentials.AccessType; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GeoNetworkController extends GeoServiceController{ + + String scopeUserPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_SCOPE_USER_PREFIX); + String scopePasswordPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_SCOPE_PASSWORD_PREFIX); + String ckanUserPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_CKAN_USER_PREFIX); + String ckanPasswordPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_CKAN_PASSWORD_PREFIX); + String managerUserPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_MANAGER_USER_PREFIX); + String managerPasswordPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_MANAGER_PASSWORD_PREFIX); + String assignedScopePrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_ASSIGNED_SCOPE_PREFIX); + String defaultGroupPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_DEFAULT_GROUP_PREFIX); + String sharedGroupPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_SHARED_GROUP_PREFIX); + String confidentialGroupPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_CONFIDENTIAL_GROUP_PREFIX); + String contextGroupPrefix=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_CONTEXT_GROUP_PREFIX); + String suffixesProperty=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_SUFFIXES); + String priorityProperty=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_PRIORITY); + + private String suffixes=null; + private Integer priority; + + + + + + public GeoNetworkController(ServiceEndpoint serviceEndpoint) throws InvalidServiceEndpointException { + super(serviceEndpoint); + suffixes=getSEProperty(suffixesProperty, true); + priority=Integer.parseInt(getSEProperty(priorityProperty, true)); + } + + + @Override + protected GeoNetworkDescriptor getLiveDescriptor(){ + GeoNetworkDescriptor descriptor=new GeoNetworkDescriptor(); + descriptor.setBaseEndpoint(baseURL); + descriptor.setVersion(version); + String currentScopeName=ScopeUtils.getCurrentScopeName(); + String suffix=getSuffixByScope(currentScopeName); + + + ArrayList availableCredentials=new ArrayList(); + availableCredentials.add(adminAccount); + + Credentials context=new Credentials(getSEProperty(scopeUserPrefix+suffix, true), + getSEProperty(scopePasswordPrefix+suffix, true), AccessType.CONTEXT_USER); + availableCredentials.add(context); + + Credentials ckan=new Credentials(getSEProperty(ckanUserPrefix+suffix, true), + getSEProperty(ckanPasswordPrefix+suffix, true), AccessType.CKAN); + availableCredentials.add(ckan); + + String managerUser=getSEProperty(managerUserPrefix+suffix, false); + if(managerUser!=null) { + Credentials manager=new Credentials(managerUser,getSEProperty(managerPasswordPrefix+suffix, true),AccessType.CONTEXT_MANAGER); + availableCredentials.add(manager); + } + + descriptor.setAccessibleCredentials(availableCredentials); + + descriptor.setPriority(priority); + + + descriptor.setContextGroup(getSEProperty(contextGroupPrefix+suffix, true)); + descriptor.setSharedGroup(getSEProperty(sharedGroupPrefix+suffix, true)); + String confidentialGroup=getSEProperty(confidentialGroupPrefix+suffix, false); + if(confidentialGroup!=null) + descriptor.setConfidentialGroup(confidentialGroup); + + + descriptor.setDefaultGroup(getSEProperty(defaultGroupPrefix+suffix, true)); + descriptor.setPublicGroup(LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_GROUP_ALL)); + + return descriptor; + } + + @Override + protected AccessPoint getTheRightAccessPoint(ServiceEndpoint endpoint) { + for(AccessPoint declaredPoint:endpoint.profile().accessPoints().asCollection()) { + if(declaredPoint.name().equals(LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_SE_ENDPOINT_NAME))) { + return declaredPoint; + } + } + return null; + } + + + @Override + protected void initServiceEndpoint() throws OutdatedServiceEndpointException, ServiceInteractionException { + String scopeName=ScopeUtils.getCurrentScopeName(); + String suffix=getSuffixByScope(scopeName); + if(suffix==null) { + insertScopeInfo(ScopeUtils.getCurrentScope()); + } + } + + + private void insertScopeInfo(String scope) throws OutdatedServiceEndpointException, ServiceInteractionException { + + String scopeName=ScopeUtils.getScopeName(scope); + + log.info("Creating scope {} configuration for GeoNetwork at {} ",scopeName,baseURL); + //Get GN Client + log.debug("Instantiating client as admin.."); + GeoNetworkClient gnClient=new GeoNetworkClient(baseURL,version,adminAccount.getPassword(),adminAccount.getUsername()); + log.debug("Getting Users and groups from instance.."); + Set existingGroups=gnClient.getGroups(); + Set existingUsers=gnClient.getUsers(); + + // Get parent scopes users and groups + // configure parent [mng,ctx] to access [sh] + // configure siblings [mng,ctx] to access [sh] + // configure users [mng,ctx] to access siblings [sh] and parent [ctx,sh] + + ArrayList sharedGroupExternalUsers=new ArrayList(); + ArrayList externalGroupsToAccess=new ArrayList(); + + // gathering users and groups from siblings + log.debug("Getting Siblings information from SE.."); + for(String siblingScope:ISUtils.getSiblingsScopesInResource(serviceEndpoint, scope)) { + for(String username:getUserNamesByScope(siblingScope, true, true, false)) + sharedGroupExternalUsers.add(UserUtils.getByName(existingUsers, username)); + + externalGroupsToAccess.addAll(getGroupIDSByScope(siblingScope, true, false, false)); + } + log.debug("Getting Parents information from SE.."); + // gathering users and groups from parents + for(String parentScope:ScopeUtils.getParentScopes(scope)) { + for(String username:getUserNamesByScope(parentScope, true, true, false)) + sharedGroupExternalUsers.add(UserUtils.getByName(existingUsers, username)); + + externalGroupsToAccess.addAll(getGroupIDSByScope(parentScope, true, true, false)); + } + + + + // Creating groups + + log.debug("Creating groups.."); + String contactMail=LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_MAIL); + int passwordLength=Integer.parseInt(LocalConfiguration.getProperty(LocalConfiguration.GEONETWORK_PASSWORD_LENGTH, "10")); + + // create user & groups [sh,conf,ctx] + Group shared=GeoNetworkUtils.generateGroup(existingGroups, "Shared_"+scopeName, "Shared metadata group for "+scopeName, contactMail); + shared=gnClient.createGroup(shared); + + Group context=GeoNetworkUtils.generateGroup(existingGroups, "Context_"+scopeName, "Context metadata group for "+scopeName, contactMail); + context=gnClient.createGroup(context); + + Group confidential=GeoNetworkUtils.generateGroup(existingGroups, "Confidential_"+scopeName, "Confidential metadata group for "+scopeName, contactMail); + confidential=gnClient.createGroup(context); + + + // Giving access to shared group + log.debug("Giving access to shared group from external scopes.."); + for(User toUpdate:sharedGroupExternalUsers) + gnClient.editUser(toUpdate, Collections.singleton(shared.getId())); + + + log.debug("Creating users.."); + // CKAN -> sh,ctx + User ckan=GeoNetworkUtils.generateUser(existingUsers, passwordLength, "CKAN_"+scopeName); + ckan=gnClient.createUsers(ckan, Arrays.asList(shared.getId(),context.getId())); + + // CTX-USR -> sh,ctx,siblings [sh], parents [sh,ctx] + User ctx=GeoNetworkUtils.generateUser(existingUsers, passwordLength, "Ctx_"+scopeName); + ArrayList ctxUserAccessibleGroups=new ArrayList<>(); + ctxUserAccessibleGroups.addAll(externalGroupsToAccess); + ctxUserAccessibleGroups.add(shared.getId()); + ctxUserAccessibleGroups.add(context.getId()); + ctx=gnClient.createUsers(ctx, ctxUserAccessibleGroups); + + // CTX-MANAGER -> sh,ctx,conf siblings [sh], parents [sh,ctx] + User manager=GeoNetworkUtils.generateUser(existingUsers, passwordLength, "Mng_"+scopeName); + ctxUserAccessibleGroups.add(confidential.getId()); + + + // Setting information in Service Endpoint + log.debug("Inserting configuration in Service Endpoint"); + + String generatedSuffix=generateSuffix(suffixes); + + ArrayList toUpdateProperties=new ArrayList<>(); + toUpdateProperties.add( new Property().nameAndValue(assignedScopePrefix+generatedSuffix, scopeName)); + toUpdateProperties.add( new Property().nameAndValue(scopeUserPrefix+generatedSuffix, ctx.getUsername())); + toUpdateProperties.add( new Property().nameAndValue(scopePasswordPrefix+generatedSuffix, ctx.getPassword()).encrypted(true)); + toUpdateProperties.add( new Property().nameAndValue(ckanUserPrefix+generatedSuffix, ckan.getUsername())); + toUpdateProperties.add( new Property().nameAndValue(ckanPasswordPrefix+generatedSuffix, ckan.getPassword()).encrypted(true)); + toUpdateProperties.add( new Property().nameAndValue(managerUserPrefix+generatedSuffix, manager.getUsername())); + toUpdateProperties.add( new Property().nameAndValue(managerPasswordPrefix+generatedSuffix, manager.getPassword()).encrypted(true)); + toUpdateProperties.add( new Property().nameAndValue(sharedGroupPrefix+generatedSuffix, shared.getId()+"")); + toUpdateProperties.add( new Property().nameAndValue(defaultGroupPrefix+generatedSuffix, shared.getId()+"")); + toUpdateProperties.add( new Property().nameAndValue(confidentialGroupPrefix+generatedSuffix, confidential.getId()+"")); + toUpdateProperties.add( new Property().nameAndValue(contextGroupPrefix+generatedSuffix, context.getId()+"")); + toUpdateProperties.add(new Property().nameAndValue(suffixesProperty, suffixes+","+generatedSuffix)); + accessPoint.properties().addAll(toUpdateProperties); + throw new OutdatedServiceEndpointException("Created scope configuration for "+scopeName); + } + + + private String getSuffixByScope(String scopeName) { + log.debug("looking for scope {} suffix. Available suffixes are : {} ",scopeName,suffixes); + for(String suff:suffixes.split(",")) + if(getSEProperty(assignedScopePrefix+suff, true).equals(scopeName)) return suff; + return null; + } + + + private static String generateSuffix(String existingSuffixes){ + log.debug("Generating suffix, existing are : "+existingSuffixes); + String[] suffixArray=existingSuffixes.split(","); + int maxIndex=0; + for(String suff:suffixArray){ + try{ + int actual=Integer.parseInt(suff); + if(actual>maxIndex) maxIndex=actual; + }catch(Throwable t){ + + } + } + String generated=(maxIndex+1)+""; + log.debug("Generated suffix is : "+generated); + return generated; + } + + + private HashSet getUserNamesByScope(String scope, boolean getContext, boolean getManager, boolean getCKAN){ + HashSet toReturn=new HashSet(); + String scopeName=ScopeUtils.getScopeName(scope); + String scopeSuffix=getSuffixByScope(scopeName); + if(scopeSuffix!=null) { // context might be not configured + if(getContext)toReturn.add(getSEProperty(scopeUserPrefix+scopeSuffix, true)); + if(getManager) { + String scopeManagerUserName=getSEProperty(managerUserPrefix+scopeSuffix, false); + if(scopeManagerUserName!=null) toReturn.add(scopeManagerUserName); + } + if(getCKAN) toReturn.add(getSEProperty(ckanUserPrefix+scopeSuffix, true)); + } + return toReturn; + } + + private HashSet getGroupIDSByScope(String scope, boolean getShared,boolean getContext,boolean getConfidential){ + HashSet toReturn=new HashSet(); + String scopeName=ScopeUtils.getScopeName(scope); + String scopeSuffix=getSuffixByScope(scopeName); + if(scopeSuffix!=null) { + if(getShared)toReturn.add(Integer.parseInt(getSEProperty(sharedGroupPrefix+scopeSuffix,true))); + if(getContext) toReturn.add(Integer.parseInt(getSEProperty(contextGroupPrefix+scopeSuffix, true))); + if(getConfidential) { + String confidentialGroupName=getSEProperty(confidentialGroupPrefix+scopeSuffix,true); + if(confidentialGroupName!=null) toReturn.add(Integer.parseInt(confidentialGroupName)); + } + } + return toReturn; + } + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerCluster.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerCluster.java new file mode 100644 index 0000000..57ad6dc --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerCluster.java @@ -0,0 +1,55 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.util.ArrayList; +import java.util.Comparator; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceInteractionException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; + +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class GeoServerCluster extends AbstractCluster{ + + private static final Comparator comparator=new Comparator() { + @Override + public int compare(GeoServerController o1, GeoServerController o2) { + return o1.getHostedLayersCount().compareTo(o2.getHostedLayersCount()); + } + }; + + + public GeoServerCluster(long objectsTTL, ISModule retriever, String cacheName) { + super(objectsTTL, retriever, cacheName); + // TODO Auto-generated constructor stub + } + + @Override + protected Comparator getComparator() { + return comparator; + } + + + @Override + protected GeoServerController translate(ServiceEndpoint e) throws InvalidServiceEndpointException { + return new GeoServerController(e); + } + + @Override + protected ArrayList getLiveControllerCollection() throws ConfigurationNotFoundException { + ArrayList toReturn= super.getLiveControllerCollection(); + for(GeoServerController controller:toReturn) + try{ + controller.configure(); + }catch(ServiceInteractionException e) { + log.warn("Unexpected exception while configuring GeoServer SE [ID : "+controller.getServiceEndpoint().id()+"]",e); + } + return toReturn; + + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerController.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerController.java new file mode 100644 index 0000000..357bc0d --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServerController.java @@ -0,0 +1,244 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.OutdatedServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISUtils; +import org.gcube.spatial.data.sdi.model.credentials.AccessType; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; + +import it.geosolutions.geoserver.rest.GeoServerRESTManager; +import it.geosolutions.geoserver.rest.GeoServerRESTPublisher; +import it.geosolutions.geoserver.rest.GeoServerRESTReader; +import it.geosolutions.geoserver.rest.manager.GeoServerRESTStoreManager; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GeoServerController extends GeoServiceController{ + + + + //CACHED INFO + private HashMap> dataStores=null; + private HashSet workspaces=null; + private HashSet styles; + private Long hostedLayerCount=0l; + + + public GeoServerController(ServiceEndpoint serviceEndpoint) throws InvalidServiceEndpointException { + super(serviceEndpoint); + } + + @Override + public GeoServerDescriptor getLiveDescriptor() { + GeoServerDescriptor toReturn=new GeoServerDescriptor(); + toReturn.setBaseEndpoint(baseURL); + toReturn.setVersion(version); + + String scopeName=ScopeUtils.getCurrentScopeName(); + + Map pointProperties=accessPoint.propertyMap(); + for(AccessType toLookForType:AccessType.values()) { + String userNameProperty=toLookForType+"_u_"+scopeName; + String passwordProperty=toLookForType+"_u_"+scopeName; + if(pointProperties.containsKey(userNameProperty)) { + String user=pointProperties.get(userNameProperty).value(); + String password=ISUtils.decryptString(pointProperties.get(passwordProperty).value()); + toReturn.getAccessibleCredentials().add(new Credentials(user,password,toLookForType)); + } + } + + toReturn.getAccessibleCredentials().add(adminAccount); + + //Getting scope data spaces + String confidentialProperty="confidential_"+scopeName; + if(pointProperties.containsKey(confidentialProperty)) + toReturn.setConfidentialWorkspace(pointProperties.get(confidentialProperty).value()); + String contextProperty="context_"+scopeName; + if(pointProperties.containsKey(contextProperty)) + toReturn.setContextVisibilityWorkspace(pointProperties.get(contextProperty).value()); + String sharedProperty="shared_"+scopeName; + if(pointProperties.containsKey(sharedProperty)) + toReturn.setSharedWorkspace(pointProperties.get(sharedProperty).value()); + String publicProperty="public_"+scopeName; + if(pointProperties.containsKey(publicProperty)) + toReturn.setPublicWorkspace(pointProperties.get(publicProperty).value()); + + toReturn.setHostedLayersCount(getHostedLayersCount()); + + return toReturn; + } + + @Override + protected AccessPoint getTheRightAccessPoint(ServiceEndpoint endpoint) { + for(AccessPoint declaredPoint:endpoint.profile().accessPoints().asCollection()) { + if(declaredPoint.name().equals(LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_SE_ENDPOINT_NAME))) { + return declaredPoint; + } + } + return null; + } + + + + + // Controller logic + + + @Override + protected void initServiceEndpoint() throws OutdatedServiceEndpointException { + // TODO Auto-generated method stub + } + + + + private long lastDatastoreUpdate=0l; + private long lastWorkspaceUpdate=0l; + private long lastStylesUpdate=0l; + private long lastLayerCountUpdate=0l; + + + public GeoServerRESTReader getReader() throws MalformedURLException{ + return getManager().getReader(); + } + + public GeoServerRESTStoreManager getDataStoreManager() throws IllegalArgumentException, MalformedURLException{ + return getManager().getStoreManager(); + } + + public GeoServerRESTPublisher getPublisher() throws IllegalArgumentException, MalformedURLException{ + return getManager().getPublisher(); + } + + protected GeoServerRESTManager getManager() throws IllegalArgumentException, MalformedURLException{ + return new GeoServerRESTManager(new URL(baseURL), adminAccount.getUsername(), adminAccount.getPassword()); + } + + + public synchronized Set getDatastores(String workspace){ + try { + if(dataStores==null || (System.currentTimeMillis()-lastDatastoreUpdate>LocalConfiguration.getTTL(LocalConfiguration.GEOSERVER_DATASTORE_TTL))){ + log.trace("Loading datastores for {} ",baseURL); + HashMap> toSet=new HashMap<>(); + for(String ws: getWorkspaces()){ + HashSet currentWsDatastores=new HashSet<>(getLiveDatastores(ws)); + log.debug("Found {} ds in {} ws ",currentWsDatastores.size(),ws); + toSet.put(ws, currentWsDatastores); + } + dataStores=toSet; + lastDatastoreUpdate=System.currentTimeMillis(); + } + }catch(Throwable t) { + log.warn("Unable to get Datastores for {} ",baseURL,t); + } + return dataStores.get(workspace); + } + + public synchronized Long getHostedLayersCount(){ + try{ + if(System.currentTimeMillis()-lastLayerCountUpdate>LocalConfiguration.getTTL(LocalConfiguration.GEOSERVER_HOSTED_LAYERS_TTL)){ + log.trace("Loading layer count for {} ",baseURL); + hostedLayerCount=getLiveHostedLayersCount(); + log.debug("Found {} layers ",hostedLayerCount); + lastLayerCountUpdate=System.currentTimeMillis(); + } + }catch(Throwable t){ + log.warn("Unable to get layer count for {} ",baseURL,t); + } + return hostedLayerCount; + } + + + public synchronized Set getStyles(){ + try { + if(styles==null||(System.currentTimeMillis()-lastStylesUpdate>LocalConfiguration.getTTL(LocalConfiguration.GEOSERVER_STYLES_TTL))){ + log.trace("Loading styles for {} ",baseURL); + styles=new HashSet<>(getLiveStyles()); + log.debug("Found {} styles ",styles.size()); + lastStylesUpdate=System.currentTimeMillis(); + } + }catch(Throwable t) { + log.warn("Unable to get Styles for {} ",baseURL,t); + } + return styles; + } + + + public synchronized Set getWorkspaces() { + try { + if(workspaces==null||(System.currentTimeMillis()-lastWorkspaceUpdate>LocalConfiguration.getTTL(LocalConfiguration.GEOSERVER_WORKSPACE_TTL))){ + log.trace("Loading workspaces for {} ",baseURL); + workspaces=new HashSet(getLiveWorkspaces()); + log.debug("Found {} workspaces",workspaces.size()); + lastWorkspaceUpdate=0l; + } + }catch(Throwable t) { + log.warn("Unable to get Workspaces for {} ",baseURL,t); + } + return workspaces; + } + + + public void invalidateWorkspacesCache(){ + lastWorkspaceUpdate=0l; + } + + public void invalidateDatastoresCache(){ + lastDatastoreUpdate=0l; + } + + public void invalidateStylesCache(){ + lastStylesUpdate=0l; + } + + public void invalidateHostedLayersCountCache(){ + lastLayerCountUpdate=0l; + } + + public void onChangedDataStores() { + invalidateDatastoresCache(); + } + public void onChangedLayers() { + invalidateHostedLayersCountCache(); + } + public void onChangedStyles() { + invalidateStylesCache(); + } + public void onChangedWorkspaces() { + invalidateWorkspacesCache(); + invalidateDatastoresCache(); + } + + + + public Set getLiveDatastores(String workspace) throws MalformedURLException { + return new HashSet(getReader().getDatastores(workspace).getNames()); + } + + + public Long getLiveHostedLayersCount() throws MalformedURLException { + return new Long(getReader().getLayers().size()); + } + + + public Set getLiveStyles() throws MalformedURLException { + return new HashSet(getReader().getStyles().getNames()); + } + + + public Set getLiveWorkspaces() throws MalformedURLException { + return new HashSet(getReader().getWorkspaceNames()); + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServiceController.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServiceController.java new file mode 100644 index 0000000..1ffc45b --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/GeoServiceController.java @@ -0,0 +1,99 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.util.Map; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Profile; +import org.gcube.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.common.resources.gcore.common.Platform; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.OutdatedServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceInteractionException; +import org.gcube.spatial.data.sdi.engine.impl.is.CachedObject; +import org.gcube.spatial.data.sdi.engine.impl.is.ISUtils; +import org.gcube.spatial.data.sdi.model.credentials.AccessType; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoServiceDescriptor; +import org.gcube.spatial.data.sdi.model.service.Version; + +import lombok.extern.slf4j.Slf4j; + + + +@Slf4j +public abstract class GeoServiceController { + + protected ServiceEndpoint serviceEndpoint; + protected AccessPoint accessPoint; + protected Map propertyMap; + protected String baseURL; + protected Credentials adminAccount; + protected Version version; + protected CachedObject cachedDescriptor=null; + + public synchronized T getDescriptor() { + if(cachedDescriptor==null||cachedDescriptor.isValid(500)) { + cachedDescriptor=new CachedObject(getLiveDescriptor()); + } + return cachedDescriptor.getTheObject(); + } + + protected abstract T getLiveDescriptor(); + + + protected abstract AccessPoint getTheRightAccessPoint(ServiceEndpoint endpoint); + + public GeoServiceController(ServiceEndpoint serviceEndpoint) throws InvalidServiceEndpointException{ + super(); + log.debug("Instantiating controller for SE {} ",serviceEndpoint); + setServiceEndpoint(serviceEndpoint); + } + + public void onUpdateServiceEndpoint() { + setServiceEndpoint(ISUtils.updateAndWait(serviceEndpoint)); + cachedDescriptor.invalidate(); + } + + protected void setServiceEndpoint(ServiceEndpoint toSet) { + this.serviceEndpoint = toSet; + + Profile profile=serviceEndpoint.profile(); + + accessPoint=getTheRightAccessPoint(serviceEndpoint); + if(accessPoint!=null) { + propertyMap=this.accessPoint.propertyMap(); + baseURL=accessPoint.address(); + adminAccount=new Credentials(accessPoint.username(),ISUtils.decryptString(accessPoint.password()),AccessType.ADMIN); + } + Platform platform=profile.platform(); + version=new Version(platform.version(),platform.minorVersion(),platform.revisionVersion()); + } + + + protected abstract void initServiceEndpoint() throws OutdatedServiceEndpointException, ServiceInteractionException; + + public void configure() throws ServiceInteractionException { + try { + initServiceEndpoint(); + }catch(OutdatedServiceEndpointException e) { + onUpdateServiceEndpoint(); + } + } + + + protected String getSEProperty(String property, boolean mandatory) throws InvalidServiceEndpointException{ + if(!propertyMap.containsKey(property)) + if(mandatory)throw new InvalidServiceEndpointException("Expected property "+property+" was not found."); + else return null; + else { + Property prop=propertyMap.get(property); + if(prop.isEncrypted()) return ISUtils.decryptString(prop.value()); + else return prop.value(); + } + } + + public ServiceEndpoint getServiceEndpoint() { + return serviceEndpoint; + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsCluster.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsCluster.java new file mode 100644 index 0000000..26f65ab --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsCluster.java @@ -0,0 +1,28 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.util.Comparator; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; + +public class ThreddsCluster extends AbstractCluster { + + + public ThreddsCluster(long objectsTTL, ISModule retriever, String cacheName) { + super(objectsTTL, retriever, cacheName); + // TODO Auto-generated constructor stub + } + + @Override + protected ThreddsController translate(ServiceEndpoint e) throws InvalidServiceEndpointException { + return new ThreddsController(e); + } + + @Override + protected Comparator getComparator() { + return null; + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsController.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsController.java new file mode 100644 index 0000000..7eec517 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cluster/ThreddsController.java @@ -0,0 +1,136 @@ +package org.gcube.spatial.data.sdi.engine.impl.cluster; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.data.transfer.library.DataTransferClient; +import org.gcube.data.transfer.library.client.AuthorizationFilter; +import org.gcube.data.transfer.library.faults.DestinationNotSetException; +import org.gcube.data.transfer.library.faults.FailedTransferException; +import org.gcube.data.transfer.library.faults.InitializationException; +import org.gcube.data.transfer.library.faults.InvalidDestinationException; +import org.gcube.data.transfer.library.faults.InvalidSourceException; +import org.gcube.data.transfer.library.faults.SourceNotSetException; +import org.gcube.data.transfer.model.Destination; +import org.gcube.data.transfer.model.DestinationClashPolicy; +import org.gcube.data.transfer.model.PluginInvocation; +import org.gcube.data.transfer.model.TransferTicket; +import org.gcube.data.transfer.model.plugins.thredds.ThreddsCatalog; +import org.gcube.data.transfer.model.plugins.thredds.ThreddsInfo; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.NetUtils; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.OutdatedServiceEndpointException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ThreddsOperationFault; +import org.gcube.spatial.data.sdi.engine.impl.is.ISUtils; +import org.gcube.spatial.data.sdi.engine.impl.metadata.GenericTemplates; +import org.gcube.spatial.data.sdi.model.CatalogDescriptor; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; +import org.glassfish.jersey.client.ClientConfig; + +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class ThreddsController extends GeoServiceController { + + @Override + protected ThreddsDescriptor getLiveDescriptor() { + return new ThreddsDescriptor(version,baseURL,Collections.EMPTY_LIST); + } + + @Override + protected AccessPoint getTheRightAccessPoint(ServiceEndpoint endpoint) { + for(AccessPoint declaredPoint:endpoint.profile().accessPoints().asCollection()) { + if(declaredPoint.name().equals(LocalConfiguration.getProperty(LocalConfiguration.THREDDS_SE_REMOTE_MANAGEMENT_ACCESS))) { + return declaredPoint; + } + } + return null; + } + + public ThreddsController(ServiceEndpoint serviceEndpoint) throws InvalidServiceEndpointException { + super(serviceEndpoint); + } + + @Override + protected void initServiceEndpoint() throws OutdatedServiceEndpointException { + // TODO Auto-generated method stub + + } + + + public ThreddsInfo getThreddsInfo() { + String infoPath=getThreddsInfoPath(); + log.info("Loading thredds info from {} ",infoPath); + WebTarget target=getWebClient().target(infoPath); + return target.request(MediaType.APPLICATION_JSON).get(ThreddsInfo.class); + } + + + private void reloadCatalog() throws IOException { + AccessPoint ap=getTheRightAccessPoint(serviceEndpoint); + NetUtils.makeAuthorizedCall(ap.address(), ap.username(), ISUtils.decryptString(ap.password())); + + } + + private String getHostName() { + return getServiceEndpoint().profile().runtime().hostedOn(); + } + + private String getThreddsInfoPath() { + return "https://"+getHostName()+"/data-transfer-service/gcube/service/Capabilities/pluginInfo/REGISTER_CATALOG"; + } + + private Client getWebClient() { + + return ClientBuilder.newClient(new ClientConfig().register(AuthorizationFilter.class)); + } + + public ThreddsCatalog publishCatalog(File catalogFile, String reference) throws ThreddsOperationFault { + + log.trace("Registering Thredds catalog with reference {} ",reference); + try { + AccessPoint ap=getTheRightAccessPoint(getServiceEndpoint()); + + log.debug("AP address is {} ",ap.address()); + + DataTransferClient client=DataTransferClient.getInstanceByEndpoint(ap.address()); + + Destination dest=new Destination(); + dest.setPersistenceId("thredds"); + dest.setDestinationFileName(reference.replace(" ", "_")+".xml"); + dest.setOnExistingFileName(DestinationClashPolicy.REWRITE); + + PluginInvocation invocation=new PluginInvocation("REGISTER_CATALOG"); + invocation.setParameters(Collections.singletonMap("CATALOG_REFERENCE", reference)); + + log.debug("Sending catalog file to Thredds for registration"); + + client.localFile(catalogFile, dest,invocation); + + log.debug("Catalog registered, calling reload.. "); + + reloadCatalog(); + ThreddsInfo info=getThreddsInfo(); + log.debug("returned ThreddsInfo is {} ",info); + return info.getById(reference); + + } catch (InvalidSourceException | SourceNotSetException | FailedTransferException | InitializationException + | InvalidDestinationException | DestinationNotSetException e) { + throw new ThreddsOperationFault("Unable to register catalog "+reference, e); + }catch(Exception e) { + throw new ThreddsOperationFault("Unable to reload catalog "+reference,e); + } + + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/InvalidServiceEndpointException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/InvalidServiceEndpointException.java new file mode 100644 index 0000000..954a448 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/InvalidServiceEndpointException.java @@ -0,0 +1,38 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults; + +public class InvalidServiceEndpointException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -3683038636163570578L; + + public InvalidServiceEndpointException() { + super(); + // TODO Auto-generated constructor stub + } + + public InvalidServiceEndpointException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + + public InvalidServiceEndpointException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public InvalidServiceEndpointException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public InvalidServiceEndpointException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/OutdatedServiceEndpointException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/OutdatedServiceEndpointException.java new file mode 100644 index 0000000..b3bb49e --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/OutdatedServiceEndpointException.java @@ -0,0 +1,38 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults; + +public class OutdatedServiceEndpointException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -1874537989302709012L; + + public OutdatedServiceEndpointException() { + super(); + // TODO Auto-generated constructor stub + } + + public OutdatedServiceEndpointException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + + public OutdatedServiceEndpointException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public OutdatedServiceEndpointException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public OutdatedServiceEndpointException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ServiceInteractionException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ServiceInteractionException.java new file mode 100644 index 0000000..788fbe9 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ServiceInteractionException.java @@ -0,0 +1,35 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults; + +public class ServiceInteractionException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 4708440073435829969L; + + public ServiceInteractionException() { + // TODO Auto-generated constructor stub + } + + public ServiceInteractionException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public ServiceInteractionException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + public ServiceInteractionException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public ServiceInteractionException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ThreddsOperationFault.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ThreddsOperationFault.java new file mode 100644 index 0000000..6d19096 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/ThreddsOperationFault.java @@ -0,0 +1,35 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults; + +public class ThreddsOperationFault extends ServiceInteractionException { + + /** + * + */ + private static final long serialVersionUID = -4389581996150834969L; + + public ThreddsOperationFault() { + // TODO Auto-generated constructor stub + } + + public ThreddsOperationFault(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public ThreddsOperationFault(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + public ThreddsOperationFault(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public ThreddsOperationFault(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataException.java new file mode 100644 index 0000000..219696a --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataException.java @@ -0,0 +1,37 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults.gn; + +public class MetadataException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -234185402179551404L; + + public MetadataException() { + super(); + // TODO Auto-generated constructor stub + } + + public MetadataException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + + public MetadataException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public MetadataException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public MetadataException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataNotFoundException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataNotFoundException.java new file mode 100644 index 0000000..b3ba6e1 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/faults/gn/MetadataNotFoundException.java @@ -0,0 +1,38 @@ +package org.gcube.spatial.data.sdi.engine.impl.faults.gn; + +public class MetadataNotFoundException extends MetadataException { + + /** + * + */ + private static final long serialVersionUID = 5964532576083669460L; + + public MetadataNotFoundException() { + super(); + // TODO Auto-generated constructor stub + } + + public MetadataNotFoundException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + + public MetadataNotFoundException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public MetadataNotFoundException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public MetadataNotFoundException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN26Extension.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN26Extension.java new file mode 100644 index 0000000..b0e03a6 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN26Extension.java @@ -0,0 +1,16 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import it.geosolutions.geonetwork.GN26Client; + +public class GN26Extension extends GN26Client { + + public GN26Extension(String serviceURL) { + super(serviceURL); + } + + public GN26Extension(String serviceURL, String username, String password) { + super(serviceURL, username, password); + super.connection=new HttpUtilsExtensions(username, password); + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN3Extension.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN3Extension.java new file mode 100644 index 0000000..3886dbb --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GN3Extension.java @@ -0,0 +1,17 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import it.geosolutions.geonetwork.GN3Client; + +public class GN3Extension extends GN3Client { + + public GN3Extension(String serviceURL) { + super(serviceURL); + // TODO Auto-generated constructor stub + } + + public GN3Extension(String serviceURL, String username, String password) { + super(serviceURL, username, password); + super.connection=new HttpUtilsExtensions(username, password); + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNClientExtension.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNClientExtension.java new file mode 100644 index 0000000..ea2a999 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNClientExtension.java @@ -0,0 +1,177 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import java.io.File; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.gcube.spatial.data.geonetwork.model.Group; +import org.gcube.spatial.data.geonetwork.model.User; +import org.gcube.spatial.data.geonetwork.model.User.Profile; +import org.gcube.spatial.data.geonetwork.utils.GroupUtils; +import org.gcube.spatial.data.geonetwork.utils.UserUtils; +import org.jdom.Element; + +import it.geosolutions.geonetwork.GNClient; +import it.geosolutions.geonetwork.exception.GNLibException; +import it.geosolutions.geonetwork.exception.GNServerException; +import it.geosolutions.geonetwork.op.gn3.GN3MetadataGetInfo.MetadataInfo; +import it.geosolutions.geonetwork.util.GNInsertConfiguration; +import it.geosolutions.geonetwork.util.GNPrivConfiguration; +import it.geosolutions.geonetwork.util.GNSearchRequest; +import it.geosolutions.geonetwork.util.GNSearchResponse; +import it.geosolutions.geonetwork.util.HTTPUtils; + +public class GNClientExtension implements GNClient { + + private GNClient client; + + private ServerAccess access; + + public GNClientExtension(ServerAccess access) { + this.access=access; + + if(access.getVersion().getMajor()==2) + client=new GN26Extension(access.getGnServiceURL(), access.getUser(), access.getPassword()); + else if(access.getVersion().getMajor()==3) + client = new GN3Extension(access.getGnServiceURL(), access.getUser(), access.getPassword()); + else throw new RuntimeException("INVALID SERVER ACCESS "+access); + + + } + + public void createGroup(String name, String description, String mail,Integer id)throws GNLibException, GNServerException { + GNMetadataAdminExtension.createGroup(getConnection(), access, name, description, mail, id); + } + + + public Set getGroups() throws GNLibException, GNServerException{ + String groupResponse=GNMetadataAdminExtension.getGroups(getConnection(), access); + if(access.getVersion().getMajor()==2) + return GroupUtils.parseGroupXMLResponse(groupResponse); + else return GroupUtils.parseUserJSONResponse(groupResponse); + } + + + + public Set getUsers() throws GNLibException, GNServerException{ + String userResponse=GNMetadataAdminExtension.getUsers(getConnection(), access); + if(access.getVersion().getMajor()==2) + return UserUtils.parseUserXMLResponse(userResponse); + else return UserUtils.parseUserJSONResponse(userResponse); + } + + + public void createUser(String name, String password, Profile profile, Collection groups) throws GNServerException, GNLibException{ + GNMetadataAdminExtension.createUser(getConnection(), access, name, password, profile, groups); + } + + public void editUser(User toAdd, Collection groups) throws GNServerException,GNLibException{ + Set alreadyAddedGroups=getGroupsByUser(toAdd.getId()); + alreadyAddedGroups.addAll(groups); + GNMetadataAdminExtension.editUser(getConnection(), access, toAdd, alreadyAddedGroups); + } + + public Set getGroupsByUser(Integer userId) throws GNLibException, GNServerException{ + return UserUtils.parseGroupsByUserResponse(GNMetadataAdminExtension.getUserGroupd(getConnection(), access, userId)); + } + + public void assignOwnership(List toTransferIds,Integer targetUserId,Integer targetGroupId) throws GNServerException, GNLibException{ + try{ + GNMetadataAdminExtension.selectMeta(getConnection(), access, toTransferIds); + GNMetadataAdminExtension.assignMassiveOwnership(getConnection(), access, targetUserId, targetGroupId); + }finally{ + GNMetadataAdminExtension.clearMetaSelection(getConnection(), access); + } + } + + public String getPossibleOwnershipTransfer(Integer userId) throws GNServerException, GNLibException{ + return GNMetadataAdminExtension.allowedOwnershipTransfer(getConnection(), access, userId); + } + public String getMetadataOwners() throws GNServerException, GNLibException{ + return GNMetadataAdminExtension.metadataOwners(getConnection(), access); + } + + public void transferOwnership(Integer sourceUserId,Integer sourceGroupId,Integer targetUserId,Integer targetGroupId) throws GNServerException, GNLibException{ + GNMetadataAdminExtension.transferOwnership(getConnection(), access, sourceUserId, sourceGroupId, targetUserId, targetGroupId); + } + + + + //***************************** OVERRIDES + + + @Override + public boolean ping() { + return client.ping(); + } + + @Override + public long insertMetadata(GNInsertConfiguration cfg, File metadataFile) throws GNLibException, GNServerException { + return client.insertMetadata(cfg, metadataFile); + } + + @Override + public long insertRequest(File requestFile) throws GNLibException, GNServerException { + return client.insertRequest(requestFile); + } + + @Override + public void setPrivileges(long metadataId, GNPrivConfiguration cfg) throws GNLibException, GNServerException { + client.setPrivileges(metadataId, cfg); + } + + @Override + public GNSearchResponse search(GNSearchRequest searchRequest) throws GNLibException, GNServerException { + return client.search(searchRequest); + } + + @Override + public GNSearchResponse search(File fileRequest) throws GNLibException, GNServerException { + return client.search(fileRequest); + } + + @Override + public Element get(Long id) throws GNLibException, GNServerException { + return client.get(id); + } + + @Override + public Element get(String uuid) throws GNLibException, GNServerException { + return client.get(uuid); + } + + @Override + public void deleteMetadata(long id) throws GNLibException, GNServerException { + client.deleteMetadata(id); + } + + @Override + public void updateMetadata(long id, File metadataFile) throws GNLibException, GNServerException { + client.updateMetadata(id, metadataFile); + } + + @Override + public void updateMetadata(long id, File metadataFile, String encoding) throws GNLibException, GNServerException { + client.updateMetadata(id, metadataFile,encoding); + } + + @Override + public MetadataInfo getInfo(Long id) throws GNLibException, GNServerException { + return client.getInfo(id); + } + + @Override + public MetadataInfo getInfo(String uuid) throws GNLibException, GNServerException { + return client.getInfo(uuid); + } + + @Override + public HTTPUtils getConnection() throws GNLibException { + return client.getConnection(); + } + + +} + + diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNMetadataAdminExtension.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNMetadataAdminExtension.java new file mode 100644 index 0000000..86a6b42 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GNMetadataAdminExtension.java @@ -0,0 +1,309 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.util.Collection; +import java.util.List; + +import org.gcube.spatial.data.geonetwork.model.User; +import org.gcube.spatial.data.geonetwork.model.User.Profile; +import org.jdom.Element; +import org.jdom.output.Format; +import org.jdom.output.XMLOutputter; +import org.json.JSONArray; +import org.json.JSONObject; + +import it.geosolutions.geonetwork.exception.GNLibException; +import it.geosolutions.geonetwork.exception.GNServerException; +import it.geosolutions.geonetwork.util.HTTPUtils; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GNMetadataAdminExtension { + + private final static XMLOutputter outputter = new XMLOutputter(Format.getCompactFormat()); + + private final static String USER_3="/srv/api/0.1/users"; + private final static String GROUPS_3="/srv/api/0.1/groups"; + + + private final static String CREATE_GROUP_METHOD_2="/srv/en/group.update"; + + private final static String GROUP_LIST_METHOD="/srv/en/xml.group.list"; + private final static String USER_LIST_METHOD_2="/srv/en/xml.user.list"; + + private final static String CREATE_USER_METHOD="/srv/en/user.update"; + private final static String GET_GROUPS_BY_USER="/srv/en/xml.usergroups.list"; + private final static String METADATA_SELECT="/srv/en/metadata.select"; + private final static String ASSIGN_MASSIVE_OWNERSHIP="/srv/en/metadata.massive.newowner"; + private final static String AVAILABLE_OWNERSHIP="/srv/en/xml.ownership.groups"; + private final static String METADATA_OWNERS="/srv/en/xml.ownership.editors"; + private final static String TRANSFER_OWNSERSHIP="/srv/en/xml.ownership.transfer"; + + + + public static String allowedOwnershipTransfer(HTTPUtils connection, ServerAccess access, Integer userId) throws GNServerException, GNLibException{ + log.debug("Getting available ownership transfer for user "+userId); + Element request=new Element("request"); + request.addContent(new Element("id").setText(userId+"")); + return gnCall(connection,access,request,AVAILABLE_OWNERSHIP); + } + + public static String metadataOwners(HTTPUtils connection, ServerAccess access) throws GNServerException, GNLibException{ + log.debug("Getting metadata owners"); + Element request=new Element("request"); + return gnCall(connection,access,request,METADATA_OWNERS); + } + + public static String selectMeta (HTTPUtils connection, ServerAccess access, List toSelectIds) throws GNServerException, GNLibException{ + log.debug("Massive metadata selection.."); + Element request=buildSelectMetadata(toSelectIds); + return gnCall(connection,access,request,METADATA_SELECT); + } + + public static String clearMetaSelection(HTTPUtils connection, ServerAccess access) throws GNServerException, GNLibException{ + log.debug("Massive metadata selection.."); + Element request=buildClearMetaSelection(); + return gnCall(connection,access,request,METADATA_SELECT); + } + + public static String assignMassiveOwnership(HTTPUtils connection, ServerAccess access,Integer userId, Integer groupId) throws GNServerException, GNLibException{ + log.debug("Assign massive ownership to u:{},g:{} ",userId,groupId); + Element request=new Element("request"); + request.addContent(new Element("user").setText(userId+"")); + request.addContent(new Element("group").setText(groupId+"")); + return gnCall(connection,access,request,ASSIGN_MASSIVE_OWNERSHIP); + } + + + public static String transferOwnership(HTTPUtils connection, ServerAccess access,Integer sourceUserId, Integer sourceGroupId,Integer destUserId, Integer destGroupId) throws GNServerException, GNLibException{ + log.debug("Transfering ownership from u:{},g:{} to u:{},g:{}",sourceUserId,sourceGroupId,destUserId,destGroupId); + Element request=new Element("request"); + request.addContent(new Element("sourceUser").setText(sourceUserId+"")); + request.addContent(new Element("sourceGroup").setText(sourceGroupId+"")); + request.addContent(new Element("targetUser").setText(destUserId+"")); + request.addContent(new Element("targetGroup").setText(destGroupId+"")); + return gnCall(connection,access,request,TRANSFER_OWNSERSHIP); + } + + public static String editUser(HTTPUtils connection,ServerAccess access,User toAdd, Collection groups)throws GNLibException, GNServerException { + log.debug("Coupling user {} to groups {} ",toAdd,groups); + + Object request=null; + String method=null; + if(access.getVersion().getMajor()==2){ + Element requestEl = new Element("request"); + requestEl.addContent(new Element("operation").setText("editinfo")); + requestEl.addContent(new Element("id").setText(toAdd.getId()+"")); + requestEl.addContent(new Element("username").setText(toAdd.getUsername())); + requestEl.addContent(new Element("password").setText(toAdd.getPassword())); + requestEl.addContent(new Element("profile").setText(toAdd.getProfile().name())); + if(groups!=null){ + for(Integer groupId:groups)requestEl.addContent(new Element("groups").setText(groupId+"")); + } + request=requestEl; + method=CREATE_USER_METHOD; + }else{ + + try{ + JSONObject object=new JSONObject(); + object.put("username", toAdd.getUsername()); + object.put("password", toAdd.getPassword()); + object.put("profile",toAdd.getProfile().toString()); + object.put("enabled", true); + if(groups!=null){ + JSONArray array=new JSONArray(); + for(Integer groupId:groups) array.put(groupId+""); + object.put("groupsReviewer", array); + } + request= object; + method=USER_3+"/"+toAdd.getId(); + }catch(Exception e){ + throw new GNLibException("Unabel to create JSON request for group creation ", e); + } + // request=buildUpdateUserRequest(toAdd.getId(), toAdd.getUsername(), toAdd.getPassword(), toAdd.getProfile(), groups); + } + + return gnCall(connection,access,request,method); + } + + public static String getUserGroupd(HTTPUtils connection,ServerAccess access,Integer userId)throws GNLibException, GNServerException { + log.debug("Getting user groups.."); + return gnCall(connection,access,new Element("request").addContent(new Element("id").setText(userId+"")),GET_GROUPS_BY_USER); + } + + + public static String getUsers(HTTPUtils connection, ServerAccess access) throws GNServerException, GNLibException{ + log.debug("Requesting users.."); + + + if(access.getVersion().getMajor()==2){ + return gnCall(connection,access,new Element("request"),USER_LIST_METHOD_2); + }else { + String toReturn=gnCall(connection,access,null,USER_3); + return toReturn; + } + } + + public static String createUser(HTTPUtils connection, ServerAccess access, String name, String password, Profile profile, Collection groups ) throws GNServerException, GNLibException{ + + log.debug("Requesting users.."); + log.debug("Compiling admin request document"); + + Object userRequest=null; + String method=null; + + if(access.getVersion().getMajor()==2){ + Element request = new Element("request"); + request.addContent(new Element("operation").setText("newuser")); + request.addContent(new Element("username").setText(name)); + request.addContent(new Element("password").setText(password)); + request.addContent(new Element("profile").setText(profile.name())); + if(groups!=null){ + for(Integer groupId:groups)request.addContent(new Element("groups").setText(groupId+"")); + } + userRequest=request; + method=CREATE_USER_METHOD; + }else{ + try{ + JSONObject object=new JSONObject(); + object.put("username", name); + object.put("password", password); + object.put("profile",profile); + object.put("enabled", true); + if(groups!=null){ + JSONArray array=new JSONArray(); + for(Integer groupId:groups) array.put(groupId+""); + object.put("groupsReviewer", array); + } + userRequest= object; + method=USER_3; + }catch(Exception e){ + throw new GNLibException("Unabel to create JSON request for group creation ", e); + } + } + + + + return gnCall(connection,access,userRequest,method); + } + + + public static String createGroup(HTTPUtils connection, ServerAccess access, String groupName, String groupDescription, String groupMail, Integer groupId) throws GNLibException, GNServerException { + log.debug(String.format("Creating group [Name : %s, Description : %s, Mail : %s ",groupName,groupDescription,groupMail)); + + Object adminRequest=null; + String method=null; + if(access.getVersion().getMajor()==2){ + Element request = new Element("request"); + request.addContent(new Element("name").setText(groupName)); + request.addContent(new Element("description").setText(groupDescription)); + request.addContent(new Element("email").setText(groupMail)); + + adminRequest= request; + method=CREATE_GROUP_METHOD_2; + } else { + try{ + JSONObject object=new JSONObject(); + object.put("name", groupName); + object.put("description", groupDescription); + object.put("email", groupMail); + object.put("id",groupId); + adminRequest= object; + method=GROUPS_3; + }catch(Exception e){ + throw new GNLibException("Unabel to create JSON request for group creation ", e); + } + } + + + + + return gnCall(connection, access, adminRequest,method); + } + + + public static String getGroups(HTTPUtils connection,ServerAccess access) throws GNServerException, GNLibException{ + log.debug("Requesting groups.."); + Object request=null; + String method=null; + if(access.getVersion().getMajor()==2){ + request=new Element("request"); + method=GROUP_LIST_METHOD; + }else{ + method=GROUPS_3; + } + return gnCall(connection, access, request,method); + } + + + private static String gnCall(HTTPUtils connection,ServerAccess access, final Object gnRequest,String toInvokeMethod)throws GNServerException, GNLibException { + + String serviceURL = access.getGnServiceURL() + toInvokeMethod; + try{ + String result=gnRequest==null?gnGET(connection,serviceURL):gnPut(connection, serviceURL, gnRequest); + int httpStatus=connection.getLastHttpStatus(); + if(httpStatus<200 ||httpStatus>=300) + throw new GNServerException("Error executing call, received "+httpStatus+". Result is "+result); + return result; + }catch(MalformedURLException e){ + throw new GNServerException("Unable to send request ",e); + }catch(UnsupportedEncodingException e){ + throw new GNServerException("Unable to send request ", e); + }catch(GNLibException e){ + throw e; + } + } + + + + + + + + + + + private static Element buildSelectMetadata(List toSelectIds){ + log.debug("building selection request"); + Element request = new Element("request"); + if(toSelectIds!=null){ + for(Long id:toSelectIds) request.addContent(new Element("id").setText(id.toString())); + request.addContent(new Element("selected").setText("add")); + }else request.addContent(new Element("selected").setText("add-all")); + return request; + } + + private static Element buildClearMetaSelection(){ + log.debug("building selection request"); + Element request = new Element("request"); + request.addContent(new Element("selected").setText("remove-all")); + return request; + } + + private static String gnPut(HTTPUtils connection, String serviceURL, final Object gnRequest) throws UnsupportedEncodingException, GNLibException, GNServerException { + + if(gnRequest instanceof Element){ + + String s = outputter.outputString((Element)gnRequest); + + connection.setIgnoreResponseContentOnSuccess(false); + String res = connection.postXml(serviceURL, s); + + return res; + } else if (gnRequest instanceof JSONObject){ + String s=((JSONObject) gnRequest).toString(); + connection.setIgnoreResponseContentOnSuccess(false); + return ((HttpUtilsExtensions)connection).putJSON(serviceURL, s); + } else throw new GNLibException("Unable to manage request element "+gnRequest); + } + + + private static String gnGET(HTTPUtils connection, String serviceURL) throws MalformedURLException, GNServerException { + + connection.setIgnoreResponseContentOnSuccess(false); + String res = ((HttpUtilsExtensions)connection).getJSON(serviceURL); + + return res; + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkClient.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkClient.java new file mode 100644 index 0000000..ba52765 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkClient.java @@ -0,0 +1,179 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import java.io.File; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; + +import org.gcube.spatial.data.geonetwork.model.Group; +import org.gcube.spatial.data.geonetwork.model.User; +import org.gcube.spatial.data.geonetwork.model.faults.MissingServiceEndpointException; +import org.gcube.spatial.data.geonetwork.utils.GroupUtils; +import org.gcube.spatial.data.geonetwork.utils.UserUtils; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceInteractionException; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; +import org.gcube.spatial.data.sdi.model.service.Version; + +import it.geosolutions.geonetwork.exception.GNLibException; +import it.geosolutions.geonetwork.exception.GNServerException; +import it.geosolutions.geonetwork.util.GNInsertConfiguration; +import it.geosolutions.geonetwork.util.GNPriv; +import it.geosolutions.geonetwork.util.GNPrivConfiguration; +import it.geosolutions.geonetwork.util.GNSearchRequest; +import it.geosolutions.geonetwork.util.GNSearchResponse; +import lombok.extern.slf4j.Slf4j; + +@Slf4j + +public class GeoNetworkClient { + + private ServerAccess access; + private GNClientExtension theClient=null; + private GeoNetworkDescriptor descriptor; + + + public GeoNetworkClient(String baseURL, Version version, String password, String user, GeoNetworkDescriptor descriptor) { + this(baseURL,version,password,user); + theClient=new GNClientExtension(access); + } + public GeoNetworkClient(String baseURL, Version version, String password, String user) { + super(); + this.access=new ServerAccess(baseURL,version,password,user); + } + + //************************************** GROUPS AND USERS + + + public Group createGroup(Group group)throws ServiceInteractionException{ + try { + theClient.createGroup(group.getName(), group.getDescription(), group.getMail(),group.getId()); + long submitTime=System.currentTimeMillis(); + + long timeout=LocalConfiguration.getTTL(LocalConfiguration.GEONETWORK_UPDATE_TIMEOUT); + long wait=LocalConfiguration.getTTL(LocalConfiguration.GEONETWORK_UPDATE_WAIT); + + log.debug("Waiting for created group to be available, timeout is {} ",timeout); + //wait for update to be available + Group created=null; + do{ + try{Thread.sleep(wait);}catch(InterruptedException e){} + created=GroupUtils.getByName(theClient.getGroups(), group.getName()); + }while(created==null && (System.currentTimeMillis()-submitTime>=timeout)); + + if(created==null) { + log.error("GN Update timeout {}ms reached. Group {} not created.",timeout,group); + throw new ServiceInteractionException("Reached timeout while creating group "+group.getName()); + } + return created; + }catch(ServiceInteractionException e) { + throw e; + }catch(Throwable t) { + throw new ServiceInteractionException("Unable to create group. ",t); + } + } + + public Set getGroups() throws ServiceInteractionException { + try { + return theClient.getGroups(); + } catch (Exception e) { + throw new ServiceInteractionException("Unable to get Groups from "+access,e); + } + } + + + public Set getUsers() throws ServiceInteractionException{ + try { + return theClient.getUsers(); + } catch (Exception e) { + throw new ServiceInteractionException("Unable to get Users from "+access,e); + } + } + + + public User createUsers(User user, Collection groups) throws ServiceInteractionException { + try{ + theClient.createUser(user.getUsername(), user.getPassword(), user.getProfile(), groups); + + long submitTime=System.currentTimeMillis(); + + long timeout=LocalConfiguration.getTTL(LocalConfiguration.GEONETWORK_UPDATE_TIMEOUT); + long wait=LocalConfiguration.getTTL(LocalConfiguration.GEONETWORK_UPDATE_WAIT); + log.debug("Waiting for created group to be available, timeout is {} ",timeout); + //wait for update to be available + User created=null; + do{ + try{Thread.sleep(wait);}catch(InterruptedException e){} + created=UserUtils.getByName(theClient.getUsers(), user.getUsername()); + }while(created==null && (System.currentTimeMillis()-submitTime>=timeout)); + if(created==null) { + log.error("GN Update timeout {}ms reached. User {} not created.",timeout,user.getUsername()); + throw new ServiceInteractionException("Reached timeout while creating user "+user.getUsername()); + } + return created; + }catch(ServiceInteractionException e) { + throw e; + }catch(Throwable t) { + throw new ServiceInteractionException("Unable to create User. ",t); + } + + } + + public void editUser(User toEdit, Collection toAddGroups) throws ServiceInteractionException{ + try{ + Set alreadyAddedGroups=getGroupsByUser(toEdit.getId()); + alreadyAddedGroups.addAll(toAddGroups); + GNMetadataAdminExtension.editUser(theClient.getConnection(), access, toEdit, alreadyAddedGroups); + }catch(Throwable t) { + throw new ServiceInteractionException("Unable to create User. ",t); + } + } + public Set getGroupsByUser(Integer userId) throws ServiceInteractionException{ + try{ + return UserUtils.parseGroupsByUserResponse(GNMetadataAdminExtension.getUserGroupd(theClient.getConnection(), access, userId)); + }catch(Throwable t) { + throw new ServiceInteractionException(t); + } + } + + + //******************************* METADATA INSERTION + + + public long insertMetadata(String category, String styleSheet,boolean validate, int group, boolean makePublic, File metadataFile) throws GNLibException, GNServerException { + GNInsertConfiguration configuration=new GNInsertConfiguration(); + configuration.setCategory(category); + configuration.setStyleSheet(styleSheet); + configuration.setValidate(validate); + configuration.setGroup(group+""); + log.debug("Inserting with {} ",configuration); + long toReturnId=theClient.insertMetadata(configuration, metadataFile); + GNPrivConfiguration privileges=(makePublic?getPrivileges(group, + Integer.parseInt(descriptor.getPublicGroup())):getPrivileges(group)); + + log.debug("Setting privileges {} on {} ",privileges,toReturnId); + + theClient.setPrivileges(toReturnId, privileges); + return toReturnId; + } + + private static final GNPrivConfiguration getPrivileges(Integer...groups ) { + GNPrivConfiguration toReturn=new GNPrivConfiguration(); + for(Integer group:groups) + toReturn.addPrivileges(group, EnumSet.of(GNPriv.DOWNLOAD,GNPriv.DYNAMIC,GNPriv.EDITING,GNPriv.FEATURED,GNPriv.NOTIFY,GNPriv.VIEW)); + return toReturn; + } + + + public void updateMeta(long toUpdateMetaId,File metadataFile) throws GNLibException, GNServerException{ + log.debug("Updating metadata by ID "+toUpdateMetaId); + theClient.updateMetadata(toUpdateMetaId, metadataFile); + } + + + //********************************* SEARCH + public GNSearchResponse query(GNSearchRequest request) throws GNLibException, GNServerException{ + return theClient.search(request); + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkUtils.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkUtils.java new file mode 100644 index 0000000..c1152fb --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/GeoNetworkUtils.java @@ -0,0 +1,87 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.gcube.spatial.data.geonetwork.model.Group; +import org.gcube.spatial.data.geonetwork.model.User; +import org.gcube.spatial.data.geonetwork.model.User.Profile; +import org.gcube.spatial.data.geonetwork.utils.StringUtils; +import org.gcube.spatial.data.sdi.engine.impl.faults.gn.MetadataNotFoundException; + +import it.geosolutions.geonetwork.exception.GNLibException; +import it.geosolutions.geonetwork.exception.GNServerException; +import it.geosolutions.geonetwork.util.GNSearchRequest; +import it.geosolutions.geonetwork.util.GNSearchRequest.Config; +import it.geosolutions.geonetwork.util.GNSearchResponse; +import it.geosolutions.geonetwork.util.GNSearchResponse.GNMetadata; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GeoNetworkUtils { + + + /** + * Adds a suffix to groupName if needed + * + * @param existing + * @param groupName + * @return + */ + public static Group generateGroup(Set existing, String groupName, String description, String contactMail){ + Set existingNames=new HashSet<>(); + int maxId=0; + for(Group g:existing){ + existingNames.add(g.getName()); + if(maxId existing, Integer passwordLength, String username){ + Set existingNames=new HashSet<>(); + for(User g:existing)existingNames.add(g.getUsername()); + + String toUseUserName=clashSafeString(username,existingNames); + + return new User(0, // NB will be updated when creating it.. + toUseUserName, + StringUtils.generateRandomString(passwordLength),Profile.RegisteredUser); + } + + + public static String clashSafeString(String originalString,Set existingSet) { + String toReturn=originalString; + int suffix=1; + while(existingSet.contains(toReturn)) { + toReturn=originalString+"_"+suffix; + suffix++; + } + return toReturn; + } + + + + public static long getIDByUUID(GeoNetworkClient client, String uuid) throws MetadataNotFoundException, GNLibException, GNServerException { + log.debug("Looking for uuid : {} ",uuid); + + GNSearchRequest req=new GNSearchRequest(); + req.addParam(GNSearchRequest.Param.any,uuid); + req.addConfig(Config.similarity, "1"); + + GNSearchResponse resp=client.query(req); + + Iterator iterator=resp.iterator(); + log.debug("Got {} hits for UUID {}",resp.getCount(),uuid); + while(iterator.hasNext()){ + GNMetadata meta=iterator.next(); + if(meta.getUUID().equals(uuid)) return meta.getId(); + } + throw new MetadataNotFoundException("Unable to find metadata from uuid "+uuid); + } +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/HttpUtilsExtensions.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/HttpUtilsExtensions.java new file mode 100644 index 0000000..5a1ccb3 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/HttpUtilsExtensions.java @@ -0,0 +1,281 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.methods.RequestEntity; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.io.IOUtils; + +import it.geosolutions.geonetwork.exception.GNServerException; +import it.geosolutions.geonetwork.util.HTTPUtils; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HttpUtilsExtensions extends HTTPUtils { + + + private final static String JSON_CONTENT_TYPE="application/json"; + private final static String XML_CONTENT_TYPE="text/xml"; + + + + + + public HttpUtilsExtensions() { + super(); + // TODO Auto-generated constructor stub + } + + String username; + String pw; + private int lastHttpStatus=0; + + public HttpUtilsExtensions(String userName, String password) { + super(userName, password); + this.username=userName; + this.pw=password; + } + + + HttpClient client=new HttpClient(); + + + public String getJSON(String url) throws MalformedURLException, GNServerException { + + GetMethod httpMethod = null; + try { + setAuth(client, url, username, pw); + + // creating call + + httpMethod = new GetMethod(url); + + //only actual difference from superclass + httpMethod.setRequestHeader("Accept", JSON_CONTENT_TYPE); + + + client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); + lastHttpStatus = client.executeMethod(httpMethod); + if(lastHttpStatus == HttpStatus.SC_OK) { + InputStream is = httpMethod.getResponseBodyAsStream(); + String response = IOUtils.toString(is); + if(response.trim().length()==0) { // sometime gs rest fails + log.warn("ResponseBody is empty"); + return null; + } else { + return response; + } + } else { + log.info("("+lastHttpStatus+") " + HttpStatus.getStatusText(lastHttpStatus) + " -- " + url ); + throw new GNServerException("ERROR from calling "+url, lastHttpStatus); + } + } catch (ConnectException e) { + log.info("Couldn't connect to ["+url+"]"); + } catch (IOException e) { + log.info("Error talking to ["+url+"]", e); + } finally { + if(httpMethod != null) + httpMethod.releaseConnection(); + } + + return null; + } + + + public String putJSON(String url, String content) throws UnsupportedEncodingException, GNServerException{ + PutMethod httpMethod=null; + try { + setAuth(client, url, username, pw); + httpMethod=new PutMethod(url); + client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); + httpMethod.setRequestEntity(new StringRequestEntity(content,JSON_CONTENT_TYPE,"UTF-8")); + + + //only actual difference from superclass + httpMethod.setRequestHeader("Accept", JSON_CONTENT_TYPE); + + + lastHttpStatus = client.executeMethod(httpMethod); + + + + if((lastHttpStatus>=200)&&(lastHttpStatus<300)){ + //OK responses + log.debug("HTTP "+ httpMethod.getStatusText() + " <-- " + url); + InputStream responseStream=httpMethod.getResponseBodyAsStream(); + if(super.isIgnoreResponseContentOnSuccess()||responseStream==null) + return ""; + return IOUtils.toString(responseStream); + }else{ + //NOT OK responses + String badresponse = IOUtils.toString(httpMethod.getResponseBodyAsStream()); + String message = super.getGeoNetworkErrorMessage(badresponse); + + log.warn("Bad response: "+lastHttpStatus + + " " + httpMethod.getStatusText() + + " -- " + httpMethod.getName() + + " " +url + + " : " + + message + ); + + log.debug("GeoNetwork response:\n"+badresponse); + throw new GNServerException("ERROR from calling "+url+". Message is "+badresponse, lastHttpStatus); + } + + } catch (ConnectException e) { + log.info("Couldn't connect to ["+url+"]"); + return null; + } catch (IOException e) { + log.error("Error talking to " + url + " : " + e.getLocalizedMessage()); + return null; + } finally { + if(httpMethod != null) + httpMethod.releaseConnection(); + } + } + + + + + protected void setAuth(HttpClient client, String url, String username, String pw) throws MalformedURLException { + URL u = new URL(url); + if(username != null && pw != null) { + Credentials defaultcreds = new UsernamePasswordCredentials(username, pw); + client.getState().setCredentials(new AuthScope(u.getHost(), u.getPort()), defaultcreds); + client.getParams().setAuthenticationPreemptive(true); // if we have the credentials, force them! + } else { + log.trace("Not setting credentials to access to " + url); + } + } + + private void reset(){ + // resets stats in subclass + this.lastHttpStatus=0; + } + + private boolean isReset(){ + return lastHttpStatus==0; + } + + @Override + public int getLastHttpStatus() { + if(isReset()) + return super.getLastHttpStatus(); + else return this.lastHttpStatus; + } + + + // OVERRIDING superclass methods in order to discriminate on lastHttpStatus member + + @Override + public boolean delete(String arg0) { + reset(); + return super.delete(arg0); + } + + @Override + public boolean exists(String arg0) { + reset(); + return super.exists(arg0); + } + + @Override + public String get(String arg0) throws MalformedURLException { + reset(); + return super.get(arg0); + } + + @Override + public boolean httpPing(String arg0) { + reset(); + return super.httpPing(arg0); + } + + @Override + public String post(String arg0, String arg1, String arg2, String arg3) { + reset(); + return super.post(arg0, arg1, arg2, arg3); + } + + @Override + public String post(String url, File file, String contentType) { + reset(); + return super.post(url, file, contentType); + } + + @Override + public String post(String url, InputStream content, String contentType) { + reset(); + return super.post(url, content, contentType); + } + + @Override + public String post(String url, RequestEntity requestEntity) { + reset(); + return super.post(url, requestEntity); + } + + @Override + public String post(String url, String content, String contentType) { + reset(); + return super.post(url, content, contentType); + } + + @Override + public String postXml(String url, InputStream content) { + reset(); + return super.postXml(url, content); + } + + @Override + public String postXml(String url, String content) { + reset(); + return super.postXml(url, content); + } + + @Override + public String postXml(String url, String content, String encoding) { + reset(); + return super.postXml(url, content, encoding); + } + + @Override + public String put(String arg0, String arg1, String arg2) { + reset(); + return super.put(arg0, arg1, arg2); + } + + @Override + public String put(String url, File file, String contentType) { + reset(); + return super.put(url, file, contentType); + } + @Override + public String put(String url, RequestEntity requestEntity) { + reset(); + return super.put(url, requestEntity); + } + + @Override + public String putXml(String url, String content) { + reset(); + return super.putXml(url, content); + } + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/ServerAccess.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/ServerAccess.java new file mode 100644 index 0000000..9d432fc --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/gn/extension/ServerAccess.java @@ -0,0 +1,34 @@ +package org.gcube.spatial.data.sdi.engine.impl.gn.extension; + +import org.gcube.spatial.data.sdi.model.service.Version; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ServerAccess{ + + + private String gnServiceURL; + private Version version; + + private String password; + private String user; + + + public ServerAccess(String gnServiceURL, Version version) { + super(); + this.gnServiceURL = gnServiceURL; + this.version = version; + } + + + @Override + public String toString() { + return "ServerAccess [gnServiceURL=" + gnServiceURL + ", version=" + version + ", password=****" + ", user=" + user + "]"; + } + + + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/AbstractISModule.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/AbstractISModule.java new file mode 100644 index 0000000..b8c9cdd --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/AbstractISModule.java @@ -0,0 +1,259 @@ +package org.gcube.spatial.data.sdi.engine.impl.is; + +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.resources.gcore.GCoreEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Profile; +import org.gcube.common.resources.gcore.common.Platform; +import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; +import org.gcube.spatial.data.sdi.model.health.Level; +import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; +import org.gcube.spatial.data.sdi.model.health.Status; +import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; + +import lombok.Synchronized; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractISModule implements ISModule { + + protected abstract String getGCoreEndpointServiceClass(); + protected abstract String getGCoreEndpointServiceName(); + protected abstract String getServiceEndpointAccessPointName(); + protected abstract String getServiceEndpointCategory(); + protected abstract String getServiceEndpointPlatformName(); + + protected abstract String getManagedServiceType(); + + protected abstract boolean isSmartGearsMandatory(); + + @Override + public List getISInformation() throws ConfigurationNotFoundException { + log.trace("Getting current information from IS. Scope {} ",ScopeUtils.getCurrentScope()); + ArrayList toReturn=new ArrayList<>(); + log.debug("MANDATORY SG FOR {} is {} ",getManagedServiceType(),isSmartGearsMandatory()); + if(isSmartGearsMandatory()) { + List GCs=queryGcoreEndpoints(); + for(ServiceEndpoint ep: queryServiceEndpoints()) { + String host=ISUtils.getHost(ep); + log.debug("Checking if ServiceEndpoint at {} is SmartGears .. ",host); + try{ + if(ISUtils.getByHostnameInCollection(host, GCs)!=null) { + log.debug("Found GC. Service Endpoint {} seems valid. ",ep.profile().name()); + toReturn.add(ep); + } + }catch(UnknownHostException e) { + log.warn("Unexpected Exception while checking hostnames. Please check configuration.",e); + } + } + }else { + toReturn.addAll(queryServiceEndpoints()); + } + return toReturn; + } + + + @Override + public ServiceHealthReport getHealthReport() { + List checkStatuses=new ArrayList<>(); + try { + + log.trace("Checking {} heatlh under context {} ",getManagedServiceType(),ScopeUtils.getCurrentScope()); + //Check if existing + List gCoreEndpoints=queryGcoreEndpoints(); + List serviceEndpoints=queryServiceEndpoints(); + log.debug("Found {} GC Endpoints and {} SE Endpoints",gCoreEndpoints.size(),serviceEndpoints.size()); + + if(serviceEndpoints.isEmpty()) + if(gCoreEndpoints.isEmpty())checkStatuses.add(new Status("No "+getManagedServiceType()+" found in context "+ScopeUtils.getCurrentScope(),Level.ERROR)); + else checkStatuses.add(new Status("Unregistered "+getManagedServiceType()+" instances found. Check following messages",Level.ERROR)); + + //For each GC check for missing SE + for(GCoreEndpoint gc:gCoreEndpoints) { + String hostname= gc.profile().endpoints().iterator().next().uri().getHost(); + if(ISUtils.getByHostnameInCollection(hostname, serviceEndpoints)==null) { + String msg="Found unregistered "+getManagedServiceType()+" hosted on "+hostname; + log.debug(msg); + checkStatuses.add(new Status(msg,Level.WARNING)); + } + } + + + for(ServiceEndpoint se : serviceEndpoints) { + try { + //check if GC up & running + String hostname=se.profile().runtime().hostedOn(); + GCoreEndpoint found=ISUtils.getByHostnameInCollection(hostname, gCoreEndpoints); + + if(found==null) + checkStatuses.add(new Status("Service endpoint [name = "+se.profile().name()+", host = "+hostname+" ID = "+se.id()+"] found but no related GC is present.",Level.ERROR)); + else { + String status=found.profile().deploymentData().status(); + switch(status) { + case "unreachable" : + case "down" : checkStatuses.add(new Status("GCoreEndpoint [ID "+found.id()+"] for instance hosted on "+hostname+" has status : "+status,Level.ERROR)); + break; + default : + } + } + + + // perform specific checks + checkStatuses.addAll(performInstanceCheck(se)); + }catch(Throwable t) { + log.error("Unable to perform checks on SE "+se.id(), t); + checkStatuses.add(new Status("Internal error while checking "+getManagedServiceType()+" [SE ID : "+se.id()+"]."+t.getMessage(),Level.ERROR)); + } + } + + }catch(Throwable t) { + log.error("Unable to perform checks", t); + checkStatuses.add(new Status("Internal error while checking "+getManagedServiceType()+" Status.",Level.ERROR)); + } + return new ServiceHealthReport(checkStatuses); + } + + protected abstract List performInstanceCheck(ServiceEndpoint se); + + + protected List queryGcoreEndpoints(){ + String geClass=getGCoreEndpointServiceClass(); + String geName=getGCoreEndpointServiceName(); + return ISUtils.queryForGCoreEndpoint(geClass, geName); + } + + + protected List queryServiceEndpoints(){ + String seCategory=getServiceEndpointCategory(); + String sePlatform=getServiceEndpointPlatformName(); + return ISUtils.queryForServiceEndpoints(seCategory, sePlatform); + } + + + + @Override + public String importHostFromToken(String sourceToken, String host) throws ServiceRegistrationException { + + log.trace("Importing host {} from token {} ",host,sourceToken); + String callerScope=ScopeUtils.getCurrentScope(); + String callerToken=SecurityTokenProvider.instance.get(); + try { + //Checking if already present + List existingSEs=ISUtils.querySEByHostname(getServiceEndpointCategory(), getServiceEndpointPlatformName(), host); + if(existingSEs.size()>0) { + throw new ServiceRegistrationException("HOST "+host+" is already registered in current scope with ID : "+existingSEs.get(0).id()); + } + + // Getting from sourceToken.. + SecurityTokenProvider.instance.set(sourceToken); + log.debug("Source token {} is from scope {}.",sourceToken,ScopeUtils.getCurrentScope()); + List foundSEs=ISUtils.querySEByHostname(getServiceEndpointCategory(), getServiceEndpointPlatformName(), host); + if(foundSEs.size()>1) throw new ServiceRegistrationException("Too many ServiceEndpoints found with hostname "+host); + else if(foundSEs.isEmpty()) throw new ServiceRegistrationException("No ServiceEndpoints found with hostname "+host); + + ServiceEndpoint toImportSE= foundSEs.get(0); + try { + GCoreEndpoint toImportGC = ISUtils.getByHostnameInCollection(host, queryGcoreEndpoints()); + if(toImportGC==null) throw new ServiceRegistrationException("No GCoreEndpoint found for hostname "+host); + + log.debug("Registering resources to caller scope {} ",callerScope); + return ISUtils.addToScope(toImportSE, toImportGC,callerScope); + }catch(Exception e) { + throw new ServiceRegistrationException("Unable to register resources",e); + } + + + }finally { + if(!SecurityTokenProvider.instance.get().equals(callerToken)) + SecurityTokenProvider.instance.set(callerToken); + } + } + + @Override + @Synchronized + public String registerService(ServiceDefinition definition) throws ServiceRegistrationException { + log.info("Registering {} ",definition); + log.debug("Checking definition type.."); + checkDefinitionType(definition); + log.debug("Checking IS .."); + checkDefinition(definition); + log.debug("Performing type specific checks.."); + checkDefinitionForServiceType(definition); + log.debug("Preparing ServiceEndpoint.. "); + ServiceEndpoint ep=prepareEndpoint(definition); + log.debug("Publishing resource.."); + String id=ISUtils.registerService(ep); + + List registered=null; + long registrationTime=System.currentTimeMillis(); + long timeout=Long.parseLong(LocalConfiguration.getProperty(LocalConfiguration.IS_REGISTRATION_TIMEOUT)); + do{ + log.debug("Waiting for IS to update. Passed {} ms.",(System.currentTimeMillis()-registrationTime)); + try{Thread.sleep(500); + }catch(Exception e) {} + + registered=ISUtils.queryById(id); + }while(registered.isEmpty()&&((System.currentTimeMillis()-registrationTime)<=timeout)); + if(registered.isEmpty()) { + log.warn("Registered resource [ID :{}] was not found before Timeout of {} ms. Returning id. ",id,timeout); + return id; + }else return registered.get(0); + } + + + protected abstract void checkDefinitionForServiceType(ServiceDefinition definition) throws InvalidServiceDefinitionException; + protected abstract void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException; + + protected void checkDefinition(ServiceDefinition definition) throws ServiceRegistrationException { + try{ + String hostname=definition.getHostname(); + List serviceEndpoints=queryServiceEndpoints(); + ServiceEndpoint existing=ISUtils.getByHostnameInCollection(hostname, serviceEndpoints); + if(existing!=null) { + throw new ServiceRegistrationException("Service is already registered"); + } + List gCoreNodes=queryGcoreEndpoints(); + GCoreEndpoint running=ISUtils.getByHostnameInCollection(hostname, gCoreNodes); + if(running==null) throw new ServiceRegistrationException("No GCoreEndpoint found for "+definition); + }catch(ServiceRegistrationException e) { + throw e; + }catch(Throwable t) { + throw new ServiceRegistrationException("Unexpected exception while trying to register "+definition, t); + } + } + + protected ServiceEndpoint prepareEndpoint(ServiceDefinition definition) throws ServiceRegistrationException { + try{ + ServiceEndpoint toCreate=new ServiceEndpoint(); + Profile profile=toCreate.newProfile(); + profile.category(getServiceEndpointCategory()); + profile.description(definition.getDescription()); + Platform platform=profile.newPlatform(); + platform.name(getServiceEndpointPlatformName()). + version(definition.getMajorVersion()). + minorVersion(definition.getMinorVersion()). + revisionVersion(definition.getReleaseVersion()); + + org.gcube.common.resources.gcore.ServiceEndpoint.Runtime runtime=profile.newRuntime(); + runtime.hostedOn(definition.getHostname()); + + GCoreEndpoint relatedGHN=ISUtils.getByHostnameInCollection(definition.getHostname(), queryGcoreEndpoints()); + + runtime.ghnId(relatedGHN.id()); + runtime.status("READY"); + + return toCreate; + }catch(Throwable t) { + throw new ServiceRegistrationException("Unexpected exception while trying to register "+definition, t); + } + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/CachedObject.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/CachedObject.java similarity index 88% rename from src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/CachedObject.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/CachedObject.java index d3d093f..c38c26f 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/CachedObject.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/CachedObject.java @@ -1,4 +1,4 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; +package org.gcube.spatial.data.sdi.engine.impl.is; public class CachedObject { diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoNetworkRetriever.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/GeoNetworkRetriever.java similarity index 64% rename from src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoNetworkRetriever.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/GeoNetworkRetriever.java index 408cbaf..2841034 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/GeoNetworkRetriever.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/GeoNetworkRetriever.java @@ -1,6 +1,7 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; +package org.gcube.spatial.data.sdi.engine.impl.is; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -20,10 +21,11 @@ import org.gcube.spatial.data.gis.GISInterface; import org.gcube.spatial.data.sdi.LocalConfiguration; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; +import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; import org.gcube.spatial.data.sdi.model.credentials.AccessType; import org.gcube.spatial.data.sdi.model.credentials.Credentials; import org.gcube.spatial.data.sdi.model.health.Status; -import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; import org.gcube.spatial.data.sdi.model.service.Version; import org.gcube.spatial.data.sdi.model.services.GeoNetworkServiceDefinition; import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; @@ -32,48 +34,48 @@ import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type; import lombok.extern.slf4j.Slf4j; @Slf4j -public class GeoNetworkRetriever extends AbstractISModule { +public class GeoNetworkRetriever extends AbstractISModule{ - @Override - public GeoNetworkConfiguration getObject() throws ConfigurationNotFoundException { - //TODO skip library - //TODO use both GCoreEndpoints and ServiceEndpoint - - -// log.info("Gathering geonetwork information under scope {} ",ScopeUtils.getCurrentScope()); -// LocalConfiguration config=LocalConfiguration.get(); -// String category=config.getProperty(LocalConfiguration.GEONETWORK_SE_CATEGORY); -// String platformName=config.getProperty(LocalConfiguration.GEONETWORK_SE_PLATFORM); -// String priorityProperty=config.getProperty(LocalConfiguration.GEONETWORK_SE_PRIORITY); -// String endpointName=config.getProperty(LocalConfiguration.GEONETWORK_SE_ENDPOINT_NAME); -// ServiceEndpoint se=getTheRightServiceEndpoint(ISUtils.queryForServiceEndpoints(category, platformName), endpointName, priorityProperty); -// AccessPoint access=getTheRightAccessPoint(se, endpointName, priorityProperty); +// @Override +// public GeoNetworkDescriptor getObject() throws ConfigurationNotFoundException { +// //TODO skip library +// //TODO use both GCoreEndpoints and ServiceEndpoint // - - try{ - //INIT LIB - GISInterface gis=GISInterface.get(); - GeoNetworkAdministration gnAdmin=(GeoNetworkAdministration) gis.getGeoNewtorkPublisher(); - Configuration config=gnAdmin.getConfiguration(); - - Version version=config.getGeoNetworkVersion().equals(ServerAccess.Version.TRE)?new Version(3,0,0):new Version(2,6,0); - String baseEndpoint=config.getGeoNetworkEndpoint(); - ScopeConfiguration scopeConfig=config.getScopeConfiguration(); - List accessibleCredentials=new ArrayList(); - for(Account acc: scopeConfig.getAccounts().values()){ - accessibleCredentials.add(fromGeoNetworkAccount(acc)); - } - - Credentials adminCredentials=fromGeoNetworkAccount(config.getAdminAccount()); - // GN Lib doesn't expose ADMIN account type - adminCredentials.setAccessType(AccessType.ADMIN); - accessibleCredentials.add(adminCredentials); - return new GeoNetworkConfiguration(version, baseEndpoint, accessibleCredentials, scopeConfig.getPrivateGroup()+"", scopeConfig.getPublicGroup()+"", "3"); - }catch(Exception e){ - log.warn("Unable to gather geonetwork information",e); - throw new ConfigurationNotFoundException("Unable to gather information on geonetwork. Please contact administrator.",e); - } - } +// +//// log.info("Gathering geonetwork information under scope {} ",ScopeUtils.getCurrentScope()); +//// LocalConfiguration config=LocalConfiguration.get(); +//// String category=config.getProperty(LocalConfiguration.GEONETWORK_SE_CATEGORY); +//// String platformName=config.getProperty(LocalConfiguration.GEONETWORK_SE_PLATFORM); +//// String priorityProperty=config.getProperty(LocalConfiguration.GEONETWORK_SE_PRIORITY); +//// String endpointName=config.getProperty(LocalConfiguration.GEONETWORK_SE_ENDPOINT_NAME); +//// ServiceEndpoint se=getTheRightServiceEndpoint(ISUtils.queryForServiceEndpoints(category, platformName), endpointName, priorityProperty); +//// AccessPoint access=getTheRightAccessPoint(se, endpointName, priorityProperty); +//// +// +// try{ +// //INIT LIB +// GISInterface gis=GISInterface.get(); +// GeoNetworkAdministration gnAdmin=(GeoNetworkAdministration) gis.getGeoNewtorkPublisher(); +// Configuration config=gnAdmin.getConfiguration(); +// +// Version version=config.getGeoNetworkVersion().equals(ServerAccess.Version.TRE)?new Version(3,0,0):new Version(2,6,0); +// String baseEndpoint=config.getGeoNetworkEndpoint(); +// ScopeConfiguration scopeConfig=config.getScopeConfiguration(); +// List accessibleCredentials=new ArrayList(); +// for(Account acc: scopeConfig.getAccounts().values()){ +// accessibleCredentials.add(fromGeoNetworkAccount(acc)); +// } +// +// Credentials adminCredentials=fromGeoNetworkAccount(config.getAdminAccount()); +// // GN Lib doesn't expose ADMIN account type +// adminCredentials.setAccessType(AccessType.ADMIN); +// accessibleCredentials.add(adminCredentials); +// return new GeoNetworkDescriptor(version, baseEndpoint, accessibleCredentials, scopeConfig.getPrivateGroup()+"", scopeConfig.getPublicGroup()+"", "3"); +// }catch(Exception e){ +// log.warn("Unable to gather geonetwork information",e); +// throw new ConfigurationNotFoundException("Unable to gather information on geonetwork. Please contact administrator.",e); +// } +// } @@ -86,7 +88,10 @@ public class GeoNetworkRetriever extends AbstractISModuleresources, String endpointName,String priorityProperty){ @@ -148,12 +153,12 @@ public class GeoNetworkRetriever extends AbstractISModule performInstanceCheck(ServiceEndpoint se) { - // TODO Auto-generated method stub - return null; + return Collections.EMPTY_LIST; } @Override @@ -192,7 +196,7 @@ public class GeoNetworkRetriever extends AbstractISModule ge throws ConfigurationNotFoundException { +// //TODO skip library +// //TODO use both GCoreEndpoints and ServiceEndpoint +// try { +// ArrayList availableInstances=new ArrayList<>(); +// for(ServiceEndpoint ep: getServiceEndpoints()) { +// try{ +// availableInstances.add(translate(ep)); +// }catch(Throwable t) { +// log.warn("Unable to translate ServiceEndpoint [ID : {}].",ep.id(),t); +// } +// } +// }catch(Throwable e){ +// log.warn("Unable to gather geoserver cluster configuration on scope "+ScopeUtils.getCurrentScope(),e); +// throw new ConfigurationNotFoundException("Unable to gather geoserver cluster configuration. Please ontact administrator.",e); +// } +// +// log.info("Retrieving GeoServer cluster configuration under scope {}",ScopeUtils.getCurrentScope()); +// try{ +// GISInterface gis=GISInterface.get(); +// ArrayList availableInstances=new ArrayList<>(); +// for(AbstractGeoServerDescriptor desc: gis.getCurrentCacheElements(true)){ +// try{ +// availableInstances.add(translate(desc)); +// }catch(Throwable t){ +// log.warn("Unable to translate descriptor for endpoint"+desc.getUrl(),t); +// } +// } +// +// return new GeoServerCluster(availableInstances); +// }catch(Exception e){ +// log.warn("Unable to gather geoserver cluster configuration on scope "+ScopeUtils.getCurrentScope(),e); +// throw new ConfigurationNotFoundException("Unable to gather geoserver cluster configuration. Please ontact administrator.",e); +// } +// } + + + @Override + protected boolean isSmartGearsMandatory() { + return LocalConfiguration.getFlag(LocalConfiguration.GEOSERVER_MANDATORY_SG); + } + + + + private static final GeoServerDescriptor translate(AbstractGeoServerDescriptor desc){ + Version version=new Version(2,1,2); + String baseEndpoint=desc.getUrl(); + List accessibleCredentials=Collections.singletonList(new Credentials(desc.getUser(), desc.getPassword(), AccessType.ADMIN)); + String confidentialWorkspace=null; + String contextVisibilityWorkspace=null; + String sharedWorkspace=null; + String publicWorkspace=null; + return new GeoServerDescriptor(version, baseEndpoint, accessibleCredentials, confidentialWorkspace, contextVisibilityWorkspace, sharedWorkspace, publicWorkspace); + } + + @Override + protected String getGCoreEndpointServiceClass() { + return LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_GE_SERVICE_CLASS); + } + @Override + protected String getGCoreEndpointServiceName() { + return LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_GE_SERVICE_NAME); + } + @Override + protected String getManagedServiceType() { + return "GeoServer"; + } + + @Override + protected String getServiceEndpointAccessPointName() { + return LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_SE_ENDPOINT_NAME); + } + + @Override + protected String getServiceEndpointCategory() { + return LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_SE_CATEGORY); + } + @Override + protected String getServiceEndpointPlatformName() { + return LocalConfiguration.getProperty(LocalConfiguration.GEOSERVER_SE_PLATFORM); + } + @Override + protected List performInstanceCheck(ServiceEndpoint se) { + return Collections.EMPTY_LIST; + } + + @Override + protected void checkDefinitionForServiceType(ServiceDefinition definition) + throws InvalidServiceDefinitionException { + // Contact GN + // try to login with credentials + } + @Override + protected void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException { + if(!definition.getType().equals(Type.GEOSERVER)||!(definition instanceof GeoServerDefinition)) + throw new InvalidServiceDefinitionException("Invalid service type [expected "+Type.GEOSERVER+"]. Definition was "+definition); + } + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISModule.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISModule.java similarity index 56% rename from src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISModule.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISModule.java index c05bfb9..c4d13a5 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ISModule.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISModule.java @@ -1,13 +1,17 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; +package org.gcube.spatial.data.sdi.engine.impl.is; +import java.util.List; + +import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException; import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; -public interface ISModule { +public interface ISModule { - public T getObject()throws ConfigurationNotFoundException; + public List getISInformation()throws ConfigurationNotFoundException; public ServiceHealthReport getHealthReport(); public String registerService(ServiceDefinition definition) throws ServiceRegistrationException; + public String importHostFromToken(String sourceToken,String host)throws ServiceRegistrationException; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISUtils.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISUtils.java new file mode 100644 index 0000000..146d84a --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ISUtils.java @@ -0,0 +1,213 @@ +package org.gcube.spatial.data.sdi.engine.impl.is; + +import static org.gcube.resources.discovery.icclient.ICFactory.client; +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.io.ByteArrayOutputStream; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import org.gcube.common.encryption.StringEncrypter; +import org.gcube.common.resources.gcore.GCoreEndpoint; +import org.gcube.common.resources.gcore.Resource; +import org.gcube.common.resources.gcore.Resources; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.informationsystem.publisher.RegistryPublisher; +import org.gcube.informationsystem.publisher.RegistryPublisherFactory; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.resources.discovery.client.queries.impl.QueryBox; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.NetUtils; +import org.gcube.spatial.data.sdi.ScopeUtils; +import org.gcube.vremanagement.resourcemanager.client.RMBinderLibrary; +import org.gcube.vremanagement.resourcemanager.client.exceptions.InvalidScopeException; +import org.gcube.vremanagement.resourcemanager.client.exceptions.ResourcesCreationException; +import org.gcube.vremanagement.resourcemanager.client.fws.Types.AddResourcesParameters; +import org.gcube.vremanagement.resourcemanager.client.fws.Types.ResourceItem; +import org.gcube.vremanagement.resourcemanager.client.fws.Types.ResourceList; +import org.gcube.vremanagement.resourcemanager.client.proxies.Proxies; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ISUtils { + + public static List queryForServiceEndpoints(String category, String platformName){ + log.debug("Querying for Service Endpoints [category : {} , platformName : {}, currentScope : {} ]",category,platformName,ScopeUtils.getCurrentScope()); + + SimpleQuery query = queryFor(ServiceEndpoint.class); + + query.addCondition("$resource/Profile/Category/text() eq '"+category+"'") + .addCondition("$resource/Profile/Platform/Name/text() eq '"+platformName+"'"); + // .setResult("$resource/Profile/AccessPoint"); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + + return client.submit(query); + } + + public static List queryForGCoreEndpoint(String serviceClass,String serviceName){ + log.debug("Querying for GCore Endpoints [ServiceClass : {} , ServiceName : {}, currentScope : {} ]",serviceClass,serviceName,ScopeUtils.getCurrentScope()); + + + SimpleQuery query =queryFor(GCoreEndpoint.class); + query.addCondition("$resource/Profile/ServiceClass/text() eq '"+serviceClass+"'") + .addCondition("$resource/Profile/ServiceName/text() eq '"+serviceName+"'"); + // .setResult("$resource/Profile/AccessPoint"); + + DiscoveryClient client = clientFor(GCoreEndpoint.class); + + return client.submit(query); + } + + + public static T getByHostnameInCollection(String hostname, Collection toCheckList) throws UnknownHostException { + for(T gc:toCheckList) { + String currentHostToCheck=getHost(gc); + if(NetUtils.isSameHost(currentHostToCheck, hostname)) return gc; + } + return null; + } + + + public static String getHost(Resource res) { + if(res instanceof GCoreEndpoint) + return (((GCoreEndpoint)res).profile().endpoints().iterator().next().uri().getHost()); + else return (((ServiceEndpoint)res).profile().runtime().hostedOn()); + } + + public static List querySEByHostname(String category,String platformName,String hostname){ + log.debug("Querying Service Endpoints by hostname [category : {} , platformName : {}, currentScope : {}, hostname {} ]",category,platformName,ScopeUtils.getCurrentScope(),hostname); + + SimpleQuery query = queryFor(ServiceEndpoint.class); + + query.addCondition("$resource/Profile/Category/text() eq '"+category+"'") + .addCondition("$resource/Profile/Platform/Name/text() eq '"+platformName+"'") + .addCondition("$resource/Profile/Runtime/HostedOn/text() eq '"+hostname+"'"); + // .setResult("$resource/Profile/AccessPoint"); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + + return client.submit(query); + } + + + public static List queryById(String id) { + DiscoveryClient client = client(); + String queryString ="declare namespace ic = 'http://gcube-system.org/namespaces/informationsystem/registry'; "+ + "for $profiles in collection('/db/Profiles')//Document/Data/ic:Profile/Resource "+ + "where $profiles/ID/text() eq '"+id+"'"+ + " return $profiles"; + return client.submit(new QueryBox(queryString)); + } + + + public static ServiceEndpoint querySEById(String id) { + SimpleQuery query = queryFor(ServiceEndpoint.class); + + query.addCondition("$resource/ID/text() eq '"+id+"'"); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + + return client.submit(query).get(0); + } + + public static String registerService(ServiceEndpoint toRegister) { + RegistryPublisher rp=RegistryPublisherFactory.create(); + Resource r=rp.create(toRegister); + return r.id(); + } + + + public static String addToScope(ServiceEndpoint se,GCoreEndpoint gc, String targetScope) throws ResourcesCreationException, InvalidScopeException { + log.trace("Publishing GC [ID : {}, Sc : {}, Sn {}, GHN-ID : {} ], SE [ID : {}, name : {}] to Scope {} from Scope {}", + gc.id(), gc.profile().serviceClass(),gc.profile().serviceName(),gc.profile().ghnId(), + se.id(),se.profile().name(),targetScope,ScopeUtils.getCurrentScope()); + + + AddResourcesParameters params=new AddResourcesParameters(); + ResourceList resourceList=new ResourceList(); + ArrayList list=new ArrayList<>(); + + ResourceItem ghnItem=new ResourceItem(); + ghnItem.id=gc.profile().ghnId(); + ghnItem.type="GHN"; + list.add(ghnItem); + + ResourceItem geItem=new ResourceItem(); + geItem.id=gc.id(); + geItem.type="RunningInstance"; + list.add(geItem); + + ResourceItem seItem=new ResourceItem(); + seItem.id=se.id(); + seItem.type="RuntimeResource"; + list.add(seItem); + + resourceList.setResource(list); + params.setTargetScope(targetScope); + params.setResources(resourceList); + + RMBinderLibrary library=Proxies.binderService().build(); + return library.addResources(params); + } + + + public static String decryptString(String toDecrypt){ + try{ + return StringEncrypter.getEncrypter().decrypt(toDecrypt); + }catch(Exception e) { + throw new RuntimeException("Unable to decrypt : "+toDecrypt,e); + } + } + + + public static ServiceEndpoint update(ServiceEndpoint toUpdate) { + RegistryPublisher rp=RegistryPublisherFactory.create(); + return rp.update(toUpdate); + } + + public static ServiceEndpoint updateAndWait(ServiceEndpoint toUpdate) { + boolean equals=true; + boolean timeoutReached=false; + long timeout=LocalConfiguration.getTTL(LocalConfiguration.IS_REGISTRATION_TIMEOUT); + log.trace("Going to update {}. Timeout is {} ",toUpdate.id(),timeout); + String toUpdateString=marshal(toUpdate); + update(toUpdate); + long updateTime=System.currentTimeMillis(); + String updatedString=null; + do { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + updatedString=queryById(toUpdate.id()).get(0); + equals=toUpdateString.equals(updatedString); + timeoutReached=(System.currentTimeMillis()-updateTime)>timeout; + }while(equals&&(!timeoutReached)); + if(timeoutReached) log.warn("Timeout reached. Check if {} is updated ",toUpdate.id()); + return querySEById(toUpdate.id()); + } + + + public static String marshal(Resource res) { + ByteArrayOutputStream stream=new ByteArrayOutputStream(); + Resources.marshal(res, stream); + return stream.toString(); + } + + + public static HashSet getSiblingsScopesInResource(Resource res,String scope){ + HashSet toReturn=new HashSet(); + String parent=ScopeUtils.getParentScope(scope); + if (parent!=null) + for(String resourceScope:res.scopes().asCollection()) + if(ScopeUtils.getParentScope(resourceScope).equals(parent)) toReturn.add(resourceScope); + return toReturn; + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ThreddsRetriever.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ThreddsRetriever.java similarity index 59% rename from src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ThreddsRetriever.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ThreddsRetriever.java index 9c37a13..4f5028d 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/cache/ThreddsRetriever.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/is/ThreddsRetriever.java @@ -1,4 +1,4 @@ -package org.gcube.spatial.data.sdi.engine.impl.cache; +package org.gcube.spatial.data.sdi.engine.impl.is; import java.io.IOException; import java.util.ArrayList; @@ -8,19 +8,14 @@ import java.util.List; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.resources.gcore.common.Platform; -import org.gcube.data.transfer.library.DataTransferClient; -import org.gcube.data.transfer.library.faults.DataTransferException; -import org.gcube.data.transfer.model.PluginDescription; -import org.gcube.spatial.data.geonetwork.utils.ScopeUtils; import org.gcube.spatial.data.sdi.LocalConfiguration; -import org.gcube.spatial.data.sdi.engine.impl.NetUtils; -import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.NetUtils; import org.gcube.spatial.data.sdi.engine.impl.faults.InvalidServiceDefinitionException; import org.gcube.spatial.data.sdi.model.credentials.AccessType; import org.gcube.spatial.data.sdi.model.credentials.Credentials; import org.gcube.spatial.data.sdi.model.health.Level; import org.gcube.spatial.data.sdi.model.health.Status; -import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; import org.gcube.spatial.data.sdi.model.service.Version; import org.gcube.spatial.data.sdi.model.services.ServiceDefinition; import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type; @@ -28,51 +23,51 @@ import org.gcube.spatial.data.sdi.model.services.ThreddsDefinition; import lombok.extern.slf4j.Slf4j; @Slf4j -public class ThreddsRetriever extends AbstractISModule { +public class ThreddsRetriever extends AbstractISModule { - @Override - public ThreddsConfiguration getObject() throws ConfigurationNotFoundException{ - log.info("Loading Thredds information from IS. Current Scope is {} ",ScopeUtils.getCurrentScope()); - - // Try to look for GCore Endpoints first - -// List gCoreEndpoints=getGcoreEndpoints(); -// if(gCoreEndpoints!=null&&!gCoreEndpoints.isEmpty()){ -// log.debug("Found {} GCore Endpoints ",gCoreEndpoints.size()); -// for(int i=0;i gCoreEndpoints=getGcoreEndpoints(); +//// if(gCoreEndpoints!=null&&!gCoreEndpoints.isEmpty()){ +//// log.debug("Found {} GCore Endpoints ",gCoreEndpoints.size()); +//// for(int i=0;i threddsSE=getServiceEndpoints(); +// if(threddsSE!=null&&!threddsSE.isEmpty()){ +// log.debug("Found {} Service Endpoints ",threddsSE.size()); +// for(int i=0;i threddsSE=getServiceEndpoints(); - if(threddsSE!=null&&!threddsSE.isEmpty()){ - log.debug("Found {} Service Endpoints ",threddsSE.size()); - for(int i=0;i { @Override protected String getGCoreEndpointServiceClass() { - return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_GE_SERVICE_CLASS); + return LocalConfiguration.getProperty(LocalConfiguration.THREDDS_GE_SERVICE_CLASS); } @Override protected String getGCoreEndpointServiceName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_GE_SERVICE_NAME); + return LocalConfiguration.getProperty(LocalConfiguration.THREDDS_GE_SERVICE_NAME); } @Override @@ -126,15 +121,20 @@ public class ThreddsRetriever extends AbstractISModule { @Override protected String getServiceEndpointCategory() { - return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_CATEGORY); + return LocalConfiguration.getProperty(LocalConfiguration.THREDDS_SE_CATEGORY); } @Override protected String getServiceEndpointPlatformName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_PLATFORM); + return LocalConfiguration.getProperty(LocalConfiguration.THREDDS_SE_PLATFORM); } @Override protected String getServiceEndpointAccessPointName() { - return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_ENDPOINT_NAME); + return LocalConfiguration.getProperty(LocalConfiguration.THREDDS_SE_ENDPOINT_NAME); + } + + @Override + protected boolean isSmartGearsMandatory() { + return LocalConfiguration.getFlag(LocalConfiguration.THREDDS_MANDATORY_SG); } @Override @@ -148,15 +148,18 @@ public class ThreddsRetriever extends AbstractISModule { if(!NetUtils.isUp(publicCatalogUrl)) toReturn.add(new Status("Unreachable default THREDDS catalog at "+publicCatalogUrl,Level.ERROR)); else { - DataTransferClient client=DataTransferClient.getInstanceByEndpoint(hostname); - //check SIS plugin presence - boolean found=false; - for(PluginDescription desc: client.getDestinationCapabilities().getAvailablePlugins()) - if(desc.getId().equals("SIS/GEOTK")) { - found=true; - break; - } - if(!found) toReturn.add(new Status("SIS/GEOTK plugin for DataTransfer service not found on "+hostname, Level.ERROR)); + +// +// +// DataTransferClient client=DataTransferClient.getInstanceByEndpoint(hostname); +// //check SIS plugin presence +// boolean found=false; +// for(PluginDescription desc: client.getDestinationCapabilities().getAvailablePlugins()) +// if(desc.getId().equals("SIS/GEOTK")) { +// found=true; +// break; +// } +// if(!found) toReturn.add(new Status("SIS/GEOTK plugin for DataTransfer service not found on "+hostname, Level.ERROR)); } }catch(IOException e) { @@ -164,11 +167,11 @@ public class ThreddsRetriever extends AbstractISModule { log.warn(msg); log.debug("Exception was ",e); toReturn.add(new Status(msg,Level.WARNING)); - } catch (DataTransferException e) { - String msg="DataTransfer not found in host "+hostname; - log.warn(msg); - log.debug("Exception was ",e); - toReturn.add(new Status(msg,Level.ERROR)); +// } catch (DataTransferException e) { +// String msg="DataTransfer not found in host "+hostname; +// log.warn(msg); +// log.debug("Exception was ",e); +// toReturn.add(new Status(msg,Level.ERROR)); } return toReturn; } @@ -181,12 +184,12 @@ public class ThreddsRetriever extends AbstractISModule { // return null; // } - private static final ThreddsConfiguration translate(ServiceEndpoint toTranslate){ + private static final ThreddsDescriptor translate(ServiceEndpoint toTranslate){ Platform platform=toTranslate.profile().platform(); Version version=new Version(platform.version(),platform.minorVersion(),platform.revisionVersion()); AccessPoint access=toTranslate.profile().accessPoints().iterator().next(); Credentials credentials=new Credentials(access.username(),access.password(),AccessType.ADMIN); - return new ThreddsConfiguration(version, access.address(), Collections.singletonList(credentials)); + return new ThreddsDescriptor(version, access.address(), Collections.singletonList(credentials)); } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/GenericTemplates.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/GenericTemplates.java new file mode 100644 index 0000000..576388f --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/GenericTemplates.java @@ -0,0 +1,15 @@ +package org.gcube.spatial.data.sdi.engine.impl.metadata; + +public class GenericTemplates { + + public static class ThreddsCatalogTemplate{ + public static final String FILENAME="thredds_catalog.ftlx"; + + public static final String CATALOG_PATH="CatalogPath"; + public static final String LOCATION="Location"; + public static final String DATASET_SCAN_NAME="DataSetScanName"; + public static final String DATASET_SCAN_ID="DataSetScanID"; + public static final String AUTHORITY_URL="AuthorityURL"; + } + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java index cf64839..0c6c060 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java @@ -14,7 +14,7 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.gcube.common.resources.gcore.utils.XPathHelper; -import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractTemplate.InsertionPoint; +import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractMetadataTemplate.InsertionPoint; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java index 0c98d11..aa41adc 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java @@ -2,6 +2,7 @@ package org.gcube.spatial.data.sdi.engine.impl.metadata; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; @@ -9,6 +10,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import javax.annotation.PostConstruct; @@ -18,8 +20,8 @@ import javax.xml.transform.TransformerException; import org.apache.commons.io.IOUtils; import org.gcube.smartgears.context.application.ApplicationContext; import org.gcube.spatial.data.sdi.LocalConfiguration; -import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager; -import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractTemplate; +import org.gcube.spatial.data.sdi.engine.TemplateManager; +import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractMetadataTemplate; import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.InvalidTemplateInvocationException; import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.ThreddsOnlineTemplate; import org.gcube.spatial.data.sdi.model.metadata.TemplateCollection; @@ -33,20 +35,21 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @Singleton -public class MetadataTemplateManagerImpl implements MetadataTemplateManager { +public class MetadataTemplateManagerImpl implements TemplateManager { private static Configuration cfg; - private static ArrayList templateDescriptors=new ArrayList<>(); - private static HashMap availableTemplates=new HashMap<>(); - - private static TemplateCollection collection; +// private static ArrayList templateDescriptors=new ArrayList<>(); + private static HashMap availableMetadataTemplates=new HashMap<>(); + + + private static TemplateCollection metadataTemplateDescriptors; @PostConstruct public void defaultInit() { - init(LocalConfiguration.get().getTemplateConfigurationObject()); + init(LocalConfiguration.getTemplateConfigurationObject()); } @@ -63,7 +66,7 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager { if(configurationObject instanceof ApplicationContext){ log.debug("Configuration is Context : {} ",configurationObject); cfg.setServletContextForTemplateLoading(((ApplicationContext)configurationObject).application(), - LocalConfiguration.get().getProperty(LocalConfiguration.METADATA_TEMPLATE_FOLDER)); + LocalConfiguration.getProperty(LocalConfiguration.TEMPLATE_FOLDER)); }else if (configurationObject instanceof File){ try{ cfg.setDirectoryForTemplateLoading((File)configurationObject); @@ -89,46 +92,26 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager { ThreddsOnlineTemplate tpl=new ThreddsOnlineTemplate(); - availableTemplates.put(tpl.getDescriptor().getId(), tpl); - templateDescriptors.add(tpl.getDescriptor()); - log.debug("Loaded templates : "); - for(TemplateDescriptor desc: templateDescriptors) - log.debug(desc.toString()); + availableMetadataTemplates.put(tpl.getDescriptor().getId(), tpl); + ArrayList metadataTemplates=new ArrayList(); + metadataTemplates.add(tpl.getDescriptor()); + log.debug("Loaded metadata templates : "); + for(TemplateDescriptor desc: metadataTemplates) + log.debug(desc.toString()); + metadataTemplateDescriptors=new TemplateCollection(new HashSet<>(metadataTemplates)); - collection=new TemplateCollection(new HashSet<>(templateDescriptors)); } -// -// public static String getTHREDDSLinks(ThreddsLinkRequest req) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{ -// Writer out=null; -// try{ -// Template temp = cfg.getTemplate("OnlineResources.ftlx"); -// ByteArrayOutputStream baos=new ByteArrayOutputStream(); -// out=new OutputStreamWriter(baos); -// temp.process(req, out); -// out.flush(); -// return baos.toString(StandardCharsets.UTF_8.toString()); -// }finally{ -// if(out!=null) -// IOUtils.closeQuietly(out); -// } -// } -// -// -// -// -// public MetadataTemplateManagerImpl() { -// // TODO Auto-generated constructor stub -// } + @Override - public TemplateCollection getAvailableTemplates() { - return collection; + public TemplateCollection getAvailableMetadataTemplates() { + return metadataTemplateDescriptors; } @Override - public TemplateApplicationReport applyTemplates(File original, Set invocations) throws IOException, TransformerException { + public TemplateApplicationReport applyMetadataTemplates(File original, Set invocations) throws IOException, TransformerException { log.debug("Applying template invocations {} to {} ",invocations,original.getAbsolutePath()); TemplateApplicationReport report=new TemplateApplicationReport(); report.setRequestedInvocations(invocations); @@ -151,7 +134,7 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager { private static void applyTemplate(File original,TemplateInvocation invocation,MetadataHandler handler) throws Exception{ log.debug("Instantiating "+invocation); - AbstractTemplate tpl=availableTemplates.get(invocation.getToInvokeTemplateID()); + AbstractMetadataTemplate tpl=availableMetadataTemplates.get(invocation.getToInvokeTemplateID()); if(tpl==null) throw new InvalidTemplateInvocationException("Template with ID "+invocation.getToInvokeTemplateID()+" was not found"); Writer out=null; try{ @@ -173,4 +156,25 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager { } } + + @Override + public File generateFromTemplate(Map parameters, String template) throws Exception { + Writer out=null; + try{ + log.info("Generating from template {}. Parameters are {} ",template,parameters); + Template temp = cfg.getTemplate(template); + File toReturn=File.createTempFile(template, ".xml"); + out=new FileWriter(toReturn); + temp.process(parameters, out); + out.flush(); + return toReturn; + } catch (Exception e) { + log.error("Unable to apply template{}. Parameters were {} ",template,parameters,e); + throw e; + }finally{ + if(out!=null) + IOUtils.closeQuietly(out); + } + } + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractMetadataTemplate.java similarity index 58% rename from src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java rename to src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractMetadataTemplate.java index b1eaad9..4b9287c 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractMetadataTemplate.java @@ -1,9 +1,10 @@ package org.gcube.spatial.data.sdi.engine.impl.metadata.templates; -import java.util.Map; +import java.util.List; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataHandler; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataUtils.Position; +import org.gcube.spatial.data.sdi.model.ParameterType; import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation; @@ -14,7 +15,7 @@ import lombok.ToString; @Getter @AllArgsConstructor -public abstract class AbstractTemplate { +public abstract class AbstractMetadataTemplate { @@ -34,10 +35,15 @@ public abstract class AbstractTemplate { public abstract T getInstantiationRequest(MetadataHandler original, TemplateInvocation invocation) throws InvalidTemplateInvocationException,Exception; - protected String getParameter(String parameterName, Map parameters, boolean mandatory,String defaultValue)throws InvalidTemplateInvocationException{ - if(parameters==null || parameters.isEmpty() || !parameters.containsKey(parameterName)) - if(mandatory) throw new InvalidTemplateInvocationException("Missing parameter "+parameterName+"."); - else return defaultValue; - else return parameters.get(parameterName); + protected String getParameter(String parameterName, List parameters, boolean mandatory,String defaultValue)throws InvalidTemplateInvocationException{ + + //if collection not empty look for it + if(!(parameters==null || parameters.isEmpty())) + for(ParameterType param:parameters) + if(param.getName().equals(parameterName)) return param.getValue(); + + //nothing found.. + if(mandatory) throw new InvalidTemplateInvocationException("Missing parameter "+parameterName+"."); + else return defaultValue; } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java index 0202b13..9e73c7f 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java +++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java @@ -1,11 +1,12 @@ package org.gcube.spatial.data.sdi.engine.impl.metadata.templates; -import java.util.HashMap; +import java.util.ArrayList; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataHandler; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataUtils; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataUtils.Position; import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.ThreddsOnlineTemplate.ThreddsOnlineRequest; +import org.gcube.spatial.data.sdi.model.ParameterType; import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocationBuilder; @@ -14,12 +15,12 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; -public class ThreddsOnlineTemplate extends AbstractTemplate { +public class ThreddsOnlineTemplate extends AbstractMetadataTemplate { - private static HashMap EXPECTED_PARAMETERS=new HashMap(); + private static ArrayList EXPECTED_PARAMETERS=new ArrayList(); private static String TEMPLATE_ID=TemplateInvocationBuilder.THREDDS_ONLINE.ID; private static String TEMPLATE_NAME="Thredds Online Resources"; private static String FILENAME="ThreddsOnlineResources.ftlx"; @@ -27,9 +28,9 @@ public class ThreddsOnlineTemplate extends AbstractTemplate availableInstances; + private String catalogURL; + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/ScopeConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/model/ScopeConfiguration.java index 0d237fb..d9473ad 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/ScopeConfiguration.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/ScopeConfiguration.java @@ -1,12 +1,14 @@ package org.gcube.spatial.data.sdi.model; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration; -import org.gcube.spatial.data.sdi.model.service.GeoServerClusterConfiguration; -import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -30,10 +32,10 @@ public class ScopeConfiguration { private String contextName; @NonNull - private GeoNetworkConfiguration geonetworkConfiguration; + private List geonetworkConfiguration; @NonNull - private GeoServerClusterConfiguration geoserverClusterConfiguration; + private List geoserverClusterConfiguration; @NonNull - private ThreddsConfiguration threddsConfiguration; + private List threddsConfiguration; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/credentials/AccessType.java b/src/main/java/org/gcube/spatial/data/sdi/model/credentials/AccessType.java index fa5e1b2..68a8088 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/credentials/AccessType.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/credentials/AccessType.java @@ -1,6 +1,10 @@ package org.gcube.spatial.data.sdi.model.credentials; public enum AccessType { + + ADMIN, + CONTEXT_MANAGER, + CONTEXT_USER, + CKAN; - CKAN,ADMIN,CONTEXT_USER,CONTEXT_MANAGER } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkDescriptor.java similarity index 52% rename from src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkConfiguration.java rename to src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkDescriptor.java index 1b3cf6f..627e833 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkConfiguration.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoNetworkDescriptor.java @@ -8,29 +8,48 @@ import javax.xml.bind.annotation.XmlRootElement; import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +@Getter +@Setter +@ToString @NoArgsConstructor @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) -public class GeoNetworkConfiguration extends GeoService{ +public class GeoNetworkDescriptor extends GeoServiceDescriptor{ - public GeoNetworkConfiguration(Version version, String baseEndpoint, List accessibleCredentials, - String contextGroup, String sharedGroup, String publicGroup) { + + public GeoNetworkDescriptor(Version version, String baseEndpoint, List accessibleCredentials, + String contextGroup, String defaultGroup, String sharedGroup, String confidentialGroup, String publicGroup, + Integer priority) { super(version, baseEndpoint, accessibleCredentials); this.contextGroup = contextGroup; + this.defaultGroup = defaultGroup; this.sharedGroup = sharedGroup; + this.confidentialGroup = confidentialGroup; this.publicGroup = publicGroup; + this.priority = priority; } @NonNull private String contextGroup; @NonNull + private String defaultGroup; + @NonNull private String sharedGroup; @NonNull + private String confidentialGroup; + @NonNull private String publicGroup; + @NonNull + private Integer priority; + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerDescriptor.java similarity index 83% rename from src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerConfiguration.java rename to src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerDescriptor.java index 7353815..ee50500 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerConfiguration.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServerDescriptor.java @@ -20,11 +20,11 @@ import lombok.ToString; @NoArgsConstructor @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) -public class GeoServerConfiguration extends GeoService { +public class GeoServerDescriptor extends GeoServiceDescriptor { - public GeoServerConfiguration(Version version, String baseEndpoint, List accessibleCredentials, + public GeoServerDescriptor(Version version, String baseEndpoint, List accessibleCredentials, String confidentialWorkspace, String contextVisibilityWorkspace, String sharedWorkspace, String publicWorkspace) { super(version, baseEndpoint, accessibleCredentials); @@ -41,6 +41,7 @@ public class GeoServerConfiguration extends GeoService { private String sharedWorkspace; @NonNull private String publicWorkspace; - + @NonNull + private Long hostedLayersCount; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoService.java b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServiceDescriptor.java similarity index 74% rename from src/main/java/org/gcube/spatial/data/sdi/model/service/GeoService.java rename to src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServiceDescriptor.java index d4f0280..9851f00 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoService.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/service/GeoServiceDescriptor.java @@ -1,5 +1,6 @@ package org.gcube.spatial.data.sdi.model.service; +import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -20,9 +21,9 @@ import lombok.ToString; @NoArgsConstructor @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) -public class GeoService { +public class GeoServiceDescriptor { - public GeoService(Version version, String baseEndpoint, List accessibleCredentials) { + public GeoServiceDescriptor(Version version, String baseEndpoint, List accessibleCredentials) { super(); this.version = version; this.baseEndpoint = baseEndpoint; @@ -33,6 +34,6 @@ public class GeoService { @NonNull private String baseEndpoint; @NonNull - private List accessibleCredentials; + private List accessibleCredentials=new ArrayList(); } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsDescriptor.java similarity index 78% rename from src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsConfiguration.java rename to src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsDescriptor.java index ce2a992..14c496b 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsConfiguration.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/service/ThreddsDescriptor.java @@ -19,10 +19,10 @@ import lombok.ToString; @NoArgsConstructor @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) -public class ThreddsConfiguration extends GeoService{ +public class ThreddsDescriptor extends GeoServiceDescriptor{ - public ThreddsConfiguration(Version version, String baseEndpoint, List accessibleCredentials) { + public ThreddsDescriptor(Version version, String baseEndpoint, List accessibleCredentials) { super(version, baseEndpoint, accessibleCredentials); // TODO Auto-generated constructor stub } diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java index a553b88..34c89fd 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java +++ b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java @@ -1,96 +1,113 @@ package org.gcube.spatial.data.sdi.rest; -import java.util.Collection; - +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; -import javax.ws.rs.PUT; 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.MediaType; +import org.gcube.smartgears.annotations.ManagedBy; +import org.gcube.spatial.data.sdi.NetUtils; +import org.gcube.spatial.data.sdi.SDIServiceManager; +import org.gcube.spatial.data.sdi.engine.RoleManager; +import org.gcube.spatial.data.sdi.engine.SDIManager; import org.gcube.spatial.data.sdi.model.ServiceConstants; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; +import org.gcube.spatial.data.sdi.model.services.GeoNetworkServiceDefinition; +import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures; + +import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; -@Slf4j @Path(ServiceConstants.GeoNetwork.INTERFACE) -//@Api(value="GeoNetwork") +@Api(value=ServiceConstants.GeoNetwork.INTERFACE) +@Slf4j +@ManagedBy(SDIServiceManager.class) public class GeoNetwork { -// -// @Inject -// GeoNetworkProvider geonetworkProvider; -// -// -// @GET -// @Path(Constants.GEONETWORK_CONFIGURATION_PATH) -// @Produces(MediaType.APPLICATION_JSON) -// public ScopeConfiguration getConfiguration(){ -// try { -// return geonetworkProvider.getGeoNetwork().getConfiguration().getScopeConfiguration(); -// } catch (MissingConfigurationException | MissingServiceEndpointException e) { -// log.warn("Unable to get GeoNetwork configuration. Current scope is {} ",ScopeUtils.getCurrentScope(),e); -// throw new WebApplicationException("Scope is not well configured. Please contact administrator.", e, Status.PRECONDITION_FAILED); -// } catch (ClientInitializationException e) { -// log.warn("Unable to get GN Client",e); -// throw new WebApplicationException("Internal Error. Please contact administrator.", e, Status.INTERNAL_SERVER_ERROR); -// } -// } -// -// @GET -// @Path(Constants.GEONETWORK_GROUPS_PATH) -// @Produces(MediaType.APPLICATION_JSON) -// public Collection getGroups(){ -// try { -// GeoNetworkAdministration admin=geonetworkProvider.getGeoNetwork(); -// admin.login(LoginLevel.ADMIN); -// return admin.getGroups(); -// } catch (MissingConfigurationException | MissingServiceEndpointException e) { -// log.warn("Unable to get GeoNetwork configuration. Current scope is {} ",ScopeUtils.getCurrentScope(),e); -// throw new WebApplicationException("Scope is not well configured. Please contact administrator.", e, Status.PRECONDITION_FAILED); -// } catch (AuthorizationException e) { -// log.warn("Unable to use Admin rights.",e); -// throw new WebApplicationException("Unable to use Admin rights on GeoNetwork. Please contact administrator.", e, Status.INTERNAL_SERVER_ERROR); -// } catch (GNLibException e) { -// log.warn("Internal library exception.",e); -// throw new WebApplicationException("Internal library exception.", e, Status.INTERNAL_SERVER_ERROR); -// } catch (GNServerException e) { -// log.warn("GeoNEtwork service exception.",e); -// throw new WebApplicationException("GeoNetwork service exception.", e, Status.INTERNAL_SERVER_ERROR); -// } catch (ClientInitializationException e) { -// log.warn("Unable to get GN Client",e); -// throw new WebApplicationException("Internal Error. Please contact administrator.", e, Status.INTERNAL_SERVER_ERROR); -// } -// } - -// @GET -// @Produces(MediaType.APPLICATION_JSON) -// public Collection getList(){ -// -// } -// -// @GET -// @Path("/{host}") -// @Produces(MediaType.APPLICATION_JSON) -// public GeoNetworkDescriptor getById() { -// -// } -// -// @POST -// @Consumes(MediaType.APPLICATION_JSON) -// public GeoNetworkDescriptor register() { -// -// } -// -// @PUT -// @Path("/{host}") -// @Consumes(MediaType.APPLICATION_JSON) -// public GeoNetworkDescriptor modify() { -// -// } -// -// + private final static String HOST_PATH_PARAM="host"; + + + + + @Inject + private SDIManager sdi; + @Inject + private RoleManager roleManager; + + + @GET + @Path("configuration/{"+HOST_PATH_PARAM+"}") + @Produces(MediaType.APPLICATION_JSON) + @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT }) + public GeoNetworkDescriptor getInstanceConfiguration(@PathParam(HOST_PATH_PARAM) String host){ + try{ + log.trace("Serving credentials for host {} ",host); + host=NetUtils.getHost(host); + + return sdi.getGeoNetworkManager().getDescriptorByHostname(host); + + }catch(WebApplicationException e){ + throw e; + }catch(Exception e){ + throw new WebApplicationException("Unable to serve request", e); + } + } + + + @GET + @Path("credentials/{"+HOST_PATH_PARAM+"}") + @Produces(MediaType.APPLICATION_JSON) + @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT }) + public Credentials getInstanceCredentials(@PathParam(HOST_PATH_PARAM) String host){ + try{ + log.trace("Serving credentials for host {} ",host); + host=NetUtils.getHost(host); + return roleManager.getMostAccessible(sdi.getGeoNetworkManager().getDescriptorByHostname(host).getAccessibleCredentials(), false); +// return .get(0); + }catch(WebApplicationException e){ + throw e; + }catch(Exception e){ + throw new WebApplicationException("Unable to serve request", e); + } + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_XML) + public String register(GeoNetworkServiceDefinition toRegister) { + try { + return sdi.registerService(toRegister); + }catch(WebApplicationException e) { + throw e; + }catch(Exception e) { + throw new WebApplicationException("Unable to serve request",e); + } + } + + @POST + @Path("import/{"+HOST_PATH_PARAM+"}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_XML) + public String importFromScope(@QueryParam("sourceToken") String sourceToken,@PathParam(HOST_PATH_PARAM) String host) { + try { + return sdi.importService(sourceToken, host, Type.GEONETWORK); + }catch(WebApplicationException e) { + throw e; + }catch(Exception e) { + throw new WebApplicationException("Unable to serve request",e); + } + } + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java index b1fcb21..5d98823 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java +++ b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java @@ -1,25 +1,25 @@ package org.gcube.spatial.data.sdi.rest; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; - import javax.inject.Inject; +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.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import org.gcube.smartgears.annotations.ManagedBy; +import org.gcube.spatial.data.sdi.NetUtils; import org.gcube.spatial.data.sdi.SDIServiceManager; import org.gcube.spatial.data.sdi.engine.SDIManager; import org.gcube.spatial.data.sdi.model.ServiceConstants; import org.gcube.spatial.data.sdi.model.credentials.Credentials; -import org.gcube.spatial.data.sdi.model.service.GeoServerConfiguration; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; import org.gcube.spatial.data.sdi.model.services.GeoServerDefinition; +import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures; @@ -43,18 +43,13 @@ public class GeoServer { @Path("configuration/{"+HOST_PATH_PARAM+"}") @Produces(MediaType.APPLICATION_JSON) @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT }) - public GeoServerConfiguration getInstanceConfiguration(@PathParam(HOST_PATH_PARAM) String host){ + public GeoServerDescriptor getInstanceConfiguration(@PathParam(HOST_PATH_PARAM) String host){ try{ log.trace("Serving credentials for host {} ",host); - host=getHost(host); - List geoservers=sdi.getContextConfiguration().getGeoserverClusterConfiguration().getAvailableInstances(); - log.trace("Got {} geoservers in current scope ",geoservers.size()); - for(GeoServerConfiguration config : geoservers){ - String configHost=getHost(config.getBaseEndpoint()); - if(configHost.equals(host)) - return config; - } - throw new WebApplicationException("Host "+host+" not found in context"); + host=NetUtils.getHost(host); + + return sdi.getGeoServerManager().getDescriptorByHostname(host); + }catch(WebApplicationException e){ throw e; }catch(Exception e){ @@ -70,15 +65,8 @@ public class GeoServer { public Credentials getInstanceCredentials(@PathParam(HOST_PATH_PARAM) String host){ try{ log.trace("Serving credentials for host {} ",host); - host=getHost(host); - List geoservers=sdi.getContextConfiguration().getGeoserverClusterConfiguration().getAvailableInstances(); - log.trace("Got {} geoservers in current scope ",geoservers.size()); - for(GeoServerConfiguration config : geoservers){ - String configHost=getHost(config.getBaseEndpoint()); - if(configHost.equals(host)) - return config.getAccessibleCredentials().get(0); - } - throw new WebApplicationException("Host "+host+" not found in context"); + host=NetUtils.getHost(host); + return sdi.getGeoServerManager().getDescriptorByHostname(host).getAccessibleCredentials().get(0); }catch(WebApplicationException e){ throw e; }catch(Exception e){ @@ -87,6 +75,7 @@ public class GeoServer { } @POST + @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_XML) public String register(GeoServerDefinition toRegister) { try { @@ -98,13 +87,20 @@ public class GeoServer { } } - - private static final String getHost(String endpoint) throws MalformedURLException{ - log.debug("Get host from endpoint {} ",endpoint); - if(endpoint.startsWith("http")){ - log.debug("Endpoint seems url.."); - return new URL(endpoint).getHost(); + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Path("import/{"+HOST_PATH_PARAM+"}") + @Produces(MediaType.APPLICATION_XML) + public String importFromScope(@QueryParam("sourceToken") String sourceToken,@PathParam(HOST_PATH_PARAM) String host) { + try { + return sdi.importService(sourceToken, host, Type.GEOSERVER); + }catch(WebApplicationException e) { + throw e; + }catch(Exception e) { + throw new WebApplicationException("Unable to serve request",e); } - return endpoint; } + + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java b/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java index 3a662be..8996c7f 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java +++ b/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java @@ -24,12 +24,13 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; import org.gcube.smartgears.annotations.ManagedBy; -import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; -import org.gcube.spatial.data.geonetwork.LoginLevel; import org.gcube.spatial.data.sdi.SDIServiceManager; -import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider; -import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager; +import org.gcube.spatial.data.sdi.engine.GeoNetworkManager; +import org.gcube.spatial.data.sdi.engine.TemplateManager; import org.gcube.spatial.data.sdi.engine.TemporaryPersistence; +import org.gcube.spatial.data.sdi.engine.impl.faults.gn.MetadataNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkClient; +import org.gcube.spatial.data.sdi.engine.impl.gn.extension.GeoNetworkUtils; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataHandler; import org.gcube.spatial.data.sdi.engine.impl.metadata.TemplateApplicationReport; import org.gcube.spatial.data.sdi.model.ServiceConstants; @@ -37,10 +38,10 @@ import org.gcube.spatial.data.sdi.model.metadata.MetadataReport; import org.gcube.spatial.data.sdi.model.metadata.TemplateCollection; import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; -import it.geosolutions.geonetwork.util.GNInsertConfiguration; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -49,10 +50,9 @@ import lombok.extern.slf4j.Slf4j; public class Metadata { @Inject - MetadataTemplateManager templateManager; + TemplateManager templateManager; @Inject - GeoNetworkProvider geonetwork; - + GeoNetworkManager geonetworkManager; @Inject TemporaryPersistence persistence; @@ -89,7 +89,7 @@ public class Metadata { if(metadataEnrichments!=null && !metadataEnrichments.isEmpty()){ try{ log.debug("Applying invocations..."); - TemplateApplicationReport report=templateManager.applyTemplates(uploaded, metadataEnrichments); + TemplateApplicationReport report=templateManager.applyMetadataTemplates(uploaded, metadataEnrichments); toReturn.setAppliedTemplates(report.getAppliedTemplates()); persistence.update(uploadedId, new FileInputStream(new File(report.getGeneratedFilePath()))); }catch(Throwable e){ @@ -109,22 +109,35 @@ public class Metadata { @QueryParam(ServiceConstants.Metadata.PUBLIC_PARAMETER) @DefaultValue("false") Boolean makePublic, @QueryParam(ServiceConstants.Metadata.STYLESHEET_PARAMETER) @DefaultValue("_none_") String styleSheet, @PathParam("gnCategory") String category, @PathParam("uploadedId") String uploadedId){ - try{ log.debug("PUBLISHING METADATA. UPLOADED ID {} ",uploadedId); MetadataReport toReturn=new MetadataReport(); File toPublish=persistence.getById(uploadedId); log.debug("Publishing metadata.. "); - GeoNetworkPublisher publisher=geonetwork.getGeoNetwork(); - publisher.login(LoginLevel.DEFAULT); - GNInsertConfiguration config=publisher.getCurrentUserConfiguration(category, styleSheet); - long id = publisher.insertMetadata(config, toPublish); + + GeoNetworkDescriptor desc=geonetworkManager.getSuggestedInstances().get(0); + GeoNetworkClient client=geonetworkManager.getClient(desc); + String uuid=new MetadataHandler(toPublish).getUUID(); + long id=0; + try { + id=client.insertMetadata(category,styleSheet,validate,Integer.parseInt(desc.getDefaultGroup()),makePublic,toPublish); + }catch(Exception e) { + log.info("INSERT OPERATION FAILED. TRYING TO UPDATE."); + try{ + id=GeoNetworkUtils.getIDByUUID(client, uuid); + client.updateMeta(id, toPublish); + }catch(MetadataNotFoundException e1) { + throw new RuntimeException("Insert Operation failed with unexpected reason (Metadata with uuid "+uuid+" has not been found).",e); + } + } + + toReturn.setPublishedID(id); toReturn.setPublishedUUID(uuid); return toReturn; } catch (FileNotFoundException e) { - log.debug("Unable to ge uploaded with ID {}. Cause : ",uploadedId,e); + log.debug("Unable to get uploaded with ID {}. Cause : ",uploadedId,e); throw new WebApplicationException("Invalid upload id "+uploadedId); }catch(Throwable e ){ log.debug("Unexpected error while publishing {} . Cause : ",uploadedId,e); @@ -139,7 +152,7 @@ public class Metadata { @Produces(MediaType.APPLICATION_JSON) public Collection getList(){ log.debug("Received LIST method"); - TemplateCollection coll= templateManager.getAvailableTemplates(); + TemplateCollection coll= templateManager.getAvailableMetadataTemplates(); log.debug("Gonna respond with {} ",coll); return coll.getAvailableTemplates(); } diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java b/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java index c1298d8..acda6bb 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java +++ b/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java @@ -51,5 +51,7 @@ public class SDI { throw new WebApplicationException("Unable to check Health. Contact administrator.",t); } } + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/Thredds.java b/src/main/java/org/gcube/spatial/data/sdi/rest/Thredds.java new file mode 100644 index 0000000..4589b92 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/rest/Thredds.java @@ -0,0 +1,78 @@ +package org.gcube.spatial.data.sdi.rest; + +import javax.inject.Inject; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; + +import org.gcube.data.transfer.model.plugins.thredds.ThreddsCatalog; +import org.gcube.smartgears.annotations.ManagedBy; +import org.gcube.spatial.data.sdi.SDIServiceManager; +import org.gcube.spatial.data.sdi.ScopeUtils; +import org.gcube.spatial.data.sdi.engine.ThreddsManager; + +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; + +@Path("Thredds") +@Api(value="Thredds") +@Slf4j +@ManagedBy(SDIServiceManager.class) +public class Thredds { + + private static class Constants{ + public static final String AUTHORITY_PARAMETER="authority"; + public static final String PATH_PARAMETER="path"; + public static final String FOLDER_PARAMETER="folder"; + public static final String BASE_NAME_PARAMETER="name"; + } + + + + @Inject + ThreddsManager threddsManager; + + + @PUT + @Produces(MediaType.APPLICATION_JSON) + public ThreddsCatalog registerCatalog(@QueryParam(Constants.AUTHORITY_PARAMETER) @DefaultValue("www.d4science.org") String authority, + @QueryParam(Constants.BASE_NAME_PARAMETER) String baseName, + @QueryParam(Constants.PATH_PARAMETER) String path, + @QueryParam(Constants.FOLDER_PARAMETER) String folder) { + try { + String scopeName=ScopeUtils.getCurrentScopeName(); + + log.info("Received register catalog request under scope {} ",scopeName); + + if(baseName==null) { + log.debug("Base name not provided, using VRE {} ",scopeName); + baseName=scopeName+"_VRE"; + } + + if(folder==null) { + log.debug("Folder not provided, using base name {} ",baseName); + folder=baseName+"_folder"; + } + + if(path==null) { + log.debug("Path not provided, using baseName {} ",baseName); + path=baseName; + } + + + String datasetScanName=(baseName+" Catalog").replace("_", " "); + String datasetScanId=baseName+"_in_"+folder; + String catalogReference=(baseName).replaceAll("_", " "); + + return threddsManager.createCatalogFromTemplate(authority,path,datasetScanId,datasetScanName,folder,catalogReference); + }catch(Throwable t) { + log.debug("Unable to create catalog",t); + throw new WebApplicationException("Unable to serve request", t); + } + } + +} diff --git a/src/main/webapp/WEB-INF/config.properties b/src/main/webapp/WEB-INF/config.properties index d17c6cd..40e58fc 100644 --- a/src/main/webapp/WEB-INF/config.properties +++ b/src/main/webapp/WEB-INF/config.properties @@ -2,26 +2,69 @@ gn.cache.TTL=120000 gn.se.category=Gis gn.se.platform=geonetwork -th.ge.serviceClass=SDI -th.ge.serviceName=GeoNetwork gn.se.priority=priority gn.se.endpointName=geonetwork +gn.se.suffixes=suffixes +gn.se.assigned.scope.prefix=scope +gn.se.scope.user.prefix=scopeUser +gn.se.scope.password.prefix=scopePwd +gn.se.ckan.user.prefix=ckanUser +gn.se.ckan.password.prefix=ckanPwd +gn.se.manager.user.prefix=mngUser +gn.se.manager.password.prefix=mngPwd +gn.se.default.group.prefix=default +gn.se.shared.group.prefix=public +gn.se.confidential.group.prefix=confidential +gn.se.context.group.prefix=private + +gn.groups.all=1 + +gn.ge.serviceClass=SDI +gn.ge.serviceName=GeoNetwork + +gn.update.timeout=60000 +gn.update.wait=500 + +gn.contact.mail=fabio.sinibaldi@isti.cnr.it +gn.password.length=10 + + +gn.mandatorySG=true + + #GEOSERVER gs.cache.TTL=120000 + +gs.cache.hostedLayers.TTL=60000 +gs.cache.styles.TTL=60000 +gs.cache.workspaces.TTL=600000 +gs.cache.datastores.TTL=600000 + + gs.se.category=Gis gs.se.platform=GeoServer gs.ge.serviceClass=SDI gs.ge.serviceName=GeoServer gs.se.endpointName=geoserver + + +gs.mandatorySG=false + + #THREDDS th.cache.TTL=120000 th.se.category=Gis -th.se.platform=thredds +th.se.platform=Thredds th.ge.serviceClass=SDI th.ge.serviceName=Thredds -th.se.endpointName=thredds +th.se.endpointName=Thredds + +th.se.remoteManagement.access=Remote_Management +th.mandatorySG=true + + #Metadata -meta.tpl.folder=WEB-INF/metadataTemplates +tpl.folder=WEB-INF/xmlTemplates #TEMP temp.ttl=120000 #IS diff --git a/src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx b/src/main/webapp/WEB-INF/xmlTemplates/ThreddsOnlineResources.ftlx similarity index 89% rename from src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx rename to src/main/webapp/WEB-INF/xmlTemplates/ThreddsOnlineResources.ftlx index 0385a63..26ae87e 100644 --- a/src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx +++ b/src/main/webapp/WEB-INF/xmlTemplates/ThreddsOnlineResources.ftlx @@ -84,7 +84,7 @@ - http://${hostname}/thredds/dodsC/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/dodsC/${cataloguedPath} WWW:LINK-1.0-http--link @@ -101,7 +101,7 @@ - http://${hostname}/thredds/ncss/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/ncss/${cataloguedPath} WWW:LINK-1.0-http--link @@ -118,7 +118,7 @@ - http://${hostname}/thredds/wcs/public/netcdf/${cataloguedPath}?service=wcs&version=1.0.0&request=GetCoverage&coverage=${layername}&CRS=EPSG:4326&format=geotiff + http://${hostname}/thredds/wcs/${cataloguedPath}?service=wcs&version=1.0.0&request=GetCoverage&coverage=${layername}&CRS=EPSG:4326&format=geotiff OGC:WCS-1.0.0-http-get-coverage @@ -135,7 +135,7 @@ - http://${hostname}/thredds/wms/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/wms/${cataloguedPath} OGC:WMS-1.3.0-http-get-map @@ -152,7 +152,7 @@ - http://${hostname}/thredds/fileServer/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/fileServer/${cataloguedPath} WWW:LINK-1.0-http--link @@ -169,7 +169,7 @@ - http://${hostname}/thredds/ncml/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/ncml/${cataloguedPath} WWW:LINK-1.0-http--link @@ -187,7 +187,7 @@ - http://${hostname}/thredds/uddc/public/netcdf/${cataloguedPath} + http://${hostname}/thredds/uddc/${cataloguedPath} WWW:LINK-1.0-http--link diff --git a/src/main/webapp/WEB-INF/xmlTemplates/thredds_catalog.ftlx b/src/main/webapp/WEB-INF/xmlTemplates/thredds_catalog.ftlx new file mode 100644 index 0000000..c97a8ab --- /dev/null +++ b/src/main/webapp/WEB-INF/xmlTemplates/thredds_catalog.ftlx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + ${AuthorityURL} + + + + + all + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java b/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java index 807d2a6..683a144 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java @@ -5,6 +5,7 @@ import java.net.URL; import org.gcube.spatial.data.sdi.LocalConfiguration; import org.gcube.spatial.data.sdi.engine.impl.GISManagerImpl; import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkManagerImpl; +import org.gcube.spatial.data.sdi.engine.impl.RoleManagerImpl; import org.gcube.spatial.data.sdi.engine.impl.SDIManagerImpl; import org.gcube.spatial.data.sdi.engine.impl.ThreddsManagerImpl; @@ -17,7 +18,7 @@ public class ConfigurationTest { LocalConfiguration.init(propertiesURL); - SDIManagerImpl sdi=new SDIManagerImpl(new GeoNetworkManagerImpl(), new ThreddsManagerImpl(), new GISManagerImpl()); + SDIManagerImpl sdi=new SDIManagerImpl(new GeoNetworkManagerImpl(new RoleManagerImpl()), new ThreddsManagerImpl(), new GISManagerImpl()); System.out.println(sdi.getContextConfiguration()); } diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java b/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java index aac641b..cbc937d 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java @@ -12,8 +12,8 @@ import org.gcube.spatial.data.sdi.LocalConfiguration; import org.gcube.spatial.data.sdi.SDIService; import org.gcube.spatial.data.sdi.engine.GISManager; import org.gcube.spatial.data.sdi.engine.GeoNetworkManager; -import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider; -import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager; +import org.gcube.spatial.data.sdi.engine.TemplateManager; +import org.gcube.spatial.data.sdi.engine.RoleManager; import org.gcube.spatial.data.sdi.engine.SDIManager; import org.gcube.spatial.data.sdi.engine.TemporaryPersistence; import org.gcube.spatial.data.sdi.engine.ThreddsManager; @@ -22,8 +22,8 @@ import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; import org.gcube.spatial.data.sdi.rest.GeoNetwork; import org.gcube.spatial.data.sdi.test.factories.GISManagerFactory; import org.gcube.spatial.data.sdi.test.factories.GeoNetworkManagerFactory; -import org.gcube.spatial.data.sdi.test.factories.GeoNetworkProviderFactory; import org.gcube.spatial.data.sdi.test.factories.MetadataTemplateManagerFactory; +import org.gcube.spatial.data.sdi.test.factories.RoleManagerFactory; import org.gcube.spatial.data.sdi.test.factories.SDIManagerFactory; import org.gcube.spatial.data.sdi.test.factories.TemporaryPersistenceFactory; import org.gcube.spatial.data.sdi.test.factories.ThreddsManagerFactory; @@ -54,12 +54,12 @@ public class MainTest extends JerseyTest{ @Override protected void configure() { bindFactory(TemporaryPersistenceFactory.class).to(TemporaryPersistence.class); - bindFactory(GeoNetworkProviderFactory.class).to(GeoNetworkProvider.class); + bindFactory(RoleManagerFactory.class).to(RoleManager.class); bindFactory(SDIManagerFactory.class).to(SDIManager.class); bindFactory(ThreddsManagerFactory.class).to(ThreddsManager.class); bindFactory(GeoNetworkManagerFactory.class).to(GeoNetworkManager.class); bindFactory(GISManagerFactory.class).to(GISManager.class); - bindFactory(MetadataTemplateManagerFactory.class).to(MetadataTemplateManager.class); + bindFactory(MetadataTemplateManagerFactory.class).to(TemplateManager.class); } } @@ -106,15 +106,15 @@ public class MainTest extends JerseyTest{ -// @Test -// public void getConfiguration(){ -// System.out.println(target(ServiceConstants.INTERFACE).request(MediaType.APPLICATION_JSON_TYPE).get(String.class)); -// } + @Test + public void getConfiguration(){ + System.out.println(target(ServiceConstants.INTERFACE).request(MediaType.APPLICATION_JSON_TYPE).get(String.class)); + } // -// @Test -// public void getGeoServer(){ -// System.out.println(target(ServiceConstants.GeoServer.INTERFACE).path("configuration/geoserver-dev.research-infrastructures.eu").request(MediaType.APPLICATION_JSON_TYPE).get(String.class)); -// } + @Test + public void getGeoServer(){ + System.out.println(target(ServiceConstants.GeoServer.INTERFACE).path("configuration/geoserver1-spatial-dev.d4science.org").request(MediaType.APPLICATION_JSON_TYPE).get(String.class)); + } @Test public void testGetTemplateList(){ diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/MetadataApplicationTest.java b/src/test/java/org/gcube/spatial/data/sdi/test/MetadataApplicationTest.java index 06a613d..63b5e4b 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/MetadataApplicationTest.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/MetadataApplicationTest.java @@ -6,7 +6,7 @@ import java.nio.file.Paths; import javax.xml.transform.TransformerException; import org.gcube.spatial.data.sdi.LocalConfiguration; -import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager; +import org.gcube.spatial.data.sdi.engine.TemplateManager; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataTemplateManagerImpl; import org.gcube.spatial.data.sdi.engine.impl.metadata.TemplateApplicationReport; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocationBuilder; @@ -24,12 +24,12 @@ public class MetadataApplicationTest { manager.init(Paths.get("src/main/webapp/WEB-INF/metadataTemplates").toFile()); - System.out.println(manager.getAvailableTemplates()); + System.out.println(manager.getAvailableMetadataTemplates()); TemplateInvocationBuilder builder=new TemplateInvocationBuilder(); builder.threddsOnlineResources("localhost", "someFileName.sc", "newCatalog"); - TemplateApplicationReport report=manager.applyTemplates(Paths.get("src/test/resources/xml/toEnrichMetadata.xml").toFile(), builder.get()); + TemplateApplicationReport report=manager.applyMetadataTemplates(Paths.get("src/test/resources/xml/toEnrichMetadata.xml").toFile(), builder.get()); System.out.println(report); } diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/NetTests.java b/src/test/java/org/gcube/spatial/data/sdi/test/NetTests.java new file mode 100644 index 0000000..fd5c021 --- /dev/null +++ b/src/test/java/org/gcube/spatial/data/sdi/test/NetTests.java @@ -0,0 +1,14 @@ +package org.gcube.spatial.data.sdi.test; + +import java.io.IOException; + +import org.gcube.spatial.data.sdi.NetUtils; + +public class NetTests { + + public static void main(String[] args) throws IOException { + TokenSetter.set("/gcube/devNext"); + NetUtils.makeAuthorizedCall("thredds-d-d4s.d4science.org", "thredds/admin/debug?catalogs/reinit", "tds", "trythat"); + } + +} diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/RoleManagerTests.java b/src/test/java/org/gcube/spatial/data/sdi/test/RoleManagerTests.java new file mode 100644 index 0000000..b1bd7da --- /dev/null +++ b/src/test/java/org/gcube/spatial/data/sdi/test/RoleManagerTests.java @@ -0,0 +1,33 @@ +package org.gcube.spatial.data.sdi.test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.gcube.spatial.data.sdi.engine.RoleManager; +import org.gcube.spatial.data.sdi.engine.impl.RoleManagerImpl; +import org.gcube.spatial.data.sdi.model.credentials.AccessType; +import org.gcube.spatial.data.sdi.model.credentials.Credentials; + +public class RoleManagerTests { + + + public static void main(String[] args) { + RoleManager manager=new RoleManagerImpl(); + + List toFilter=new ArrayList(); + toFilter.add(new Credentials("admin","adminpwd",AccessType.ADMIN)); + toFilter.add(new Credentials("manager","managerpwd",AccessType.CONTEXT_MANAGER)); + toFilter.add(new Credentials("user","userpwd",AccessType.CONTEXT_USER)); + toFilter.add(new Credentials("ckan","ckanPWD",AccessType.CKAN)); + + +// System.out.println(manager.getMostAccessible(toFilter, false)); +// System.out.println(manager.getMostAccessible(toFilter, true)); +// + System.out.println(manager.getMostAccessible(Arrays.asList( + new Credentials("user","pwd",AccessType.CONTEXT_USER), + new Credentials("ckan","ckanPWD",AccessType.CKAN)), true)); + } + +} diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/TestIS.java b/src/test/java/org/gcube/spatial/data/sdi/test/TestIS.java new file mode 100644 index 0000000..4692e76 --- /dev/null +++ b/src/test/java/org/gcube/spatial/data/sdi/test/TestIS.java @@ -0,0 +1,26 @@ +package org.gcube.spatial.data.sdi.test; + +import java.net.MalformedURLException; +import java.nio.file.Paths; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.spatial.data.sdi.LocalConfiguration; +import org.gcube.spatial.data.sdi.ScopeUtils; +import org.gcube.spatial.data.sdi.engine.impl.is.ISUtils; + +public class TestIS { + + public static void main(String[] args) throws MalformedURLException { + TokenSetter.set("/gcube/devNext"); + LocalConfiguration.init(Paths.get("src/main/webapp/WEB-INF/config.properties").toUri().toURL()); + ServiceEndpoint e=ISUtils.querySEById("c8afa8c0-c781-11e2-8f67-be3b57c971ee"); + System.out.println(ISUtils.updateAndWait(e)); + + System.out.println("PARENTS"); + System.out.println(ScopeUtils.getParentScope("/gcube")); + System.out.println(ScopeUtils.getParentScope("/gcube/devNext")); + System.out.println(ScopeUtils.getParentScope("/gcube/devNext/NextNext")); + + } + +} diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GISManagerFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/GISManagerFactory.java index 80666f3..281897e 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GISManagerFactory.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/factories/GISManagerFactory.java @@ -2,8 +2,12 @@ package org.gcube.spatial.data.sdi.test.factories; import org.gcube.spatial.data.sdi.engine.GISManager; import org.gcube.spatial.data.sdi.engine.impl.GISManagerImpl; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoServerCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoServerController; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.model.service.GeoServerClusterConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoServerDescriptor; import org.gcube.spatial.data.sdi.test.TestCommon; import org.gcube.spatial.data.sdi.test.TokenSetter; import org.glassfish.hk2.api.Factory; @@ -14,11 +18,19 @@ public class GISManagerFactory implements Factory{ public GISManagerFactory() { manager=new GISManagerImpl(){ + @Override - public GeoServerClusterConfiguration getConfiguration() throws ConfigurationNotFoundException { + protected ISModule getRetriever() { TokenSetter.set(TestCommon.TEST_SCOPE); - return super.getConfiguration(); + return super.getRetriever(); } + + @Override + protected AbstractCluster getCluster() { + TokenSetter.set(TestCommon.TEST_SCOPE); + return super.getCluster(); + } + }; } diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkManagerFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkManagerFactory.java index 87564dc..eb0a8bc 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkManagerFactory.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkManagerFactory.java @@ -2,8 +2,10 @@ package org.gcube.spatial.data.sdi.test.factories; import org.gcube.spatial.data.sdi.engine.GeoNetworkManager; import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkManagerImpl; -import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; -import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.GeoNetworkController; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; +import org.gcube.spatial.data.sdi.model.service.GeoNetworkDescriptor; import org.gcube.spatial.data.sdi.test.TestCommon; import org.gcube.spatial.data.sdi.test.TokenSetter; import org.glassfish.hk2.api.Factory; @@ -13,12 +15,18 @@ public class GeoNetworkManagerFactory implements Factory{ private GeoNetworkManager manager; public GeoNetworkManagerFactory() { - manager=new GeoNetworkManagerImpl(){ + manager=new GeoNetworkManagerImpl(new RoleManagerFactory().provide()){ @Override - public GeoNetworkConfiguration getConfiguration() throws ConfigurationNotFoundException { + protected ISModule getRetriever() { TokenSetter.set(TestCommon.TEST_SCOPE); - return super.getConfiguration(); + return super.getRetriever(); } + + @Override + protected AbstractCluster getCluster() { + TokenSetter.set(TestCommon.TEST_SCOPE); + return super.getCluster(); + } }; } diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkProviderFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkProviderFactory.java deleted file mode 100644 index a1c556a..0000000 --- a/src/test/java/org/gcube/spatial/data/sdi/test/factories/GeoNetworkProviderFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.gcube.spatial.data.sdi.test.factories; - -import org.gcube.spatial.data.geonetwork.GeoNetworkAdministration; -import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider; -import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkProviderImpl; -import org.gcube.spatial.data.sdi.engine.impl.faults.ClientInitializationException; -import org.gcube.spatial.data.sdi.test.TokenSetter; -import org.glassfish.hk2.api.Factory; - - -public class GeoNetworkProviderFactory implements Factory{ - - private static class GeoNetworkTestProvider extends GeoNetworkProviderImpl{ - - @Override - public GeoNetworkAdministration getGeoNetwork() throws ClientInitializationException { - TokenSetter.set("/gcube/devsec"); - return super.getGeoNetwork(); - } - - - } - - - @Override - public GeoNetworkProvider provide() { - return new GeoNetworkTestProvider(); - } - - @Override - public void dispose(GeoNetworkProvider arg0) { - // TODO Auto-generated method stub - - } - - - -} diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/MetadataTemplateManagerFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/MetadataTemplateManagerFactory.java index 4d1bcfe..b368743 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/factories/MetadataTemplateManagerFactory.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/factories/MetadataTemplateManagerFactory.java @@ -2,25 +2,25 @@ package org.gcube.spatial.data.sdi.test.factories; import java.nio.file.Paths; -import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager; +import org.gcube.spatial.data.sdi.engine.TemplateManager; import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataTemplateManagerImpl; import org.glassfish.hk2.api.Factory; -public class MetadataTemplateManagerFactory implements Factory{ +public class MetadataTemplateManagerFactory implements Factory{ public MetadataTemplateManagerFactory() { // TODO Auto-generated constructor stub } @Override - public void dispose(MetadataTemplateManager arg0) { + public void dispose(TemplateManager arg0) { // TODO Auto-generated method stub } @Override - public MetadataTemplateManager provide() { + public TemplateManager provide() { MetadataTemplateManagerImpl manager=new MetadataTemplateManagerImpl(); - manager.init(Paths.get("src/main/webapp/WEB-INF/metadataTemplates").toFile()); + manager.init(Paths.get("src/main/webapp/WEB-INF/xmlTemplates").toFile()); return manager; } } diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/RoleManagerFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/RoleManagerFactory.java new file mode 100644 index 0000000..422e89c --- /dev/null +++ b/src/test/java/org/gcube/spatial/data/sdi/test/factories/RoleManagerFactory.java @@ -0,0 +1,19 @@ +package org.gcube.spatial.data.sdi.test.factories; + +import org.gcube.spatial.data.sdi.engine.RoleManager; +import org.gcube.spatial.data.sdi.engine.impl.RoleManagerImpl; +import org.glassfish.hk2.api.Factory; + +public class RoleManagerFactory implements Factory{ + + @Override + public RoleManager provide() { + return new RoleManagerImpl(); + } + + @Override + public void dispose(RoleManager arg0) { + // TODO Auto-generated method stub + + } +} diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/factories/ThreddsManagerFactory.java b/src/test/java/org/gcube/spatial/data/sdi/test/factories/ThreddsManagerFactory.java index 285fc9e..aed6a0b 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/test/factories/ThreddsManagerFactory.java +++ b/src/test/java/org/gcube/spatial/data/sdi/test/factories/ThreddsManagerFactory.java @@ -2,9 +2,12 @@ package org.gcube.spatial.data.sdi.test.factories; import org.gcube.spatial.data.sdi.engine.ThreddsManager; import org.gcube.spatial.data.sdi.engine.impl.ThreddsManagerImpl; +import org.gcube.spatial.data.sdi.engine.impl.cluster.AbstractCluster; +import org.gcube.spatial.data.sdi.engine.impl.cluster.ThreddsController; import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException; +import org.gcube.spatial.data.sdi.engine.impl.is.ISModule; import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport; -import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration; +import org.gcube.spatial.data.sdi.model.service.ThreddsDescriptor; import org.gcube.spatial.data.sdi.test.TestCommon; import org.gcube.spatial.data.sdi.test.TokenSetter; import org.glassfish.hk2.api.Factory; @@ -17,15 +20,16 @@ public class ThreddsManagerFactory implements Factory{ public ThreddsManagerFactory() { manager=new ThreddsManagerImpl(){ @Override - public ThreddsConfiguration getConfiguration() throws ConfigurationNotFoundException { + protected AbstractCluster getCluster() { TokenSetter.set(TestCommon.TEST_SCOPE); - return super.getConfiguration(); + return super.getCluster(); } + @Override - public ServiceHealthReport getHealthReport() { + protected ISModule getRetriever() { TokenSetter.set(TestCommon.TEST_SCOPE); - return super.getHealthReport(); - } + return super.getRetriever(); + } }; }