in taverna-rest-activity/src/main/java/org/apache/taverna/activities/rest/RESTActivity.java [220:363]
public void executeAsynch(final Map<String, T2Reference> inputs,
final AsynchronousActivityCallback callback) {
// Don't execute service directly now, request to be run asynchronously
callback.requestRun(new Runnable() {
private Logger logger = Logger.getLogger(RESTActivity.class);
@Override
public void run() {
InvocationContext context = callback.getContext();
ReferenceService referenceService = context.getReferenceService();
// ---- RESOLVE INPUTS ----
// RE-ASSEMBLE REQUEST URL FROM SIGNATURE AND PARAMETERS
// (just use the configuration that was determined in
// configurePorts() - all ports in this set are required)
Map<String, String> urlParameters = new HashMap<>();
try {
for (String inputName : configBean.getActivityInputs().keySet())
urlParameters.put(inputName, (String) referenceService.renderIdentifier(
inputs.get(inputName), configBean.getActivityInputs()
.get(inputName), context));
} catch (Exception e) {
// problem occurred while resolving the inputs
callback.fail("REST activity was unable to resolve all necessary inputs"
+ "that contain values for populating the URI signature placeholders "
+ "with values.", e);
// make sure we don't call callback.receiveResult later
return;
}
String completeURL = URISignatureHandler.generateCompleteURI(
configBean.getUrlSignature(), urlParameters,
configBean.getEscapeParameters());
// OBTAIN THE INPUT BODY IF NECESSARY
// ("IN_BODY" is treated as *optional* for now)
Object inputMessageBody = null;
if (hasMessageBodyInputPort() && inputs.containsKey(IN_BODY)) {
inputMessageBody = referenceService.renderIdentifier(inputs.get(IN_BODY),
configBean.getOutgoingDataFormat().getDataFormat(), context);
}
// ---- DO THE ACTUAL SERVICE INVOCATION ----
HTTPRequestResponse requestResponse = HTTPRequestHandler.initiateHTTPRequest(
completeURL, configBean, inputMessageBody, urlParameters,
credentialsProvider);
// test if an internal failure has occurred
if (requestResponse.hasException()) {
callback.fail(
"Internal error has occurred while trying to execute the REST activity",
requestResponse.getException());
// make sure we don't call callback.receiveResult later
return;
}
// ---- REGISTER OUTPUTS ----
Map<String, T2Reference> outputs = new HashMap<String, T2Reference>();
T2Reference responseBodyRef = null;
if (requestResponse.hasServerError()) {
// test if a server error has occurred -- if so, return
// output as an error document
// Check if error returned is a string - sometimes services return byte[]
ErrorDocument errorDocument = null;
if (requestResponse.getResponseBody() == null) {
// No response body - register empty string
errorDocument = referenceService.getErrorDocumentService().registerError(
"", 0, context);
} else {
if (requestResponse.getResponseBody() instanceof String) {
errorDocument = referenceService.getErrorDocumentService()
.registerError((String) requestResponse.getResponseBody(), 0,
context);
} else if (requestResponse.getResponseBody() instanceof byte[]) {
// Do the only thing we can - try to convert to
// UTF-8 encoded string
// and hope we'll get back something intelligible
String str = null;
try {
str = new String((byte[]) requestResponse.getResponseBody(),
"UTF-8");
} catch (UnsupportedEncodingException e) {
logger.error(
"Failed to reconstruct the response body byte[]"
+ " into string using UTF-8 encoding",
e);
// try with no encoding, probably will get garbage
str = new String((byte[]) requestResponse.getResponseBody());
}
errorDocument = referenceService.getErrorDocumentService()
.registerError(str, 0, context);
} else {
// Do what we can - call toString() method and hope
// for the best
errorDocument = referenceService.getErrorDocumentService()
.registerError(requestResponse.getResponseBody().toString(), 0,
context);
}
}
responseBodyRef = referenceService.register(errorDocument, 0, true, context);
} else if (requestResponse.getResponseBody() != null) {
// some response data is available
responseBodyRef = referenceService.register(requestResponse.getResponseBody(),
0, true, context);
} else {
// no data was received in response to the request - must
// have been just a response header...
responseBodyRef = referenceService.register("", 0, true, context);
}
outputs.put(OUT_RESPONSE_BODY, responseBodyRef);
T2Reference statusRef = referenceService.register(requestResponse.getStatusCode(),
0, true, context);
outputs.put(OUT_STATUS, statusRef);
if (configBean.getShowActualUrlPort()) {
T2Reference completeURLRef = referenceService.register(completeURL, 0, true,
context);
outputs.put(OUT_COMPLETE_URL, completeURLRef);
}
if (configBean.getShowResponseHeadersPort())
outputs.put(OUT_RESPONSE_HEADERS, referenceService.register(
requestResponse.getHeadersAsStrings(), 1, true, context));
// only put an output to the Redirection port if the processor
// is configured to display that port
if (configBean.getShowRedirectionOutputPort()) {
T2Reference redirectionRef = referenceService.register(
requestResponse.getRedirectionURL(), 0, true, context);
outputs.put(OUT_REDIRECTION, redirectionRef);
}
// return map of output data, with empty index array as this is
// the only and final result (this index parameter is used if
// pipelining output)
callback.receiveResult(outputs, new int[0]);
}
});
}