Fabio Sinibaldi 7 years ago
parent 3e4744f651
commit f05904a914

@ -22,15 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>

@ -1,6 +1,7 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/main/webapp=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.7"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="jst.jaxrs" version="2.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.8"/>
</faceted-project>

@ -15,7 +15,7 @@
<properties>
<webappDirectory>${project.basedir}/src/main/webapp/WEB-INF</webappDirectory>
<distroDirectory>${project.basedir}/distro</distroDirectory>
<jersey-version>2.14</jersey-version>
<jersey-version>2.22</jersey-version>
<jersey-cdi-version>2.14</jersey-cdi-version>
<weld-version>2.2.4.Final</weld-version>
</properties>
@ -46,13 +46,25 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.gcube.spatial.data</groupId>
<artifactId>sdi-interface</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.data.transfer</groupId>
<artifactId>data-transfer-library</artifactId>
<version>[1.2.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.resources</groupId>
<artifactId>registry-publisher</artifactId>
</dependency>
<!-- SMARTGEARS -->
<dependency>
<groupId>org.gcube.core</groupId>
@ -155,6 +167,14 @@
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.26-b08</version>
</dependency>
<!-- weld -->
<dependency>
<groupId>javax.enterprise</groupId>
@ -214,6 +234,18 @@
</dependency>
</dependencies>
<repositories>
<repository>
<id>GeoSolutions</id>
<url>http://maven.research-infrastructures.eu/nexus/content/repositories/geo-solutions-snapshots/</url>
</repository>
<repository>
<id>GeoToolkit</id>
<url>http://maven.research-infrastructures.eu:8081/nexus/content/repositories/geotoolkit/</url>
</repository>
</repositories>
<build>
<finalName>${project.artifactId}</finalName>
<testResources>

@ -5,6 +5,7 @@ import java.util.Properties;
import javax.servlet.ServletContext;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -17,8 +18,15 @@ public class LocalConfiguration {
final static public String GEONETWORK_SE_PRIORITY="gn.se.priority";
final static public String GEONETWORK_SE_ENDPOINT_NAME="gn.se.endpointName";
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 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";
final static public String GEOSERVER_SE_CATEGORY="gs.se.category";
final static public String GEOSERVER_SE_PLATFORM="gs.se.platform";
final static public String GEOSERVER_SE_ENDPOINT_NAME="gs.se.endpointName";
final static public String THREDDS_CACHE_TTL="th.cache.TTL";
@ -26,10 +34,14 @@ public class LocalConfiguration {
final static public String THREDDS_SE_PLATFORM="th.se.platform";
final static public String THREDDS_GE_SERVICE_CLASS="th.ge.serviceClass";
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 TEMPORARY_PERSISTENCE_TTL="temp.ttl";
final static public String IS_REGISTRATION_TIMEOUT="is.registration.timeout";
static LocalConfiguration instance=null;
@ -37,8 +49,11 @@ public class LocalConfiguration {
return instance;
}
public static void init(URL propertiesURL){
instance=new LocalConfiguration(propertiesURL);
@Synchronized
public static LocalConfiguration init(URL propertiesURL){
if(instance==null)
instance=new LocalConfiguration(propertiesURL);
return instance;
}
private Properties props=new Properties();
@ -59,4 +74,10 @@ public class LocalConfiguration {
public String getProperty(String property,String defaultValue){
return props.getProperty(property, defaultValue);
}
private Object templateConfiguration=null;
public Object getTemplateConfigurationObject() {return templateConfiguration;}
public void setTemplateConfigurationObject(Object obj) {this.templateConfiguration=obj;}
}

@ -9,6 +9,8 @@ import org.gcube.smartgears.configuration.container.ContainerConfiguration;
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;
@ -17,22 +19,31 @@ import lombok.extern.slf4j.Slf4j;
@ApplicationPath(ServiceConstants.APPLICATION)
public class SDIService extends ResourceConfig{
// @Inject
// MetadataTemplateManager templateManager;
// @Inject
// TemporaryPersistence persistence;
//
public SDIService() {
super();
packages("org.gcube.spatial.data");
packages("org.gcube.spatial.data.sdi.model");
register(io.swagger.jaxrs.listing.ApiListingResource.class);
register(io.swagger.jaxrs.listing.SwaggerSerializers.class);
ApplicationContext context=ContextProvider.get();
register(MultiPartFeature.class);
register(MoxyXmlFeature.class);
ApplicationContext context=ContextProvider.get();
ContainerConfiguration configuration=context.container().configuration();
String hostName=configuration.hostname();
Integer port=configuration.port();
try{
URL resourceUrl = context.application().getResource("/WEB-INF/config.properties");
LocalConfiguration.init(resourceUrl);
LocalConfiguration.init(resourceUrl).
setTemplateConfigurationObject(ContextProvider.get());
}catch(Throwable t){
log.debug("Listing available paths");
for(Object obj:context.application().getResourcePaths("/WEB-INF"))
@ -43,6 +54,7 @@ public class SDIService extends ResourceConfig{
//SWAGGER
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.0");
@ -55,6 +67,23 @@ public class SDIService extends ResourceConfig{
beanConfig.setPrettyPrint(true);
beanConfig.setScan(true);
// System.out.println("********************** SDI INIT *****************************");
//
// log.debug("Initializing persistence manager.. {} :",persistence);
//
// try {
// persistence.init();
// } catch (Throwable t) {
// throw new RuntimeException("Unabel to init persistence. ",t);
// }
// log.debug("Initializing template manager.. {} : ",templateManager);
//
// ApplicationContext ctx = ContextProvider.get();
// templateManager.init(ctx);
//
}

@ -0,0 +1,38 @@
package org.gcube.spatial.data.sdi;
import javax.xml.bind.annotation.XmlRootElement;
import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent.Start;
import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent.Stop;
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@XmlRootElement(name = "sdi-lifecycle")
public class SDIServiceLifecycleManager extends ApplicationLifecycleHandler{
public SDIServiceLifecycleManager() {
// System.out.println("SDI Lifecycle manager created ");
// System.out.println("persistence manager is "+persistence);
// System.out.println("template manager is "+templateManager);
// for(StackTraceElement el:Thread.currentThread().getStackTrace())
// System.out.println(""+el);
}
@Override
public void onStart(Start e) {
super.onStart(e);
}
@Override
public void onStop(Stop e) {
super.onStop(e);
// System.out.println("********************** SDI SHUTDOWN *****************************");
// persistence.shutdown();
}
}

@ -1,33 +1,22 @@
package org.gcube.spatial.data.sdi;
import javax.inject.Inject;
import org.gcube.smartgears.ApplicationManager;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SDIServiceManager implements ApplicationManager {
@Inject
MetadataTemplateManager templateManager;
@Override
public void onInit() {
log.trace("Initializing template manager..");
ApplicationContext ctx = ContextProvider.get();
templateManager.init(ctx);
}
@Override
public void onShutdown() {
// TODO Auto-generated method stub
}
}

@ -1,10 +1,14 @@
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.GeoServerClusterConfiguration;
import org.gcube.spatial.data.sdi.model.services.GeoServerDefinition;
public interface GISManager {
public GeoServerClusterConfiguration getConfiguration() throws ConfigurationNotFoundException;
public ServiceHealthReport getHealthReport();
public String registerService(GeoServerDefinition definition)throws ServiceRegistrationException;
}

@ -1,10 +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.model.services.GeoNetworkServiceDefinition;
public interface GeoNetworkManager {
public GeoNetworkConfiguration getConfiguration() throws ConfigurationNotFoundException;
public ServiceHealthReport getHealthReport();
public String registerService(GeoNetworkServiceDefinition definition)throws ServiceRegistrationException;
}

@ -1,18 +1,19 @@
package org.gcube.spatial.data.sdi.engine;
import java.io.File;
import java.io.IOException;
import java.util.Set;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.spatial.data.sdi.model.metadata.MetadataReport;
import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor;
import javax.xml.transform.TransformerException;
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 Set<TemplateDescriptor> getAvailableTemplates();
public MetadataReport applyTemplates(File original,Set<TemplateInvocation> invocations);
public void init(ApplicationContext ctx);
public TemplateCollection getAvailableTemplates();
public TemplateApplicationReport applyTemplates(File original,Set<TemplateInvocation> invocations) throws IOException, TransformerException;
}

@ -1,9 +1,15 @@
package org.gcube.spatial.data.sdi.engine;
import org.gcube.spatial.data.sdi.engine.impl.faults.ServiceRegistrationException;
import org.gcube.spatial.data.sdi.model.ScopeConfiguration;
import org.gcube.spatial.data.sdi.model.health.HealthReport;
import org.gcube.spatial.data.sdi.model.services.ServiceDefinition;
public interface SDIManager {
public ScopeConfiguration getContextConfiguration();
public HealthReport getHealthReport();
public String registerService(ServiceDefinition definition) throws ServiceRegistrationException;
}

@ -0,0 +1,16 @@
package org.gcube.spatial.data.sdi.engine;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public interface TemporaryPersistence {
public void init() throws IOException;
public String store(InputStream is) throws FileNotFoundException, IOException;
public void clean(String id) throws IOException;
public void update(String id, InputStream is) throws FileNotFoundException, IOException;
public File getById(String id) throws FileNotFoundException;
public void shutdown();
}

@ -1,10 +1,14 @@
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.ThreddsConfiguration;
import org.gcube.spatial.data.sdi.model.services.ThreddsDefinition;
public interface ThreddsManager {
public ThreddsConfiguration getConfiguration() throws ConfigurationNotFoundException;
public ServiceHealthReport getHealthReport();
public String registerService(ThreddsDefinition definition)throws ServiceRegistrationException;
}

@ -7,15 +7,21 @@ 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.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.model.services.GeoServerDefinition;
@Singleton
public class GISManagerImpl implements GISManager {
private Cache<GeoServerClusterConfiguration> theCache=null;
private GeoServerClusterRetriever retriever=null;
public GISManagerImpl() {
theCache=Cache.getCache(new GeoServerClusterRetriever(), Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_CACHE_TTL)), "GeoCluster - cache");
retriever=new GeoServerClusterRetriever();
theCache=Cache.getCache(retriever, Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.GEOSERVER_CACHE_TTL)), "GeoCluster - cache");
}
@ -24,4 +30,14 @@ public class GISManagerImpl implements GISManager {
return theCache.get();
}
@Override
public ServiceHealthReport getHealthReport() {
return retriever.getHealthReport();
}
@Override
public String registerService(GeoServerDefinition definition) throws ServiceRegistrationException {
return retriever.registerService(definition);
}
}

@ -7,16 +7,20 @@ 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.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.model.services.GeoNetworkServiceDefinition;
@Singleton
public class GeoNetworkManagerImpl implements GeoNetworkManager {
private Cache<GeoNetworkConfiguration> cache=null;
private GeoNetworkRetriever retriever=null;
public GeoNetworkManagerImpl() {
cache=Cache.getCache(new GeoNetworkRetriever(),
retriever=new GeoNetworkRetriever();
cache=Cache.getCache(retriever,
Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_CACHE_TTL)),"GeoNetwork - cache");
}
@ -26,4 +30,16 @@ public class GeoNetworkManagerImpl implements GeoNetworkManager {
return cache.get();
}
@Override
public ServiceHealthReport getHealthReport() {
return retriever.getHealthReport();
}
@Override
public String registerService(GeoNetworkServiceDefinition definition) throws ServiceRegistrationException {
return retriever.registerService(definition);
}
}

@ -0,0 +1,36 @@
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;
}
}

