Namespace handling: reader, encoder, CRUD & unit tests

This commit is contained in:
Oscar Fonts 2012-04-27 16:33:20 +02:00
parent 667a9b2f69
commit 48655e3db5
7 changed files with 522 additions and 0 deletions

View File

@ -28,6 +28,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTCoverageList;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSNamespaceEncoder;
import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy;
@ -110,6 +111,84 @@ public class GeoServerRESTPublisher {
final String result = HTTPUtils.postXml(sUrl, wsxml, gsuser, gspass);
return result != null;
}
/**
* Create both a workspace and its associated namespace.
*
* Note that this method is equivalent to {@link #createNamespace}.
*
* @param name Name for the new workspace, which will be also its associated namespace prefix.
* @param uri Namespace URI. Cannot be empty.
* @return <TT>true</TT> if the Workspace and its associated namespace were successfully created.
*/
public boolean createWorkspace(final String name, final URI uri) {
// This is really an alias to createNamespace, as GeoServer
// will automatically create the workspace as well.
return createNamespace(name, uri);
}
// ==========================================================================
// === NAMESPACES
// ==========================================================================
/**
* Create a new namespace. GeoServer will automatically create the corresponding workspace.
*
* Prefix and uri are mandatory and cannot be empty.
* If a namespace with the given prefix already exists, it won't be created.
*
* @param prefix The name of the new namespace.
* @param uri The URI of the new namespace.
* @return <TT>true</TT> if the namespace was successfully created.
* @see <a href="http://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html#namespaces"> GeoServer Documentation</a>
*/
public boolean createNamespace(final String prefix, final URI uri) {
final String sUrl = restURL + "/rest/namespaces";
final GSNamespaceEncoder nsenc = new GSNamespaceEncoder(prefix, uri);
final String nsxml = nsenc.toString();
final String result = HTTPUtils.postXml(sUrl, nsxml, gsuser, gspass);
return result != null;
}
/**
* Update a namespace URI.
*
* Prefix and uri are mandatory and cannot be empty.
* A namespace with the given prefix should exist.
*
* @param prefix The prefix of an existing namespace.
* @param uri The new URI.
* @return <TT>true</TT> if the namespace was successfully updated.
*/
public boolean updateNamespace(final String prefix, final URI uri) {
final String sUrl = restURL + "/rest/namespaces/"+ encode(prefix);
final GSNamespaceEncoder nsenc = new GSNamespaceEncoder(prefix, uri);
final String nsxml = nsenc.toString();
final String result = HTTPUtils.put(sUrl, nsxml, "application/xml", gsuser, gspass);
return result != null;
}
/**
* Remove a given Namespace. It will remove the associated workspace as well.
*
* @param prefix
* The namespace prefix
* @param recurse
* The recurse parameter is used to recursively delete all
* resources contained in the workspace associated with this
* namespace. This includesdata stores, coverage stores,
* feature types, etc... Allowable values for this parameter
* are <i>true</i> or <i>false</i>. The default (safer) value
* is <i>false</i>.
* @return <TT>true</TT> if the namespace was successfully removed.
*/
public boolean removeNamespace(final String prefix, boolean recurse) {
// Hack: We are instead calling removeWorkspace, as DELETE on
// a namespace will leave associated workspace in an inconsistent
// state. See https://jira.codehaus.org/browse/GEOS-5075
// TODO switch to namespace when GEOS-5075 is solved
return removeWorkspace(prefix, recurse);
}
// ==========================================================================
// === STYLES

View File

