Fabio Sinibaldi 7 years ago
parent 53ca9690e6
commit 3e4744f651

@ -4,5 +4,6 @@
</Changeset>
<Changeset component="sdi-service-1.1.0" date="2017-05-16">
<Change>Added GeoServer interface</Change>
<Change>Added Metadata interface</Change>
</Changeset>
</ReleaseNotes>

@ -8,7 +8,7 @@
</parent>
<groupId>org.gcube.spatial.data</groupId>
<artifactId>sdi-service</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
<name>SDI Service</name>
<description>REST Interface towards SDI facilities</description>
<packaging>war</packaging>
@ -46,7 +46,12 @@
</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>
<!-- SMARTGEARS -->
<dependency>
@ -211,67 +216,14 @@
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warName>${project.artifactId}</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-profile</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<outputDirectory>${webappDirectory}</outputDirectory>
<resources>
<resource>
<directory>${distroDirectory}</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptors>
<descriptor>${distroDirectory}/descriptor.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>servicearchive</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>src/main/webapps</directory>
</testResource>
</testResources>
</build>
</project>

@ -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";
}

@ -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;

@ -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() {

@ -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
}
}

@ -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<TemplateDescriptor> getAvailableTemplates();
public MetadataReport applyTemplates(File original,Set<TemplateInvocation> invocations);
public void init(ApplicationContext ctx);
}

@ -2,4 +2,15 @@ package org.gcube.spatial.data.sdi.engine.impl.metadata;
public class CommonMetadataPieces {
public static final String resourceIdentifier="<identifier xmlns=\"http://www.isotc211.org/2005/gmd\" xmlns:gco=\"http://www.isotc211.org/2005/gco\"> <MD_Identifier>"
+ " <code><gco:CharacterString>%s</gco:CharacterString></code>"
+ " </MD_Identifier>"
+ "</identifier>";
public static final String fileIdentifier="<fileIdentifier xmlns=\"http://www.isotc211.org/2005/gmd\" xmlns:gco=\"http://www.isotc211.org/2005/gco\">"
+ " <gco:CharacterString>%s</gco:CharacterString> </fileIdentifier>";
}

@ -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<String> 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());
}
}

@ -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<TemplateDescriptor> templateDescriptors=new ArrayList<>();
private static HashMap<String,AbstractTemplate> 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<TemplateDescriptor> getAvailableTemplates() {
return new HashSet<>(templateDescriptors);
}
@Override
public MetadataReport applyTemplates(File original, Set<TemplateInvocation> invocations) {
MetadataReport report=new MetadataReport();
HashSet<String> 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);
}
}
}

@ -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<String,String> namespaces=new HashMap<String,String>();
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<String,String> 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<String,String> 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;
}
}
}
}

@ -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<T> {
@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;
}

@ -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
}
}

@ -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<ThreddsOnlineRequest> {
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());
}
}
}

@ -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 {
//

@ -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<GeoServerConfiguration> 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<GeoServerConfiguration> 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;
}
}

@ -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<String> metadataEnrichments){
//Receive metadata
//Optionally enrich it
//Publish it NB : validate & make public
return null;
}
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public Set<TemplateDescriptor> getList(){
return templateManager.getAvailableTemplates();
}
}

@ -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

@ -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.

@ -4,5 +4,6 @@
</Changeset>
<Changeset component="sdi-service-1.1.0" date="2017-05-16">
<Change>Added GeoServer interface</Change>
<Change>Added Metadata interface</Change>
</Changeset>
</ReleaseNotes>

@ -13,4 +13,6 @@ th.cache.TTL=120000
th.se.category=Gis
th.se.platform=thredds
th.ge.serviceClass=SDI
th.ge.serviceName=THREDDS
th.ge.serviceName=THREDDS
#Metadata
meta.tpl.folder=metadataTemplates

@ -1,7 +1,7 @@
<application mode='online'>
<name>sdi-service</name>
<group>SDI</group>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
<description>REST Interface towards SDI facilities</description>
<local-persistence location='target' />
</application>

@ -0,0 +1,220 @@
<gmd:distributionInfo>
<gmd:MD_Distribution>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>OPeNDAP</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>2.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>NetCDFSubSet</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>WCS</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>WMS</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.1.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>HTTPServer</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.1.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>NCML</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>UDDC</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:transferOptions>
<gmd:MD_DigitalTransferOptions>
<#if catalog??>
<#assign cataloguedPath=catalog+"/"+filename>
<#else>
<#assign cataloguedPath=filename>
</#if>
<#assign layername=filename?keep_before_last(".")>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/dodsC/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : OPeNDAP</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS data (OPenNDAP)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/ncss/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : NetCDF Subset</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS data (NetCDF Subset)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/wcs/public/netcdf/${cataloguedPath}?service=wcs&amp;version=1.0.0&amp;request=GetCoverage&amp;coverage=${layername}&amp;CRS=EPSG:4326&amp;format=geotiff</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WCS-1.0.0-http-get-coverage</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : WCS</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS data (WCS)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/wms/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WMS-1.3.0-http-get-map</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : WMS</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS data (WMS)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/fileServer/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : HTTP </gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS data (HTTP FileServer)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/ncml/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : NCML </gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS metadata (NCML Format)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://${hostname}/thredds/uddc/public/netcdf/${cataloguedPath}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>${layername} : UDDC </gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>GIS metadata quality (UDDC)</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>${gisViewerLink}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>GIS Viewer link</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
</gmd:MD_DigitalTransferOptions>
</gmd:transferOptions>
</gmd:MD_Distribution>
</gmd:distributionInfo>

@ -10,11 +10,11 @@
<Packages>
<Software>
<Name>sdi-service</Name>
<Version>1.0.0-SNAPSHOT</Version>
<Version>1.1.0-SNAPSHOT</Version>
<MavenCoordinates>
<groupId>org.gcube.spatial.data</groupId>
<artifactId>sdi-service</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
</MavenCoordinates>
<Files>
<File>sdi-service.jar</File>

@ -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());
}
}

@ -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

@ -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";
}

Loading…
Cancel
Save