2017-07-11 17:42:42 +02:00
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 ;
2018-10-12 15:50:32 +02:00
import org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mapping.EnvironmentVariableManager ;
2017-07-11 17:42:42 +02:00
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 ;
2018-10-12 15:50:32 +02:00
private EnvironmentVariableManager env ;
2017-07-11 17:42:42 +02:00
/ * *
* Creates an ExecuteRequest based on a Document ( HTTP_POST )
*
* @param doc
* The clients submission
* @throws ExceptionReport
* /
2018-10-12 15:50:32 +02:00
public ExecuteRequest ( Document doc , EnvironmentVariableManager env ) throws ExceptionReport {
2017-07-11 17:42:42 +02:00
super ( doc ) ;
2018-10-12 15:50:32 +02:00
this . env = env ;
2017-07-11 17:42:42 +02:00
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
* /
2018-10-12 15:50:32 +02:00
public ExecuteRequest ( CaseInsensitiveMap ciMap , EnvironmentVariableManager env ) throws ExceptionReport {
2017-07-11 17:42:42 +02:00
super ( ciMap ) ;
2018-10-12 15:50:32 +02:00
this . env = env ;
2017-07-11 17:42:42 +02:00
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 ( " & " , " & " ) ;
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 ) ;
2018-10-12 15:50:32 +02:00
( ( AbstractEcologicalEngineMapper ) algorithm ) . setEnvironmentVariableManager ( env ) ;
2017-07-13 11:14:40 +02:00
( ( AbstractEcologicalEngineMapper ) algorithm ) . setObserver ( GCubeObserver . getObserver ( ) ) ;
2017-07-11 17:42:42 +02:00
}
2018-10-12 15:50:32 +02:00
//TODO: running algorithm
2017-07-11 17:42:42 +02:00
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 ) {
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 ) ;
}
}
}