@ -1,7 +1,5 @@
package org.gcube.spatial.data.sdi.engine.impl;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -10,14 +8,17 @@ 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;
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.GeoNetworkConfiguration;
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.ThreddsConfiguration;
import org.gcube.spatial.data.sdi.model.service.Version;
import org.gcube.spatial.data.sdi.model.health.HealthReport;
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.services.GeoNetworkServiceDefinition;
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.ThreddsDefinition;
import lombok.extern.slf4j.Slf4j;
@ -26,16 +27,16 @@ import lombok.extern.slf4j.Slf4j;
@Singleton
public class SDIManagerImpl implements SDIManager {
// @Inject
// @Inject
GeoNetworkManager geonetworkManager;
// @Inject
// @Inject
ThreddsManager threddsManager;
// @Inject
// @Inject
GISManager gisManager;
@Inject
public SDIManagerImpl(GeoNetworkManager geonetworkManager, ThreddsManager threddsManager, GISManager gisManager) {
super();
@ -50,9 +51,9 @@ public class SDIManagerImpl implements SDIManager {
@Override
public ScopeConfiguration getContextConfiguration() {
// TODO filter info by user role
ScopeConfiguration toReturn=new ScopeConfiguration();
toReturn.setContextName(ScopeUtils.getCurrentScopeName());
try{
@ -60,20 +61,72 @@ public class SDIManagerImpl implements SDIManager {
}catch(Exception e){
log.warn("Scope is not well configured. Missing GeoNetwork. ",e);
}
try{
toReturn.setThreddsConfiguration(threddsManager.getConfiguration());
}catch(Exception e){
log.warn("THREDDS not found in current scope {} ",ScopeUtils.getCurrentScope());
}
try{
toReturn.setGeoserverClusterConfiguration(gisManager.getConfiguration());
}catch(Exception e){
log.warn("GeoServer not found in current scope {} ",ScopeUtils.getCurrentScope());
}
return toReturn;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
@Override
public HealthReport getHealthReport() {
HealthReport report=new HealthReport();
report.setContext(ScopeUtils.getCurrentScope());
ServiceHealthReport threddsReport=threddsManager.getHealthReport();
report.setThredds(threddsReport);
ServiceHealthReport gnReport=geonetworkManager.getHealthReport();
report.setGeonetwork(gnReport);
ServiceHealthReport gsReport=gisManager.getHealthReport();
report.setGeoserverCluster(gsReport);
Level overall=Level.OK;
if(threddsReport.getOverallStatus().equals(Level.ERROR)||
gnReport.getOverallStatus().equals(Level.ERROR)||
gsReport.getOverallStatus().equals(Level.ERROR)) overall=Level.ERROR;
else if(threddsReport.getOverallStatus().equals(Level.WARNING)||
gnReport.getOverallStatus().equals(Level.WARNING)||
gsReport.getOverallStatus().equals(Level.WARNING)) overall=Level.WARNING;
report.setOverallStatus(overall);
log.debug("Returning report : {} ",report);
return report;
}
@Override
public String registerService(ServiceDefinition definition) throws ServiceRegistrationException{
try {
switch(definition.getType()) {
case GEONETWORK :
return geonetworkManager.registerService((GeoNetworkServiceDefinition)definition);
case GEOSERVER :
return gisManager.registerService((GeoServerDefinition)definition);
case THREDDS :
return threddsManager.registerService((ThreddsDefinition)definition);
default : throw new InvalidServiceDefinitionException("Unable to register. Invalid service type. Definition was "+definition);
}
}catch(ClassCastException e) {
throw new InvalidServiceDefinitionException("Unable to register. Incoherent service type. Definition was "+definition);
}
}
}

@ -0,0 +1,178 @@
package org.gcube.spatial.data.sdi.engine.impl;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;
import org.apache.commons.io.IOUtils;
import org.gcube.spatial.data.sdi.LocalConfiguration;
import org.gcube.spatial.data.sdi.engine.TemporaryPersistence;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Singleton
public class TemporaryPersistenceImpl implements TemporaryPersistence {
private final static String UPLOADING_FILE_SUFFIX=".part";
private final static FileFilter TO_CHECK_FILES_FILTER=new FileFilter() {
@Override
public boolean accept(File pathname) {
return !pathname.isDirectory()&&!pathname.getName().endsWith(UPLOADING_FILE_SUFFIX);
}
};
// *************** CHECKER THREAD
@AllArgsConstructor
private static class CleanUpThread implements Runnable{
private Long TTL;
private File persistenceLocation;
private FileFilter toCheckFiles;
@Override
public void run() {
try{
log.debug("Executing cleanup..");
long count=0l;
for(File found:persistenceLocation.listFiles(toCheckFiles))
if(found.lastModified()-System.currentTimeMillis()>=TTL){
try{
Files.delete(found.toPath());
}catch(Throwable t){
log.warn("Unable to delete {} ",found.getAbsolutePath(),t);
}
}
log.debug("Cleaned up {} files.",count);
}catch(Throwable t){
log.error("Unexpected error.",t);
}
}
}
// private static TemporaryPersistenceImpl singleton=null;
// *************** INSTANCE LOGIC
private File persistenceLocation=null;
private ScheduledExecutorService service=null;
@Override
@PostConstruct
public void init() {
try {
persistenceLocation=Files.createTempDirectory("SDI").toFile();
System.out.println("************************************** TEMPORARY PERSISTENCE INIT **************************");
System.out.println("SDI-Service - Temporary persistence location is "+persistenceLocation.getAbsolutePath());
System.out.println("**************************************");
log.trace("Temporary persistence is "+persistenceLocation.getAbsolutePath());
// init check thread
service = new ScheduledThreadPoolExecutor (1);
long TTL=Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.TEMPORARY_PERSISTENCE_TTL, "120000"));
log.debug("Temp TTL is {} ",TTL);
long delay=TTL/4;
service.scheduleWithFixedDelay(new CleanUpThread(TTL, persistenceLocation, TO_CHECK_FILES_FILTER), delay, delay, TimeUnit.MILLISECONDS);
}catch(Throwable t) {
throw new RuntimeException("Unable to init persistence ",t);
}
}
@Override
public File getById(String id) throws FileNotFoundException {
File toReturn=new File(persistenceLocation,id);
if(!toReturn.exists()) throw new FileNotFoundException();
return toReturn;
}
@Override
public String store(InputStream is) throws FileNotFoundException, IOException {
String partUUID=getUUID()+".part";
log.debug("Storing file "+partUUID);
File created=transferStream(is, new File(persistenceLocation,partUUID));
String toReturn=created.getName().substring(0, created.getName().lastIndexOf(".")-1);
created.renameTo(new File(persistenceLocation,toReturn));
log.debug("Completed. Part renamed to "+toReturn);
return toReturn;
}
@Override
@PreDestroy
public void clean(String id){
try{
System.out.println("*************************************** TEMPORARY PERSISTENCE PRE DESTROY ******************************");
Files.delete(Paths.get(persistenceLocation.getAbsolutePath(), id));
}catch(Throwable t) {
throw new RuntimeException("Unable to clean up temporary persistence. ",t);
}
}
@Override
public void shutdown() {
log.debug("Shutting down persistence..");
service.shutdownNow();
log.debug("Clearing persistence folder..");
for(File f:persistenceLocation.listFiles())
try{
if(!f.delete()) f.deleteOnExit();
}catch(Throwable t){
log.warn("Exception while clearing persistence.. ",t);
}
}
@Override
public void update(String id, InputStream is) throws FileNotFoundException, IOException {
File toUpdate=getById(id);
transferStream(is,toUpdate);
}
private static File transferStream(InputStream in, File destination) throws FileNotFoundException, IOException{
FileOutputStream out=null;
try{
;
out=new FileOutputStream(destination,false);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
return destination;
}finally{
if(out!=null) IOUtils.closeQuietly(out);
}
}
private static String getUUID(){
return UUID.randomUUID().toString().replace(" ", "_");
}
}

@ -7,15 +7,21 @@ 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.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.model.services.ThreddsDefinition;
@Singleton
public class ThreddsManagerImpl implements ThreddsManager {
private Cache<ThreddsConfiguration> cache=null;
private ThreddsRetriever retriever=null;
public ThreddsManagerImpl() {
cache=Cache.getCache(new ThreddsRetriever(),
retriever=new ThreddsRetriever();
cache=Cache.getCache(retriever,
Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_CACHE_TTL)), "THREDDS - CACHE");
}
@ -24,4 +30,14 @@ public class ThreddsManagerImpl implements ThreddsManager {
return cache.get();
}
@Override
public ServiceHealthReport getHealthReport() {
return retriever.getHealthReport();
}
@Override
public String registerService(ThreddsDefinition definition) throws ServiceRegistrationException {
return retriever.registerService(definition);
}
}

@ -0,0 +1,156 @@
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<T> implements ISModule<T> {
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<Status> checkStatuses=new ArrayList<>();
try {
log.trace("Checking {} heatlh under context {} ",getManagedServiceType(),ScopeUtils.getCurrentScope());
//Check if existing
List<GCoreEndpoint> gCoreEndpoints=getGcoreEndpoints();
List<ServiceEndpoint> 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<Status> performInstanceCheck(ServiceEndpoint se);
protected List<GCoreEndpoint> getGcoreEndpoints(){
String geClass=getGCoreEndpointServiceClass();
String geName=getGCoreEndpointServiceName();
return ISUtils.queryForGCoreEndpoint(geClass, geName);
}
protected List<ServiceEndpoint> 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<String> 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<ServiceEndpoint> serviceEndpoints=getServiceEndpoints();
ServiceEndpoint existing=ISUtils.getGCEByHostname(hostname, serviceEndpoints);
if(existing!=null) {
throw new ServiceRegistrationException("Service is already registered");
}
List<GCoreEndpoint> 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;
}
}

@ -13,13 +13,13 @@ public class Cache<T> {
private long objectsTTL;
private ConcurrentHashMap<String,CachedObject<T>> theCache;
private ObjectRetriever<T> retriever;
private ISModule<T> retriever;
private String cacheName;
private Cache(long objectsTTL, ObjectRetriever<T> retriever, String cacheName) {
private Cache(long objectsTTL, ISModule<T> retriever, String cacheName) {
super();
this.objectsTTL = objectsTTL;
this.retriever = retriever;
@ -46,7 +46,7 @@ public class Cache<T> {
for(CachedObject<?> obj:theCache.values())obj.invalidate();
}
public static<T> Cache<T> getCache(ObjectRetriever<T> retriever, long objectsTTL,String cacheName){
public static<T> Cache<T> getCache(ISModule<T> retriever, long objectsTTL,String cacheName){
return new Cache<T>(objectsTTL,retriever,cacheName);
}

@ -4,28 +4,35 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.gcube.common.resources.gcore.GCoreEndpoint;
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.GeoNetworkAdministration;
import org.gcube.spatial.data.geonetwork.configuration.Configuration;
import org.gcube.spatial.data.geonetwork.extension.ServerAccess;
import org.gcube.spatial.data.geonetwork.model.Account;
import org.gcube.spatial.data.geonetwork.model.Account.Type;
import org.gcube.spatial.data.geonetwork.model.ScopeConfiguration;
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.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.Version;
import org.gcube.spatial.data.sdi.model.services.GeoNetworkServiceDefinition;
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 GeoNetworkRetriever implements ObjectRetriever<GeoNetworkConfiguration> {
public class GeoNetworkRetriever extends AbstractISModule<GeoNetworkConfiguration> {
@Override
public GeoNetworkConfiguration getObject() throws ConfigurationNotFoundException {
@ -137,4 +144,82 @@ public class GeoNetworkRetriever implements ObjectRetriever<GeoNetworkConfigurat
return toReturn;
}
@Override
protected String getGCoreEndpointServiceClass() {
return LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_GE_SERVICE_CLASS);
}
@Override
protected String getGCoreEndpointServiceName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_GE_SERVICE_NAME);
}
@Override
protected String getManagedServiceType() {
return "GeoNetwork";
}
@Override
protected String getServiceEndpointCategory() {
return LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_SE_CATEGORY);
}
@Override
protected String getServiceEndpointPlatformName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_SE_PLATFORM);
}
@Override
protected String getServiceEndpointAccessPointName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.GEONETWORK_SE_ENDPOINT_NAME);
}
@Override
protected List<Status> performInstanceCheck(ServiceEndpoint se) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void checkDefinitionForServiceType(ServiceDefinition definition) {
log.info("Checking geonetwork for {} ",definition);
// Contact GN
// try to login with credentials
// check priority of other GNs against the defined one
}
@Override
protected ServiceEndpoint prepareEndpoint(ServiceDefinition definition) {
ServiceEndpoint toReturn= super.prepareEndpoint(definition);
GeoNetworkServiceDefinition gnDefinition=(GeoNetworkServiceDefinition) definition;
AccessPoint point=new AccessPoint();
point.address("http://"+definition.getHostname()+"/geonetwork");
point.credentials(definition.getAdminPassword(), "admin");
point.description("Main Access point");
point.name(getServiceEndpointAccessPointName());
// Priority property
Property priorityProperty=new Property();
priorityProperty.nameAndValue("priority", gnDefinition.getPriority()+"");
point.properties().add(priorityProperty);
// Suffixes property
Property suffixesProperty=new Property();
suffixesProperty.nameAndValue("suffixes", " ");
point.properties().add(suffixesProperty);
toReturn.profile().accessPoints().add(point);
return toReturn;
}
@Override
protected void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException {
if(!definition.getType().equals(Type.GEONETWORK)||!(definition instanceof GeoNetworkServiceDefinition))
throw new InvalidServiceDefinitionException("Invalid service type [expected "+Type.GEONETWORK+"]. Definition was "+definition);
}
}

