first commit on work for StructuredCoverage

This commit is contained in:
Simone Giannecchini 2013-05-07 11:00:04 +02:00 committed by Daniele Romagnoli
parent 37987049e5
commit 715fb71508
8 changed files with 1135 additions and 9 deletions

View File

@ -26,6 +26,7 @@ package it.geosolutions.geoserver.rest;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageList;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem;
import it.geosolutions.geoserver.rest.encoder.GSBackupEncoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
@ -37,9 +38,11 @@ import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy
import it.geosolutions.geoserver.rest.encoder.GSWorkspaceEncoder;
import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredCoverageGridReaderManager;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@ -2537,7 +2540,7 @@ public class GeoServerRESTPublisher {
*
* configured - Only setup or configured feature types are returned. This is the default value. available - Only unconfigured feature types
* (not yet setup) but are available from the specified datastore will be returned. available_with_geom - Same as available but only
* includes feature types that have a geometry attribute. all - The union of configured and available.
* includes feature types that have a geometry granule. all - The union of configured and available.
*
*
* @return true if success
@ -2647,4 +2650,94 @@ public class GeoServerRESTPublisher {
return URLEncoder.encode(s);
// }
}
// ==> StructuredCoverageGridReader
/**
* Create a store or harvest the coverage from the provided <b>external</b> path.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
* @param the absolut path to the file to upload
*
* @return <code>true</code> if the call succeeds or <code>false</code> otherwise.
*/
public boolean createOrHarvestExternal(String workspace, String coverageStore, String format, String path) {
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(restURL), gsuser, gspass);
return manager.createOrHarvestExternal(workspace, coverageStore, format, path);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return false;
}
/**
* Remove a granule from a structured coverage by id.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage from which we are going to remove
* @param filter the absolute path to the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
public boolean removeGranuleById(final String workspace, String coverageStore, String coverage, String granuleId) {
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(restURL), gsuser, gspass);
return manager.removeGranuleById(workspace, coverageStore, coverage, granuleId);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return false;
}
/**
* Remove granules from a structured coverage, by providing a CQL filter.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage from which we are going to remove
* @param filter the absolute path to the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
public boolean removeGranulesByCQL(final String workspace, String coverageStore,String coverage, String filter) throws UnsupportedEncodingException{
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(restURL), gsuser, gspass);
return manager.removeGranulesByCQL(workspace, coverageStore, coverage, filter);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return false;
}
}

View File

@ -39,16 +39,20 @@ import it.geosolutions.geoserver.rest.decoder.RESTLayerList;
import it.geosolutions.geoserver.rest.decoder.RESTNamespace;
import it.geosolutions.geoserver.rest.decoder.RESTNamespaceList;
import it.geosolutions.geoserver.rest.decoder.RESTResource;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
import it.geosolutions.geoserver.rest.decoder.RESTStyleList;
import it.geosolutions.geoserver.rest.decoder.RESTWorkspaceList;
import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredCoverageGridReaderManager;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -575,4 +579,101 @@ public class GeoServerRESTReader {
return names;
}
/**
* Get information about a granule for a structured coverage.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
* @param the absolute path to the file to upload
* @param id the ID of the granule to get information for
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
public RESTStructuredCoverageGranulesList getGranuleById(final String workspace,
String coverageStore, String coverage, String id) throws MalformedURLException,
UnsupportedEncodingException {
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(baseurl), username, password);
return manager.getGranuleById(workspace, coverageStore, coverage, id);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return null;
}
/**
* Get information about the schema of the index for a structured coverage.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
@Test
public RESTStructuredCoverageIndexSchema getGranuleIndexSchema(final String workspace, String coverageStore, String coverage) throws MalformedURLException {
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(baseurl), username, password);
return manager.getGranuleIndexSchema(workspace, coverageStore, coverage);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return null;
}
/**
* Get information about the granules for a coverage with optional filter and paging.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage
* @param filter the format of the file to upload, can be <code>null</code> to include all the granules
* @param offset the start page, can be <code>null</code> or an integer
* @param limit the dimension of the page, can be <code>null</code> or a positive integer
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
@Test
public RESTStructuredCoverageGranulesList getGranules(final String workspace, String coverageStore, String coverage, String filter, String offset, String limit)
throws MalformedURLException, UnsupportedEncodingException {
try {
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL(baseurl), username, password);
return manager.getGranules(workspace, coverageStore, coverage, filter, offset, limit);
} catch (IllegalArgumentException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
} catch (MalformedURLException e) {
if(LOGGER.isInfoEnabled()){
LOGGER.info(e.getLocalizedMessage(),e);
}
}
return null;
}
}

View File

@ -336,7 +336,7 @@ public class HTTPUtils {
InputStream is = httpMethod.getResponseBodyAsStream();
response = IOUtils.toString(is);
IOUtils.closeQuietly(is);
if (response.trim().equals("")) { // sometimes gs rest fails
if (response.trim().equals("")) {
if (LOGGER.isDebugEnabled())
LOGGER
.debug("ResponseBody is empty (this may be not an error since we just performed a DELETE call)");
@ -467,14 +467,14 @@ public class HTTPUtils {
/**
* @param str a string array
* @return create a StringBuffer appending all the passed arguments
* @return create a StringBuilder appending all the passed arguments
*/
public static StringBuffer append(String ... str){
public static StringBuilder append(String ... str){
if (str==null){
return null;
}
StringBuffer buf=new StringBuffer();
StringBuilder buf=new StringBuilder();
for (String s: str){
if (s!=null)
buf.append(s);
@ -488,12 +488,12 @@ public class HTTPUtils {
* @param str strings to append
* @return the base URL with parameters attached
*/
public static StringBuffer append(URL base, String ... str){
public static StringBuilder append(URL base, String ... str){
if (str==null){
return append(base.toString());
}
StringBuffer buf=new StringBuffer(base.toString());
StringBuilder buf=new StringBuilder(base.toString());
for (String s: str){
if (s!=null)
buf.append(s);

View File

@ -0,0 +1,230 @@
/*
* GeoServer-Manager - Simple Manager Library for GeoServer
*
* Copyright (C) 2007,2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package it.geosolutions.geoserver.rest.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import org.jdom.Namespace;
/**
* This decode turns index format for a GeoServer StructuredGridCoverageReader into something
* useful, giving access to the definition of the single attributes.
*
* <P>This is the XML REST representation:
* <PRE>
{@code
<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns:gf="http://www.geoserver.org/rest/granules" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:coord>
<gml:X>5.0</gml:X>
<gml:Y>45.0</gml:Y>
</gml:coord>
<gml:coord>
<gml:X>14.875</gml:X>
<gml:Y>50.9375</gml:Y>
</gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<gf:V fid="V.337">
<gf:the_geom>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates>5.0,45.0 5.0,50.9375 14.875,50.9375 14.875,45.0 5.0,45.0</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</gf:the_geom>
<gf:location>..\\polyphemus\\polyphemus_20130302.nc</gf:location>
<gf:imageindex>672</gf:imageindex>
<gf:time>2013-03-01T23:00:00Z</gf:time>
<gf:elevation>10.0</gf:elevation>
<gf:fileDate>2013-03-01T23:00:00Z</gf:fileDate>
<gf:updated>2013-04-08T05:40:29.061Z</gf:updated>
</gf:V>
</gml:featureMember>
</wfs:FeatureCollection>
}</PRE>
* @author Simone Giannecchini, GeoSolutions SAS
*
*/
public class RESTStructuredCoverageGranulesList implements Iterable<RESTStructuredCoverageGranulesList.RESTStructuredCoverageGranule> {
/** GML_NAMESPACE */
private static final Namespace GML_NAMESPACE = Namespace.getNamespace("gml", "http://www.opengis.net/gml");
private final List<RESTStructuredCoverageGranule> granulesList;
private final Element bbox;
/**
* @return the bbox
*/
public Element getBbox() {
return bbox;
}
/**
* @param list
*/
@SuppressWarnings("unchecked")
protected RESTStructuredCoverageGranulesList(Element featureCollection) {
// check ordering of elements
if(!featureCollection.getName().equals("FeatureCollection")){
throw new IllegalStateException("Root element should be wfs:FeatureCollection");
}
Element boundedBy = featureCollection.getChild("boundedBy",GML_NAMESPACE);
if(boundedBy==null){
throw new IllegalStateException("Unable to find boundedBy element");
}
// save bbox
bbox=boundedBy.getChild("Box",GML_NAMESPACE);
// now get the feature members
List<RESTStructuredCoverageGranule> tmpList = new ArrayList<RESTStructuredCoverageGranule>();
for(Element el : (List<Element>)featureCollection.getChildren("featureMember",GML_NAMESPACE)){
tmpList.add(new RESTStructuredCoverageGranule(el));
}
granulesList = Collections.unmodifiableList(tmpList);
}
public static RESTStructuredCoverageGranulesList build(String response) {
if(response == null)
return null;
Element pb = JDOMBuilder.buildElement(response);
if(pb != null){
return new RESTStructuredCoverageGranulesList(pb);
} else {
return null;
}
}
public int size() {
return granulesList.size();
}
public boolean isEmpty() {
return granulesList.isEmpty();
}
public RESTStructuredCoverageGranule get(int index) {
return granulesList.get(index);
}
/* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<RESTStructuredCoverageGranule> iterator() {
return granulesList.iterator();
}
/**
* Generic granule of the index.
*
* <P>This is the XML REST representation:
* <PRE>
{@code
<gml:featureMember>
<gf:V fid="V.1">
<gf:the_geom>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates>5.0,45.0 5.0,50.9375 14.875,50.9375 14.875,45.0 5.0,45.0</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</gf:the_geom>
<gf:location>polyphemus_20130301.nc</gf:location>
<gf:imageindex>672</gf:imageindex>
<gf:time>2013-02-28T23:00:00Z</gf:time>
<gf:elevation>10.0</gf:elevation>
<gf:fileDate>2013-02-28T23:00:00Z</gf:fileDate>
<gf:updated>2013-04-08T06:18:41.597Z</gf:updated>
</gf:V>
</gml:featureMember>
* @author Simone Giannecchini, GeoSolutions SAS
*
*/
public static class RESTStructuredCoverageGranule {
protected final Element granule;
private final String fid;
private final List<Element> children;
@SuppressWarnings("unchecked")
public RESTStructuredCoverageGranule(Element elem) {
if(!elem.getName().equals("featureMember")){
throw new IllegalStateException("Root element should be gml:featureMember for a granule");
}
Element feature = (Element) elem.getChildren().get(0);
if(feature==null){
throw new IllegalStateException("Unable to find feature element for this granule");
}
this.granule = feature;
this.fid=granule.getAttribute("fid").getValue();
this.children=granule.getChildren();
}
public String getAttributeByName(String name) {
return granule.getChildTextTrim(name,null);
}
public String getAttributeByIndex(int index) {
return children.get(index).getValue();
}
@SuppressWarnings("unchecked")
public Iterator<Element> getAttributesIterator() {
return granule.getChildren().iterator();
}
/**
* @return the fid
*/
public String getFid() {
return fid;
}
}
}

View File

@ -0,0 +1,212 @@
/*
* GeoServer-Manager - Simple Manager Library for GeoServer
*
* Copyright (C) 2007,2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package it.geosolutions.geoserver.rest.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
/**
* This decode turns index format for a GeoServer StructuredGridCoverageReader into something
* useful, giving access to the definition of the single attributes.
*
* <P>This is the XML REST representation:
* <PRE>
{@code
<Schema>
<attributes>
<Attribute>
<name>the_geom</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>com.vividsolutions.jts.geom.Polygon</binding>
</Attribute>
<Attribute>
<name>location</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.lang.String</binding>
</Attribute>
<Attribute>
<name>imageindex</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.lang.Integer</binding>
</Attribute>
<Attribute>
<name>time</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.sql.Timestamp</binding>
</Attribute>
<Attribute>
<name>elevation</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.lang.Double</binding>
</Attribute>
<Attribute>
<name>fileDate</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.sql.Timestamp</binding>
</Attribute>
<Attribute>
<name>updated</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>java.sql.Timestamp</binding>
</Attribute>
</attributes>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/coveragestores/polyphemus/coverages/V/index/granules.xml" type="application/xml"/>
</Schema>
}</PRE>
* @author Simone Giannecchini, GeoSolutions SAS
*
*/
public class RESTStructuredCoverageIndexSchema implements Iterable<RESTStructuredCoverageIndexSchema.RESTStructuredCoverageIndexAttribute> {
private final List<RESTStructuredCoverageIndexAttribute> attributeList;
/**
* @param list
*/
@SuppressWarnings("unchecked")
protected RESTStructuredCoverageIndexSchema(Element schema) {
// check ordering of elements
if(!schema.getName().equals("Schema")){
throw new IllegalStateException("Root element should be Schema");
}
Element attributes = schema.getChild("attributes");
if(attributes==null){
throw new IllegalStateException("Root element should be Schema");
}
List<RESTStructuredCoverageIndexAttribute> tmpList = new ArrayList<RESTStructuredCoverageIndexAttribute>();
for(Element el : (List<Element>)attributes.getChildren()){
tmpList.add(new RESTStructuredCoverageIndexAttribute(el));
}
attributeList = Collections.unmodifiableList(tmpList);
}
public static RESTStructuredCoverageIndexSchema build(String response) {
if(response == null)
return null;
Element pb = JDOMBuilder.buildElement(response);
if(pb != null){
return new RESTStructuredCoverageIndexSchema(pb);
} else {
return null;
}
}
public int size() {
return attributeList.size();
}
public boolean isEmpty() {
return attributeList.isEmpty();
}
public RESTStructuredCoverageIndexAttribute get(int index) {
return attributeList.get(index);
}
/* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<RESTStructuredCoverageIndexAttribute> iterator() {
return attributeList.iterator();
}
/**
* Generic granule of the index.
*
* <P>This is the XML REST representation:
* <PRE>
{@code
<Attribute>
<name>the_geom</name>
<minOccurs>0</minOccurs>
<maxOccurs>1</maxOccurs>
<nillable>true</nillable>
<binding>com.vividsolutions.jts.geom.Polygon</binding>
</Attribute>
* @author Simone Giannecchini, GeoSolutions SAS
*
*/
public static class RESTStructuredCoverageIndexAttribute {
protected final Element attribute;
public RESTStructuredCoverageIndexAttribute(Element elem) {
this.attribute = elem;
}
public String getName() {
return attribute.getChildTextTrim("name");
}
public String getMinOccurs() {
return attribute.getChildTextTrim("minOccurs");
}
public String getMaxOccurs() {
return attribute.getChildTextTrim("maxOccurs");
}
public String getNillable() {
return attribute.getChildTextTrim("nillable");
}
public String getBinding() {
return attribute.getChildTextTrim("binding");
}
@Override
public String toString() {
return "RESTStructuredCoverageGranule [getName()=" + getName()
+ ", getMinOccurs()=" + getMinOccurs() + ", getMaxOccurs()=" + getMaxOccurs()
+ ", getNillable()=" + getNillable() + ", getBinding()=" + getBinding() + "]";
}
}
}

View File

@ -107,7 +107,7 @@ public class GeoServerRESTStoreManager extends GeoServerRESTAbstractManager {
// if (workspace.isEmpty() || storename.isEmpty())
// throw new IllegalArgumentException("Arguments may not be empty!");
final StringBuffer url=HTTPUtils.append(restURL,"/rest/workspaces/",workspace,"/", store.getStoreType().toString(), "/",store.getName());
final StringBuilder url=HTTPUtils.append(restURL,"/rest/workspaces/",workspace,"/", store.getStoreType().toString(), "/",store.getName());
if (recurse)
url.append("?recurse=true");
final URL deleteStore = new URL(url.toString());

View File

@ -0,0 +1,354 @@
/*
* GeoServer-Manager - Simple Manager Library for GeoServer
*
* Copyright (C) 2007,2012 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package it.geosolutions.geoserver.rest.manager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher.UploadMethod;
import it.geosolutions.geoserver.rest.HTTPUtils;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manage GeoTools StructuredCoverageGridReader. It allows to create a store from a file or harvest
* the coverages contained in a file, to delete granules from an existing coverage and eventually
* to get information about the granules insi a StructuredCoverageGridReader.
*
* @author Simone Giannecchini, GeoSolutions
*/
public class GeoServerRESTStructuredCoverageGridReaderManager extends GeoServerRESTAbstractManager {
/**
* Default logger
*/
private final static Logger LOGGER = LoggerFactory.getLogger(GeoServerRESTStructuredCoverageGridReaderManager.class);
/**
* Default constructor.
*
* @param restURL GeoServer REST API endpoint
* @param username GeoServer REST API authorized username
* @param password GeoServer REST API password for the former username
* @throws IllegalArgumentException
*/
public GeoServerRESTStructuredCoverageGridReaderManager(URL restURL, String username, String password) throws IllegalArgumentException, MalformedURLException{
super(restURL, username, password);
}
/**
* Create a store or harvest the coverage from the provided <b>external</b> path.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
* @param the absolut path to the file to upload
*
* @return <code>true</code> if the call succeeds or <code>false</code> otherwise.
*/
public boolean createOrHarvestExternal(String workspace, String coverageStore, String format, String path) {
// checks
checkString(workspace);
checkString(coverageStore);
checkString(format);
checkString(path);
// create URL
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/",coverageStore,"/",UploadMethod.EXTERNAL.toString(),".", format).toString();
// POST request
String result = HTTPUtils.post(sUrl, "file:/"+path, "text/plain", gsuser, gspass);
return result != null;
}
/**
* Check the provided string for not being null or empty.
*
* <p>
* It throws an exception in case the string is either null or empty.
*
* @param string the {@link String} to be checked
*/
private static void checkString(String string) {
if(string==null){
throw new NullPointerException("Provided string is is null!");
}
if(string.length()<=0){
throw new IllegalArgumentException("Provided string is is empty!");
}
}
/**
* Remove granules from a structured coverage, by providing a CQL filter.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage from which we are going to remove
* @param filter the absolute path to the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
public boolean removeGranulesByCQL(final String workspace, String coverageStore,String coverage, String filter) throws UnsupportedEncodingException{
// checks
checkString(workspace);
checkString(coverage);
checkString(filter);
checkString(coverageStore);
// does it exist?
RESTStructuredCoverageGranulesList granulesList=null;
try {
granulesList = getGranules(workspace, coverageStore, coverageStore, filter, null, "1");
} catch (MalformedURLException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
} catch (UnsupportedEncodingException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
}
if (granulesList == null||granulesList.isEmpty()) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace("Granules for filter: "+filter+ " does not exist for coverage "+coverage);
}
return true; // nothing to remove
}
// method
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores", "/",coverageStore,"/coverages/",coverage,"/index/granules?filter=",URLEncoder.encode(filter, "UTF-8")).toString();
if(!HTTPUtils.delete(sUrl, gsuser, gspass)){
return false;
}
// does it exist?
granulesList=null;
try {
granulesList = getGranules(workspace, coverageStore, coverageStore, filter, null, "1");
} catch (MalformedURLException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
} catch (UnsupportedEncodingException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
}
if (granulesList == null||granulesList.isEmpty()) {
return true; // nothing to remove
}
return false;
}
/**
* Remove a granule from a structured coverage by id.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage from which we are going to remove
* @param filter the absolute path to the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
public boolean removeGranuleById(final String workspace, String coverageStore, String coverage, String granuleId) {
// checks
checkString(workspace);
checkString(coverage);
checkString(granuleId);
checkString(coverageStore);
// does it exist?
RESTStructuredCoverageGranulesList granule=null;
try {
granule = getGranuleById(workspace, coverageStore, coverage, granuleId);
} catch (MalformedURLException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
} catch (UnsupportedEncodingException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
}
if (granule == null) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace("Granule for id: "+granuleId+ " does not exist for coverage "+coverage);
}
return true; // nothing to remove
}
// delete
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores",
"/", coverageStore, "/coverages/", coverage, "/index/granules/", granuleId)
.toString();
if(!HTTPUtils.delete(sUrl, gsuser, gspass)){
return false;
}
// has it been canceled?
// does it exist?
granule=null;
try {
granule = getGranuleById(workspace, coverageStore, coverage, granuleId);
} catch (MalformedURLException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
} catch (UnsupportedEncodingException e) {
if(LOGGER.isTraceEnabled()){
LOGGER.trace(e.getMessage(), e);
}
}
if (granule == null) {
return true;
}
return false;
}
/**
* Get information about the schema of the index for a structured coverage.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
@Test
public RESTStructuredCoverageIndexSchema getGranuleIndexSchema(final String workspace, String coverageStore, String coverage) throws MalformedURLException {
// checks
checkString(workspace);
checkString(coverage);
checkString(coverageStore);
// create URL and then call it
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index.xml").toString();
String result = HTTPUtils.get(sUrl, gsuser, gspass);
if (result != null) {
return RESTStructuredCoverageIndexSchema.build(result);
}
return null;
}
/**
* Get information about the granules for a coverage with optional filter and paging.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param coverage the name of the target coverage
* @param filter the format of the file to upload, can be <code>null</code> to include all the granules
* @param offset the start page, can be <code>null</code> or an integer
* @param limit the dimension of the page, can be <code>null</code> or a positive integer
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
@Test
public RESTStructuredCoverageGranulesList getGranules(final String workspace, String coverageStore, String coverage, String filter, String offset, String limit)
throws MalformedURLException, UnsupportedEncodingException {
// checks
checkString(workspace);
checkString(coverage);
checkString(coverageStore);
// method
boolean append = false;
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index/granules.xml").toString();
if (filter != null && !filter.isEmpty()) {
append = true;
sUrl = HTTPUtils.append(sUrl, "?filter=", URLEncoder.encode(filter, "UTF-8")).toString();
}
if (offset != null && !offset.isEmpty()) {
sUrl = HTTPUtils.append(sUrl, append ? "&offset=" : "?offset=", offset).toString();
append = true;
}
if (limit != null && !limit.isEmpty()) {
sUrl = HTTPUtils.append(sUrl, append ? "&limit=" : "?limit=", limit).toString();
append = true;
}
String result = HTTPUtils.get(sUrl, gsuser, gspass);
if (result != null) {
return RESTStructuredCoverageGranulesList.build(result);
}
return null;
}
/**
* Get information about a granule for a structured coverage.
*
* @param workspace the GeoServer workspace
* @param coverageStore the GeoServer coverageStore
* @param format the format of the file to upload
* @param the absolute path to the file to upload
* @param id the ID of the granule to get information for
*
* @return <code>null</code> in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
*
* @throws MalformedURLException
* @throws UnsupportedEncodingException
*/
@Test
public RESTStructuredCoverageGranulesList getGranuleById(final String workspace,
String coverageStore, String coverage, String id) throws MalformedURLException,
UnsupportedEncodingException {
// checks
checkString(workspace);
checkString(coverage);
checkString(coverageStore);
checkString(id);
try{
Integer.parseInt(id);
}catch (NumberFormatException e) {
throw new IllegalArgumentException(e);
}
// method
String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index/granules/", id, ".xml").toString();
String result = HTTPUtils.get(sUrl, gsuser, gspass);
if (result != null) {
return RESTStructuredCoverageGranulesList.build(result);
}
return null;
}
}

View File

@ -0,0 +1,136 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2011, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package it.geosolutions.geoserver.rest.manager;
import it.geosolutions.geoserver.rest.datastore.StoreIntegrationTest;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList.RESTStructuredCoverageGranule;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema.RESTStructuredCoverageIndexAttribute;
import it.geosolutions.geoserver.rest.encoder.GSAbstractStoreEncoder;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import junit.framework.Assert;
import org.junit.Test;
/**
* @author Simone Giannecchini, simone.giannecchini@geo-solutions.it
*
*/
public class GeoServerRESTStructuredCoverageGridReaderManagerTest extends StoreIntegrationTest {
/**
* @param ignore
* @throws IllegalArgumentException
* @throws MalformedURLException
*/
public GeoServerRESTStructuredCoverageGridReaderManagerTest()
throws IllegalArgumentException, MalformedURLException {
super(true);
}
@Override
public GSAbstractStoreEncoder getStoreEncoderTest() {
// TODO Auto-generated method stub
return null;
}
@Test
public void createAndDelete() throws IllegalArgumentException, MalformedURLException, UnsupportedEncodingException{
GeoServerRESTStructuredCoverageGridReaderManager manager =
new GeoServerRESTStructuredCoverageGridReaderManager(new URL("http://localhost:8080/geoserver"), "admin", "geoserver");
// boolean result=manager.createOrHarvestExternal("it.geosolutions", "polyphemus", "imagemosaic", "D:\\DLR\\Geoserver-MD\\polyphemus\\polyphemus_20130301.nc");
// Assert.assertTrue(result);
// check index format
RESTStructuredCoverageIndexSchema indexFormat = manager.getGranuleIndexSchema("it.geosolutions", "polyphemus","V");
assertNotNull(indexFormat);
assertFalse(indexFormat.isEmpty());
assertEquals(7, indexFormat.size());
Iterator<RESTStructuredCoverageIndexAttribute> iterator = indexFormat.iterator();
while(iterator.hasNext()){
final RESTStructuredCoverageIndexAttribute element = iterator.next();
if(element.getName().equals("location")){
assertEquals("0", element.getMinOccurs());
assertEquals("1", element.getMaxOccurs());
assertEquals("true", element.getNillable());
assertEquals("java.lang.String", element.getBinding());
break;
}
}
// get some granules by id
RESTStructuredCoverageGranulesList granulesList = manager.getGranuleById("it.geosolutions", "polyphemus","V","348");
assertNotNull(granulesList);
assertSame(1, granulesList.size());
assertFalse(granulesList.isEmpty());
RESTStructuredCoverageGranule granule = granulesList.get(0);
assertNotNull(granule);
assertEquals(granule.getAttributeByIndex(4), "1250.0");
assertEquals(granule.getAttributeByName("elevation"), "1250.0");
// get with paging
granulesList = manager.getGranules("it.geosolutions", "polyphemus","V",null,"0","10");
assertNotNull(granulesList);
assertEquals(10, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules("it.geosolutions", "polyphemus","V",null,null,"10");
assertNotNull(granulesList);
assertEquals(10, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules("it.geosolutions", "polyphemus","V",null,null,null);
assertNotNull(granulesList);
assertEquals(1007, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules("it.geosolutions", "polyphemus","V","elevation = 10",null,null);
assertNotNull(granulesList);
assertEquals(72, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules("it.geosolutions", "polyphemus","V","elevation = 10","0","10");
assertNotNull(granulesList);
assertEquals(10, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
// remove by id
boolean result = manager.removeGranuleById("it.geosolutions", "polyphemus","V", "349");
assertTrue(result);
// remove by filter
result = manager.removeGranulesByCQL("it.geosolutions", "polyphemus","V", "location = 'polyphemus_20130301.nc'");
Assert.assertTrue(result);
}
}