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