@ -3,27 +3,55 @@ 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 implements ObjectRetriever<GeoServerClusterConfiguration>{
public class GeoServerClusterRetriever extends AbstractISModule<GeoServerClusterConfiguration>{
@Override
public GeoServerClusterConfiguration getObject() throws ConfigurationNotFoundException {
//TODO skip library
//TODO use both GCoreEndpoints and ServiceEndpoint
try {
ArrayList<GeoServerConfiguration> 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{
@ -44,6 +72,60 @@ public class GeoServerClusterRetriever implements ObjectRetriever<GeoServerClust
}
}
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<Credentials> accessibleCredentials=toReturn.getAccessibleCredentials();
//Admin credentials
accessibleCredentials.add(new Credentials(point.username(),ISUtils.decryptString(point.password()),AccessType.ADMIN));
Map<String,Property> 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);
@ -55,4 +137,50 @@ public class GeoServerClusterRetriever implements ObjectRetriever<GeoServerClust
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<Status> 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);
}
}

@ -0,0 +1,13 @@
package org.gcube.spatial.data.sdi.engine.impl.cache;
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<T> {
public T getObject()throws ConfigurationNotFoundException;
public ServiceHealthReport getHealthReport();
public String registerService(ServiceDefinition definition) throws ServiceRegistrationException;
}

@ -1,14 +1,21 @@
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;
@ -43,4 +50,41 @@ public class ISUtils {
return client.submit(query);
}
static <T> T getGCEByHostname(String hostname, Collection<T> 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<String> queryById(String id) {
DiscoveryClient<String> 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);
}
}
}

@ -1,9 +0,0 @@
package org.gcube.spatial.data.sdi.engine.impl.cache;
import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException;
public interface ObjectRetriever<T> {
public T getObject()throws ConfigurationNotFoundException;
}

