public void executeAsynch()

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]);
			}
		});
	}