/* (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.wps.gs;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.junit.Assert.assertFalse;
import org.springframework.mock.web.MockHttpServletResponse;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.XpathEngine;
import org.geoserver.data.test.MockData;
import org.geoserver.wps.WPSTestSupport;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Document;
import java.util.Map;
public class AggregateProcessTest extends WPSTestSupport {
@Test
public void testSum() throws Exception {
String xml = aggregateCall("Sum");
Document dom = postAsDOM(root(), xml);
//print(dom);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("-111.0", "/AggregationResults/Sum", dom);
}
@Test
public void testMin() throws Exception {
String xml = aggregateCall("Min");
Document dom = postAsDOM(root(), xml);
//print(dom);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("-900.0", "/AggregationResults/Min", dom);
}
@Test
public void testMax() throws Exception {
String xml = aggregateCall("Max");
Document dom = postAsDOM(root(), xml);
//print(dom);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("300.0", "/AggregationResults/Max", dom);
}
@Test
public void testAverage() throws Exception {
String xml = aggregateCall("Average");
Document dom = postAsDOM(root(), xml);
//print(dom);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("-22.2", "/AggregationResults/Average", dom);
}
@Test
public void testStdDev() throws Exception {
String xml = aggregateCall("StdDev");
Document dom = postAsDOM(root(), xml);
// print(dom);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
XpathEngine xpath = XMLUnit.newXpathEngine();
assertTrue(xpath.evaluate("/AggregationResults/StandardDeviation", dom).matches("442\\.19380.*"));
}
@Test
public void testNonRawOutput() throws Exception {
String xml = aggregateCall("StdDev", false);
Document dom = postAsDOM(root(), xml);
//print(dom);
assertXpathEvaluatesTo("1", "count(//AggregationResults/*)", dom);
}
private String aggregateCall(String function) {
return aggregateCall(function, true);
}
private String aggregateCall(String function, boolean rawOutput) {
return aggregateCall(function, rawOutput, "text/xml", false);
}
private String aggregateCall(String function, boolean rawOutput, String mimeType, boolean groupBy) {
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<wps:Execute version=\"1.0.0\" service=\"WPS\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.opengis.net/wps/1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">\n"
+ " <ows:Identifier>gs:Aggregate</ows:Identifier>\n"
+ " <wps:DataInputs>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>features</ows:Identifier>\n"
+ " <wps:Reference mimeType=\"text/xml; subtype=wfs-collection/1.0\" xlink:href=\"http://geoserver/wfs\" method=\"POST\">\n"
+ " <wps:Body>\n"
+ " <wfs:GetFeature service=\"WFS\" version=\"1.0.0\" outputFormat=\"GML2\">\n"
+ " <wfs:Query typeName=\""
+ getLayerId(MockData.PRIMITIVEGEOFEATURE)
+ "\"/>\n"
+ " </wfs:GetFeature>\n"
+ " </wps:Body>\n"
+ " </wps:Reference>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>aggregationAttribute</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>intProperty</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>"
+ function
+ "</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n";
if (groupBy) {
xml += " <wps:Input>\n"
+ " <ows:Identifier>groupByAttributes</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>name</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n";
}
xml += " </wps:DataInputs>\n"
+ " <wps:ResponseForm>\n";
if (rawOutput) {
xml += " <wps:RawDataOutput mimeType=\""
+ mimeType
+ "\">\n"
+ " <ows:Identifier>result</ows:Identifier>\n"
+ " </wps:RawDataOutput>\n";
}
else {
xml += " <wps:Output mimeType=\""
+ mimeType
+ "\">\n"
+ " <ows:Identifier>result</ows:Identifier>\n"
+ " </wps:Output>\n";
}
xml += " </wps:ResponseForm>\n" + "</wps:Execute>";
return xml;
}
@Test
public void testAllOneByOne() throws Exception {
String xml = callAll(false);
Document dom = postAsDOM(root(), xml);
// print(dom);
assertXpathEvaluatesTo("5", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("-111.0", "/AggregationResults/Sum", dom);
assertXpathEvaluatesTo("-900.0", "/AggregationResults/Min", dom);
assertXpathEvaluatesTo("300.0", "/AggregationResults/Max", dom);
assertXpathEvaluatesTo("-22.2", "/AggregationResults/Average", dom);
XpathEngine xpath = XMLUnit.newXpathEngine();
assertTrue(xpath.evaluate("/AggregationResults/StandardDeviation", dom).matches("442\\.19380.*"));
}
@Test
public void testAllSinglePass() throws Exception {
String xml = callAll(true);
Document dom = postAsDOM(root(), xml);
// print(dom);
assertXpathEvaluatesTo("5", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("-111.0", "/AggregationResults/Sum", dom);
assertXpathEvaluatesTo("-900.0", "/AggregationResults/Min", dom);
assertXpathEvaluatesTo("300.0", "/AggregationResults/Max", dom);
assertXpathEvaluatesTo("-22.2", "/AggregationResults/Average", dom);
XpathEngine xpath = XMLUnit.newXpathEngine();
assertTrue(xpath.evaluate("/AggregationResults/StandardDeviation", dom).matches("442\\.19380.*"));
}
private String callAll(boolean singlePass) {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<wps:Execute version=\"1.0.0\" service=\"WPS\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.opengis.net/wps/1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">\n"
+ " <ows:Identifier>gs:Aggregate</ows:Identifier>\n"
+ " <wps:DataInputs>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>features</ows:Identifier>\n"
+ " <wps:Reference mimeType=\"text/xml; subtype=wfs-collection/1.0\" xlink:href=\"http://geoserver/wfs\" method=\"POST\">\n"
+ " <wps:Body>\n"
+ " <wfs:GetFeature service=\"WFS\" version=\"1.0.0\" outputFormat=\"GML2\">\n"
+ " <wfs:Query typeName=\""
+ getLayerId(MockData.PRIMITIVEGEOFEATURE)
+ "\"/>\n"
+ " </wfs:GetFeature>\n"
+ " </wps:Body>\n"
+ " </wps:Reference>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>aggregationAttribute</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>intProperty</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>Min</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>Max</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>Average</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>Sum</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>function</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>StdDev</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " <wps:Input>\n"
+ " <ows:Identifier>singlePass</ows:Identifier>\n"
+ " <wps:Data>\n"
+ " <wps:LiteralData>" + singlePass + "</wps:LiteralData>\n"
+ " </wps:Data>\n"
+ " </wps:Input>\n"
+ " </wps:DataInputs>\n"
+ " <wps:ResponseForm>\n"
+ " <wps:RawDataOutput>\n"
+ " <ows:Identifier>result</ows:Identifier>\n"
+ " </wps:RawDataOutput>\n"
+ " </wps:ResponseForm>\n" + "</wps:Execute>";
}
@Test
public void testSumAsJson() throws Exception {
String xml = aggregateCall("Sum", true, "application/json", false);
JSONObject result = executeJsonRequest(xml);
assertTrue(result.size() == 4);
String aggregationAttribute = (String) result.get("AggregationAttribute");
JSONArray aggregationFunctions = (JSONArray) result.get("AggregationFunctions");
JSONArray groupByAttributes = (JSONArray) result.get("GroupByAttributes");
JSONArray aggregationResults = (JSONArray) result.get("AggregationResults");
assertTrue(aggregationAttribute.equals("intProperty"));
assertTrue(aggregationFunctions.size() == 1);
assertTrue(aggregationFunctions.get(0).equals("Sum"));
assertTrue(groupByAttributes.size() == 0);
assertTrue(aggregationResults.size() == 1);
JSONArray sumResult = (JSONArray) aggregationResults.get(0);
assertTrue(sumResult.size() == 1);
assertTrue(sumResult.get(0).equals(-111L));
}
@Test
public void testSumWithGroupBy() throws Exception {
String xml = aggregateCall("Sum", true, "text/xml", true);
Document dom = postAsDOM(root(), xml);
assertXpathEvaluatesTo("1", "count(/AggregationResults/*)", dom);
assertXpathEvaluatesTo("5", "count(/AggregationResults/GroupByResult/*)", dom);
}
@Test
public void testSumAsJsonWithGroupBy() throws Exception {
String xml = aggregateCall("Sum", true, "application/json", true);
JSONObject result = executeJsonRequest(xml);
assertTrue(result.size() == 4);
String aggregationAttribute = (String) result.get("AggregationAttribute");
JSONArray aggregationFunctions = (JSONArray) result.get("AggregationFunctions");
JSONArray groupByAttributes = (JSONArray) result.get("GroupByAttributes");
JSONArray aggregationResults = (JSONArray) result.get("AggregationResults");
assertTrue(aggregationAttribute.equals("intProperty"));
assertTrue(aggregationFunctions.size() == 1);
assertTrue(aggregationFunctions.get(0).equals("Sum"));
assertTrue(groupByAttributes.size() == 1);
assertTrue(groupByAttributes.get(0).equals("name"));
assertTrue(aggregationResults.size() == 5);
}
private JSONObject executeJsonRequest(String wpsRequest) throws Exception {
MockHttpServletResponse response = postAsServletResponse("wps?", wpsRequest);
String content = response.getContentAsString();
assertFalse(content.isEmpty());
Object jsonObject = new JSONParser().parse(content);
assertNotNull(jsonObject);
return (JSONObject) jsonObject;
}
}