@ -36,6 +36,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.decoder.RESTLayerGroup;
import it.geosolutions.geoserver.rest.decoder.RESTLayerGroupList;
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.RESTStyleList;
@ -454,6 +455,25 @@ public class GeoServerRESTReader {
//=== NAMESPACES
//==========================================================================
/**
* Get a namespace.
*
* @param prefix namespace prefix.
*
* @return a RESTNamespace, or null if couldn't be created.
*/
public RESTNamespace getNamespace(String prefix) {
if (prefix == null || prefix.isEmpty()) {
throw new IllegalArgumentException(
"Namespace prefix cannot be null or empty");
}
String url = "/rest/namespaces/"+prefix+".xml";
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("### Getting namespace from " + url);
}
return RESTNamespace.build(load(url));
}
/**
* Get summary info about all Namespaces.
*

View File

@ -0,0 +1,99 @@
/*
* 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.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
import org.jdom.Element;
import java.net.URI;
/**
* Parse <TT>namespace</TT>s returned as XML REST objects.
*
* This is the XML REST representation:
* <pre>{@code
<namespace>
<prefix>topp</prefix>
<uri>http://www.openplans.org/topp</uri>
<featureTypes>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/topp/featuretypes.xml" type="application/xml"/>
</featureTypes>
</namespace>
* }</pre>
*
* @author Oscar Fonts
*/
public class RESTNamespace {
public final static String NAMESPACE="namespace";
public final static String PREFIX="prefix";
public final static String URI="uri";
public final static String FEATURE_TYPES="featureTypes";
private final Element namespaceElem;
/**
* Build a RESTNamespace from a REST response.
*
* @param response XML representation of the namespace.
* @return a new RESTNamespace, or null if XML could not be parsed.
*/
public static RESTNamespace build(String response) {
if(response == null)
return null;
Element pb = JDOMBuilder.buildElement(response);
if(pb != null)
return new RESTNamespace(pb);
else
return null;
}
/**
* Create a RESTNamespace from a XML element.
*
* @param elem The jdom XML Element describing a namespace.
*/
public RESTNamespace(Element elem) {
this.namespaceElem = elem;
}
/**
* Get the namespace prefix
*
* @return the namespace prefix.
*/
public String getPrefix() {
return namespaceElem.getChildText(PREFIX);
}
/**
* Get the namespace URI.
*
* @return the namespace uri.
*/
public URI getURI() {
return java.net.URI.create(namespaceElem.getChildText(URI));
}
}

View File

@ -0,0 +1,131 @@
/*
* 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.encoder;
import java.net.URI;
import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
import it.geosolutions.geoserver.rest.encoder.utils.PropertyXMLEncoder;
/**
* Namespace XML encoder. Namespaces must contain a non empty prefix and a URI:
*
* <pre>
* &lt;namespace>
* &lt;prefix>example&lt;/prefix>
* &lt;uri>http://example.com&lt;/uri>
* &lt;/namespace>
* </pre>
*
* @see <a href="http://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html#namespaces"> GeoServer Documentation</a>
* @author Oscar Fonts
*/
public class GSNamespaceEncoder extends PropertyXMLEncoder {
public final static String NAMESPACE="namespace";
public final static String PREFIX="prefix";
public final static String URI="uri";
/**
* Create a namespace XML encoder.
*
* @param prefix the namespace prefix
* @param uri the namespace URI
* @throws IllegalArgumentException if prefix or uri are null or empty
*/
public GSNamespaceEncoder(String prefix, URI uri) {
super(NAMESPACE);
ensureValidPrefix(prefix);
ensureValidURI(uri);
add(PREFIX, prefix);
add(URI, uri.toString());
}
/**
* Get the namespace prefix.
* @return the prefix
*/
public String getPrefix() {
return ElementUtils.contains(getRoot(), PREFIX).getTextTrim();
}
/**
* Change the namespace prefix.
* @param prefix the new prefix
* @throws IllegalArgumentException if prefix is null or empty
*/
public void setPrefix(final String prefix) {
ensureValidPrefix(prefix);
ElementUtils.contains(getRoot(), PREFIX).setText(prefix);
}
/**
* Get the namespace uri.
* @return the uri
*/
public URI getURI() {
String sUri = ElementUtils.contains(getRoot(), URI).getTextTrim();
return java.net.URI.create(sUri);
}
/**
* change the nampespace uri.
* @param URI the new uri
* @throws IllegalArgumentException if uri is null or empty
*/
public void setURI(final URI uri) {
ensureValidURI(uri);
String sUri = uri.toString();
ElementUtils.contains(getRoot(), URI).setText(sUri);
}
/**
* Check prefix value.
*
* @param prefix the prefix
* @throws IllegalArgumentException if prefix is null or empty
*/
private static void ensureValidPrefix(String prefix) {
if (prefix == null || prefix.isEmpty()) {
throw new IllegalArgumentException(
"Namespace prefix cannot be null or empty");
}
}
/**
* Check uri value.
*
* @param prefix the uri
* @throws IllegalArgumentException if uri is null or empty
*/
private static void ensureValidURI(URI uri) {
if (uri == null || uri.toString().isEmpty()) {
throw new IllegalArgumentException(
"Namespace uri cannot be null or empty");
}
}
}

View File