@ -1,56 +1,60 @@
package org.gcube.spatial.data.sdi.engine.impl.cache;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
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.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.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.Version;
import org.gcube.spatial.data.sdi.model.services.ServiceDefinition;
import org.gcube.spatial.data.sdi.model.services.ServiceDefinition.Type;
import org.gcube.spatial.data.sdi.model.services.ThreddsDefinition;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ThreddsRetriever implements ObjectRetriever<ThreddsConfiguration> {
public class ThreddsRetriever extends AbstractISModule<ThreddsConfiguration> {
@Override
public ThreddsConfiguration getObject() throws ConfigurationNotFoundException{
log.info("Loading Thredds information from IS. Current Scope is {} ",ScopeUtils.getCurrentScope());
LocalConfiguration config=LocalConfiguration.get();
// Try to look for GCore Endpoints first
String geClass=config.getProperty(LocalConfiguration.THREDDS_GE_SERVICE_CLASS);
String geName=config.getProperty(LocalConfiguration.THREDDS_GE_SERVICE_NAME);
List<GCoreEndpoint> gCoreEndpoints=ISUtils.queryForGCoreEndpoint(geClass, geName);
if(gCoreEndpoints!=null&&!gCoreEndpoints.isEmpty()){
log.debug("Found {} GCore Endpoints ",gCoreEndpoints.size());
for(int i=0;i<gCoreEndpoints.size();i++){
GCoreEndpoint endpoint=gCoreEndpoints.get(i);
try{
log.debug("Checking element {}, ID {} ",i,endpoint.id());
ThreddsConfiguration toReturn=translate(endpoint);
if(toReturn==null) throw new Exception("Translated configuration was null");
return toReturn;
}catch(Throwable t){
log.warn("Unable to read retrieved gCore endpoint ID "+endpoint.id(),t);
}
}
}
// List<GCoreEndpoint> gCoreEndpoints=getGcoreEndpoints();
// if(gCoreEndpoints!=null&&!gCoreEndpoints.isEmpty()){
// log.debug("Found {} GCore Endpoints ",gCoreEndpoints.size());
// for(int i=0;i<gCoreEndpoints.size();i++){
// GCoreEndpoint endpoint=gCoreEndpoints.get(i);
// try{
// log.debug("Checking element {}, ID {} ",i,endpoint.id());
// ThreddsConfiguration toReturn=translate(endpoint);
// if(toReturn==null) throw new Exception("Translated configuration was null");
// return toReturn;
// }catch(Throwable t){
// log.warn("Unable to read retrieved gCore endpoint ID "+endpoint.id(),t);
// }
// }
// }
// Code is executed only if no configuration has been retrieved from gCore endpoints
String seCategory=config.getProperty(LocalConfiguration.THREDDS_SE_CATEGORY);
String sePlatform=config.getProperty(LocalConfiguration.THREDDS_SE_PLATFORM);
List<ServiceEndpoint> threddsSE=ISUtils.queryForServiceEndpoints(seCategory, sePlatform);
List<ServiceEndpoint> threddsSE=getServiceEndpoints();
if(threddsSE!=null&&!threddsSE.isEmpty()){
log.debug("Found {} Service Endpoints ",threddsSE.size());
for(int i=0;i<threddsSE.size();i++){
@ -70,12 +74,112 @@ public class ThreddsRetriever implements ObjectRetriever<ThreddsConfiguration> {
}
private static final ThreddsConfiguration translate(GCoreEndpoint toTranslate){
//
// ThreddsConfiguration toReturn=new ThreddsConfiguration(version, baseEndpoint, accessibleCredentials);
return null;
// @Override
// public ServiceHealthReport getHealthReport() {
// List<Status> checkStatuses=new ArrayList<>();
// try {
//
// log.trace("Checking Thredds heatlh under context {} ",ScopeUtils.getCurrentScope());
// //Check if existing
// List<GCoreEndpoint> gCoreEndpoints=getGcoreEndpoints();
// List<ServiceEndpoint> 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 Thredds service found in context "+ScopeUtils.getCurrentScope(),Level.ERROR));
// else checkStatuses.add(new Status("Unregistered Thredds 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 Thredds hosted on "+hostname;
// log.debug(msg);
// checkStatuses.add(new Status(msg,Level.WARNING));
// }
// }
//
// for(ServiceEndpoint se: serviceEndpoints) {
//
// }
// }catch(Throwable t) {
// log.error("Unable to perform checks", t);
// checkStatuses.add(new Status("Internal error while checking Thredds Status.",Level.ERROR));
// }
// return new ServiceHealthReport(checkStatuses);
// }
@Override
protected String getGCoreEndpointServiceClass() {
return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_GE_SERVICE_CLASS);
}
@Override
protected String getGCoreEndpointServiceName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_GE_SERVICE_NAME);
}
@Override
protected String getManagedServiceType() {
return "THREDDS";
}
@Override
protected String getServiceEndpointCategory() {
return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_CATEGORY);
}
@Override
protected String getServiceEndpointPlatformName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_PLATFORM);
}
@Override
protected String getServiceEndpointAccessPointName() {
return LocalConfiguration.get().getProperty(LocalConfiguration.THREDDS_SE_ENDPOINT_NAME);
}
@Override
protected List<Status> performInstanceCheck(ServiceEndpoint se) {
ArrayList<Status> toReturn=new ArrayList<Status>();
String hostname=se.profile().runtime().hostedOn();
try {
log.trace("Checking thredds hosted on {} ",hostname);
String publicCatalogUrl="www."+hostname+"/thredds/catalog/public/netcdf/catalog.html";
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));
}
}catch(IOException e) {
String msg="Unable to check thredds instance hosted on "+hostname;
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));
}
return toReturn;
}
// private static final ThreddsConfiguration translate(GCoreEndpoint toTranslate){
////
//// ThreddsConfiguration toReturn=new ThreddsConfiguration(version, baseEndpoint, accessibleCredentials);
// return null;
// }
private static final ThreddsConfiguration translate(ServiceEndpoint toTranslate){
Platform platform=toTranslate.profile().platform();
@ -84,4 +188,19 @@ public class ThreddsRetriever implements ObjectRetriever<ThreddsConfiguration> {
Credentials credentials=new Credentials(access.username(),access.password(),AccessType.ADMIN);
return new ThreddsConfiguration(version, access.address(), Collections.singletonList(credentials));
}
@Override
protected void checkDefinitionForServiceType(ServiceDefinition definition)
throws InvalidServiceDefinitionException {
// TODO Auto-generated method stub
}
@Override
protected void checkDefinitionType(ServiceDefinition definition) throws InvalidServiceDefinitionException {
if(!definition.getType().equals(Type.THREDDS)||!(definition instanceof ThreddsDefinition))
throw new InvalidServiceDefinitionException("Invalid service type [expected "+Type.THREDDS+"]. Definition was "+definition);
}
}

@ -0,0 +1,41 @@
package org.gcube.spatial.data.sdi.engine.impl.faults;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import org.gcube.spatial.data.sdi.model.faults.ErrorMessage;
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable ex) {
ErrorMessage errorMessage = new ErrorMessage();
setHttpStatus(ex, errorMessage);
errorMessage.setCode(500);
errorMessage.setMessage(ex.getMessage());
StringWriter errorStackTrace = new StringWriter();
ex.printStackTrace(new PrintWriter(errorStackTrace));
errorMessage.setDeveloperMessage(errorStackTrace.toString());
errorMessage.setLink("www.d4science.org");
return Response.status(errorMessage.getStatus())
.entity(errorMessage)
.type(MediaType.APPLICATION_JSON)
.build();
}
private void setHttpStatus(Throwable ex, ErrorMessage errorMessage) {
if(ex instanceof WebApplicationException ) {
errorMessage.setStatus(((WebApplicationException)ex).getResponse().getStatus());
} else {
errorMessage.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); //defaults to internal server error 500
}
}
}

