/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.rest.catalog;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathExists;
import static org.geoserver.rest.catalog.HttpTestUtils.hasHeader;
import static org.geoserver.rest.catalog.HttpTestUtils.hasStatus;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.*;
import java.net.URL;
import java.util.List;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.TestHttpClientRule;
import org.geoserver.catalog.WMSLayerInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.rest.RestBaseController;
import org.geoserver.test.http.MockHttpClient;
import org.geoserver.test.http.MockHttpResponse;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletResponse;
public class WMSStoreTest extends CatalogRESTTestSupport {
@ClassRule
public static TestHttpClientRule clientMocker = new TestHttpClientRule();
private static String capabilities;
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
// we need to add a wms store
CatalogBuilder cb = new CatalogBuilder(catalog);
cb.setWorkspace(catalog.getWorkspaceByName("sf"));
WMSStoreInfo wms = cb.buildWMSStore("demo");
wms.setCapabilitiesURL(capabilities);
catalog.add(wms);
cb.setStore(wms);
WMSLayerInfo layer = cb.buildWMSLayer("world4326");
catalog.add(layer);
}
@BeforeClass
public static void mockServer() throws Exception {
capabilities = clientMocker.getServer()+"/geoserver/wms?REQUEST=GetCapabilities&VERSION=1.3.0&SERVICE=WMS";
MockHttpClient client = new MockHttpClient();
client.expectGet(
new URL(capabilities),
new MockHttpResponse(WMSStoreTest.class.getResource("caps130.xml"), "text/xml"));
clientMocker.bind(client, capabilities);
}
@Test
public void testBeanPresent() throws Exception {
assertThat(GeoServerExtensions.extensions(RestBaseController.class),
hasItem(instanceOf(WMSStoreController.class)));
}
@Test
public void testGetAllAsXML() throws Exception {
Document dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores.xml");
assertEquals("wmsStores", dom.getDocumentElement().getNodeName());
assertEquals( catalog.getStoresByWorkspace( "sf", WMSStoreInfo.class ).size(),
dom.getElementsByTagName( "wmsStore").getLength() );
}
@Test
public void testGetAllAsJSON() throws Exception {
JSON json = getAsJSON( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores.json");
assertTrue( json instanceof JSONObject );
Object stores = ((JSONObject)json).getJSONObject("wmsStores").get("wmsStore");
assertNotNull( stores );
if( stores instanceof JSONArray ) {
assertEquals( catalog.getStoresByWorkspace("sf", WMSStoreInfo.class).size() , ((JSONArray)stores).size() );
} else {
assertEquals( 1, catalog.getStoresByWorkspace("sf", WMSStoreInfo.class).size() );
}
}
@Test
public void testGetAllAsHTML() throws Exception {
Document dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores.html");
List<WMSStoreInfo> stores = catalog.getStoresByWorkspace("sf", WMSStoreInfo.class);
NodeList links = xp.getMatchingNodes("//html:a", dom );
assertEquals( stores.size(), links.getLength() );
for ( int i = 0; i < stores.size(); i++ ){
WMSStoreInfo store = stores.get( i );
Element link = (Element) links.item( i );
assertTrue( link.getAttribute("href").endsWith( store.getName() + ".html") );
}
}
@Test
public void testPutAllUnauthorized() throws Exception {
assertEquals( 405, putAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores").getStatus() );
}
@Test
public void testDeleteAllUnauthorized() throws Exception {
assertEquals( 405, deleteAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores").getStatus() );
}
@Test
public void testGetAsXML() throws Exception {
Document dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo.xml");
assertEquals( "wmsStore", dom.getDocumentElement().getNodeName() );
assertEquals( "demo", xp.evaluate( "/wmsStore/name", dom) );
assertEquals( "sf", xp.evaluate( "/wmsStore/workspace/name", dom) );
assertXpathExists( "/wmsStore/capabilitiesURL", dom );
}
@Test
public void testGetAsHTML() throws Exception {
WMSStoreInfo store = catalog.getStoreByName("sf", "demo", WMSStoreInfo.class);
assertThat(store, notNullValue());
List<WMSLayerInfo> resources = catalog.getResourcesByStore(store, WMSLayerInfo.class);
assertThat(resources, not(empty()));
Document dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo.html");
WMSStoreInfo wms = catalog.getStoreByName( "demo", WMSStoreInfo.class );
List<WMSLayerInfo> wmsLayers = catalog.getResourcesByStore( wms, WMSLayerInfo.class );
NodeList links = xp.getMatchingNodes("//html:a", dom );
assertEquals( wmsLayers.size(), links.getLength() );
for ( int i = 0; i < wmsLayers.size(); i++ ){
WMSLayerInfo wl = wmsLayers.get( i );
Element link = (Element) links.item( i );
assertTrue( link.getAttribute("href").endsWith( wl.getName() + ".html") );
}
}
@Test
public void testGetWrongWMSStore() throws Exception {
// Parameters for the request
String ws = "sf";
String wms = "sfssssss";
// Request path
String requestPath = RestBaseController.ROOT_PATH+"/workspaces/" + ws + "/wmsstores/" + wms + ".html";
// Exception path
String exception = "No such wms store: " + ws + "," + wms;
// First request should thrown an exception
MockHttpServletResponse response = getAsServletResponse(requestPath);
assertEquals(404, response.getStatus());
assertTrue(response.getContentAsString().contains(
exception));
// Same request with ?quietOnNotFound should not throw an exception
response = getAsServletResponse(requestPath + "?quietOnNotFound=true");
assertEquals(404, response.getStatus());
assertFalse(response.getContentAsString().contains(
exception));
// No exception thrown
assertTrue(response.getContentAsString().isEmpty());
}
@Test
public void testPostAsXML() throws Exception {
String xml =
"<wmsStore>" +
"<name>newWMSStore</name>" +
"<capabilitiesURL>http://somehost/wms?</capabilitiesURL>" +
"<workspace>sf</workspace>" +
"</wmsStore>";
MockHttpServletResponse response =
postAsServletResponse( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores", xml, "text/xml" );
assertThat(response, hasStatus(HttpStatus.CREATED) );
assertThat(response, hasHeader("Location", endsWith("/workspaces/sf/wmsstores/newWMSStore")) );
WMSStoreInfo newStore = catalog.getStoreByName( "newWMSStore", WMSStoreInfo.class );
assertNotNull( newStore );
assertEquals("http://somehost/wms?", newStore.getCapabilitiesURL());
}
@Test
public void testPostAsXMLNoWorkspace() throws Exception {
String xml =
"<wmsStore>" +
"<name>newWMSStore</name>" +
"<capabilitiesURL>http://somehost/wms?</capabilitiesURL>" +
"</wmsStore>";
MockHttpServletResponse response =
postAsServletResponse( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores", xml, "text/xml" );
assertThat(response, hasStatus(HttpStatus.CREATED) );
assertThat(response, hasHeader("Location", endsWith("/workspaces/sf/wmsstores/newWMSStore")) );
WMSStoreInfo newStore = catalog.getStoreByName( "newWMSStore", WMSStoreInfo.class );
assertNotNull( newStore );
assertEquals("http://somehost/wms?", newStore.getCapabilitiesURL());
}
@Test
public void testGetAsJSON() throws Exception {
JSON json = getAsJSON( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo.json" );
JSONObject store = ((JSONObject)json).getJSONObject("wmsStore");
assertNotNull(store);
assertEquals( "demo", store.get( "name") );
assertEquals( "sf", store.getJSONObject( "workspace").get( "name" ) );
assertEquals( capabilities, store.getString( "capabilitiesURL") );
}
@Test
public void testPostAsJSON() throws Exception {
removeStore("sf", "newWMSStore");
String json =
"{'wmsStore':{" +
"'capabilitiesURL': 'http://somehost/wms?'," +
"'workspace':'sf'," +
"'name':'newWMSStore'," +
"}" +
"}";
MockHttpServletResponse response =
postAsServletResponse( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores", json, "text/json" );
assertEquals( 201, response.getStatus() );
assertNotNull( response.getHeader( "Location") );
assertTrue( response.getHeader("Location").endsWith( "/workspaces/sf/wmsstores/newWMSStore" ) );
WMSStoreInfo newStore = catalog.getStoreByName( "newWMSStore", WMSStoreInfo.class );
assertNotNull( newStore );
assertEquals("http://somehost/wms?", newStore.getCapabilitiesURL());
}
@Test
public void testPostToResource() throws Exception {
String xml =
"<wmsStore>" +
"<name>demo</name>" +
"<enabled>false</enabled>" +
"</wmsStore>";
MockHttpServletResponse response =
postAsServletResponse( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo", xml, "text/xml");
assertEquals( 405, response.getStatus() );
}
@Test
public void testPut() throws Exception {
Document dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo.xml");
assertXpathEvaluatesTo("true", "/wmsStore/enabled", dom );
String xml =
"<wmsStore>" +
"<name>demo</name>" +
"<enabled>false</enabled>" +
"</wmsStore>";
MockHttpServletResponse response =
putAsServletResponse( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo", xml, "text/xml");
assertEquals( 200, response.getStatus() );
dom = getAsDOM( RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo.xml");
assertXpathEvaluatesTo("false", "/wmsStore/enabled", dom );
assertFalse( catalog.getStoreByName("sf", "demo", WMSStoreInfo.class).isEnabled() );
}
@Test
public void testPutNonDestructive() throws Exception {
WMSStoreInfo wsi = catalog.getStoreByName("sf", "demo", WMSStoreInfo.class);
wsi.setEnabled(true);
catalog.save(wsi);
assertTrue(wsi.isEnabled());
int maxConnections = wsi.getMaxConnections();
int readTimeout = wsi.getReadTimeout();
int connectTimeout = wsi.getConnectTimeout();
boolean useConnectionPooling = wsi.isUseConnectionPooling();
String xml =
"<wmsStore>" +
"<name>demo</name>" +
"</wmsStore>";
MockHttpServletResponse response =
putAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo", xml, "text/xml" );
assertEquals( 200, response.getStatus() );
wsi = catalog.getStoreByName("sf", "demo", WMSStoreInfo.class);
assertTrue(wsi.isEnabled());
assertEquals(maxConnections, wsi.getMaxConnections());
assertEquals(readTimeout, wsi.getReadTimeout());
assertEquals(connectTimeout, wsi.getConnectTimeout());
assertEquals(useConnectionPooling, wsi.isUseConnectionPooling());
}
@Test
public void testPutNonExistant() throws Exception {
String xml =
"<wmsStore>" +
"<name>changed</name>" +
"</wmsStore>";
MockHttpServletResponse response =
putAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/nonExistant", xml, "text/xml" );
assertEquals( 404, response.getStatus() );
}
@Test
public void testDeleteNonExistant() throws Exception {
assertEquals( 404, deleteAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/datastores/nonExistant").getStatus() );
}
@Test
public void testDelete() throws Exception {
removeStore("sf", "newWMSStore");
testPostAsXML();
assertNotNull( catalog.getStoreByName("sf", "newWMSStore", WMSStoreInfo.class));
assertEquals( 200, deleteAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/newWMSStore").getStatus());
assertNull( catalog.getStoreByName("sf", "newWMSStore", WMSStoreInfo.class));
}
// public void testDeleteNonEmptyForbidden() throws Exception {
// assertEquals( 403, deleteAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/datastores/sf").getStatusCode());
// }
@Test
public void testPutNameChangeForbidden() throws Exception {
String xml = "<wmsStore>" +
"<name>newName</name>" +
"</wmsStore>";
assertEquals( 403, putAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo", xml, "text/xml").getStatus());
}
@Test
public void testPutWorkspaceChangeForbidden() throws Exception {
String xml = "<wmsStore>" +
"<workspace>gs</workspace>" +
"</wmsStore>";
MockHttpServletResponse response = putAsServletResponse(RestBaseController.ROOT_PATH+"/workspaces/sf/wmsstores/demo", xml, "text/xml");
assertThat(response, hasStatus(HttpStatus.FORBIDDEN));
}
}