diff --git a/distro/changelog.xml b/distro/changelog.xml
index 393e4ec..14e216e 100644
--- a/distro/changelog.xml
+++ b/distro/changelog.xml
@@ -4,5 +4,6 @@
Added GeoServer interface
+ Added Metadata interface
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 031ef7b..daa1837 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
org.gcube.spatial.data
sdi-service
- 1.0.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
SDI Service
REST Interface towards SDI facilities
war
@@ -46,7 +46,12 @@
-
+
+
+ org.gcube.spatial.data
+ sdi-interface
+ [1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)
+
@@ -211,67 +216,14 @@
${project.artifactId}
-
-
- maven-compiler-plugin
- 2.3.2
-
-
- 1.7
-
-
-
- org.apache.maven.plugins
- maven-war-plugin
- 2.4
-
- ${project.artifactId}
- false
-
-
-
- org.apache.maven.plugins
- maven-resources-plugin
- 2.6
-
-
- copy-profile
-
- copy-resources
-
- process-resources
-
- ${webappDirectory}
-
-
- ${distroDirectory}
- true
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 2.2
-
-
- ${distroDirectory}/descriptor.xml
-
-
-
-
- servicearchive
- install
-
- single
-
-
-
-
-
+
+
+ src/test/resources
+
+
+ src/main/webapps
+
+
\ No newline at end of file
diff --git a/src/main/java/org/gcube/spatial/data/sdi/Constants.java b/src/main/java/org/gcube/spatial/data/sdi/Constants.java
deleted file mode 100644
index 61ec723..0000000
--- a/src/main/java/org/gcube/spatial/data/sdi/Constants.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.gcube.spatial.data.sdi;
-
-public class Constants {
-
-
- public static final String APPLICATION="SDI-Service";
- public static final String GEONETWORK_INTERFACE="GeoNetwork";
- public static final String GEONETWORK_CONFIGURATION_PATH="configuration";
- public static final String GEONETWORK_GROUPS_PATH="groups";
-
- public static final String SDI_INTERFACE="SDI";
-}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java b/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java
index d6873a0..90e0642 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/LocalConfiguration.java
@@ -28,6 +28,7 @@ public class LocalConfiguration {
final static public String THREDDS_GE_SERVICE_NAME="th.ge.serviceName";
+ final static public String METADATA_TEMPLATE_FOLDER="meta.tpl.folder";
static LocalConfiguration instance=null;
diff --git a/src/main/java/org/gcube/spatial/data/sdi/SDIService.java b/src/main/java/org/gcube/spatial/data/sdi/SDIService.java
index 56006b4..a2b9f3b 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/SDIService.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/SDIService.java
@@ -7,13 +7,14 @@ import javax.ws.rs.ApplicationPath;
import org.gcube.smartgears.ContextProvider;
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.server.ResourceConfig;
import io.swagger.jaxrs.config.BeanConfig;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-@ApplicationPath(Constants.APPLICATION)
+@ApplicationPath(ServiceConstants.APPLICATION)
public class SDIService extends ResourceConfig{
public SDIService() {
diff --git a/src/main/java/org/gcube/spatial/data/sdi/SDIServiceManager.java b/src/main/java/org/gcube/spatial/data/sdi/SDIServiceManager.java
new file mode 100644
index 0000000..fe26eef
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/SDIServiceManager.java
@@ -0,0 +1,33 @@
+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
+
+ }
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java b/src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java
new file mode 100644
index 0000000..ae341c8
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/MetadataTemplateManager.java
@@ -0,0 +1,18 @@
+package org.gcube.spatial.data.sdi.engine;
+
+import java.io.File;
+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 org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation;
+
+public interface MetadataTemplateManager {
+
+
+ public Set getAvailableTemplates();
+ public MetadataReport applyTemplates(File original,Set invocations);
+ public void init(ApplicationContext ctx);
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/CommonMetadataPieces.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/CommonMetadataPieces.java
index 2f17b1c..db86d0c 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/CommonMetadataPieces.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/CommonMetadataPieces.java
@@ -2,4 +2,15 @@ package org.gcube.spatial.data.sdi.engine.impl.metadata;
public class CommonMetadataPieces {
+ public static final String resourceIdentifier=" "
+ + " %s
"
+ + " "
+ + "";
+
+ public static final String fileIdentifier=""
+ + " %s ";
+
+
+
+
}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java
new file mode 100644
index 0000000..254a842
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataHandler.java
@@ -0,0 +1,73 @@
+package org.gcube.spatial.data.sdi.engine.impl.metadata;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.List;
+import java.util.UUID;
+
+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;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class MetadataHandler {
+
+ private Document document=null;
+ private String metaUUID=null;
+ private XPathHelper helper;
+ public MetadataHandler(File xmlFile){
+ // Get document owner
+ Element documentNode=null;
+ try{
+ InputStream inputStream= new FileInputStream(xmlFile);
+ Reader reader = new InputStreamReader(inputStream,"UTF-8");
+
+ InputSource is = new InputSource(reader);
+ documentNode = MetadataUtils.docBuilder.parse(is).getDocumentElement();
+ document=documentNode.getOwnerDocument();
+
+ helper=MetadataUtils.getHelper(document);
+
+ // document = (Document)xpath.evaluate("/", inputSource, XPathConstants.NODE);
+ }catch(Exception e){
+ // throw e;
+ throw new RuntimeException("Unable to fix : unable to get Document",e);
+ }
+
+
+ }
+
+ public String getUUID() throws SAXException, IOException{
+ //Set | get meta UUID
+ if(metaUUID==null){
+ log.debug("Managing metadata ID.. ");
+
+
+ List metaUUIDList=helper.evaluate("//gmd:fileIdentifier/gco:CharacterString/text()");
+ if(metaUUIDList.isEmpty()){
+ metaUUID=UUID.randomUUID().toString();
+ log.debug("Stting uuid {} ",metaUUID);
+ 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");
+ }
+ }
+ return metaUUID;
+ }
+
+
+ public void addContent(String content, InsertionPoint insertion) throws SAXException, IOException{
+ MetadataUtils.addContent(insertion.getElementReference(), document, content, helper, insertion.getPosition());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java
new file mode 100644
index 0000000..11d24b3
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl.java
@@ -0,0 +1,151 @@
+package org.gcube.spatial.data.sdi.engine.impl.metadata;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.apache.commons.io.IOUtils;
+import org.gcube.smartgears.context.application.ApplicationContext;
+import org.gcube.spatial.data.sdi.LocalConfiguration;
+import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
+import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractTemplate;
+import org.gcube.spatial.data.sdi.engine.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.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
+@Singleton
+public class MetadataTemplateManagerImpl implements MetadataTemplateManager {
+
+
+ private static Configuration cfg;
+
+ private static ArrayList templateDescriptors=new ArrayList<>();
+ private static HashMap availableTemplates=new HashMap<>();
+
+ @Override
+ public void init(ApplicationContext ctx) {
+
+ // 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));
+
+ // Set the preferred charset template files are stored in. UTF-8 is
+ // a good choice in most applications:
+ cfg.setDefaultEncoding("UTF-8");
+
+ // Sets how errors will appear.
+ // During web page *development* TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
+ cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+
+ // Don't log exceptions inside FreeMarker that it will thrown at you anyway:
+ cfg.setLogTemplateExceptions(false);
+
+
+ // availableTemplates.add(new TemplateDescriptor("THREDDS-ONLINE", "Thredds online resources", "Template for online resources exposed by thredds.", "http://sdi-d4s.d4science.org"));
+
+
+ ThreddsOnlineTemplate tpl=new ThreddsOnlineTemplate();
+ availableTemplates.put(tpl.getDescriptor().getId(), tpl);
+ templateDescriptors.add(tpl.getDescriptor());
+
+
+ }
+
+//
+// public static String getTHREDDSLinks(ThreddsLinkRequest req) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
+// Writer out=null;
+// try{
+// Template temp = cfg.getTemplate("OnlineResources.ftlx");
+// ByteArrayOutputStream baos=new ByteArrayOutputStream();
+// out=new OutputStreamWriter(baos);
+// temp.process(req, out);
+// out.flush();
+// return baos.toString(StandardCharsets.UTF_8.toString());
+// }finally{
+// if(out!=null)
+// IOUtils.closeQuietly(out);
+// }
+// }
+//
+//
+//
+//
+// public MetadataTemplateManagerImpl() {
+// // TODO Auto-generated constructor stub
+// }
+
+
+ @Override
+ public Set getAvailableTemplates() {
+ return new HashSet<>(templateDescriptors);
+ }
+
+ @Override
+ public MetadataReport applyTemplates(File original, Set invocations) {
+ MetadataReport report=new MetadataReport();
+ HashSet appliedTemplates=new HashSet<>();
+ for(TemplateInvocation invocation:invocations){
+ try{
+ applyTemplate(original, invocation);
+ appliedTemplates.add(invocation.getToInvokeTemplateID());
+ }catch(Throwable t){
+ log.warn("Unable to apply template {} ",invocation.getToInvokeTemplateID());
+ }
+ }
+ report.setAppliedTemplates(appliedTemplates);
+ return report;
+ }
+
+ private static void applyTemplate(File original,TemplateInvocation invocation) 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);
+ try{
+ Template temp = cfg.getTemplate(tpl.getFileName());
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ out=new OutputStreamWriter(baos);
+ temp.process(tpl.getInstantiationRequest(handler,invocation), out);
+ out.flush();
+ String instantiatedTemplate= baos.toString(StandardCharsets.UTF_8.toString());
+
+ //apply to original
+ handler.addContent(instantiatedTemplate, tpl.getInsertionPoint());
+
+ } catch (Exception e) {
+ log.error("Unable to apply template. Invocation was {} ",invocation,e);
+ throw e;
+ }finally{
+ if(out!=null)
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataUtils.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataUtils.java
new file mode 100644
index 0000000..5ce7271
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataUtils.java
@@ -0,0 +1,126 @@
+package org.gcube.spatial.data.sdi.engine.impl.metadata;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+
+import org.gcube.common.resources.gcore.utils.XPathHelper;
+import org.gcube.portlets.user.uriresolvermanager.UriResolverManager;
+import org.gcube.portlets.user.uriresolvermanager.exception.IllegalArgumentException;
+import org.gcube.portlets.user.uriresolvermanager.exception.UriResolverMapException;
+import org.gcube.spatial.data.geonetwork.utils.ScopeUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class MetadataUtils {
+
+ public static Transformer transformer =null;
+ public static DocumentBuilder docBuilder =null;
+
+
+ static HashMap namespaces=new HashMap();
+
+ static{
+ try{
+ DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+
+ docBuilder = factory.newDocumentBuilder();
+
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ transformer = transformerFactory.newTransformer();
+
+
+ namespaces.put("gmd", "http://www.isotc211.org/2005/gmd");
+ namespaces.put("gco", "http://www.isotc211.org/2005/gco");
+ namespaces.put("fra", "http://www.cnig.gouv.fr/2005/fra");
+ namespaces.put("xlink", "http://www.w3.org/1999/xlink");
+ namespaces.put("gml", "http://www.opengis.net/gml");
+ namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
+ namespaces.put("gmi", "http://www.isotc211.org/2005/gmi");
+ namespaces.put("gmx", "http://www.isotc211.org/2005/gmx");
+
+
+
+
+ }catch(Exception e){
+ throw new RuntimeException("Unable to init Fixer ",e);
+ }
+ }
+
+
+ public static enum Position{
+ sibling_after,sibling_before,first_child,last_child,replace
+ }
+
+ public static XPathHelper getHelper(Node root){
+ XPathHelper toReturn =new XPathHelper(root);
+ for(Entry entry:namespaces.entrySet())
+ toReturn.addNamespace(entry.getKey(), entry.getValue());
+ return toReturn;
+ }
+
+
+ public static String readFile(String path) throws IOException{
+ byte[] encoded = Files.readAllBytes(Paths.get(path));
+ return new String(encoded);
+ }
+
+ public static String getGisLinkByUUID(String uuid) throws UriResolverMapException, IllegalArgumentException{
+ Map params=new HashMap();
+ params.put("scope", ScopeUtils.getCurrentScope());
+ params.put("gis-UUID", uuid);
+ UriResolverManager resolver = new UriResolverManager("GIS");
+ String toReturn= resolver.getLink(params, false);
+ return toReturn;
+ }
+
+ public static void addContent(String path, Document doc, String toAddContent, XPathHelper documentHelper,Position position) throws SAXException, IOException{
+ NodeList nodelist=documentHelper.evaluateForNodes(path);
+ if(nodelist==null||nodelist.getLength()==0) throw new RuntimeException("Path "+path+" not found in document");
+// if(nodelist.getLength()>1) throw new RuntimeException("Invalid Path "+path+"."+nodelist.getLength()+" entries found");
+ Node targetNode=nodelist.item(0);
+
+ Document online=docBuilder.parse(new ByteArrayInputStream(toAddContent.getBytes()));
+ Node toAdd=doc.importNode(online.getDocumentElement(), true);
+ switch(position){
+ case first_child: {
+ targetNode.insertBefore(toAdd, targetNode.getFirstChild());
+ break;
+ }
+ case last_child:{targetNode.appendChild(toAdd);
+ break;}
+ case replace : {
+ Node parent=targetNode.getParentNode();
+ parent.replaceChild(toAdd, targetNode);
+ break;
+ }
+ case sibling_after :{
+ Node currentlyNext=targetNode.getNextSibling();
+ Node parent=targetNode.getParentNode();
+ if(currentlyNext!=null)parent.insertBefore(toAdd, currentlyNext);
+ else parent.appendChild(toAdd);
+ break;
+ }
+ case sibling_before :{
+ Node parent=targetNode.getParentNode();
+ parent.insertBefore(toAdd, targetNode);
+ break;
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java
index 9b60ce0..aa4993b 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/AbstractTemplate.java
@@ -1,5 +1,36 @@
package org.gcube.spatial.data.sdi.engine.impl.metadata.templates;
-public class AbstractTemplate {
+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;
+import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@AllArgsConstructor
+public abstract class AbstractTemplate {
+
+
+
+ @Getter
+ @Setter
+ @ToString
+ @AllArgsConstructor
+ public static class InsertionPoint{
+ private Position position;
+ private String elementReference;
+ }
+
+
+ private String fileName;
+ private InsertionPoint insertionPoint;
+ private TemplateDescriptor descriptor;
+
+ public abstract T getInstantiationRequest(MetadataHandler original, TemplateInvocation invocation) throws InvalidTemplateInvocationException,Exception;
+
+
}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/InvalidTemplateInvocationException.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/InvalidTemplateInvocationException.java
new file mode 100644
index 0000000..6ac74fa
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/InvalidTemplateInvocationException.java
@@ -0,0 +1,36 @@
+package org.gcube.spatial.data.sdi.engine.impl.metadata.templates;
+
+public class InvalidTemplateInvocationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8921135030360257131L;
+
+ public InvalidTemplateInvocationException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public InvalidTemplateInvocationException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ // TODO Auto-generated constructor stub
+ }
+
+ public InvalidTemplateInvocationException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ public InvalidTemplateInvocationException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ public InvalidTemplateInvocationException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java
new file mode 100644
index 0000000..5d5efc3
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/templates/ThreddsOnlineTemplate.java
@@ -0,0 +1,51 @@
+package org.gcube.spatial.data.sdi.engine.impl.metadata.templates;
+
+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 lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.ToString;
+
+public class ThreddsOnlineTemplate extends AbstractTemplate {
+
+ private static String TEMPLATE_ID="THREDDS-ONLINE";
+ 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");
+
+
+ public ThreddsOnlineTemplate() {
+ super(FILENAME, INSERTION, DESCRIPTOR);
+ }
+
+
+ @Getter
+ @AllArgsConstructor
+ @ToString
+ public static class ThreddsOnlineRequest{
+ private String hostname;
+ private String catalog;
+ private String filename;
+ private String gisViewerLink;
+ }
+
+ @Override
+ public ThreddsOnlineRequest getInstantiationRequest(MetadataHandler handler, TemplateInvocation invocation) throws InvalidTemplateInvocationException,Exception{
+ try{
+ ThreddsOnlineTemplateInvocation threddsInvocation=(ThreddsOnlineTemplateInvocation) invocation;
+ 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());
+ }
+ }
+
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java
index ba5e136..9cfefec 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoNetwork.java
@@ -2,12 +2,12 @@ package org.gcube.spatial.data.sdi.rest;
import javax.ws.rs.Path;
-import org.gcube.spatial.data.sdi.Constants;
+import org.gcube.spatial.data.sdi.model.ServiceConstants;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-@Path(Constants.GEONETWORK_INTERFACE)
+@Path(ServiceConstants.GeoNetwork.INTERFACE)
//@Api(value="GeoNetwork")
public class GeoNetwork {
//
diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java
new file mode 100644
index 0000000..f5c087f
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/rest/GeoServer.java
@@ -0,0 +1,93 @@
+package org.gcube.spatial.data.sdi.rest;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+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.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 com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+@Path(ServiceConstants.GeoServer.INTERFACE)
+@Api(value=ServiceConstants.GeoServer.INTERFACE)
+@Slf4j
+public class GeoServer {
+
+ private final static String HOST_PATH_PARAM="host";
+
+
+ @Inject
+ private SDIManager sdi;
+
+ @GET
+ @Path("configuration/{"+HOST_PATH_PARAM+"}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT })
+ public GeoServerConfiguration getInstanceConfiguration(@PathParam(HOST_PATH_PARAM) String host){
+ try{
+ log.trace("Serving credentials for host {} ",host);
+ host=getHost(host);
+ List geoservers=sdi.getContextConfiguration().getGeoserverClusterConfiguration().getAvailableInstances();
+ log.trace("Got {} geoservers in current scope ",geoservers.size());
+ for(GeoServerConfiguration config : geoservers){
+ String configHost=getHost(config.getBaseEndpoint());
+ if(configHost.equals(host))
+ return config;
+ }
+ throw new WebApplicationException("Host "+host+" not found in context");
+ }catch(WebApplicationException e){
+ throw e;
+ }catch(Exception e){
+ throw new WebApplicationException("Unable to serve request", e);
+ }
+ }
+
+
+ @GET
+ @Path("credentials/{"+HOST_PATH_PARAM+"}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT })
+ public Credentials getInstanceCredentials(@PathParam(HOST_PATH_PARAM) String host){
+ try{
+ log.trace("Serving credentials for host {} ",host);
+ host=getHost(host);
+ List geoservers=sdi.getContextConfiguration().getGeoserverClusterConfiguration().getAvailableInstances();
+ log.trace("Got {} geoservers in current scope ",geoservers.size());
+ for(GeoServerConfiguration config : geoservers){
+ String configHost=getHost(config.getBaseEndpoint());
+ if(configHost.equals(host))
+ return config.getAccessibleCredentials().get(0);
+ }
+ throw new WebApplicationException("Host "+host+" not found in context");
+ }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);
+ if(endpoint.startsWith("http")){
+ log.debug("Endpoint seems url..");
+ return new URL(endpoint).getHost();
+ }
+ return endpoint;
+ }
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java b/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java
new file mode 100644
index 0000000..5e34c7c
--- /dev/null
+++ b/src/main/java/org/gcube/spatial/data/sdi/rest/Metadata.java
@@ -0,0 +1,57 @@
+package org.gcube.spatial.data.sdi.rest;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
+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.TemplateDescriptor;
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+import org.glassfish.jersey.media.multipart.FormDataParam;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Path(ServiceConstants.Metadata.INTERFACE)
+public class Metadata {
+
+ @Inject
+ MetadataTemplateManager templateManager;
+
+
+ @POST
+ @Path("/{gnCategory}")
+ @Consumes(MediaType.WILDCARD)
+ @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 metadataEnrichments){
+
+ //Receive metadata
+ //Optionally enrich it
+ //Publish it NB : validate & make public
+ return null;
+ }
+
+ @GET
+ @Path("/list")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Set getList(){
+ return templateManager.getAvailableTemplates();
+ }
+}
diff --git a/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java b/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java
index 1220dca..ce90cf6 100644
--- a/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java
+++ b/src/main/java/org/gcube/spatial/data/sdi/rest/SDI.java
@@ -6,17 +6,17 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import org.gcube.spatial.data.sdi.Constants;
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 com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;
import io.swagger.annotations.Api;
-@Path(Constants.SDI_INTERFACE)
-@Api(value=Constants.SDI_INTERFACE)
+@Path(ServiceConstants.INTERFACE)
+@Api(value=ServiceConstants.INTERFACE)
public class SDI {
@Inject
diff --git a/src/main/webapp/WEB-INF/README b/src/main/webapp/WEB-INF/README
index 1cd9e37..fc64f84 100644
--- a/src/main/webapp/WEB-INF/README
+++ b/src/main/webapp/WEB-INF/README
@@ -25,7 +25,7 @@ no. 654119), SoBigData (grant no. 654024);
Version
--------------------------------------------------
-1.0.0-SNAPSHOT (2017-07-05)
+1.1.0-SNAPSHOT (2017-06-19)
Please see the file named "changelog.xml" in this directory for the release notes.
diff --git a/src/main/webapp/WEB-INF/changelog.xml b/src/main/webapp/WEB-INF/changelog.xml
index 393e4ec..14e216e 100644
--- a/src/main/webapp/WEB-INF/changelog.xml
+++ b/src/main/webapp/WEB-INF/changelog.xml
@@ -4,5 +4,6 @@
Added GeoServer interface
+ Added Metadata interface
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/config.properties b/src/main/webapp/WEB-INF/config.properties
index c358e97..1d291aa 100644
--- a/src/main/webapp/WEB-INF/config.properties
+++ b/src/main/webapp/WEB-INF/config.properties
@@ -13,4 +13,6 @@ th.cache.TTL=120000
th.se.category=Gis
th.se.platform=thredds
th.ge.serviceClass=SDI
-th.ge.serviceName=THREDDS
\ No newline at end of file
+th.ge.serviceName=THREDDS
+#Metadata
+meta.tpl.folder=metadataTemplates
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml
index 0e1ff87..d034671 100644
--- a/src/main/webapp/WEB-INF/gcube-app.xml
+++ b/src/main/webapp/WEB-INF/gcube-app.xml
@@ -1,7 +1,7 @@
sdi-service
SDI
- 1.0.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
REST Interface towards SDI facilities
diff --git a/src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx b/src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx
new file mode 100644
index 0000000..e00e7ba
--- /dev/null
+++ b/src/main/webapp/WEB-INF/metadataTemplates/ThreddsOnlineResources.ftlx
@@ -0,0 +1,220 @@
+
+
+
+
+
+ OPeNDAP
+
+
+ 2.0.0
+
+
+
+
+
+
+ NetCDFSubSet
+
+
+ 1.0.0
+
+
+
+
+
+
+ WCS
+
+
+ 1.0.0
+
+
+
+
+
+
+ WMS
+
+
+ 1.1.0
+
+
+
+
+
+
+ HTTPServer
+
+
+ 1.1.0
+
+
+
+
+
+
+ NCML
+
+
+ 1.0.0
+
+
+
+
+
+
+ UDDC
+
+
+ 1.0.0
+
+
+
+
+
+
+ <#if catalog??>
+ <#assign cataloguedPath=catalog+"/"+filename>
+ <#else>
+ <#assign cataloguedPath=filename>
+ #if>
+
+ <#assign layername=filename?keep_before_last(".")>
+
+
+
+
+ http://${hostname}/thredds/dodsC/public/netcdf/${cataloguedPath}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ ${layername} : OPeNDAP
+
+
+ GIS data (OPenNDAP)
+
+
+
+
+
+
+
+ http://${hostname}/thredds/ncss/public/netcdf/${cataloguedPath}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ ${layername} : NetCDF Subset
+
+
+ GIS data (NetCDF Subset)
+
+
+
+
+
+
+
+ http://${hostname}/thredds/wcs/public/netcdf/${cataloguedPath}?service=wcs&version=1.0.0&request=GetCoverage&coverage=${layername}&CRS=EPSG:4326&format=geotiff
+
+
+ OGC:WCS-1.0.0-http-get-coverage
+
+
+ ${layername} : WCS
+
+
+ GIS data (WCS)
+
+
+
+
+
+
+
+ http://${hostname}/thredds/wms/public/netcdf/${cataloguedPath}
+
+
+ OGC:WMS-1.3.0-http-get-map
+
+
+ ${layername} : WMS
+
+
+ GIS data (WMS)
+
+
+
+
+
+
+
+ http://${hostname}/thredds/fileServer/public/netcdf/${cataloguedPath}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ ${layername} : HTTP
+
+
+ GIS data (HTTP FileServer)
+
+
+
+
+
+
+
+ http://${hostname}/thredds/ncml/public/netcdf/${cataloguedPath}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ ${layername} : NCML
+
+
+ GIS metadata (NCML Format)
+
+
+
+
+
+
+
+
+ http://${hostname}/thredds/uddc/public/netcdf/${cataloguedPath}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ ${layername} : UDDC
+
+
+ GIS metadata quality (UDDC)
+
+
+
+
+
+
+
+ ${gisViewerLink}
+
+
+ WWW:LINK-1.0-http--link
+
+
+ GIS Viewer link
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/profile.xml b/src/main/webapp/WEB-INF/profile.xml
index bfc8d18..1867fa0 100644
--- a/src/main/webapp/WEB-INF/profile.xml
+++ b/src/main/webapp/WEB-INF/profile.xml
@@ -10,11 +10,11 @@
sdi-service
- 1.0.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
org.gcube.spatial.data
sdi-service
- 1.0.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
sdi-service.jar
diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java b/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java
new file mode 100644
index 0000000..807d2a6
--- /dev/null
+++ b/src/test/java/org/gcube/spatial/data/sdi/test/ConfigurationTest.java
@@ -0,0 +1,25 @@
+package org.gcube.spatial.data.sdi.test;
+
+import java.net.URL;
+
+import org.gcube.spatial.data.sdi.LocalConfiguration;
+import org.gcube.spatial.data.sdi.engine.impl.GISManagerImpl;
+import org.gcube.spatial.data.sdi.engine.impl.GeoNetworkManagerImpl;
+import org.gcube.spatial.data.sdi.engine.impl.SDIManagerImpl;
+import org.gcube.spatial.data.sdi.engine.impl.ThreddsManagerImpl;
+
+public class ConfigurationTest {
+
+ public static void main(String[] args) {
+ TokenSetter.set("/gcube/devNext");
+
+ URL propertiesURL=ConfigurationTest.class.getResource("/WEB-INF/config.properties");
+
+ LocalConfiguration.init(propertiesURL);
+
+ SDIManagerImpl sdi=new SDIManagerImpl(new GeoNetworkManagerImpl(), new ThreddsManagerImpl(), new GISManagerImpl());
+
+ System.out.println(sdi.getContextConfiguration());
+ }
+
+}
diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java b/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java
index b900244..5b0f0aa 100644
--- a/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java
+++ b/src/test/java/org/gcube/spatial/data/sdi/test/MainTest.java
@@ -3,12 +3,12 @@ package org.gcube.spatial.data.sdi.test;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
-import org.gcube.spatial.data.sdi.Constants;
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.SDIManager;
import org.gcube.spatial.data.sdi.engine.ThreddsManager;
+import org.gcube.spatial.data.sdi.model.ServiceConstants;
import org.gcube.spatial.data.sdi.rest.GeoNetwork;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
@@ -39,7 +39,7 @@ public class MainTest extends JerseyTest{
@Override
protected Application configure() {
- System.out.println("Configuration for "+Constants.APPLICATION);
+ System.out.println("Configuration for "+ServiceConstants.APPLICATION);
ResourceConfig config= new ResourceConfig(SDIService.class);
config.register(new MyBinder());
@@ -80,9 +80,13 @@ public class MainTest extends JerseyTest{
@Test
public void getConfiguration(){
- System.out.println(target(Constants.SDI_INTERFACE).request(MediaType.APPLICATION_JSON_TYPE).get(String.class));
+ 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
diff --git a/src/test/java/org/gcube/spatial/data/sdi/test/TestCommon.java b/src/test/java/org/gcube/spatial/data/sdi/test/TestCommon.java
index cc0a074..6e54dee 100644
--- a/src/test/java/org/gcube/spatial/data/sdi/test/TestCommon.java
+++ b/src/test/java/org/gcube/spatial/data/sdi/test/TestCommon.java
@@ -2,6 +2,6 @@ package org.gcube.spatial.data.sdi.test;
public class TestCommon {
- public static final String TEST_SCOPE="/gcube/devsec";
+ public static final String TEST_SCOPE="/gcube/devNext";
}