diff --git a/gcube-geoserver-client/pom.xml b/gcube-geoserver-client/pom.xml index 4def66c..540fb95 100644 --- a/gcube-geoserver-client/pom.xml +++ b/gcube-geoserver-client/pom.xml @@ -43,6 +43,8 @@ jersey-media-json-jackson + + com.jayway.jsonpath diff --git a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClient.java b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClient.java index 05bbc1a..33ddd85 100644 --- a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClient.java +++ b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClient.java @@ -7,6 +7,13 @@ import org.gcube.spatial.data.clients.geoserver.model.FeatureTypeInfo; import org.gcube.spatial.data.sdi.model.faults.RemoteException; import org.json.simple.JSONObject; +/** + * + * Based on https://docs.geoserver.org/latest/en/user/rest/index.html + * + * @author FabioISTI + * + */ public interface GSRESTClient extends GenericLoginClient{ // ********** READ OPS @@ -51,16 +58,6 @@ public interface GSRESTClient extends GenericLoginClient{ public void createStyle(String name,String content)throws RemoteException,Exception; - // create store for postgis db - - - /** - * - * gis.getCurrentGeoServer().getPublisher().publishDBLayer(workspace, storeName, fte, layerEncoder)) - */ - - - /** * Publish a DS described in @param parameters. Parameters vary depending on DS type. See https://docs.geoserver.org/latest/en/api/#1.0.0/datastores.yaml for more details. * @@ -72,13 +69,22 @@ public interface GSRESTClient extends GenericLoginClient{ -// public void pushFile(String ws,String storeName, String format,Map options)throws RemoteException,Exception; -// public void pushFile(String ws,String storeName, String format)throws RemoteException,Exception; -// public void registerFile(String ws,String storeName, String format,Map options)throws RemoteException,Exception; -// public void registerFile(String ws,String storeName, String format)throws RemoteException,Exception; -// public void registerUrl(String ws,String storeName, String format,Map options)throws RemoteException,Exception; -// public void registerUrl(String ws,String storeName, String format)throws RemoteException,Exception; -// + /** + * + * /workspaces/{workspaceName}/coveragestores/{coveragestoreName}/coverages, + * /workspaces/{workspaceName}/datastores/{datastoreName}/featuretypes, + * /workspaces/{workspaceName}/wmsstores/{wmsstoreName}/wmslayers, or + * /workspaces/{workspaceName}/wmtsstores/{wmststoreName}/wmtslayers + * + * @param ws + * @param recurse + * @throws RemoteException + * @throws Exception + */ + + + public void createLayerAsFeatureType(String ws,String dataStoreName,FeatureTypeInfo ft)throws RemoteException, Exception; + // // +********** DELETE OPS diff --git a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClientImpl.java b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClientImpl.java index 8f67ab4..a4b23c3 100644 --- a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClientImpl.java +++ b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/GSRESTClientImpl.java @@ -31,10 +31,11 @@ public class GSRESTClientImpl extends AbstractGenericRESTClient implements GSRES private static final String DATASTORE_BASE_PATH="datastores"; private static final String STYLES_BASE_PATH="styles"; private static final String LAYERS_BASE_PATH="layers"; - private static final String FEATURES_BASE_PATH="featuretype"; + private static final String FEATURES_BASE_PATH="featuretypes"; - static Configuration JSON_PATH_ALWAYS_LIST_CONFIG= Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); + static Configuration JSON_PATH_ALWAYS_LIST_CONFIG= + Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); @@ -225,12 +226,15 @@ public class GSRESTClientImpl extends AbstractGenericRESTClient implements GSRES @Override public void createStyle(String name, String content) throws RemoteException, Exception { - -// JSONObject obj=new JSONObject(); -// obj.put("name", name); -// obj.put(""); post(STYLES_BASE_PATH, Entity.entity(content, "application/vnd.ogc.sld+xml"),String.class,Collections.singletonMap("name", name)); } + @Override + public void createLayerAsFeatureType(String ws, String dataStoreName, FeatureTypeInfo ft) + throws RemoteException, Exception { + post(WS_BASE_PATH+"/"+ws+"/"+DATASTORE_BASE_PATH+"/"+dataStoreName+"/"+FEATURES_BASE_PATH, Entity.entity( + new JSONObject(Collections.singletonMap("featureType",ft)), MediaType.APPLICATION_JSON_TYPE)); + } + } diff --git a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/model/FeatureTypeInfo.java b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/model/FeatureTypeInfo.java index 741be15..cd9b969 100644 --- a/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/model/FeatureTypeInfo.java +++ b/gcube-geoserver-client/src/main/java/org/gcube/spatial/data/clients/geoserver/model/FeatureTypeInfo.java @@ -4,28 +4,42 @@ import java.util.List; import javax.xml.bind.annotation.XmlElement; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import lombok.AllArgsConstructor; import lombok.Data; @Data +@JsonInclude(Include.NON_NULL) public class FeatureTypeInfo { - + + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class Namespace{ private String name; private String href; } - + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class Keyword{ private List string; } - + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class MetadataLink{ private String type; private String metadataType; private String content; } - + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class BoundingBox{ private Number minx; private Number maxx; @@ -33,21 +47,37 @@ public class FeatureTypeInfo { private Number maxy; private String crs; } - + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class Entry{ private String key; private String value; } - + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class Store{ private String clazz; private String name; private String href; } + + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor + public static class AttributeList{ + public List attribute; + } + + @Data + @JsonInclude(Include.NON_NULL) + @AllArgsConstructor public static class Attribute{ + private String name; private Integer minOccurs; private Integer maxOccurs; @@ -60,6 +90,8 @@ public class FeatureTypeInfo { private String nativeName; private Namespace namespace; private String title; + + @XmlElement(name="abstract") private String abstractField; private List keywords; @@ -87,6 +119,6 @@ public class FeatureTypeInfo { private Boolean circularArcPresent; private Number linearizationTolerance; - private List attributes; + private AttributeList attributes; } diff --git a/gcube-geoserver-client/src/test/java/org/gcube/spatial/data/clients/geoserver/GSTests.java b/gcube-geoserver-client/src/test/java/org/gcube/spatial/data/clients/geoserver/GSTests.java index d0647a9..e0e2678 100644 --- a/gcube-geoserver-client/src/test/java/org/gcube/spatial/data/clients/geoserver/GSTests.java +++ b/gcube-geoserver-client/src/test/java/org/gcube/spatial/data/clients/geoserver/GSTests.java @@ -7,10 +7,14 @@ import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import org.gcube.sdi.test.GCubeSDITest; import org.gcube.spatial.data.clients.SDIGenericPlugin; +import org.gcube.spatial.data.clients.geoserver.model.FeatureTypeInfo; +import org.gcube.spatial.data.clients.geoserver.model.FeatureTypeInfo.AttributeList; import org.gcube.spatial.data.clients.model.engine.Engine; import org.gcube.spatial.data.sdi.model.faults.RemoteException; import org.gcube.spatial.data.sdi.utils.Files; @@ -64,6 +68,7 @@ public class GSTests extends GCubeSDITest{ for(String ft : client.getFeatureTypesInWorkspace(ws)) if(ft!=null)try { + assertTrue(client.getFeatureType(ws, ft).getNativeName()!=null); System.out.println(client.getFeatureType(ws, ft)); }catch(RemoteException e ) {System.err.println("Unable to read FT "+ft+" from "+ws+". Cause "+e.getResponseHTTPCode()+": "+e.getMessage());} @@ -102,18 +107,6 @@ public class GSTests extends GCubeSDITest{ client.createWorkspace(ws); client.getWorkspace(ws); - // DS -// String myDS=UUID.randomUUID().toString().replace("-", "_"); -// -// HashMap parameters=new HashMap(); -// -//// parameters.put("dbtype","gpkg"); -// parameters.put("url","gpkg"); -// -//// client.publishDataStore(ws, -//// new DataStoreRegistrationRequest(myDS,parameters).getDatastore()); -// -// client.deleteWorkspace(ws,true); // SLD @@ -124,6 +117,34 @@ public class GSTests extends GCubeSDITest{ client.deleteStyle(myStyle, true, true); assertFalse("SLD Removed",client.getStylesNames().contains(myStyle)); + // DS +// String myDS=UUID.randomUUID().toString().replace("-", "_"); +// +// HashMap parameters=new HashMap(); +// +//// parameters.put("dbtype","gpkg"); +// parameters.put("url","gpkg"); +// +// client.publishDataStore(ws, +// new DataStoreRegistrationRequest(myDS,parameters).getDatastore()); +// +// client.deleteWorkspace(ws,true); +// +// + //FT + + + FeatureTypeInfo ft= new FeatureTypeInfo(); + ft.setName(UUID.randomUUID().toString().replace("-", "_")); + ft.setNativeCRS("EPSG:4326"); + + List atts=new ArrayList(); + atts.add(new FeatureTypeInfo.Attribute("the_geom",1,1,true,"com.vividsolutions.jts.geom.Point",0)); + + ft.setAttributes(new AttributeList(atts)); + System.out.println("Writing "+ft); + client.createLayerAsFeatureType("aquamaps", "timeseriesws", ft); + } diff --git a/sdi-generic-client/src/main/java/org/gcube/spatial/data/clients/AbstractGenericRESTClient.java b/sdi-generic-client/src/main/java/org/gcube/spatial/data/clients/AbstractGenericRESTClient.java index 4ed5289..40d5841 100644 --- a/sdi-generic-client/src/main/java/org/gcube/spatial/data/clients/AbstractGenericRESTClient.java +++ b/sdi-generic-client/src/main/java/org/gcube/spatial/data/clients/AbstractGenericRESTClient.java @@ -184,6 +184,10 @@ public abstract class AbstractGenericRESTClient implements GenericLoginClient{ post(path,entity,null,Collections.emptyMap()); } + protected T post(String path,Entity entity,Class returnClazz)throws RemoteException,Exception{ + return post(path,entity,returnClazz,Collections.emptyMap()); + } + protected void put(String path,Object obj) throws Exception { post(path,Entity.entity(obj, MediaType.APPLICATION_JSON_TYPE)); } @@ -241,8 +245,17 @@ public abstract class AbstractGenericRESTClient implements GenericLoginClient{ } }catch(RemoteException e) { throw e; - }catch(Exception e) { - throw new RemoteException("Unable to read response from server.",e); + }catch(Exception e1) { + log.error("Reporting Remote Exception for ",e1); + RemoteException e = new RemoteException("Unable to read response from server.", e1); + e.setRemoteMessage(resp.getMessage()); + e.setResponseHTTPCode(resp.getHTTPCode()); + try{ + e.setContent(resp.getStreamedContentAsString()); + }catch(IOException e2) { + log.error("Error while reading resposne content",e2); + } + throw e; } }