@ -161,7 +161,24 @@ public class GeoserverRESTReaderTest extends GeoserverRESTTest {
}
System.out.println();
}
/**
* Test of getWorkspaceNames method, of class GeoServerRESTReader.
*/
public void testGetNamespaceNames() {
if(!enabled()) return;
List<String> names = reader.getNamespaceNames();
assertNotNull(names);
// assertEquals(7, names.size()); // value in default gs installation
System.out.println("Namespaces:" + names.size());
System.out.print("Namespaces:");
for (String name : names) {
System.out.print(name + " ");
}
System.out.println();
}
/**
* Test of getWorkspaceNames method, of class GeoServerRESTReader.

View File

@ -0,0 +1,73 @@
/*
* 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.encoder;
import static org.junit.Assert.*;
import java.net.URI;
import org.junit.Test;
/**
* @author Oscar Fonts
*/
public class GSNamespaceEncoderTest {
private static final String ROOT_NAME = "namespace";
private static final String TEST_PREFIX = "example";
private static final URI TEST_URI = URI.create("http://example.com");
/**
* Test method for {@link GSNamespaceEncoder#GSNamespaceEncoder()}.
*/
@Test
public void testGSNamespaceEncoder() {
// Test constructor and getters.
GSNamespaceEncoder enc = new GSNamespaceEncoder(TEST_PREFIX, TEST_URI);
assertEquals(enc.getRoot().getName(), ROOT_NAME);
assertEquals(enc.getPrefix(), TEST_PREFIX);
assertEquals(enc.getURI(), TEST_URI);
assertEquals(enc.toString(),"<namespace><prefix>"+TEST_PREFIX+"</prefix>"+
"<uri>"+TEST_URI+"</uri></namespace>");
// Test constructor parameter extreme values.
// Should throw IllegalArgumentException if null or empty.
try {
new GSNamespaceEncoder(null, TEST_URI);
fail("Namespace encoder should not accept a null prefix");
} catch (IllegalArgumentException e) {}
try {
new GSNamespaceEncoder("", TEST_URI);
fail("Namespace encoder should not accept an empty prefix");
} catch (IllegalArgumentException e) {}
try {
new GSNamespaceEncoder(TEST_PREFIX, null);
fail("Namespace encoder should not accept a null uri");
} catch (IllegalArgumentException e) {}
try {
new GSNamespaceEncoder(TEST_PREFIX, URI.create(""));
fail("Namespace encoder should not accept an empty uri");
} catch (IllegalArgumentException e) {}
}
}

View File

@ -0,0 +1,103 @@
/*
* 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.publisher;
import org.junit.Test;
import it.geosolutions.geoserver.rest.GeoserverRESTTest;
import it.geosolutions.geoserver.rest.decoder.RESTNamespace;
import java.net.URI;
/**
* Testcase for namespace management.
*
* We need a running GeoServer to properly run the tests.
* If such geoserver instance cannot be contacted, tests will be skipped.
*
* @author Oscar Fonts
*/
public class GeoserverRESTNamespaceTest extends GeoserverRESTTest {
public GeoserverRESTNamespaceTest(String testName) {
super(testName);
}
/**
* Test Namespace create
*/
@Test
public void testCreate() {
if (!enabled()) return;
deleteAll();
assertEquals(0, reader.getNamespaces().size());
assertEquals(0, reader.getWorkspaces().size());
// Test Namespace Creation
assertTrue(publisher.createNamespace("NS1", URI.create("http://a.example.com")));
assertTrue(publisher.createNamespace("NS2", URI.create("http://b.example.com")));
assertEquals(2, reader.getNamespaces().size());
// When creating a namespace, its associated workspace will be automatically created:
assertEquals(2, reader.getWorkspaces().size());
// Existing prefix / existing URI
assertFalse(publisher.createNamespace("NS1", URI.create("http://c.example.com")));
assertFalse(publisher.createNamespace("NS3", URI.create("http://a.example.com")));
assertEquals(2, reader.getWorkspaces().size());
}
/**
* Test Namespace read, update and delete
*/
@Test
public void testReadUpdateDelete() {
if (!enabled()) return;
deleteAll();
assertTrue(publisher.createNamespace("NS1", URI.create("http://a.example.com")));
// Test read namespace list
String nsName = reader.getNamespaceNames().get(0);
assertEquals(nsName, "NS1");
// Read a namespace
RESTNamespace ns = reader.getNamespace(nsName);
assertEquals(ns.getPrefix(), "NS1");
assertEquals(ns.getURI(), URI.create("http://a.example.com"));
// Update namespaces (change URI)
assertTrue(publisher.updateNamespace("NS1", URI.create("http://b.example.com")));
assertFalse(publisher.updateNamespace("NS2", URI.create("http://a.example.com"))); // Nonexistent
// Delete namespaces
assertTrue(publisher.removeNamespace("NS1", true));
assertFalse(publisher.removeNamespace("NS3", true)); // Nonexistent
assertEquals(0, reader.getNamespaces().size());
assertEquals(0, reader.getWorkspaces().size());
}
}