wps/src/main/java/org/gcube/data/analysis/wps/ExecuteRequest.java

845 lines
30 KiB
Java
Executable File

package org.gcube.data.analysis.wps;
/**
* Handles an ExecuteRequest
*/
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import net.opengis.ows.x11.BoundingBoxType;
import net.opengis.ows.x11.ExceptionType;
import net.opengis.wps.x100.ComplexDataType;
import net.opengis.wps.x100.DataInputsType;
import net.opengis.wps.x100.DocumentOutputDefinitionType;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.ExecuteDocument.Execute;
import net.opengis.wps.x100.InputDescriptionType;
import net.opengis.wps.x100.InputReferenceType;
import net.opengis.wps.x100.InputType;
import net.opengis.wps.x100.LiteralDataType;
import net.opengis.wps.x100.OutputDefinitionType;
import net.opengis.wps.x100.OutputDescriptionType;
import net.opengis.wps.x100.ProcessDescriptionType;
import net.opengis.wps.x100.ResponseDocumentType;
import net.opengis.wps.x100.ResponseFormType;
import net.opengis.wps.x100.StatusType;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.io.IOUtils;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mapping.AbstractEcologicalEngineMapper;
import org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mapping.EnvironmentVariableManager;
import org.n52.wps.commons.context.ExecutionContext;
import org.n52.wps.commons.context.ExecutionContextFactory;
import org.n52.wps.io.data.IComplexData;
import org.n52.wps.io.data.IData;
import org.n52.wps.server.AbstractTransactionalAlgorithm;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.IAlgorithm;
import org.n52.wps.server.RepositoryManager;
import org.n52.wps.server.database.DatabaseFactory;
import org.n52.wps.server.observerpattern.IObserver;
import org.n52.wps.server.observerpattern.ISubject;
import org.n52.wps.server.request.InputHandler;
import org.n52.wps.server.request.Request;
import org.n52.wps.server.response.Response;
import org.n52.wps.util.XMLBeansHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class ExecuteRequest extends Request implements IObserver {
private static Logger LOGGER = LoggerFactory.getLogger(ExecuteRequest.class);
private ExecuteDocument execDom;
private Map<String, IData> returnResults;
private ExecuteResponseBuilder execRespType;
private EnvironmentVariableManager env;
/**
* Creates an ExecuteRequest based on a Document (HTTP_POST)
*
* @param doc
* The clients submission
* @throws ExceptionReport
*/
public ExecuteRequest(Document doc, EnvironmentVariableManager env) throws ExceptionReport {
super(doc);
this.env = env;
initWpsID();
try {
LOGGER.debug("Preparing the ExecuteRequest for POST");
XmlOptions option = new XmlOptions();
option.setLoadTrimTextBuffer();
LOGGER.debug("Parsing document");
this.execDom = ExecuteDocument.Factory.parse(doc, option);
if (this.execDom == null) {
LOGGER.error("ExecuteDocument is null");
LOGGER.debug("EXCEPTION ExecuteDocument is null");
throw new ExceptionReport("Error while parsing post data", ExceptionReport.MISSING_PARAMETER_VALUE);
}
} catch (XmlException e) {
LOGGER.debug("EXCEPTION Error while parsing post data" + ExceptionReport.MISSING_PARAMETER_VALUE + e.getLocalizedMessage());
throw new ExceptionReport("Error while parsing post data", ExceptionReport.MISSING_PARAMETER_VALUE, e);
}
LOGGER.debug("Validating document");
// validate the client input
// validate();
LOGGER.debug("Document OK");
// create an initial response
execRespType = new ExecuteResponseBuilder(this);
LOGGER.debug("Response Builder Ready");
storeRequest(execDom);
LOGGER.debug("Request Stored");
}
/*
* Creates an ExecuteRequest based on a Map (HTTP_GET). NOTE: Parameters are
* treated as non case sensitive. @param ciMap The client input @throws
* ExceptionReport
*/
public ExecuteRequest(CaseInsensitiveMap ciMap, EnvironmentVariableManager env) throws ExceptionReport {
super(ciMap);
this.env = env;
initWpsID();
initForGET(ciMap);
// validate the client input
validate();
// create an initial response
execRespType = new ExecuteResponseBuilder(this);
storeRequest(ciMap);
}
public void getKVPDataInputs() {
}
/**
* @param ciMap
*/
private void initForGET(CaseInsensitiveMap ciMap) throws ExceptionReport {
String version = getMapValue("version", ciMap, true);
if (!version.equals(Request.SUPPORTED_VERSION)) {
throw new ExceptionReport("request version is not supported: " + version, ExceptionReport.VERSION_NEGOTIATION_FAILED);
}
this.execDom = ExecuteDocument.Factory.newInstance();
Execute execute = execDom.addNewExecute();
String processID = getMapValue("Identifier", true);
if (!RepositoryManager.getInstance().containsAlgorithm(processID)) {
throw new ExceptionReport("Process does not exist", ExceptionReport.INVALID_PARAMETER_VALUE);
}
execute.addNewIdentifier().setStringValue(processID);
DataInputsType dataInputs = execute.addNewDataInputs();
String dataInputString = getMapValue("DataInputs", true);
dataInputString = dataInputString.replace("&amp;", "&");
String[] inputs = dataInputString.split(";");
// Handle data inputs
for (String inputString : inputs) {
int position = inputString.indexOf("=");
if (position == -1) {
throw new ExceptionReport("No \"=\" supplied for attribute: " + inputString, ExceptionReport.MISSING_PARAMETER_VALUE);
}
// get name
String key = inputString.substring(0, position);
String value = null;
if (key.length() + 1 < inputString.length()) {
// BS int valueDelimiter = inputString.indexOf("@");
int valueDelimiter = inputString.indexOf("@");
if (valueDelimiter != -1 && position + 1 < valueDelimiter) {
value = inputString.substring(position + 1, valueDelimiter);
} else {
value = inputString.substring(position + 1);
}
}
ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(processID);
if (description == null) {
throw new ExceptionReport("Data Identifier not supported: " + key, ExceptionReport.MISSING_PARAMETER_VALUE);
}
InputDescriptionType inputDesc = XMLBeansHelper.findInputByID(key, description.getDataInputs());
if (inputDesc == null) {
throw new ExceptionReport("Data Identifier not supported: " + key, ExceptionReport.MISSING_PARAMETER_VALUE);
}
InputType input = dataInputs.addNewInput();
input.addNewIdentifier().setStringValue(key);
// prepare attributes
String encodingAttribute = null;
String mimeTypeAttribute = null;
String schemaAttribute = null;
String hrefAttribute = null;
String uom = null;
String dataType = null;
String[] inputItemstemp = inputString.split("@");
String[] inputItems = null;
if (inputItemstemp.length == 2) {
inputItems = inputItemstemp[1].split("@");
} else {
inputItems = inputString.split("@");
}
if (inputItemstemp.length > 1) {
for (int i = 0; i < inputItems.length; i++) {
int attributePos = inputItems[i].indexOf("=");
if (attributePos == -1 || attributePos + 1 >= inputItems[i].length()) {
continue;
}
String attributeName = inputItems[i].substring(0, attributePos);
String attributeValue = inputItems[i].substring(attributePos + 1);
// attribute is input name
if (attributeName.equals(key)) {
continue;
}
try {
attributeValue = URLDecoder.decode(attributeValue, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new ExceptionReport("Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e);
}
if (attributeName.equalsIgnoreCase("encoding")) {
encodingAttribute = attributeValue;
} else if (attributeName.equalsIgnoreCase("mimeType")) {
mimeTypeAttribute = attributeValue;
} else if (attributeName.equalsIgnoreCase("schema")) {
schemaAttribute = attributeValue;
} else if (attributeName.equalsIgnoreCase("href") | attributeName.equalsIgnoreCase("xlink:href")) {
hrefAttribute = attributeValue;
} else if (attributeName.equalsIgnoreCase("uom")) {
uom = attributeValue;
} else if (attributeName.equalsIgnoreCase("datatype")) {
dataType = attributeValue;
} else {
throw new ExceptionReport("Attribute is not supported: " + attributeName, ExceptionReport.INVALID_PARAMETER_VALUE);
}
}
}
if (inputDesc.isSetComplexData()) {
// TODO: check for different attributes
// handling ComplexReference
if (!(hrefAttribute == null) && !hrefAttribute.equals("")) {
InputReferenceType reference = input.addNewReference();
reference.setHref(hrefAttribute);
if (schemaAttribute != null) {
reference.setSchema(schemaAttribute);
}
if (mimeTypeAttribute != null) {
reference.setMimeType(mimeTypeAttribute);
}
if (encodingAttribute != null) {
reference.setEncoding(encodingAttribute);
}
}
// Handling ComplexData
else {
ComplexDataType data = input.addNewData().addNewComplexData();
InputStream stream = new ByteArrayInputStream(value.getBytes());
try {
data.set(XmlObject.Factory.parse(stream));
} catch (Exception e) {
LOGGER.warn("Could not parse value: " + value + " as XMLObject. Trying to create text node.");
try {
Node textNode = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().createTextNode(value);
data.set(XmlObject.Factory.parse(textNode));
} catch (Exception e1) {
throw new ExceptionReport("Exception while trying to parse value: " + value, ExceptionReport.NO_APPLICABLE_CODE, e1);
}
}
if (schemaAttribute != null) {
data.setSchema(schemaAttribute);
}
if (mimeTypeAttribute != null) {
data.setMimeType(mimeTypeAttribute);
}
if (encodingAttribute != null) {
data.setEncoding(encodingAttribute);
}
}
} else if (inputDesc.isSetLiteralData()) {
LiteralDataType data = input.addNewData().addNewLiteralData();
if (value == null) {
throw new ExceptionReport("No value provided for literal: " + inputDesc.getIdentifier().getStringValue(), ExceptionReport.MISSING_PARAMETER_VALUE);
}
data.setStringValue(value);
if (uom != null) {
data.setUom(uom);
}
if (dataType != null) {
data.setDataType(dataType);
}
} else if (inputDesc.isSetBoundingBoxData()) {
BoundingBoxType data = input.addNewData().addNewBoundingBoxData();
String[] values = value.split(",");
if (values.length < 4) {
throw new ExceptionReport("Invalid Number of BBOX Values: " + inputDesc.getIdentifier().getStringValue(), ExceptionReport.MISSING_PARAMETER_VALUE);
}
List<String> lowerCorner = new ArrayList<String>();
lowerCorner.add(values[0]);
lowerCorner.add(values[1]);
data.setLowerCorner(lowerCorner);
List<String> upperCorner = new ArrayList<String>();
upperCorner.add(values[2]);
upperCorner.add(values[3]);
data.setUpperCorner(upperCorner);
if (values.length > 4) {
data.setCrs(values[4]);
}
if (values.length > 5) {
data.setDimensions(BigInteger.valueOf(Long.valueOf(values[5])));
}
}
}
// retrieve status
boolean status = false;
String statusString = getMapValue("status", false);
LOGGER.debug("Incoming Status Request: "+statusString);
if (statusString != null) {
status = Boolean.parseBoolean(statusString);
}
boolean store = false;
String storeString = getMapValue("storeExecuteResponse", false);
LOGGER.debug("Incoming storeExecuteResponse Request: "+storeString);
if (storeString != null) {
store = Boolean.parseBoolean(storeString);
}
// Handle ResponseDocument option
String responseDocument = getMapValue("ResponseDocument", false);
if (responseDocument != null) {
String[] outputs = responseDocument.split(";");
ResponseDocumentType responseDoc = execute.addNewResponseForm().addNewResponseDocument();
responseDoc.setStatus(status);
responseDoc.setStoreExecuteResponse(store);
for (String outputID : outputs) {
String[] outputDataparameters = outputID.split("@");
String outputDataInput = "";
if (outputDataparameters.length > 0) {
outputDataInput = outputDataparameters[0];
} else {
outputDataInput = outputID;
}
outputDataInput = outputDataInput.replace("=", "");
ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(processID);
OutputDescriptionType outputDesc = XMLBeansHelper.findOutputByID(outputDataInput, description.getProcessOutputs().getOutputArray());
if (outputDesc == null) {
throw new ExceptionReport("Data output Identifier not supported: " + outputDataInput, ExceptionReport.MISSING_PARAMETER_VALUE);
}
DocumentOutputDefinitionType output = responseDoc.addNewOutput();
output.addNewIdentifier().setStringValue(outputDataInput);
for (int i = 1; i < outputDataparameters.length; i++) {
int attributePos = outputDataparameters[i].indexOf("=");
if (attributePos == -1 || attributePos + 1 >= outputDataparameters[i].length()) {
continue;
}
String attributeName = outputDataparameters[i].substring(0, attributePos);
String attributeValue = outputDataparameters[i].substring(attributePos + 1);
try {
attributeValue = URLDecoder.decode(attributeValue, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new ExceptionReport("Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e);
}
if (attributeName.equalsIgnoreCase("mimeType")) {
output.setMimeType(attributeValue);
} else if (attributeName.equalsIgnoreCase("schema")) {
output.setSchema(attributeValue);
} else if (attributeName.equalsIgnoreCase("encoding")) {
output.setEncoding(attributeValue);
}
}
}
}
String rawData = getMapValue("RawDataOutput", false);
if (rawData != null) {
String[] rawDataparameters = rawData.split("@");
String rawDataInput = "";
if (rawDataparameters.length > 0) {
rawDataInput = rawDataparameters[0];
} else {
rawDataInput = rawData;
}
ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(processID);
OutputDescriptionType outputDesc = XMLBeansHelper.findOutputByID(rawDataInput, description.getProcessOutputs().getOutputArray());
if (outputDesc == null) {
throw new ExceptionReport("Data output Identifier not supported: " + rawData, ExceptionReport.MISSING_PARAMETER_VALUE);
}
ResponseFormType responseForm = execute.addNewResponseForm();
OutputDefinitionType output = responseForm.addNewRawDataOutput();
output.addNewIdentifier().setStringValue(outputDesc.getIdentifier().getStringValue());
if (rawDataparameters.length > 0) {
for (int i = 0; i < rawDataparameters.length; i++) {
int attributePos = rawDataparameters[i].indexOf("=");
if (attributePos == -1 || attributePos + 1 >= rawDataparameters[i].length()) {
continue;
}
String attributeName = rawDataparameters[i].substring(0, attributePos);
String attributeValue = rawDataparameters[i].substring(attributePos + 1);
try {
attributeValue = URLDecoder.decode(attributeValue, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new ExceptionReport("Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e);
}
if (attributeName.equalsIgnoreCase("mimeType")) {
output.setMimeType(attributeValue);
} else if (attributeName.equalsIgnoreCase("schema")) {
output.setSchema(attributeValue);
} else if (attributeName.equalsIgnoreCase("encoding")) {
output.setEncoding(attributeValue);
} else {
throw new ExceptionReport("Attribute is not supported: " + attributeName, ExceptionReport.INVALID_PARAMETER_VALUE);
}
}
}
}
}
/**
* Validates the client request
*
* @return True if the input is valid, False otherwise
*/
public boolean validate() throws ExceptionReport {
// Identifier must be specified.
/*
* Only for HTTP_GET: String identifier = getMapValue("identifier");
*
* try{ // Specifies if all complex valued output(s) of this process
* should be stored by process // as web-accessible resources store =
* getMapValue("store").equals("true"); // Specifies if Execute
* operation response shall be returned quickly with status information
* status = getMapValue("status").equals("true"); }catch(ExceptionReport
* e){ // if parameters "store" or "status" are not included, they
* default to false; } // just testing if the number of arguments is
* even... String[] diArray = getMapValue("DataInputs").split(",");
* if(diArray.length % 2 != 0) { throw new ExceptionReport("Incorrect
* number of arguments for parameter dataInputs, please only a even
* number of parameter values",
* ExceptionReport.INVALID_PARAMETER_VALUE); }
*/
if (!execDom.getExecute().getVersion().equals(SUPPORTED_VERSION)) {
throw new ExceptionReport("Specified version is not supported.", ExceptionReport.INVALID_PARAMETER_VALUE, "version=" + getExecute().getVersion());
}
// Fix for bug https://bugzilla.52north.org/show_bug.cgi?id=906
String identifier = getAlgorithmIdentifier();
if (identifier == null) {
throw new ExceptionReport("No process identifier supplied.", ExceptionReport.MISSING_PARAMETER_VALUE, "identifier");
}
// check if the algorithm is in our repository
if (!RepositoryManager.getInstance().containsAlgorithm(identifier)) {
throw new ExceptionReport("Specified process identifier does not exist", ExceptionReport.INVALID_PARAMETER_VALUE, "identifier=" + identifier);
}
// validate if the process can be executed
ProcessDescriptionType desc = RepositoryManager.getInstance().getProcessDescription(getAlgorithmIdentifier());
// We need a description of the inputs for the algorithm
if (desc == null) {
LOGGER.warn("desc == null");
return false;
}
// Get the inputdescriptions of the algorithm
if (desc.getDataInputs() != null) {
InputDescriptionType[] inputDescs = desc.getDataInputs().getInputArray();
// prevent NullPointerException for zero input values in execute
// request (if only default values are used)
InputType[] inputs;
if (getExecute().getDataInputs() == null)
inputs = new InputType[0];
else
inputs = getExecute().getDataInputs().getInputArray();
// For each input supplied by the client
for (InputType input : inputs) {
boolean identifierMatched = false;
// Try to match the input with one of the descriptions
for (InputDescriptionType inputDesc : inputDescs) {
// If found, then process:
if (inputDesc.getIdentifier().getStringValue().equals(input.getIdentifier().getStringValue())) {
identifierMatched = true;
// If it is a literal value,
if (input.getData() != null && input.getData().getLiteralData() != null) {
// then check if the desription is also of type
// literal
if (inputDesc.getLiteralData() == null) {
throw new ExceptionReport("Inputtype LiteralData is not supported", ExceptionReport.INVALID_PARAMETER_VALUE);
}
// literalValue.getDataType ist optional
if (input.getData().getLiteralData().getDataType() != null) {
if (inputDesc.getLiteralData() != null)
if (inputDesc.getLiteralData().getDataType() != null)
if (inputDesc.getLiteralData().getDataType().getReference() != null)
if (!input.getData().getLiteralData().getDataType().equals(inputDesc.getLiteralData().getDataType().getReference())) {
throw new ExceptionReport("Specified dataType is not supported " + input.getData().getLiteralData().getDataType() + " for input " + input.getIdentifier().getStringValue(), ExceptionReport.INVALID_PARAMETER_VALUE);
}
}
}
// Excluded, because ProcessDescription validation
// should be
// done on startup!
// else if (input.getComplexValue() != null) {
// if(ParserFactory.getInstance().getParser(input.getComplexValue().getSchema())
// == null) {
// LOGGER.warn("Request validation message: schema
// attribute
// null, so the simple one will be used!");
// }
// }
// else if (input.getComplexValueReference() != null) {
// // we found a complexvalue input, try to get the
// parser.
// if(ParserFactory.getInstance().getParser(input.getComplexValueReference().getSchema())
// == null) {
// LOGGER.warn("Request validation message: schema
// attribute
// null, so the simple one will be used!");
// }
// }
break;
}
}
// if the identifier did not match one of the descriptions, it
// is
// invalid
if (!identifierMatched) {
throw new ExceptionReport("Input Identifier is not valid: " + input.getIdentifier().getStringValue(), ExceptionReport.INVALID_PARAMETER_VALUE, "input identifier");
}
}
}
return true;
}
/**
* Actually serves the Request.
*
* @throws ExceptionReport
*/
String wpsid = null;
private void initWpsID(){
wpsid = getUniqueId().toString();
}
public Response call() throws ExceptionReport {
IAlgorithm algorithm = null;
Map<String, List<IData>> inputMap = null;
try {
ExecutionContext context;
if (getExecute().isSetResponseForm()) {
context = getExecute().getResponseForm().isSetRawDataOutput() ? new ExecutionContext(getExecute().getResponseForm().getRawDataOutput()) : new ExecutionContext(Arrays.asList(getExecute().getResponseForm().getResponseDocument().getOutputArray()));
} else {
context = new ExecutionContext();
}
// register so that any function that calls
// ExecuteContextFactory.getContext() gets the instance registered
// with this thread
ExecutionContextFactory.registerContext(context);
LOGGER.debug("started with execution");
updateStatusStarted();
// parse the input
InputType[] inputs = new InputType[0];
if (getExecute().getDataInputs() != null) {
inputs = getExecute().getDataInputs().getInputArray();
}
InputHandler parser = new InputHandler.Builder(inputs, getAlgorithmIdentifier()).build();
// we got so far:
// get the algorithm, and run it with the clients input
/*
* IAlgorithm algorithm =
* RepositoryManager.getInstance().getAlgorithm
* (getAlgorithmIdentifier()); returnResults =
* algorithm.run((Map)parser.getParsedInputLayers(),
* (Map)parser.getParsedInputParameters());
*/
algorithm = RepositoryManager.getInstance().getAlgorithm(getAlgorithmIdentifier());
if (algorithm instanceof ISubject) {
ISubject subject = (ISubject) algorithm;
subject.addObserver(this);
}
if (algorithm instanceof AbstractEcologicalEngineMapper) {
((AbstractEcologicalEngineMapper) algorithm).setWpsExternalID(wpsid);
((AbstractEcologicalEngineMapper) algorithm).setEnvironmentVariableManager(env);
((AbstractEcologicalEngineMapper) algorithm).setObserver(GCubeObserver.getObserver());
}
//TODO: running algorithm
if (algorithm instanceof AbstractTransactionalAlgorithm) {
returnResults = ((AbstractTransactionalAlgorithm) algorithm).run(execDom);
} else {
inputMap = parser.getParsedInputData();
returnResults = algorithm.run(inputMap);
}
List<String> errorList = algorithm.getErrors();
if (errorList != null && !errorList.isEmpty()) {
String errorMessage = errorList.get(0);
LOGGER.error("Error reported while handling ExecuteRequest for " + getAlgorithmIdentifier() + ": " + errorMessage);
updateStatusError(errorMessage);
} else {
updateStatusSuccess();
}
} catch (Throwable e) {
e.printStackTrace();
String errorMessage = null;
if (algorithm != null && algorithm.getErrors() != null && !algorithm.getErrors().isEmpty()) {
errorMessage = algorithm.getErrors().get(0);
}
if (errorMessage == null) {
errorMessage = e.toString();
}
if (errorMessage == null) {
errorMessage = "UNKNOWN ERROR";
}
LOGGER.error("Exception/Error while executing ExecuteRequest for " + getAlgorithmIdentifier() + ": " + errorMessage);
updateStatusError(errorMessage);
if (e instanceof Error) {
// This is required when catching Error
throw (Error) e;
}
if (e instanceof ExceptionReport) {
throw (ExceptionReport) e;
} else {
throw new ExceptionReport("Error while executing the embedded process for: " + getAlgorithmIdentifier(), ExceptionReport.NO_APPLICABLE_CODE, e);
}
} finally {
// you ***MUST*** call this or else you will have a PermGen
// ClassLoader memory leak due to ThreadLocal use
ExecutionContextFactory.unregisterContext();
if (algorithm instanceof ISubject) {
((ISubject) algorithm).removeObserver(this);
}
if (inputMap != null) {
for (List<IData> l : inputMap.values()) {
for (IData d : l) {
if (d instanceof IComplexData) {
((IComplexData) d).dispose();
}
}
}
}
if (returnResults != null) {
for (IData d : returnResults.values()) {
if (d instanceof IComplexData) {
((IComplexData) d).dispose();
}
}
}
}
ExecuteResponse response = new ExecuteResponse(this);
return response;
}
/**
* Gets the identifier of the algorithm the client requested
*
* @return An identifier
*/
public String getAlgorithmIdentifier() {
// Fix for bug https://bugzilla.52north.org/show_bug.cgi?id=906
if (getExecute().getIdentifier() != null) {
return getExecute().getIdentifier().getStringValue();
}
return null;
}
/**
* Gets the Execute that is associated with this Request
*
* @return The Execute
*/
public Execute getExecute() {
return execDom.getExecute();
}
public Map<String, IData> getAttachedResult() {
return returnResults;
}
public boolean isStoreResponse() {
if (execDom.getExecute().getResponseForm() == null) {
return false;
}
if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) {
return false;
}
return execDom.getExecute().getResponseForm().getResponseDocument().getStoreExecuteResponse();
}
public boolean isQuickStatus() {
if (execDom.getExecute().getResponseForm() == null) {
return false;
}
if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) {
return false;
}
return execDom.getExecute().getResponseForm().getResponseDocument().getStatus();
}
public ExecuteResponseBuilder getExecuteResponseBuilder() {
return this.execRespType;
}
public boolean isRawData() {
if (execDom.getExecute().getResponseForm() == null) {
return false;
}
if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) {
return true;
} else {
return false;
}
}
public void update(ISubject subject) {
Object state = subject.getState();
LOGGER.info("Update received from Subject, state changed to : " + state);
StatusType status = StatusType.Factory.newInstance();
int percentage = 0;
if (state instanceof Integer) {
percentage = (Integer) state;
status.addNewProcessStarted().setPercentCompleted(percentage);
} else if (state instanceof String) {
status.addNewProcessStarted().setStringValue((String) state);
}
updateStatus(status);
}
public void updateStatusAccepted() {
StatusType status = StatusType.Factory.newInstance();
status.setProcessAccepted("Process Accepted");
updateStatus(status);
}
public void updateStatusStarted() {
StatusType status = StatusType.Factory.newInstance();
status.addNewProcessStarted().setPercentCompleted(0);
updateStatus(status);
}
public void updateStatusSuccess() {
StatusType status = StatusType.Factory.newInstance();
status.setProcessSucceeded("Process successful");
updateStatus(status);
}
public void updateStatusError(String errorMessage) {
StatusType status = StatusType.Factory.newInstance();
net.opengis.ows.x11.ExceptionReportDocument.ExceptionReport excRep = status.addNewProcessFailed().addNewExceptionReport();
excRep.setVersion("1.0.0");
ExceptionType excType = excRep.addNewException();
excType.addNewExceptionText().setStringValue(errorMessage);
excType.setExceptionCode(ExceptionReport.NO_APPLICABLE_CODE);
updateStatus(status);
}
private void updateStatus(StatusType status) {
getExecuteResponseBuilder().setStatus(status);
try {
getExecuteResponseBuilder().update();
if (isStoreResponse()) {
ExecuteResponse executeResponse = new ExecuteResponse(this);
InputStream is = null;
try {
is = executeResponse.getAsStream();
DatabaseFactory.getDatabase().storeResponse(wpsid, is);
} finally {
IOUtils.closeQuietly(is);
}
}
} catch (ExceptionReport e) {
LOGGER.error("Update of process status failed.", e);
throw new RuntimeException(e);
}
}
private void storeRequest(ExecuteDocument executeDocument) {
InputStream is = null;
try {
is = executeDocument.newInputStream();
DatabaseFactory.getDatabase().insertRequest(wpsid, is, true);
//DatabaseFactory.getDatabase().insertRequest(wpsid, is, false);
} catch (Exception e) {
LOGGER.error("Exception storing ExecuteRequest", e);
} finally {
IOUtils.closeQuietly(is);
}
}
private void storeRequest(CaseInsensitiveMap map) {
BufferedWriter w = null;
ByteArrayOutputStream os = null;
ByteArrayInputStream is = null;
try {
os = new ByteArrayOutputStream();
w = new BufferedWriter(new OutputStreamWriter(os));
for (Object key : map.keySet()) {
Object value = map.get(key);
String valueString = "";
if (value instanceof String[]) {
valueString = ((String[]) value)[0];
} else {
valueString = value.toString();
}
w.append(key.toString()).append('=').append(valueString);
w.newLine();
}
w.flush();
is = new ByteArrayInputStream(os.toByteArray());
DatabaseFactory.getDatabase().insertRequest(wpsid, is, false);
} catch (Exception e) {
LOGGER.error("Exception storing ExecuteRequest", e);
} finally {
IOUtils.closeQuietly(w);
IOUtils.closeQuietly(os);
IOUtils.closeQuietly(is);
}
}
}