Author: aaime Date: 2012-03-19 07:36:02 -0700 (Mon, 19 Mar 2012) New Revision: 38636 Modified: trunk/modules/unsupported/wps/pom.xml trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java Log: [GEOT-4083] Add a way to extract the raw response in the WPS client Modified: trunk/modules/unsupported/wps/pom.xml =================================================================== --- trunk/modules/unsupported/wps/pom.xml 2012-03-19 09:15:58 UTC (rev 38635) +++ trunk/modules/unsupported/wps/pom.xml 2012-03-19 14:36:02 UTC (rev 38636) @@ -124,6 +124,10 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>xpp3</groupId> + <artifactId>xpp3_min</artifactId> + </dependency> + <dependency> <groupId>org.geotools</groupId> <artifactId>gt-xml</artifactId> <version>${project.version}</version> Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java =================================================================== --- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 09:15:58 UTC (rev 38635) +++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 14:36:02 UTC (rev 38636) @@ -286,7 +286,7 @@ public Response createResponse(HTTPResponse httpResponse) throws ServiceException, IOException { - return new ExecuteProcessResponse(httpResponse); + return new ExecuteProcessResponse(httpResponse, responseForm != null && responseForm.getRawDataOutput() != null); } } Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java =================================================================== --- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java 2012-03-19 09:15:58 UTC (rev 38635) +++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java 2012-03-19 14:36:02 UTC (rev 38636) @@ -65,7 +65,7 @@ */ private Properties inputs; - private ResponseFormType responseForm; + protected ResponseFormType responseForm; /** * Constructs a basic ExecuteProcessRequest, without versioning info. Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java =================================================================== --- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-03-19 09:15:58 UTC (rev 38635) +++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-03-19 14:36:02 UTC (rev 38636) @@ -16,6 +16,7 @@ */ package org.geotools.data.wps.response; +import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -31,6 +32,9 @@ import org.geotools.xml.Configuration; import org.geotools.xml.Parser; import org.xml.sax.SAXException; +import org.xmlpull.mxp1.MXParser; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; /** @@ -47,6 +51,8 @@ private ExecuteResponseType exeResponse; private ExceptionReportType excepResponse; + private InputStream rawResponseStream; + private String rawContentType; /** * @param contentType @@ -54,47 +60,52 @@ * @throws ServiceException * @throws SAXException */ - public ExecuteProcessResponse(HTTPResponse httpResponse) throws IOException, ServiceException + public ExecuteProcessResponse(HTTPResponse httpResponse, boolean raw) throws IOException, ServiceException { super(httpResponse); InputStream inputStream = null; try { - inputStream = httpResponse.getResponseStream(); + if(!raw) { + inputStream = httpResponse.getResponseStream(); + parseDocumentResponse(inputStream); + } else { + // we need to know if the response was an exception, unfortunately we cannot + // make that determination just by looking at the mime type ... - // Map hints = new HashMap(); - // hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WPSSchema.getInstance()); - Configuration config = new WPSConfiguration(); - Parser parser = new Parser(config); + // could be gml or other stuff, not necessarily a service exception, we need to check if it's an exception or not + rawContentType = httpResponse.getContentType(); + if(rawContentType.startsWith("text/xml")) { + // make sure we don't throw away info + inputStream = new BufferedInputStream(httpResponse.getResponseStream()); + inputStream.mark(8192); + + try { + XmlPullParser parser = new MXParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + parser.setInput(inputStream, "UTF-8"); + parser.nextTag(); + + // get the first tag name + String name = parser.getName(); + String namespace = parser.getNamespace(); + inputStream.reset(); + if("ServiceException".equals(name) || "ExecuteResponse".equals(name)) { + parseDocumentResponse(inputStream); + return; + } + } catch(XmlPullParserException e) { + throw new IOException("Failed to parse the response", e); + } + } else { + inputStream = httpResponse.getResponseStream(); + } - Object object; - excepResponse = null; - exeResponse = null; - try - { - // object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING); - object = parser.parse(inputStream); + // ok, it's really the raw response, store it and avoid closing it + rawResponseStream = inputStream; + inputStream = null; } - catch (SAXException e) - { - throw (IOException) new IOException().initCause(e); - } - catch (ParserConfigurationException e) - { - throw (IOException) new IOException().initCause(e); - } - - // try casting the response - if (object instanceof ExecuteResponseType) - { - exeResponse = (ExecuteResponseType) object; - } - // exception caught on server and returned - else if (object instanceof ExceptionReportType) - { - excepResponse = (ExceptionReportType) object; - } } finally { @@ -105,6 +116,41 @@ } } + private void parseDocumentResponse(InputStream inputStream) throws IOException { + // Map hints = new HashMap(); + // hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WPSSchema.getInstance()); + Configuration config = new WPSConfiguration(); + Parser parser = new Parser(config); + + Object object; + excepResponse = null; + exeResponse = null; + try + { + // object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING); + object = parser.parse(inputStream); + } + catch (SAXException e) + { + throw (IOException) new IOException().initCause(e); + } + catch (ParserConfigurationException e) + { + throw (IOException) new IOException().initCause(e); + } + + // try casting the response + if (object instanceof ExecuteResponseType) + { + exeResponse = (ExecuteResponseType) object; + } + // exception caught on server and returned + else if (object instanceof ExceptionReportType) + { + excepResponse = (ExceptionReportType) object; + } + } + public ExecuteResponseType getExecuteResponse() { return exeResponse; @@ -115,4 +161,20 @@ return excepResponse; } + /** + * If a raw response was requested, and no service exception has been sent, we should get + * the raw response stream here + */ + public InputStream getRawResponseStream() { + return rawResponseStream; + } + + /** + * The raw response stream content type + * @return + */ + public String getRawContentType() { + return rawContentType; + } + } Modified: trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java =================================================================== --- trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 09:15:58 UTC (rev 38635) +++ trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 14:36:02 UTC (rev 38636) @@ -16,35 +16,27 @@ */ package org.geotools.data.wps; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.List; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.LineString; -import com.vividsolutions.jts.geom.MultiLineString; -import com.vividsolutions.jts.geom.MultiPoint; -import com.vividsolutions.jts.geom.MultiPolygon; -import com.vividsolutions.jts.geom.Point; -import com.vividsolutions.jts.geom.Polygon; -import com.vividsolutions.jts.io.ParseException; -import com.vividsolutions.jts.io.WKTReader; - -import junit.framework.TestCase; - import net.opengis.ows11.ExceptionReportType; import net.opengis.wps10.DataType; import net.opengis.wps10.ExecuteResponseType; import net.opengis.wps10.InputDescriptionType; import net.opengis.wps10.LiteralDataType; import net.opengis.wps10.OutputDataType; +import net.opengis.wps10.OutputDefinitionType; import net.opengis.wps10.ProcessBriefType; import net.opengis.wps10.ProcessDescriptionType; import net.opengis.wps10.ProcessDescriptionsType; import net.opengis.wps10.ProcessOfferingsType; +import net.opengis.wps10.ResponseFormType; import net.opengis.wps10.WPSCapabilitiesType; import org.eclipse.emf.common.util.EList; @@ -55,7 +47,18 @@ import org.geotools.ows.ServiceException; import org.geotools.test.OnlineTestCase; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPoint; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + /** * Test making requests by manually building up requests using the utility methods. * @@ -80,6 +83,8 @@ private String processIden; + private ResponseFormType response ; + /** * The wps.geoserver fixture consisting of service and processId. */ @@ -635,4 +640,179 @@ exeRequest.addInput(idt2.getIdentifier().getValue(), list2); } + + /** + * Try to get an area grid in arcgrid format, raw + * + * @throws ServiceException + * @throws IOException + * @throws ParseException + */ + public void testExecuteLocalAreaGrid() throws ServiceException, IOException, ParseException + { + + // don't run the test if the server is not up + if (fixture == null) + { + return; + } + + if (DISABLE) + { + return; + } + + String processIdenLocal = "gs:AreaGrid"; + + WPSCapabilitiesType capabilities = wps.getCapabilities(); + + // get the first process and execute it + ProcessOfferingsType processOfferings = capabilities.getProcessOfferings(); + EList processes = processOfferings.getProcess(); + // ProcessBriefType process = (ProcessBriefType) processes.get(0); + + // does the server contain the specific process I want + boolean found = false; + Iterator iterator = processes.iterator(); + while (iterator.hasNext()) + { + ProcessBriefType process = (ProcessBriefType) iterator.next(); + if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal)) + { + found = true; + + break; + } + } + + // exit test if my process doesn't exist on server + if (!found) + { + System.out.println("Skipping, gs:AreaGrid not found!"); + return; + } + + // do a full describeprocess on my process + DescribeProcessRequest descRequest = wps.createDescribeProcessRequest(); + descRequest.setIdentifier(processIdenLocal); + + DescribeProcessResponse descResponse = wps.issueRequest(descRequest); + + // based on the describeprocess, setup the execute + ProcessDescriptionsType processDesc = descResponse.getProcessDesc(); + ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest(); + exeRequest.setIdentifier(processIdenLocal); + exeRequest.addInput("envelope", Arrays.asList(wps.createBoundingBoxInputValue("EPSG:4326", 2, Arrays.asList(-180d, -90d), Arrays.asList(180d, 90d)))); + exeRequest.addInput("width", Arrays.asList(wps.createLiteralInputValue("2"))); + exeRequest.addInput("height", Arrays.asList(wps.createLiteralInputValue("1"))); + OutputDefinitionType rawOutput = wps.createOutputDefinitionType("result"); + rawOutput.setMimeType("application/arcgrid"); + ResponseFormType responseForm = wps.createResponseForm(null, rawOutput); + exeRequest.setResponseForm(responseForm); + + // send the request + ExecuteProcessResponse response = wps.issueRequest(exeRequest); + + // response should not be null and no exception should occur. + assertNotNull(response); + + // we should get a raw response, no exception, no response document + ExecuteResponseType executeResponse = response.getExecuteResponse(); + assertNull(executeResponse); + ExceptionReportType exceptionResponse = response.getExceptionResponse(); + assertNull(exceptionResponse); + + // check result correctness + assertEquals("application/arcgrid", response.getRawContentType()); + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getRawResponseStream())); + StringBuilder sb = new StringBuilder(); + String line = null; + while((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + String arcgrid = sb.toString(); + String expectedHeader = "NCOLS 2\n" + + "NROWS 1\n" + + "XLLCORNER -180.0\n" + + "YLLCORNER -90.0\n" + + "CELLSIZE 180.0\n" + + "NODATA_VALUE -9999"; + assertTrue(arcgrid.startsWith(expectedHeader)); + } + + /** + * Request for area grid with raw output but wrong parameters, check the response is an exception + * + * @throws ServiceException + * @throws IOException + * @throws ParseException + */ + public void testExecuteLocalAreaGridException() throws ServiceException, IOException, ParseException + { + + // don't run the test if the server is not up + if (fixture == null) + { + return; + } + + if (DISABLE) + { + return; + } + + String processIdenLocal = "gs:AreaGrid"; + + WPSCapabilitiesType capabilities = wps.getCapabilities(); + + // get the first process and execute it + ProcessOfferingsType processOfferings = capabilities.getProcessOfferings(); + EList processes = processOfferings.getProcess(); + // ProcessBriefType process = (ProcessBriefType) processes.get(0); + + // does the server contain the specific process I want + boolean found = false; + Iterator iterator = processes.iterator(); + while (iterator.hasNext()) + { + ProcessBriefType process = (ProcessBriefType) iterator.next(); + if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal)) + { + found = true; + + break; + } + } + + // exit test if my process doesn't exist on server + if (!found) + { + System.out.println("Skipping, gs:AreaGrid not found!"); + return; + } + + // build the request + ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest(); + exeRequest.setIdentifier(processIdenLocal); + exeRequest.addInput("envelope", Arrays.asList(wps.createBoundingBoxInputValue("EPSG:4326", 2, Arrays.asList(-180d, -90d), Arrays.asList(180d, 90d)))); + // don't set the width, height required params + // exeRequest.addInput("width", Arrays.asList(wps.createLiteralInputValue("abc"))); + // exeRequest.addInput("height", Arrays.asList(wps.createLiteralInputValue("def"))); + OutputDefinitionType rawOutput = wps.createOutputDefinitionType("result"); + rawOutput.setMimeType("application/arcgrid"); + ResponseFormType responseForm = wps.createResponseForm(null, rawOutput); + exeRequest.setResponseForm(responseForm); + + // send the request + ExecuteProcessResponse response = wps.issueRequest(exeRequest); + + // response should not be null and no exception should occur. + assertNotNull(response); + + // we should get a raw response, no exception, no response document + ExecuteResponseType executeResponse = response.getExecuteResponse(); + assertNotNull(executeResponse); + assertNotNull(executeResponse.getStatus().getProcessFailed()); + assertNotNull( executeResponse.getStatus().getProcessFailed().getExceptionReport()); + } } |