/* (c) 2014 - 2015 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.wcs;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.geoserver.data.test.MockData.ROTATED_CAD;
import static org.geoserver.data.test.MockData.TASMANIA_BM;
import static org.geoserver.data.test.MockData.TASMANIA_DEM;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageDimensionInfo;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.MetadataLinkInfo;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wcs.test.WCSTestSupport;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DescribeCoverageTest extends WCSTestSupport {
public static QName NO_RANGE = new QName(MockData.WCS_URI, "NoRange", MockData.WCS_PREFIX);
private static final QName SF_RAIN = new QName(MockData.SF_URI, "rain", MockData.SF_PREFIX);
private static final QName GS_RAIN = new QName(MockData.DEFAULT_URI, "rain", MockData.DEFAULT_PREFIX);
// @Override
// protected String getDefaultLogConfiguration() {
// return "/DEFAULT_LOGGING.properties";
// }
// public void testCRS() throws NoSuchAuthorityCodeException, FactoryException {
// System.out.println(CRS.decode("EPSG:4326"));
// System.out.println(CRS.decode("urn:ogc:def:crs:EPSG:4326"));
// }
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
testData.addRasterLayer(SF_RAIN, "rain.zip", "asc", getCatalog());
testData.addRasterLayer(GS_RAIN, "rain.zip", "asc", getCatalog());
testData.addRasterLayer(NO_RANGE, "norange.tiff", null, null, DescribeCoverageTest.class,
getCatalog());
// the GUI builds the dimension without range, let's do the same here
CoverageInfo noRange = getCatalog().getCoverageByName(getLayerId(NO_RANGE));
CoverageDimensionInfo cdi = noRange.getDimensions().get(0);
cdi.setRange(null);
getCatalog().save(noRange);
GeoServerInfo global = getGeoServer().getGlobal();
global.getSettings().setProxyBaseUrl("src/test/resources/geoserver");
getGeoServer().save(global);
}
@Before
public void revertTasmaniaDem() throws IOException {
getTestData().addDefaultRasterLayer(TASMANIA_DEM, getCatalog());
}
@Test
public void testDescribeNoIdentifiers() throws Exception {
Document dom = getAsDOM(BASEPATH + "?request=DescribeCoverage&service=WCS&version=1.1.1");
// print(dom);
assertEquals(1, dom.getElementsByTagName("ows:ExceptionReport").getLength());
Element element = (Element) dom.getElementsByTagName("ows:Exception").item(0);
assertEquals("MissingParameterValue", element.getAttribute("exceptionCode"));
assertEquals("identifiers", element.getAttribute("locator"));
}
@Test
public void testDescribeByIdentifiers() throws Exception {
String queryString = "&request=getcoverage&service=wcs&version=1.1.1&&format=image/geotiff"
+ "&BoundingBox=-45,146,-42,149,urn:ogc:def:crs:EPSG:6.6:4326";
//Get identifiers from getCapabilities
Document dom = getAsDOM("wcs?request=GetCapabilities&service=WCS");
NodeList nodes = xpath.getMatchingNodes("//wcs:CoverageSummary/wcs:Identifier[text()[contains(.,'rain')]]", dom);
assertTrue(nodes.getLength() >= 2);
for (int i = 0; i < nodes.getLength(); i++) {
String identifier = nodes.item(i).getTextContent();
dom = getAsDOM("wcs?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ identifier);
//Response should be a valid document consisting of 1 coverage with a matching identifier
print(dom);
assertEquals("wcs:CoverageDescriptions", dom.getDocumentElement().getNodeName());
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescription").getLength());
assertEquals(identifier, dom.getElementsByTagName("wcs:Identifier").item(0).getTextContent());
}
}
@Test
public void testDescribeUnknownCoverageKvp() throws Exception {
Document dom = getAsDOM(BASEPATH
+ "?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers=plop");
// print(dom);
checkOws11Exception(dom);
Element element = (Element) dom.getElementsByTagName("ows:Exception").item(0);
assertEquals("InvalidParameterValue", element.getAttribute("exceptionCode"));
assertEquals("identifiers", element.getAttribute("locator"));
assertTrue(element.getTextContent().contains("plop"));
}
@Test
public void testDescribeMissingVersion() throws Exception {
Document dom = getAsDOM(BASEPATH + "?request=DescribeCoverage&service=WCS&identifiers="
+ getLayerId(TASMANIA_DEM));
// print(dom);
checkOws11Exception(dom);
Element element = (Element) dom.getElementsByTagName("ows:Exception").item(0);
assertEquals("MissingParameterValue", element.getAttribute("exceptionCode"));
assertEquals("version", element.getAttribute("locator"));
}
@Test
public void testDescribeUnknownCoverageXml() throws Exception {
List<Exception> errors = new ArrayList<Exception>();
String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<wcs:DescribeCoverage service=\"WCS\" " + //
"xmlns:ows=\"http://www.opengis.net/ows/1.1\"\r\n" + //
" xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\"\r\n" + //
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \r\n" + //
" version=\"1.1.1\" >\r\n" + //
" <wcs:Identifier>plop</wcs:Identifier>\r\n" + //
"</wcs:DescribeCoverage>";
Document dom = postAsDOM(BASEPATH, request, errors);
// print(dom);
checkOws11Exception(dom);
Element element = (Element) dom.getElementsByTagName("ows:Exception").item(0);
assertEquals("InvalidParameterValue", element.getAttribute("exceptionCode"));
assertEquals("identifiers", element.getAttribute("locator"));
assertTrue(element.getTextContent().contains("plop"));
}
@Test
public void testDescribeDemCoverageKvp() throws Exception {
Document dom = getAsDOM(BASEPATH
+ "?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ getLayerId(TASMANIA_DEM));
checkValidationErrors(dom, WCS11_SCHEMA);
checkDemCoverageDescription(dom);
}
@Test
public void testDescribeNoRangeKvp() throws Exception {
Document dom = getAsDOM(BASEPATH
+ "?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ getLayerId(NO_RANGE));
print(dom);
checkValidationErrors(dom, WCS11_SCHEMA);
// check the basics, the output is a single coverage description with the expected id
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescriptions").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescription").getLength());
assertXpathEvaluatesTo(getLayerId(NO_RANGE),
"/wcs:CoverageDescriptions/wcs:CoverageDescription/wcs:Identifier", dom);
// check we generated a ows:AnyValue for the field definition (since we have no validity range)
assertXpathEvaluatesTo("1", "count(//wcs:Field/wcs:Definition/ows:AnyValue)", dom);
}
@Test
public void testDescribeDemCoverageXml() throws Exception {
List<Exception> errors = new ArrayList<Exception>();
String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<wcs:DescribeCoverage service=\"WCS\" " + //
"xmlns:ows=\"http://www.opengis.net/ows/1.1\"\r\n" + //
" xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\"\r\n" + //
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \r\n" + //
" version=\"1.1.1\" >\r\n" + //
" <wcs:Identifier>" + getLayerId(TASMANIA_DEM) + "</wcs:Identifier>\r\n" + //
"</wcs:DescribeCoverage>";
Document dom = postAsDOM(BASEPATH, request, errors);
checkValidationErrors(dom, WCS11_SCHEMA);
checkDemCoverageDescription(dom);
}
private void checkDemCoverageDescription(Document dom) throws Exception {
// check the basics, the output is a single coverage description with the expected id
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescriptions").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescription").getLength());
assertXpathEvaluatesTo(getLayerId(TASMANIA_DEM),
"/wcs:CoverageDescriptions/wcs:CoverageDescription/wcs:Identifier", dom);
// check there is no rotation
Node gridOffsets = xpath.getMatchingNodes(
"/wcs:CoverageDescriptions/wcs:CoverageDescription/"
+ "wcs:Domain/wcs:SpatialDomain/wcs:GridCRS/wcs:GridOffsets", dom).item(0);
String[] offsetStrs = gridOffsets.getTextContent().split(" ");
assertEquals(4, offsetStrs.length);
double[] offsets = new double[4];
for (int i = 0; i < offsetStrs.length; i++) {
offsets[i] = Double.parseDouble(offsetStrs[i]);
}
assertTrue(offsets[0] > 0);
assertEquals(0.0, offsets[1]);
assertEquals(0.0, offsets[2]);
assertTrue(offsets[3] < 0);
// check there is one field, one axis, one key (this one is a dem, just one band)
assertEquals(1, dom.getElementsByTagName("wcs:Field").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:Axis").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:Key").getLength());
}
@Test
public void testDescribeRotatedCoverage() throws Exception {
Document dom = getAsDOM(BASEPATH
+ "?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ getLayerId(ROTATED_CAD));
// print(dom);
checkValidationErrors(dom, WCS11_SCHEMA);
// check the basics, the output is a single coverage description with the expected id
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescriptions").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescription").getLength());
assertXpathEvaluatesTo(getLayerId(ROTATED_CAD),
"/wcs:CoverageDescriptions/wcs:CoverageDescription/wcs:Identifier", dom);
// check there is no rotation
Node gridOffsets = xpath.getMatchingNodes(
"/wcs:CoverageDescriptions/wcs:CoverageDescription/"
+ "wcs:Domain/wcs:SpatialDomain/wcs:GridCRS/wcs:GridOffsets", dom).item(0);
String[] offsetStrs = gridOffsets.getTextContent().split(" ");
assertEquals(4, offsetStrs.length);
double[] offsets = new double[4];
for (int i = 0; i < offsetStrs.length; i++) {
offsets[i] = Double.parseDouble(offsetStrs[i]);
}
// System.out.println(Arrays.toString(offsets));
assertTrue(offsets[0] < 0);
assertTrue(offsets[1] > 0);
assertTrue(offsets[2] > 0);
assertTrue(offsets[3] > 0);
// check there is one field, one axis, one key (this one is a dem, just one band)
assertEquals(1, dom.getElementsByTagName("wcs:Field").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:Axis").getLength());
assertEquals(4, dom.getElementsByTagName("wcs:Key").getLength());
}
@Test
public void testDescribeImageCoverage() throws Exception {
Document dom = getAsDOM(BASEPATH
+ "?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ getLayerId(TASMANIA_BM));
// print(dom);
checkValidationErrors(dom, WCS11_SCHEMA);
// check the basics, the output is a single coverage description with the expected id
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescriptions").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:CoverageDescription").getLength());
assertXpathEvaluatesTo(getLayerId(TASMANIA_BM),
"/wcs:CoverageDescriptions/wcs:CoverageDescription/wcs:Identifier", dom);
// check there is no rotation
Node gridOffsets = xpath.getMatchingNodes(
"/wcs:CoverageDescriptions/wcs:CoverageDescription/"
+ "wcs:Domain/wcs:SpatialDomain/wcs:GridCRS/wcs:GridOffsets", dom).item(0);
String[] offsetStrs = gridOffsets.getTextContent().split(" ");
assertEquals(4, offsetStrs.length);
double[] offsets = new double[4];
for (int i = 0; i < offsetStrs.length; i++) {
offsets[i] = Double.parseDouble(offsetStrs[i]);
}
assertTrue(offsets[0] > 0);
assertEquals(0.0, offsets[1]);
assertEquals(0.0, offsets[2]);
assertTrue(offsets[3] < 0);
// check there is one field, one axis, three keys (bands)
assertEquals(1, dom.getElementsByTagName("wcs:Field").getLength());
assertEquals(1, dom.getElementsByTagName("wcs:Axis").getLength());
assertEquals(3, dom.getElementsByTagName("wcs:Key").getLength());
// make sure key names do not have spaces inside
NodeList keys = dom.getElementsByTagName("wcs:Key");
for (int i = 0; i < keys.getLength(); i++) {
Node key = keys.item(i);
assertFalse(key.getTextContent().contains(" "));
}
// make sure the field name is "contents" (just a reasonable default)
assertXpathEvaluatesTo("contents", "/wcs:CoverageDescriptions/wcs:CoverageDescription/"
+ "wcs:Range/wcs:Field/wcs:Identifier", dom);
}
@Test
public void testWorkspaceQualified() throws Exception {
Document dom = getAsDOM("cdf/wcs?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ TASMANIA_DEM.getLocalPart());
assertEquals("ows:ExceptionReport", dom.getDocumentElement().getNodeName());
dom = getAsDOM("wcs?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ TASMANIA_DEM.getLocalPart());
assertEquals("wcs:CoverageDescriptions", dom.getDocumentElement().getNodeName());
}
@Test
public void testMetadataLink() throws Exception {
Catalog catalog = getCatalog();
CoverageInfo ci = catalog.getCoverageByName(getLayerId(TASMANIA_DEM));
MetadataLinkInfo ml = catalog.getFactory().createMetadataLink();
ml.setContent("http://www.geoserver.org/tasmania/dem.xml");
ml.setAbout("http://www.geoserver.org");
ci.getMetadataLinks().add(ml);
catalog.save(ci);
Document dom = getAsDOM("wcs?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ TASMANIA_DEM.getLocalPart());
// print(dom);
checkValidationErrors(dom, WCS11_SCHEMA);
String xpathBase = "//wcs:CoverageDescription/ows:Metadata";
assertXpathEvaluatesTo("http://www.geoserver.org", xpathBase + "/@about", dom);
assertXpathEvaluatesTo("simple", xpathBase + "/@xlink:type", dom);
assertXpathEvaluatesTo("http://www.geoserver.org/tasmania/dem.xml", xpathBase
+ "/@xlink:href", dom);
}
@Test
public void testMetadataLinksTransormToProxyBaseURL() throws Exception {
Catalog catalog = getCatalog();
CoverageInfo ci = catalog.getCoverageByName(getLayerId(TASMANIA_DEM));
MetadataLinkInfo ml = catalog.getFactory().createMetadataLink();
ml.setContent("/metadata?key=value");
ml.setAbout("http://www.geoserver.org");
ci.getMetadataLinks().add(ml);
catalog.save(ci);
String proxyBaseUrl = getGeoServer().getGlobal().getSettings().getProxyBaseUrl();
Document dom = getAsDOM("wcs?request=DescribeCoverage&service=WCS&version=1.1.1&identifiers="
+ TASMANIA_DEM.getLocalPart());
checkValidationErrors(dom, WCS11_SCHEMA);
String xpathBase = "//wcs:CoverageDescription/ows:Metadata";
assertXpathEvaluatesTo("http://www.geoserver.org", xpathBase + "/@about", dom);
assertXpathEvaluatesTo("simple", xpathBase + "/@xlink:type", dom);
assertXpathEvaluatesTo(proxyBaseUrl + "/metadata?key=value", xpathBase + "/@xlink:href", dom);
}
}