@ -0,0 +1,39 @@
package org.gcube.spatial.data.sdi.engine.impl.faults;
public class InvalidServiceDefinitionException extends ServiceRegistrationException {
/**
*
*/
private static final long serialVersionUID = -5251767289981417513L;
public InvalidServiceDefinitionException() {
super();
// TODO Auto-generated constructor stub
}
public InvalidServiceDefinitionException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public InvalidServiceDefinitionException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public InvalidServiceDefinitionException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public InvalidServiceDefinitionException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

@ -0,0 +1,38 @@
package org.gcube.spatial.data.sdi.engine.impl.faults;
public class ServiceRegistrationException extends Exception {
/**
*
*/
private static final long serialVersionUID = -1570185699121566715L;
public ServiceRegistrationException() {
super();
// TODO Auto-generated constructor stub
}
public ServiceRegistrationException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public ServiceRegistrationException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ServiceRegistrationException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ServiceRegistrationException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

@ -9,6 +9,10 @@ import java.io.Reader;
import java.util.List;
import java.util.UUID;
import javax.xml.transform.TransformerException;
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.w3c.dom.Document;
@ -59,8 +63,7 @@ public class MetadataHandler {
MetadataUtils.addContent("gmd:MD_Metadata",document,String.format(CommonMetadataPieces.fileIdentifier, metaUUID),helper,MetadataUtils.Position.first_child);
}else {
metaUUID=metaUUIDList.get(0);
log.debug("Found meta UUID {} ",metaUUID);
throw new RuntimeException("FOUND META ID");
log.debug("Found meta UUID {} ",metaUUID);
}
}
return metaUUID;
@ -70,4 +73,13 @@ public class MetadataHandler {
public void addContent(String content, InsertionPoint insertion) throws SAXException, IOException{
MetadataUtils.addContent(insertion.getElementReference(), document, content, helper, insertion.getPosition());
}
public File writeOut() throws IOException, TransformerException{
DOMSource source = new DOMSource(document);
File output=File.createTempFile("meta_", ".xml");
output.createNewFile();
StreamResult result = new StreamResult(output);
MetadataUtils.transformer.transform(source, result);
return output;
}
}

@ -11,7 +11,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Singleton;
import javax.xml.transform.TransformerException;
import org.apache.commons.io.IOUtils;
import org.gcube.smartgears.context.application.ApplicationContext;
@ -20,17 +22,13 @@ 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.impl.metadata.templates.InvalidTemplateInvocationException;
import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.ThreddsOnlineTemplate;
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 freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateNotFoundException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -43,17 +41,37 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager {
private static ArrayList<TemplateDescriptor> templateDescriptors=new ArrayList<>();
private static HashMap<String,AbstractTemplate> availableTemplates=new HashMap<>();
@Override
public void init(ApplicationContext ctx) {
private static TemplateCollection collection;
@PostConstruct
public void defaultInit() {
init(LocalConfiguration.get().getTemplateConfigurationObject());
}
public void init(Object configurationObject) {
log.debug("Configuring with {} ",configurationObject);
// Create your Configuration instance, and specify if up to what FreeMarker
// version (here 2.3.25) do you want to apply the fixes that are not 100%
// backward-compatible. See the Configuration JavaDoc for details.
cfg = new Configuration(Configuration.VERSION_2_3_25);
// cfg.setDirectoryForTemplateLoading(TamplateManager.class.getPackage().new File("src/xmlTemplates"));
cfg.setServletContextForTemplateLoading(ctx, LocalConfiguration.get().getProperty(LocalConfiguration.METADATA_TEMPLATE_FOLDER));
if(configurationObject instanceof ApplicationContext){
log.debug("Configuration is Context : {} ",configurationObject);
cfg.setServletContextForTemplateLoading(((ApplicationContext)configurationObject).application(),
LocalConfiguration.get().getProperty(LocalConfiguration.METADATA_TEMPLATE_FOLDER));
}else if (configurationObject instanceof File){
try{
cfg.setDirectoryForTemplateLoading((File)configurationObject);
}catch(IOException e){
throw new RuntimeException(e);
}
}else throw new RuntimeException("Invalid configuration object");
// Set the preferred charset template files are stored in. UTF-8 is
// a good choice in most applications:
@ -73,8 +91,11 @@ 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());
collection=new TemplateCollection(new HashSet<>(templateDescriptors));
}
//
@ -102,32 +123,37 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager {
@Override
public Set<TemplateDescriptor> getAvailableTemplates() {
return new HashSet<>(templateDescriptors);
public TemplateCollection getAvailableTemplates() {
return collection;
}
@Override
public MetadataReport applyTemplates(File original, Set<TemplateInvocation> invocations) {
MetadataReport report=new MetadataReport();
public TemplateApplicationReport applyTemplates(File original, Set<TemplateInvocation> invocations) throws IOException, TransformerException {
log.debug("Applying template invocations {} to {} ",invocations,original.getAbsolutePath());
TemplateApplicationReport report=new TemplateApplicationReport();
report.setRequestedInvocations(invocations);
HashSet<String> appliedTemplates=new HashSet<>();
MetadataHandler handler=new MetadataHandler(original);
for(TemplateInvocation invocation:invocations){
try{
applyTemplate(original, invocation);
applyTemplate(original, invocation,handler);
appliedTemplates.add(invocation.getToInvokeTemplateID());
}catch(Throwable t){
log.warn("Unable to apply template {} ",invocation.getToInvokeTemplateID());
log.debug("StackTrace : ",t);
}
}
}
log.debug("Writing out result..");
report.setGeneratedFilePath(handler.writeOut().getAbsolutePath());
report.setAppliedTemplates(appliedTemplates);
return report;
}
private static void applyTemplate(File original,TemplateInvocation invocation) throws Exception{
private static void applyTemplate(File original,TemplateInvocation invocation,MetadataHandler handler) throws Exception{
log.debug("Instantiating "+invocation);
AbstractTemplate tpl=availableTemplates.get(invocation.getToInvokeTemplateID());
if(tpl==null) throw new InvalidTemplateInvocationException("Template with ID "+invocation.getToInvokeTemplateID()+" was not found");
Writer out=null;
MetadataHandler handler=new MetadataHandler(original);
Writer out=null;
try{
Template temp = cfg.getTemplate(tpl.getFileName());
ByteArrayOutputStream baos=new ByteArrayOutputStream();
@ -137,8 +163,7 @@ public class MetadataTemplateManagerImpl implements MetadataTemplateManager {
String instantiatedTemplate= baos.toString(StandardCharsets.UTF_8.toString());
//apply to original
handler.addContent(instantiatedTemplate, tpl.getInsertionPoint());
handler.addContent(instantiatedTemplate, tpl.getInsertionPoint());
} catch (Exception e) {
log.error("Unable to apply template. Invocation was {} ",invocation,e);
throw e;

@ -0,0 +1,15 @@
package org.gcube.spatial.data.sdi.engine.impl.metadata;
import java.util.Set;
import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation;
import lombok.Data;
@Data
public class TemplateApplicationReport {
private String generatedFilePath;
private Set<String> appliedTemplates;
private Set<TemplateInvocation> requestedInvocations;
}

@ -1,5 +1,7 @@
package org.gcube.spatial.data.sdi.engine.impl.metadata.templates;
import java.util.Map;
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.metadata.TemplateDescriptor;
@ -32,5 +34,10 @@ public abstract class AbstractTemplate<T> {
public abstract T getInstantiationRequest(MetadataHandler original, TemplateInvocation invocation) throws InvalidTemplateInvocationException,Exception;
protected String getParameter(String parameterName, Map<String,String> 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);
}
}

@ -1,12 +1,14 @@
package org.gcube.spatial.data.sdi.engine.impl.metadata.templates;
import java.util.HashMap;
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.metadata.TemplateDescriptor;
import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation;
import org.gcube.spatial.data.sdi.model.metadata.ThreddsOnlineTemplateInvocation;
import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocationBuilder;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ -14,11 +16,23 @@ import lombok.ToString;
public class ThreddsOnlineTemplate extends AbstractTemplate<ThreddsOnlineRequest> {
private static String TEMPLATE_ID="THREDDS-ONLINE";
private static HashMap<String,String> EXPECTED_PARAMETERS=new HashMap<String,String>();
private static String TEMPLATE_ID=TemplateInvocationBuilder.THREDDS_ONLINE.ID;
private static String TEMPLATE_NAME="Thredds Online Resources";
private static String FILENAME="ThreddsOnlineResources.ftlx";
private static InsertionPoint INSERTION=new InsertionPoint(Position.sibling_after, "");
private static TemplateDescriptor DESCRIPTOR=new TemplateDescriptor(TEMPLATE_ID, TEMPLATE_NAME, "Template for online resources exposed by thredds.", "http://sdi-d4s.d4science.org");
private static InsertionPoint INSERTION=new InsertionPoint(Position.sibling_after, "//gmd:identificationInfo");
private static TemplateDescriptor DESCRIPTOR;
static {
EXPECTED_PARAMETERS.put(TemplateInvocationBuilder.THREDDS_ONLINE.CATALOG, "The thredds catalog name");
EXPECTED_PARAMETERS.put(TemplateInvocationBuilder.THREDDS_ONLINE.FILENAME, "The dataset's file name");
EXPECTED_PARAMETERS.put(TemplateInvocationBuilder.THREDDS_ONLINE.HOSTNAME, "Thredds hostname");
DESCRIPTOR=new TemplateDescriptor(TEMPLATE_ID, TEMPLATE_NAME, "Template for online resources exposed by thredds.", "http://sdi-d4s.d4science.org",EXPECTED_PARAMETERS);
}
public ThreddsOnlineTemplate() {
@ -38,14 +52,14 @@ public class ThreddsOnlineTemplate extends AbstractTemplate<ThreddsOnlineRequest
@Override
public ThreddsOnlineRequest getInstantiationRequest(MetadataHandler handler, TemplateInvocation invocation) throws InvalidTemplateInvocationException,Exception{
try{
ThreddsOnlineTemplateInvocation threddsInvocation=(ThreddsOnlineTemplateInvocation) invocation;
if(!invocation.getToInvokeTemplateID().equals(TEMPLATE_ID)) throw new InvalidTemplateInvocationException("Invalid template ID : "+invocation.getToInvokeTemplateID());
String filename =getParameter(TemplateInvocationBuilder.THREDDS_ONLINE.FILENAME, invocation.getTemplateParameters(), true, null);
String catalog =getParameter(TemplateInvocationBuilder.THREDDS_ONLINE.CATALOG, invocation.getTemplateParameters(), true, null);
String hostname =getParameter(TemplateInvocationBuilder.THREDDS_ONLINE.HOSTNAME, invocation.getTemplateParameters(), true, null);
String uuid=handler.getUUID();
String gisLink=MetadataUtils.getGisLinkByUUID(uuid);
return new ThreddsOnlineRequest(threddsInvocation.getHostname(), threddsInvocation.getCatalog(), threddsInvocation.getFilename(), gisLink);
}catch(ClassCastException e){
throw new InvalidTemplateInvocationException("Invalid invocation type : "+invocation.getClass());
}
return new ThreddsOnlineRequest(hostname, catalog, filename, gisLink);
}
}

@ -0,0 +1,32 @@
package org.gcube.spatial.data.sdi.model.health;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class HealthReport {
private Level overallStatus;
private String context;
private ServiceHealthReport thredds;
private ServiceHealthReport geonetwork;
private ServiceHealthReport geoserverCluster;
}

@ -0,0 +1,8 @@
package org.gcube.spatial.data.sdi.model.health;
import javax.xml.bind.annotation.XmlEnum;
@XmlEnum
public enum Level{
WARNING,ERROR,OK
}

@ -0,0 +1,48 @@
package org.gcube.spatial.data.sdi.model.health;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class ServiceHealthReport {
private Level overallStatus;
private List<Status> checkReports;
public ServiceHealthReport(List<Status> checkReports) {
super();
this.checkReports = checkReports;
overallStatus =Level.OK;
for(Status st:checkReports)
if(st.getLevel().equals(Level.ERROR)) {
overallStatus=Level.ERROR;
break;
}
else if(st.getLevel().equals(Level.WARNING)&&(overallStatus.equals(Level.OK)))
overallStatus=Level.WARNING;
}
}

@ -0,0 +1,28 @@
package org.gcube.spatial.data.sdi.model.health;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Status {
private String message;
private Level level;
}

@ -22,8 +22,7 @@ import lombok.ToString;
@XmlAccessorType(XmlAccessType.FIELD)
public class GeoServerConfiguration extends GeoService {
public GeoServerConfiguration(Version version, String baseEndpoint, List<Credentials> accessibleCredentials,
String confidentialWorkspace, String contextVisibilityWorkspace, String sharedWorkspace,

@ -1,6 +1,14 @@
package org.gcube.spatial.data.sdi.rest;
import java.util.Collection;
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.Produces;
import javax.ws.rs.core.MediaType;
import org.gcube.spatial.data.sdi.model.ServiceConstants;
@ -56,7 +64,33 @@ public class GeoNetwork {
// }
// }
// @GET
// @Produces(MediaType.APPLICATION_JSON)
// public Collection<GeoNetworkDescriptor> 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() {
//
// }
//
//
}

@ -6,16 +6,20 @@ import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import org.gcube.smartgears.annotations.ManagedBy;
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.services.GeoServerDefinition;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
@ -26,6 +30,7 @@ import lombok.extern.slf4j.Slf4j;
@Path(ServiceConstants.GeoServer.INTERFACE)
@Api(value=ServiceConstants.GeoServer.INTERFACE)
@Slf4j
@ManagedBy(SDIServiceManager.class)
public class GeoServer {
private final static String HOST_PATH_PARAM="host";
@ -81,6 +86,18 @@ public class GeoServer {
}
}
@POST
@Produces(MediaType.APPLICATION_XML)
public String register(GeoServerDefinition toRegister) {
try {
return sdi.registerService(toRegister);
}catch(WebApplicationException e) {
throw e;
}catch(Exception e) {
throw new WebApplicationException("Unable to serve request",e);
}
}
private static final String getHost(String endpoint) throws MalformedURLException{
log.debug("Get host from endpoint {} ",endpoint);

@ -1,7 +1,12 @@
package org.gcube.spatial.data.sdi.rest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
@ -9,49 +14,138 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
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 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.TemporaryPersistence;
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;
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.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import it.geosolutions.geonetwork.util.GNInsertConfiguration;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Path(ServiceConstants.Metadata.INTERFACE)
@ManagedBy(SDIServiceManager.class)
public class Metadata {
@Inject
MetadataTemplateManager templateManager;
@Inject
GeoNetworkProvider geonetwork;
@Inject
TemporaryPersistence persistence;
@POST
@Path("/{gnCategory}")
@Consumes(MediaType.WILDCARD)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public MetadataReport pushMetadata(@QueryParam(ServiceConstants.Metadata.VALIDATE_PARAMETER) @DefaultValue("true") Boolean validate,
@QueryParam(ServiceConstants.Metadata.PUBLIC_PARAMETER) @DefaultValue("false") Boolean makePublic,
@FormDataParam(ServiceConstants.Metadata.UPLOADED_FILE_PARAMETER) InputStream uploadedMeta,
@FormDataParam(ServiceConstants.Metadata.UPLOADED_FILE_PARAMETER) FormDataContentDisposition uploadedMetaDetails,
@FormDataParam(ServiceConstants.Metadata.METADATA_ENRICHMENTS_PARAMETER) Set<String> metadataEnrichments){
public String uploadMetadata(@FormDataParam(ServiceConstants.Metadata.UPLOADED_FILE_PARAMETER) InputStream uploadedMeta,
@FormDataParam(ServiceConstants.Metadata.UPLOADED_FILE_PARAMETER) FormDataContentDisposition uploadedMetaDetails){
try {
log.debug("Receiving metadata upload... size {} ",uploadedMetaDetails.getSize());
return persistence.store(uploadedMeta);
} catch (IOException e) {
log.error("Unable to store file. ",e);
throw new WebApplicationException("Unable to store file locally. Cause : "+e.getMessage(),Status.INTERNAL_SERVER_ERROR);
}
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{uploadedId}")
public MetadataReport applyTemplates(Collection<TemplateInvocation> templateInvocations, @PathParam("uploadedId") String uploadedId){
log.debug("Checking uploaded id {} ",uploadedId);
File uploaded=null;
try {
uploaded=persistence.getById(uploadedId);
} catch (FileNotFoundException e) {
log.debug("Unable to ge uploaded with ID {}. Cause : ",uploadedId,e);
throw new WebApplicationException("Invalid upload id "+uploadedId);
}
MetadataReport toReturn=new MetadataReport();
Set<TemplateInvocation> metadataEnrichments=new HashSet<>(templateInvocations);
//Receive metadata
//Optionally enrich it
//Publish it NB : validate & make public
return null;
if(metadataEnrichments!=null && !metadataEnrichments.isEmpty()){
try{
log.debug("Applying invocations...");
TemplateApplicationReport report=templateManager.applyTemplates(uploaded, metadataEnrichments);
toReturn.setAppliedTemplates(report.getAppliedTemplates());
persistence.update(uploadedId, new FileInputStream(new File(report.getGeneratedFilePath())));
}catch(Throwable e){
log.debug("Unable to apply templates. ",e);
throw new WebApplicationException("Unable to apply templates. Cause : "+e.getMessage(),Status.INTERNAL_SERVER_ERROR);
}
}
return toReturn;
}
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/publish/{uploadedId}/{gnCategory}")
public MetadataReport publishMetadata(@QueryParam(ServiceConstants.Metadata.VALIDATE_PARAMETER) @DefaultValue("true") Boolean validate,
@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);
String uuid=new MetadataHandler(toPublish).getUUID();
toReturn.setPublishedID(id);
toReturn.setPublishedUUID(uuid);
return toReturn;
} catch (FileNotFoundException e) {
log.debug("Unable to ge 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);
throw new WebApplicationException("Unabel to publish metadata. Cause "+e.getMessage(),Status.INTERNAL_SERVER_ERROR);
}
}
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public Set<TemplateDescriptor> getList(){
return templateManager.getAvailableTemplates();
public Collection<TemplateDescriptor> getList(){
log.debug("Received LIST method");
TemplateCollection coll= templateManager.getAvailableTemplates();
log.debug("Gonna respond with {} ",coll);
return coll.getAvailableTemplates();
}
}

@ -4,19 +4,26 @@ import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import org.gcube.smartgears.annotations.ManagedBy;
import org.gcube.spatial.data.sdi.SDIServiceManager;
import org.gcube.spatial.data.sdi.engine.SDIManager;
import org.gcube.spatial.data.sdi.model.ScopeConfiguration;
import org.gcube.spatial.data.sdi.model.ServiceConstants;
import org.gcube.spatial.data.sdi.model.health.HealthReport;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
@Path(ServiceConstants.INTERFACE)
@Api(value=ServiceConstants.INTERFACE)
@ManagedBy(SDIServiceManager.class)
@Slf4j
public class SDI {
@Inject
@ -30,5 +37,19 @@ public class SDI {
return sdiManager.getContextConfiguration();
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT })
@Path("status")
public HealthReport getReport() {
try{
return sdiManager.getHealthReport();
}catch(Throwable t) {
log.error("Unabel to get Health Report ",t);
throw new WebApplicationException("Unable to check Health. Contact administrator.",t);
}
}
}

@ -2,17 +2,27 @@
gn.cache.TTL=120000
gn.se.category=Gis
gn.se.platform=geonetwork
th.ge.serviceClass=SDI
th.ge.serviceName=GeoNetwork
gn.se.priority=priority
gn.se.endpointName=geonetwork
#GEOSERVER
gs.cache.TTL=120000
gs.se.category=Gis
gs.se.platform=GeoServer
gs.ge.serviceClass=SDI
gs.ge.serviceName=GeoServer
gs.se.endpointName=geoserver
#THREDDS
th.cache.TTL=120000
th.se.category=Gis
th.se.platform=thredds
th.ge.serviceClass=SDI
th.ge.serviceName=THREDDS
th.ge.serviceName=Thredds
th.se.endpointName=thredds
#Metadata
meta.tpl.folder=metadataTemplates
meta.tpl.folder=WEB-INF/metadataTemplates
#TEMP
temp.ttl=120000
#IS
is.registration.timeout=60000

@ -9,7 +9,7 @@
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<directory>/home/fabio/workspaces/trunk_workspace/sdi-service-TRUNK/distro</directory>
<directory>/home/fabio/workspaces/trunk_workspace/sdi-service/distro</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>

@ -0,0 +1,5 @@
<handlers>
<lifecycle>
<sdi-lifecycle />
</lifecycle>
</handlers>

@ -1,4 +1,4 @@
<gmd:distributionInfo>
<gmd:distributionInfo xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:fra="http://www.cnig.gouv.fr/2005/fra" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink">
<gmd:MD_Distribution>
<gmd:distributionFormat>
<gmd:MD_Format>

@ -1,19 +1,25 @@
<web-app>
<servlet>
<servlet-name>org.gcube.spatial.data.sdi.SDIService</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.gcube.spatial.data.sdi.SDIService</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>org.gcube.spatial.data.sdi.SDIService</servlet-name>
<url-pattern>/gcube/service/*</url-pattern>
</servlet-mapping>
<servlet-name>org.gcube.spatial.data.sdi.SDIService</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.gcube.spatial.data.sdi.SDIService</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.xml.formatOutput</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>org.gcube.spatial.data.sdi.SDIService</servlet-name>
<url-pattern>/gcube/service/*</url-pattern>
</servlet-mapping>
</web-app>

@ -1,24 +1,48 @@
package org.gcube.spatial.data.sdi.test;
import java.net.MalformedURLException;
import java.nio.file.Paths;
import java.util.List;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import org.gcube.spatial.data.sdi.LocalConfiguration;
import org.gcube.spatial.data.sdi.SDIService;
import org.gcube.spatial.data.sdi.engine.GISManager;
import org.gcube.spatial.data.sdi.engine.GeoNetworkManager;
import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider;
import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
import org.gcube.spatial.data.sdi.engine.SDIManager;
import org.gcube.spatial.data.sdi.engine.TemporaryPersistence;
import org.gcube.spatial.data.sdi.engine.ThreddsManager;
import org.gcube.spatial.data.sdi.model.ServiceConstants;
import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor;
import org.gcube.spatial.data.sdi.rest.GeoNetwork;
import org.gcube.spatial.data.sdi.test.factories.GISManagerFactory;
import org.gcube.spatial.data.sdi.test.factories.GeoNetworkManagerFactory;
import org.gcube.spatial.data.sdi.test.factories.GeoNetworkProviderFactory;
import org.gcube.spatial.data.sdi.test.factories.MetadataTemplateManagerFactory;
import org.gcube.spatial.data.sdi.test.factories.SDIManagerFactory;
import org.gcube.spatial.data.sdi.test.factories.TemporaryPersistenceFactory;
import org.gcube.spatial.data.sdi.test.factories.ThreddsManagerFactory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.BeforeClass;
import org.junit.Test;
import io.swagger.jaxrs.config.BeanConfig;
public class MainTest extends JerseyTest{
@BeforeClass
public static void init() throws MalformedURLException {
LocalConfiguration.init(Paths.get("src/main/webapp/WEB-INF/config.properties").toUri().toURL());
}
public static class MyBinder extends AbstractBinder{
@ -29,11 +53,13 @@ public class MainTest extends JerseyTest{
@Override
protected void configure() {
// bindFactory(GeoNetworkProviderFactory.class).to(GeoNetworkProvider.class);
bindFactory(TemporaryPersistenceFactory.class).to(TemporaryPersistence.class);
bindFactory(GeoNetworkProviderFactory.class).to(GeoNetworkProvider.class);
bindFactory(SDIManagerFactory.class).to(SDIManager.class);
bindFactory(ThreddsManagerFactory.class).to(ThreddsManager.class);
bindFactory(GeoNetworkManagerFactory.class).to(GeoNetworkManager.class);
bindFactory(GISManagerFactory.class).to(GISManager.class);
bindFactory(MetadataTemplateManagerFactory.class).to(MetadataTemplateManager.class);
}
}
@ -63,7 +89,7 @@ public class MainTest extends JerseyTest{
//Multipart
// config.packages("org.glassfish.jersey.media.multipart");
config.packages("org.gcube.spatial.data");
// config.register(MultiPartFeature.class);
config.register(MultiPartFeature.class);
return config;
}
@ -78,16 +104,34 @@ public class MainTest extends JerseyTest{
// getUri());
// }
// @Test
// public void getConfiguration(){
// System.out.println(target(ServiceConstants.INTERFACE).request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
// }
//
// @Test
// public void getGeoServer(){
// System.out.println(target(ServiceConstants.GeoServer.INTERFACE).path("configuration/geoserver-dev.research-infrastructures.eu").request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
// }
@Test
public void getConfiguration(){
System.out.println(target(ServiceConstants.INTERFACE).request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
public void testGetTemplateList(){
List<TemplateDescriptor> result=target(ServiceConstants.Metadata.INTERFACE).
path(ServiceConstants.Metadata.LIST_METHOD).
request(MediaType.APPLICATION_JSON_TYPE).get().
readEntity(new GenericType<List<TemplateDescriptor>>() {});
System.out.println(result);
}
@Test
public void getGeoServer(){
System.out.println(target(ServiceConstants.GeoServer.INTERFACE).path("configuration/geoserver-dev.research-infrastructures.eu").request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
public void testHealthReport() {
System.out.println(target(ServiceConstants.INTERFACE).path("status").request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
System.out.println(target(ServiceConstants.INTERFACE).path("status").request(MediaType.APPLICATION_XML_TYPE).get(String.class));
}
//
// @Test
// public void getSwagger(){

@ -0,0 +1,37 @@
package org.gcube.spatial.data.sdi.test;
import java.io.IOException;
import java.nio.file.Paths;
import javax.xml.transform.TransformerException;
import org.gcube.spatial.data.sdi.LocalConfiguration;
import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataTemplateManagerImpl;
import org.gcube.spatial.data.sdi.engine.impl.metadata.TemplateApplicationReport;
import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocationBuilder;
import org.junit.Test;
public class MetadataApplicationTest {
@Test
public void apply() throws IOException, TransformerException{
TokenSetter.set("/gcube/devsec/devVRE");
MetadataTemplateManagerImpl manager=new MetadataTemplateManagerImpl();
// LocalConfiguration.init(Paths.get("src/main/webapp/WEB-INF/config.properties").toUri().toURL())
// .setTemplateConfigurationObject(Paths.get("src/main/webapp/WEB-INF/metadataTemplates").toFile());
manager.init(Paths.get("src/main/webapp/WEB-INF/metadataTemplates").toFile());
System.out.println(manager.getAvailableTemplates());
TemplateInvocationBuilder builder=new TemplateInvocationBuilder();
builder.threddsOnlineResources("localhost", "someFileName.sc", "newCatalog");
TemplateApplicationReport report=manager.applyTemplates(Paths.get("src/test/resources/xml/toEnrichMetadata.xml").toFile(), builder.get());
System.out.println(report);
}
}

@ -1,9 +1,11 @@
package org.gcube.spatial.data.sdi.test;
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.sdi.engine.GISManager;
import org.gcube.spatial.data.sdi.engine.impl.GISManagerImpl;
import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException;
import org.gcube.spatial.data.sdi.model.service.GeoServerClusterConfiguration;
import org.gcube.spatial.data.sdi.test.TestCommon;
import org.gcube.spatial.data.sdi.test.TokenSetter;
import org.glassfish.hk2.api.Factory;
public class GISManagerFactory implements Factory<GISManager>{

@ -1,9 +1,11 @@
package org.gcube.spatial.data.sdi.test;
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.sdi.engine.GeoNetworkManager;
import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkManagerImpl;
import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException;
import org.gcube.spatial.data.sdi.model.service.GeoNetworkConfiguration;
import org.gcube.spatial.data.sdi.test.TestCommon;
import org.gcube.spatial.data.sdi.test.TokenSetter;
import org.glassfish.hk2.api.Factory;
public class GeoNetworkManagerFactory implements Factory<GeoNetworkManager>{

@ -1,9 +1,10 @@
package org.gcube.spatial.data.sdi.test;
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.geonetwork.GeoNetworkAdministration;
import org.gcube.spatial.data.sdi.engine.GeoNetworkProvider;
import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkProviderImpl;
import org.gcube.spatial.data.sdi.engine.impl.faults.ClientInitializationException;
import org.gcube.spatial.data.sdi.test.TokenSetter;
import org.glassfish.hk2.api.Factory;

@ -0,0 +1,26 @@
package org.gcube.spatial.data.sdi.test.factories;
import java.nio.file.Paths;
import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
import org.gcube.spatial.data.sdi.engine.impl.metadata.MetadataTemplateManagerImpl;
import org.glassfish.hk2.api.Factory;
public class MetadataTemplateManagerFactory implements Factory<MetadataTemplateManager>{
public MetadataTemplateManagerFactory() {
// TODO Auto-generated constructor stub
}
@Override
public void dispose(MetadataTemplateManager arg0) {
// TODO Auto-generated method stub
}
@Override
public MetadataTemplateManager provide() {
MetadataTemplateManagerImpl manager=new MetadataTemplateManagerImpl();
manager.init(Paths.get("src/main/webapp/WEB-INF/metadataTemplates").toFile());
return manager;
}
}

@ -1,8 +1,11 @@
package org.gcube.spatial.data.sdi.test;
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.sdi.engine.SDIManager;
import org.gcube.spatial.data.sdi.engine.impl.SDIManagerImpl;
import org.gcube.spatial.data.sdi.model.ScopeConfiguration;
import org.gcube.spatial.data.sdi.model.health.HealthReport;
import org.gcube.spatial.data.sdi.test.TestCommon;
import org.gcube.spatial.data.sdi.test.TokenSetter;
import org.glassfish.hk2.api.Factory;
public class SDIManagerFactory implements Factory<SDIManager>{
@ -17,6 +20,11 @@ public class SDIManagerFactory implements Factory<SDIManager>{
TokenSetter.set(TestCommon.TEST_SCOPE);
return super.getContextConfiguration();
}
@Override
public HealthReport getHealthReport() {
TokenSetter.set(TestCommon.TEST_SCOPE);
return super.getHealthReport();
}
};
}

@ -0,0 +1,24 @@
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.sdi.engine.TemporaryPersistence;
import org.gcube.spatial.data.sdi.engine.impl.TemporaryPersistenceImpl;
import org.glassfish.hk2.api.Factory;
public class TemporaryPersistenceFactory implements Factory<TemporaryPersistence>{
@Override
public void dispose(TemporaryPersistence arg0) {
arg0.shutdown();
}
@Override
public TemporaryPersistence provide() {
TemporaryPersistenceImpl temp=new TemporaryPersistenceImpl();
temp.init();
return temp;
}
}

@ -1,9 +1,12 @@
package org.gcube.spatial.data.sdi.test;
package org.gcube.spatial.data.sdi.test.factories;
import org.gcube.spatial.data.sdi.engine.ThreddsManager;
import org.gcube.spatial.data.sdi.engine.impl.ThreddsManagerImpl;
import org.gcube.spatial.data.sdi.engine.impl.faults.ConfigurationNotFoundException;
import org.gcube.spatial.data.sdi.model.health.ServiceHealthReport;
import org.gcube.spatial.data.sdi.model.service.ThreddsConfiguration;
import org.gcube.spatial.data.sdi.test.TestCommon;
import org.gcube.spatial.data.sdi.test.TokenSetter;
import org.glassfish.hk2.api.Factory;
public class ThreddsManagerFactory implements Factory<ThreddsManager>{
@ -18,6 +21,11 @@ public class ThreddsManagerFactory implements Factory<ThreddsManager>{
TokenSetter.set(TestCommon.TEST_SCOPE);
return super.getConfiguration();
}
@Override
public ServiceHealthReport getHealthReport() {
TokenSetter.set(TestCommon.TEST_SCOPE);
return super.getHealthReport();
}
};
}

@ -0,0 +1,446 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gmd:MD_Metadata xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:fra="http://www.cnig.gouv.fr/2005/fra" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink">
<gmd:language>
<gmd:LanguageCode codeListValue="eng" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/ML_gmxCodelists.xml#LanguageCode">English</gmd:LanguageCode>
</gmd:language>
<gmd:characterSet>
<gmd:MD_CharacterSetCode codeListValue="utf8" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_CharacterSetCode">UTF-8</gmd:MD_CharacterSetCode>
</gmd:characterSet>
<gmd:hierarchyLevel>
<gmd:MD_ScopeCode codeSpace="eng" codeListValue="dataset" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_ScopeCode">Dataset</gmd:MD_ScopeCode>
</gmd:hierarchyLevel>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>fabio.sinibaldi</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine Consortium</gco:CharacterString>
</gmd:organisationName>
<gmd:role>
<gmd:CI_RoleCode codeListValue="author" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Author</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>iMarine Consortium</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine.eu</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:address>
<gmd:CI_Address>
<gmd:electronicMailAddress>
<gco:CharacterString>info@i-marine.eu</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.i-marine.eu</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>i-Marine project website</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="distributor" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Distributor</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>iMarine Consortium Technical Support</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine.eu</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:address>
<gmd:CI_Address>
<gmd:electronicMailAddress>
<gco:CharacterString>support@i-marine.eu</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.i-marine.eu</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>i-Marine project website</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="resourceProvider" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Resource provider</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:dateStamp>
<gco:DateTime>2013-06-19T04:41:20.762+02:00</gco:DateTime>
</gmd:dateStamp>
<gmd:spatialRepresentationInfo>
<gmd:MD_VectorSpatialRepresentation>
<gmd:topologyLevel>
<gmd:MD_TopologyLevelCode codeListValue="geometryOnly" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_TopologyLevelCode">Geometry only</gmd:MD_TopologyLevelCode>
</gmd:topologyLevel>
<gmd:geometricObjects>
<gmd:MD_GeometricObjects>
<gmd:geometricObjectType>
<gmd:MD_GeometricObjectTypeCode codeListValue="surface" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_GeometricObjectTypeCode">Surface</gmd:MD_GeometricObjectTypeCode>
</gmd:geometricObjectType>
<gmd:geometricObjectCount>
<gco:Integer>362</gco:Integer>
</gmd:geometricObjectCount>
</gmd:MD_GeometricObjects>
</gmd:geometricObjects>
</gmd:MD_VectorSpatialRepresentation>
</gmd:spatialRepresentationInfo>
<gmd:identificationInfo>
<gmd:MD_DataIdentification>
<gmd:citation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>Latimeria chalumnae</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2012-12-21T00:47:59.555+01:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeSpace="eng" codeListValue="creation" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:presentationForm>
<gmd:CI_PresentationFormCode codeListValue="mapDigital" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_PresentationFormCode">Map digital</gmd:CI_PresentationFormCode>
</gmd:presentationForm>
</gmd:CI_Citation>
</gmd:citation>
<gmd:abstract>
<gco:CharacterString>This Latimeria chalumnae Species Distribution Map has been generated with the AquaMaps methodology by exploiting the technology and the computational resources provided by iMarine. In particular, this map has been produced using the HSPEC 2050 Native Range dataset, generated using AquaMaps NativeRange2050 algorithm.</gco:CharacterString>
</gmd:abstract>
<gmd:purpose>
<gco:CharacterString>The aim of this Species Distribution map is to provide its users with a model-based map displaying prediction of species distributions based on occurrence records.</gco:CharacterString>
</gmd:purpose>
<gmd:credit>
<gco:CharacterString>This layer has been produced by iMarine (www.i-marine.eu). iMarine (283644) is funded by the European Commission under Framework Programme 7</gco:CharacterString>
</gmd:credit>
<gmd:credit>
<gco:CharacterString>Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008.</gco:CharacterString>
</gmd:credit>
<gmd:resourceMaintenance>
<gmd:MD_MaintenanceInformation>
<gmd:maintenanceAndUpdateFrequency>
<gmd:MD_MaintenanceFrequencyCode codeListValue="asNeeded" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_MaintenanceFrequencyCode">As needed</gmd:MD_MaintenanceFrequencyCode>
</gmd:maintenanceAndUpdateFrequency>
</gmd:MD_MaintenanceInformation>
</gmd:resourceMaintenance>
<gmd:graphicOverview>
<gmd:MD_BrowseGraphic>
<gmd:fileName>
<gco:CharacterString>http://node49.p.d4science.research-infrastructures.eu:9003/83/Animalia/Chordata/Sarcopterygii/Coelacanthiformes/Latimeriidae/Fis-30189/Earth.jpg</gco:CharacterString>
</gmd:fileName>
</gmd:MD_BrowseGraphic>
</gmd:graphicOverview>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>Coelacanth</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeListValue="theme" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>FISHBASE</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-18T18:06:55.662+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeSpace="eng" codeListValue="creation" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:citedResponsibleParty>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>FISHBASE</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>IFM-GEOMAR</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.fishbase.org/search.php</gmd:URL>
</gmd:linkage>
<gmd:name>
<gco:CharacterString>FISHBASE website</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="pointOfContact" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Point of contact</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:citedResponsibleParty>
<gmd:otherCitationDetails>
<gco:CharacterString>FishBase is a global species database of fish species (specifically finfish).</gco:CharacterString>
</gmd:otherCitationDetails>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>Latimeria chalumnae</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeListValue="theme" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>OBIS</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-18T18:06:55.662+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeSpace="eng" codeListValue="creation" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:citedResponsibleParty>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>OBIS</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>UNESCO</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.iobis.org</gmd:URL>
</gmd:linkage>
<gmd:name>
<gco:CharacterString>OBIS website</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="pointOfContact" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Point of contact</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:citedResponsibleParty>
<gmd:otherCitationDetails>
<gco:CharacterString>Intergovernmental Oceanographic Commission (IOC) of UNESCO. The Ocean Biogeographic Information System. Web. http://www.iobis.org. (Consulted on DATE)</gco:CharacterString>
</gmd:otherCitationDetails>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>Ecological niche modelling</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>AquaMaps</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>SpeciesDistribution</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>iMarine</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeListValue="theme" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>General</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-19T04:41:20.762+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeSpace="eng" codeListValue="creation" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:spatialResolution>
<gmd:MD_Resolution>
<gmd:distance>
<gco:Distance uom="http://schemas.opengis.net/iso/19139/20070417/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])">0.5</gco:Distance>
</gmd:distance>
</gmd:MD_Resolution>
</gmd:spatialResolution>
<gmd:language>
<gmd:LanguageCode codeListValue="eng" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/ML_gmxCodelists.xml#LanguageCode">English</gmd:LanguageCode>
</gmd:language>
<gmd:topicCategory>
<gmd:MD_TopicCategoryCode>biota</gmd:MD_TopicCategoryCode>
</gmd:topicCategory>
<gmd:extent>
<gmd:EX_Extent>
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:extentTypeCode>
<gco:Boolean>true</gco:Boolean>
</gmd:extentTypeCode>
<gmd:westBoundLongitude>
<gco:Decimal>-180.0</gco:Decimal>
</gmd:westBoundLongitude>
<gmd:eastBoundLongitude>
<gco:Decimal>180.0</gco:Decimal>
</gmd:eastBoundLongitude>
<gmd:southBoundLatitude>
<gco:Decimal>-90.0</gco:Decimal>
</gmd:southBoundLatitude>
<gmd:northBoundLatitude>
<gco:Decimal>90.0</gco:Decimal>
</gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
</gmd:EX_Extent>
</gmd:extent>
</gmd:MD_DataIdentification>
</gmd:identificationInfo>
<gmd:dataQualityInfo>
<gmd:DQ_DataQuality>
<gmd:scope>
<gmd:DQ_Scope>
<gmd:level>
<gmd:MD_ScopeCode codeSpace="eng" codeListValue="dataset" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_ScopeCode">Dataset</gmd:MD_ScopeCode>
</gmd:level>
</gmd:DQ_Scope>
</gmd:scope>
<gmd:lineage>
<gmd:LI_Lineage>
<gmd:statement>
<gco:CharacterString>Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008.</gco:CharacterString>
</gmd:statement>
<gmd:processStep>
<gmd:LI_ProcessStep>
<gmd:description>
<gco:CharacterString>AquaMaps Ecological Niche Modelling</gco:CharacterString>
</gmd:description>
</gmd:LI_ProcessStep>
</gmd:processStep>
<gmd:source>
<gmd:LI_Source>
<gmd:sourceCitation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>HSPEC 2050 Native Range</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2011-10-05T00:39:17.101+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeSpace="eng" codeListValue="creation" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:identifier>
<gmd:MD_Identifier>
<gmd:code>
<gco:CharacterString>hspec2011_10_04_21_00_23_274</gco:CharacterString>
</gmd:code>
</gmd:MD_Identifier>
</gmd:identifier>
</gmd:CI_Citation>
</gmd:sourceCitation>
<gmd:sourceExtent>
<gmd:EX_Extent>
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:extentTypeCode>
<gco:Boolean>true</gco:Boolean>
</gmd:extentTypeCode>
<gmd:westBoundLongitude>
<gco:Decimal>-180.0</gco:Decimal>
</gmd:westBoundLongitude>
<gmd:eastBoundLongitude>
<gco:Decimal>180.0</gco:Decimal>
</gmd:eastBoundLongitude>
<gmd:southBoundLatitude>
<gco:Decimal>-90.0</gco:Decimal>
</gmd:southBoundLatitude>
<gmd:northBoundLatitude>
<gco:Decimal>90.0</gco:Decimal>
</gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
</gmd:EX_Extent>
</gmd:sourceExtent>
</gmd:LI_Source>
</gmd:source>
</gmd:LI_Lineage>
</gmd:lineage>
</gmd:DQ_DataQuality>
</gmd:dataQualityInfo>
<gmd:metadataConstraints>
<gmd:MD_LegalConstraints>
<gmd:useLimitation>
<gco:CharacterString>CC-BY-SA</gco:CharacterString>
</gmd:useLimitation>
<gmd:accessConstraints>
<gmd:MD_RestrictionCode codeListValue="license" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode">License</gmd:MD_RestrictionCode>
</gmd:accessConstraints>
<gmd:useConstraints>
<gmd:MD_RestrictionCode codeListValue="license" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode">License</gmd:MD_RestrictionCode>
</gmd:useConstraints>
</gmd:MD_LegalConstraints>
</gmd:metadataConstraints>
</gmd:MD_Metadata>
Loading…
Cancel
Save