Name
global.WebServiceActivityHandler
Description
Base class for web service activities. Driven by REST Message and SOAP Message activities that shared many common pieces of functionality.
Script
var WebServiceActivityHandler = Class.create();
WebServiceActivityHandler.prototype = Object.extendsObject(WFActivityHandler, {
initialize: function() {
WFActivityHandler.prototype.initialize.call(this);
this.endpoint = '';
this.variables = '';
this.use_midserver = 'false';
this.midserver = '';
this.executionType = '';
},
onExecute: function() {
var execId = '';
var outputPayload = '';
activity.state = 'waiting';
try {
this._getValues();
this._processValues();
if (activity.state == 'finished')
return;
if (gs.nil(this.web_service_message)) {
this.setResultFailed('Message is not selected');
activity.state = 'finished';
return;
}
if (gs.nil(this.web_service_message_function)) {
this.setResultFailed('Message function is not selected');
activity.state = 'finished';
return;
}
this.mo = this._getMessageObject();
if (!this.mo) {
this.setResultFailed('Error creating message object with given message and function parameters');
activity.state = 'finished';
return;
}
// Handle parameters sent to the web service message
var params = this.getMessageParameters();
if (params)
for (var param in params) {
this.mo.setStringParameter(param, params[param]);
outputPayload += param + ' ' + params[param];
}
var xmlParams = this.getXmlMessageParameters();
if (xmlParams)
for (var xmlParam in xmlParams) {
this.mo.setXMLParameter(xmlParam, xmlParams[xmlParam]);
outputPayload += xmlParam + ' ' + xmlParams[xmlParam];
}
// Set authentication
this.setAuthentication();
// If there is an endpoint set, override the one in the message object
if (!gs.nil(this.endpoint)) {
this._setEndpoint();
var ePoint = this.endpoint + '';
outputPayload += ePoint;
}
var func = this.web_service_message_function + '';
outputPayload += func;
// If we're supposed to use a MID server, if one is not specified, find one using
// the finder, otherwise just use the specified one
if (this.use_midserver != 'false') {
if (gs.nil(this.midserver)) {
var midSel = new MIDServerSelector();
midSel.setCapabilities([this.capability]);
var target = this._getTargetHost(this.endpoint);
if (gs.nil(target)) {
activity.state = 'finished';
return;
}
var mid = midSel.findAgent(target);
this.errorMsg = midSel.getError();
this.warningMsg = midSel.getWarning();
if (!gs.nil(this.warningMsg))
this.warn(this.warningMsg);
if (!gs.nil(this.errorMsg)) {
this.setResultFailed(this.errorMsg);
activity.state = 'finished';
return;
}
this.mo.setMIDServer(mid);
} else
this.mo.setMIDServer(this.midserver);
// Need these fields on the queue record to trigger the event for probe complete and have
// it come back to the handler method below
this.mo.setEccParameter('skip_sensor', 'true');
this.mo.setEccParameter('workflow', activity.sys_id);
this.mo.setEccCorrelator('rba.' + activity.context.sys_id);
}
try {
execId = SNC.OrchestrationUsage.logExecution(activity.context.sys_id, activity.activity.sys_id,
this.executionType, this.endpoint, 'useMid=' + this.use_midserver);
this.mo.setEccParameter('execution_sys_id', execId);
} catch (e) {
gs.log('Error logging orchestration execution in WebServiceActivityHandler: ' + e.getMessage());
}
this.response = this._launch();
if (this.use_midserver == 'false') {
var httpStatus = this._getStatusCode();
if (this._hasOtherErrors()) {
activity.state = 'finished';
return;
}
// Failure outside of the 200 range
if (httpStatus < 200 || httpStatus >= 300) {
var errorMsg = "Request failed with status code: " + httpStatus
+ "\n" + this._getOutput();
this.setResultFailed(errorMsg);
workflow.error(errorMsg);
activity.state = 'finished';
return;
}
var inputPayload = this._getOutput() + '';
// Update with I/O payload size here when we don't use the MID
try {
SNC.OrchestrationUsage.updateExecutionLog(execId, inputPayload, outputPayload);
} catch (exep) {
gs.log('Error updating orchestration execution in WebServiceActivityHandler: ' + exep.getMessage());
}
this.setActivityOutput(this._getOutput());
this.processResults();
}
} catch (ex) {
this.setResultFailed(ex);
activity.state = 'finished';
}
},
onProbe_complete: function() {
if (!gs.nil(arguments) && !gs.nil(arguments[1]))
SncRBSensorProcessor.validateProbeGlobals(arguments[1].ecc_id);
activity.state = 'finished';
this.setActivityOutput(this._getRawOutput());
this.response = activity.output;
var httpStatus = this._getHttpStatus();
try {
var execId = this._getExecLogId();
var inputPayload = this._getRawOutput();
var outputPayload = "";
var ecc = new GlideRecord(GlideappIECC.ECC_QUEUE);
ecc.addQuery(GlideappIECC.AGENT_CORRELATOR, 'rba.' + activity.context.sys_id);
ecc.addQuery(GlideappIECC.ECC_QUEUE, GlideappIECC.OUTPUT);
ecc.query();
if (ecc.next()) {
outputPayload = ecc.getValue("payload");
}
SNC.OrchestrationUsage.updateExecutionLog(execId, inputPayload, outputPayload);
} catch (e) {
gs.log('Error updating orchestration execution log in WebServiceActivityHandler: ' + e.getMessage());
}
var error = this._getError();
if (error) {
workflow.error(error);
this.setResultFailed(error);
return;
}
if (this._hasOtherErrors())
return;
this.processResults();
},
processResults: function() {
activity.state = 'finished';
this.setResultSuccessful();
this.processResponse();
var sensorScript = this.getSensorScript();
if (!sensorScript)
return;
this._evalScript(sensorScript);
},
processResponse: function() {
},
getMessageParameters: function() {
// Process the variables string, and add them to the web service message for substitution
var messageParams = {};
if (!gs.nil(this.variables)) {
var params = this._processVars();
for (var name in params) {
messageParams[name] = params[name];
}
}
return messageParams;
},
/**
* Current planned usage for this method is for activities extending this activity
*/
getXmlMessageParameters: function() {
var xmlMessageParams = {};
return xmlMessageParams;
},
/**
* Current planned usage for this method is for those needing to use this to extend SOAP Message or REST Message and give this
* method a body in the extended class to populate the fields accordingly
*/
setAuthentication: function() {
},
getSensorScript: function() {
return this.js(activity.vars.sensor_script);
},
_checkOtherErrors: function() {
},
_getEccResultParameter: function(params, name) {
var value = '';
for (var i = 0; i < params.length; i++)
if (params[i]['@name'] == name) {
value = params[i]['@value'];
break;
}
return value;
},
_getHttpStatus: function() {
if (document.parameters && document.parameters.parameter)
return this._getEccResultParameter(document.parameters.parameter, 'http_status_code');
return 0;
},
_getExecLogId: function() {
if (document.parameters && document.parameters.parameter)
return this._getEccResultParameter(document.parameters.parameter, 'execution_sys_id');
return '';
},
_getMessageObject: function() {
},
_getOutput: function() {
},
_getStatusCode: function() {
},
_getValues: function() {
},
_hasOtherErrors: function() {
},
_processValues: function() {
},
_setEndpoint: function() {
},
_evalScript: function(s) {
var scriptId = activity.name + '.' + activity.sys_id;
var answer = workflow.evaluateString(s, scriptId); // evaluate: cache/compile the script
if (workflow.isFailed()) {
workflow.error(answer);
this.setResultFailed(answer);
}
},
_getRawOutput: function() {
if (!document.result)
return '';
var output = document.result.output;
if (!output)
output = '';
return output;
},
_getError: function() {
var error = document['@error'];
if (error)
return error;
if (document.result) {
var error = document.result['@error'];
if (error)
return error;
error = document.result.error;
if (error)
return error;
}
return '';
},
_getTargetHost: function(url) {
var host = '';
try {
var urlObj = new Packages.java.net.URL(url);
host = urlObj.getHost() + '';
} catch (e) {
var err = 'Unable to parse the provided URL: ' + e;
workflow.error(err);
this.setResultFailed(err);
}
return host;
},
_processVars : function() {
var pairs = this._split(this.variables, '\\', ',');
var params = {};
for (var i = 0; i < pairs.length; i++) {
var s = pairs[i];
var pair = this._split(s, '\\', '=');
if (pair.length == 2)
params[pair[0]] = pair[1];
else
workflow.warning("Unable to process parameter: " + s);
}
return params;
},
_split : function(origStr, escape, delimiter) {
var parts = [];
var str = "";
var start = 0;
var i = 0;
for (i = 0; i < origStr.length; i++) {
if (origStr[i] == delimiter) {
if (i > 0 && origStr[i-1] == escape)
continue;
str = origStr.substr(start, i - start);
str = this._trim(str);
str = this._cleanEscapeChar(str, escape, delimiter);
parts.push(str);
start = i + 1;
}
}
str = origStr.substr(start, i - start);
str = this._trim(str);
str = this._cleanEscapeChar(str, escape, delimiter);
parts.push(str);
return parts;
},
_cleanEscapeChar : function(str, escapeChar, delimiter) {
var newstr = str.replace(escapeChar + delimiter, delimiter);
while (newstr != str) {
str = newstr;
newstr = str.replace(escapeChar + delimiter, delimiter);
}
return newstr;
},
_trim : function(str) {
return str.trim();
},
type: 'WebServiceActivityHandler'
});
Sys ID
88fffeeb07771000dada43c0d1021e34