JavaScript Plug-in

Ops Center Automator Service Builder User Guide

Version
11.0.x
Audience
anonymous
Part Number
MK-99AUT002-18

The JavaScript Plug-in Runs a specific JavaScript code. The plug-in can run any specified JavaScript code as follows:

  • To view any service property and plug-in property value.
  • To pass the maximum of 10 arguments via plug-in properties to the JavaScript code.
  • To keep the maximum of 10 values in plug-in output properties.
  • To return a value and keep the return value in the output properties.

Return codes

The JavaScript Plug-in generates the following return codes:

Return Code Description
0 Ended normally.
1 Script has ended due to an error.
60 A JavaScript library read error has occurred.
61 A JavaScript compile error has occurred.
62 The JavaScript code is not properly formatted.
63 An error occurred during the processing of the plug-in.
80 Task execution has stopped.

Property list

The following properties are available for the JavaScript Plug-in:

Property key Property name Description Default value I/O type Required
scriptBody Script body Specifies the JavaScript code strings. -- Input true
importedScript Imported script Specifies methods and constants (code string of JavaScript) to be used in common with other JavaScript Plug-ins placed on the same service template.

The following items can be used in the script of importedScript:

  • JS library: Same as the JS library available at scriptBody.
  • Functions: print() function. Same as the print() function available at scriptBody.
- Input false
arg0 Argument(0) Specifies an argument to be passed to the script. -- Input false
arg1 Argument(1) Specifies an argument to be passed to the script. -- Input false
arg2 Argument(2) Specifies an argument to be passed to the script. -- Input false
arg3 Argument(3) Specifies an argument to be passed to the script. -- Input false
arg4 Argument(4) Specifies an argument to be passed to the script. -- Input false
arg5 Argument(5) Specifies an argument to be passed to the script. -- Input false
arg6 Argument(6) Specifies an argument to be passed to the script. -- Input false
arg7 Argument(7) Specifies an argument to be passed to the script. -- Input false
arg8 Argument(8) Specifies an argument to be passed to the script. -- Input false
arg9 Argument(9) Specifies an argument to be passed to the script. -- Input false
notify Notification flag Specifies a non-empty string if the script detects something to notify; the plug-in ends with a return value of 1 if a non-empty string is specified here. -- Output false
returnValue Return value The content of the object returned from the function of the specified script is output as a character string. -- Output false
out0 Output(0) A value set to the out0 key in the map of the second argument in the user-specified script is output. -- Output false
out1 Output(1) A value set to the out1 key in the map of the second argument in the user-specified script is output. -- Output false
out2 Output(2) A value set to the out2 key in the map of the second argument in the user-specified script is output. -- Output false
out3 Output(3) A value set to the out3 key in the map of the second argument in the user-specified script is output. -- Output false
out4 Output(4) A value set to the out4 key in the map of the second argument in the user-specified script is output. -- Output false
out5 Output(5) A value set to the out5 key in the map of the second argument in the user-specified script is output. -- Output false
out6 Output(6) A value set to the out6 key in the map of the second argument in the user-specified script is output. -- Output false
out7 Output(7) A value set to the out7 key in the map of the second argument in the user-specified script is output. -- Output false
out8 Output(8) A value set to the out8 key in the map of the second argument in the user-specified script is output. -- Output false
out9 Output(9) A value set to the out9 key in the map of the second argument in the user-specified script is output. -- Output false

You specify the plug-in input/output properties in the property list. Combinations of service property values, reserved property values, and literal characters can be used for the input properties.

JavaScript code specifiable for the JavaScript body

The following table shows the JavaScript codes that are allowable in the body of the script:

Character encoding UTF-8
Available JS Library

underscore.js 1.8.3

auto_util-1.0.1.js (Bundled library of Ops Center Automator)

Format Must be an unnamed function (See the sample code.)
Function call interface Argument serviceProperties Object type Service input properties are mapped. The values of the service properties can be viewed from the script. Note that even if the script updates, deletes, or adds any of the values, the modified values will not be reflected in the service properties after the script is called.
pluginProperties Object type Plug-in properties are mapped. The values of the plug-in properties can be viewed from the script.
arg0 to arg9 Strings specified in the plug-in properties are directly mapped. Even the strings conform to JSON, if the script refers to here, and arguments can be obtained as strings, not objects. When you do not expect the validation JSON strings to objects described afterward, verify here.
notify If you specify a value other than a non-empty string to a member specified for notify in the script, the plug-in finishes with a return value of 1 after calling.
out0 to out9 If you specify values to members specified for out0 to out9 in the script, the values are reflected in the plug-in output properties of Argument(0) to Argument(9) after calling. The values are reflected in the processing results of the script, and the results will be used for the next step. (See the sample code.)
arg0 to arg9 Plug-in properties Argument(0) to Argument(9) are mapped. (Optional)

If you specify JSON strings to the plug-in properties, the strings can be obtained as objects in the functions of the script.

  • Strings that are enclosed with double quotation marks are mapped as is.
  • If strings are not enclosed, strings that fail JSON validation are mapped as is.
Return code Any objects can be returned from the script. After calling the script, the return codes are extracted as JSON strings that are then reflected in the plug-in output property Return value. The values are reflected in the processing results of the script and then used for the next step. (See the sample code.)
print () function By using the print() function in the script, you can output any strings to the task log. In this case, choose a log level by adding a specific prefix to the beginning of the string. Note that alphabetical prefixes are case-sensitive. (See the sample code.)
Prefix [Severe] Outputs as log level 0
[Information] Outputs as log level 10
[Fine] Outputs as log level 20
[Finer] Outputs as log level 30
[Debug] Outputs as log level 40
(No prefix) Same as the prefix [Information]
Other functionalities If an exception is thrown in the script or an unexpected exception occurs in the script, the plug-in ends abnormally and shows the exception in the task log.
When the script finishes properly, and when the values returned from the script or the values specified in the plug-in output properties (out0 to out9) of the script contain null or undefined, those values are stored as null or undefined.

auto util Library

The JavaScript plug-in supports the auto util library with the following features:

  • Sends an http or https request to any destination.
  • The setting values of Web Service Connection can be referred to as the connection information.

The following table shows the auto util methods that are available:

Table. auto util methods
Method Name Argument Return Value Description
sleep Specify the time to sleep in a numeric type (in milliseconds) None Sleep for the specified time.
parseJson Specify a string representation of JSON by string type. JSON object Convert a string to a JSON object.
stringifyJson Specify any JSON object. String representation of JSON Convert a JSON object to a string.
base64.encode Specify a string to be converted to BASE64. String encoded to BASE64 Encode into BASE64.
base64.decode Specify a BASE64 string. String decoded from BASE64 Decode from BASE64.
http.call JSON object of the request JSON object of the response Perform http or https request and return a response.
storage.restCall JSON object of the request JSON object of the response Perform an http or https request and return a response. Use this method when you run the Configuration Manager REST API. Compared with tbe http.call method, the specifications of the accept header, timeout period, and log output are different. For details about the differences, see the separate table below.
http.toRawHeader JSON object of the header Header string Return the header in the form of string. To the argument, specify the JSON object where the key and its value is set.
http.defaultErrorHandler Error None Throw HttpError instance.
JSON object of the request
JSON object of the response
http.handleCall
  1. httpCall method
  2. JSON object of the request
  3. Method to call when the http call is successful (The result status code is 200 or more and less than 400).
  4. Method to call when the http call fails (The result status code is less than 200 or more than 400).
  5. Method to call when the http call fails and the http response is not received.
  6. Object with retry conditions

    (For members of this object, see the separate table below.)

None Call the httpCall method of the first argument by specifying the request of the second argument. If the response of the result is 200 or more and less than 400, call the third argument, and in the case of other response codes, call the fourth argument. If the http call fails and the http response is not received, call the fifth argument.

The JSON objects of the request, response, and error when calling the httpCall method in the first argument can be called with the variables "req", "resp", "err", respectively, and you can use them as the argument of the function object in the third through fifth arguments.

If auto.util.storage.retrySettings is specified as the sixth argument, the retry is performed with the following retry count and interval when the HTTP response meets the following conditions.

  • Retry conditions: One of the following conditions is met:

    (1) Status code is 503.

    (2) Status code is 500 & Content-Type of response headers is text/html

  • Retry count: 130 (30 when called from the external resource provider)
  • Retry interval: 30 seconds (10 seconds when called from the external provider)
http.getHeaderValue Specify headers of the JSON object of the response by string type. String value of the header key name. Gets the value of the response header. If there are duplicate response header keys, the first header found is returned. If a nonexistent key is specified, an empty character is returned.
Specify the key name of the header to acquire by string type. The value to be specified is case-insensitive.
http.buildQuery Specify the query parameters in the Map format. Output query parameters in the string format. Builds query parameters and perform URL encoding.

For a code sample, see Sample code (Running the Configuration Manager REST API)

env.getServiceTemplate - Service template object Get the object of the service template.
env.getService - Service object Get the object of the service.
env.getWebServiceConnections Category name of the Web Service Connection. If not specified, all categories are obtained. A list of JSON objects (except for passwords) of Web Service Connections with the same category name as the one specified as an input parameter. Get a list of Web Service Connections. Web Service Connections that are accessible by the service or task are obtained by considering the defined relation between the Service, Service Group, Infrastructure Group, and Web Service Connection.

The following members are available for the JSON object of the request:

Member Type Description
requestUrl String [If not using Web Service Connection] Specify the request URL starting with http or https. [If using Web Service Connection] Specify the part from the "/" after the host name of the request URL to the en. Example: In the case of http://host:port/folder, specify "/Folder".
requestMethod String HTTP request method. Specify the following value as the string.
  • GET
  • POST
  • PUT
  • DELETE
  • PATCH (Supported only when "none" or "basic" is specified for authScheme.)
requestHeaders String Request header. Assume that the return value of the http.toRawHeader method is set. [When using Web Service Connection] The following values can be used as pad characters for user ID and password. - ${connection.username} - ${connection.password}
requestBody String Request body
authScheme String Specify one of the following values:
  • none
  • basic
  • digest
  • negotiate

If you specify the Authorization header for the request in the JavaScript code of the JavaScript Plug-in or external resource provider, specify “none”.

productName String Specify Web Service Connection category. Make sure to specify if using Web Service Connection.
connectionName String Specify Web Service Connection name. Make sure to specify if using Web Service Connection.
userName String Specify the user name to authenticate to the destination. Do not specify if using Web Service Connection.
password String Specify the password to authenticate to the destination.
useProxy boolean Specify whether to use a proxy (true/false).
proxyHost String Specify the host name or IP address of the proxy server.
proxyPort int Specify the port number of the proxy server.
proxyAuthScheme String If you specify "true" for useProxy, specify one of the following values:
  • none
  • basic
  • digest
proxyUserName String Specify the user name if the authentication is required at the proxy server.
proxyPassword String Specify the password if the authentication is required at the proxy server.
conntectionTimeout int Specify the timeout value in seconds (0-3600) when establishing an HTTP/HTTPS connection. If “0” is specified, no timeout occurs.
readTimeout int Specify the timeout value in seconds (0-86400) for reading data after an HTTP/HTTPS connection is established. If “0” is specified, no timeout occurs.
outputLog boolean Specify whether or not to output the response body to the task log.

If anything other than true/false is specified, the default value "true" is used.

Note that it can be specified only when the auto.util.storage.restCall method is run (it is ignored if specified in another method).

The following table shows the allowable response members:

Member Type Description
responseHeaders String Response header
responseStatusCode int Response code
responseStatusMessage String Response message
responseBody String Response body

The following members are available for the object with retry conditions:

Member Type Description
retryCondition Function object Function that returns the retry necessity (true/false) based on the response of the API that was run immediately before. If true, the retry is performed, and if false, the retry is not performed. For a sample code, see "Sample code (Retry settings)" below.
maxRetryCount int Retry count. Specify an integer between 0 and 1000.
retryWaitTime int Retry interval (in seconds). Specify an integer between 0 and 3600.

The following table shows the specification differences between the http.call and storage.restCall methods.

Item http.call storage.restCall
Accept header application/json */*
Timeout period Connection: 60 seconds (1 minutes)

Read: 600 seconds (10 minutes)

Connection: 600 seconds (10 minutes)

Read: 10800 seconds (180 minutes)

Log output Logs for the request URL, response code, and response body are not output to the task log. Logs including the request URL, response code, and response body are output to the task log.

Sample code (scriptBody)

JavaScript sample code that can be specified in the plug-in property JavaScript body is as follows:

function(serviceProperties, pluginProperties, arg0, arg1, arg2) {
    var obj = new Object();
    print("[Debug] Function begin.");

    obj.mem1 = arg0;
    obj.mem2 = arg1;

    if (arg2 == "") {
        pluginProperties["notify"] = 999;
        pluginProperties["out1"] = "NOTE!: The arg2 is EMPTY.";
    } else {
        obj.mem3 = arg2;
        obj.status = "success";
        pluginProperties["out1"] = "Finished successfully.";
    }

    print("[Debug] Function end.");

    return obj;
}

As described in the previous table, there are two ways of obtaining arg0, arg1,... where each can provide a different value. For pluginProperties, the arguments are obtained as a string but when obtained from the argument arg0, arg1,..., the evaluated value can be obtained from JavaScript. The example that shows the difference between the case of obtaining the input property of the plug-in from pluginProperties and the case of obtaining it from arg0, arg1,... is as follows.

Suppose that the following sample code is run by specifying 3 to arg0 and 5 to arg1.

function(serviceProperties, pluginProperties, arg0, arg1) {
    pluginProperties["out0"] = pluginProperties["arg0"] + pluginProperties["arg1"];
    pluginProperties["out1"] = arg0 + arg1;
}

When this sample code is run, "35" is set to out0, and "8.0" is set to out1. From pluginProperties, the arguments are handled as strings of "3" and "5" respectively, while the "+" symbol is handled as the string concatenation. In addition, for arg0 and arg1, they become 3.0 and 5.0 respectively, while the "+" symbol is handled as the addition function.

The following sample shows how to get the pool list from the Platform REST API server included in the storage system by referring to the connection information provided by Web Service Connection, and sets to the output property out0. As a prerequisite, the Web Service Connection whose category is StorageSystem" and whose name is "storage1" must already be registered.

function getPools(productname, connectionname) {
  var respBody = null;
  var request = {
    requestMethod:'GET',
    requestUrl:'/ConfigurationManager/v1/objects/pools',
    requestHeaders:auto.util.http.toRawHeader({
      'Accept':'application/json',
      'Accept-Language':'en',
      'Content-Type':'application/json',
    }),
    authScheme:'basic',
    connectionName: connectionname,
    productName: productname,
  };
  auto.util.http.handleCall(auto.util.http.call, request,
    function(resp, req) {
      respBody = resp.responseBody;
    }, function(resp, req) {
      auto.util.http.defaultErrorHandler(null, req, resp);
    }, function(err, req) {
      auto.util.http.defaultErrorHandler(err, req);
    }
  );
  return JSON.parse(respBody);
}
function fn(serviceProperties, pluginProperties, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
  var data = getPools('StorageSystem', 'storage1').data;
  var poolList = [];
  _.each(data, function(d){
    poolList.push({
      poolId: d.poolId,
      poolStatus: d.poolStatus,
      availableVolumeCapacity: d.availableVolumeCapacity
    }); 
  }); 
  pluginProperties.out0 = JSON.stringify(poolList, null, 2);
}

The following sample shows how to get the pool list from the Platform REST API server included in the storage system without referring to the connection information of Web Service Connection, and sets to the output property out0. As a prerequisite, the host name of Platform REST API server must be "host", the logon user name is "user", and the password is "password".

function getPools() {
  var respBody = null;
  var request = {
    requestMethod:'GET',
    requestUrl:'https://host/ConfigurationManager/v1/objects/pools',
    requestHeaders:auto.util.http.toRawHeader({
      'Accept':'application/json',
      'Accept-Language':'en',
      'Content-Type':'application/json',
    }),
    authScheme:'basic',
    userName:'user',
    password:'password',
    useProxy:'false'
  };
  auto.util.http.handleCall(auto.util.http.call, request,
    function(resp, req) {
      respBody = resp.responseBody;
    }, function(resp, req) {
      auto.util.http.defaultErrorHandler(null, req, resp);
    }, function(err, req) {
      auto.util.http.defaultErrorHandler(err, req);
    }
  );
  return JSON.parse(respBody);
}
function fn(serviceProperties, pluginProperties, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
  var data = getPools().data;
  var poolList = [];
  _.each(data, function(d){
    poolList.push({
      poolId: d.poolId,
      poolStatus: d.poolStatus,
      availableVolumeCapacity: d.availableVolumeCapacity
    }); 
  });
  pluginProperties.out0 = JSON.stringify(poolList, null, 2);
}

Sample code (scriptBody/importedScript)

JavaScript sample code that can be specified in the plug-in property scriptBody/importedScript is as follows:

-------------------------------------------
(scriptBody)
-------------------------------------------
function fn(serviceProperties, pluginProperties, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {

  hoge(CNST);

}
-------------------------------------------
(importedScript)
-------------------------------------------
var CNST = "hoge";

function hoge(a){
  print(a + " from common js!");
}
-------------------------------------------

Sample code (Retry settings)

JavaScript sample code in which the custom retry condition is specified as the sixth argument of http.handleCall.

var retrySettings = {};
retrySettings.retryCondition = function (response) {return response.responseStatusCode===503;};  // Retry when the response is 503
retrySettings.maxRetryCount = 10;  // Retry up to 10 times
retrySettings.retryWaitTime = 60;  // Retry every 60 seconds

auto.util.http.handleCall(auto.util.storage.restCall, request, successHandler, serverErrorHandler, clientErrorHandler, retrySettings);

Sample code (Running the Configuration Manager REST API)

The following shows a sample code when running the Configuration Manager REST API to obtain the pool information.

function fn(serviceProperties, pluginProperties, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
  var storageDeviceId = <storageDeviceId>;

  //Step 1. Generate a method to run REST API to Configuration Manager.
  var configurationManagerCall = function(request) {
    var respBody = null;
    auto.util.http.handleCall(auto.util.storage.restCall, request, 
      function(resp, req) {
        respBody = auto.util.parseJson(resp.responseBody);
      }, function(resp, req) {
        auto.util.http.defaultErrorHandler(null, req, resp);
      }, function(err, req) {
        auto.util.http.defaultErrorHandler(err, req);
      }, auto.util.storage.retrySettings
    );
    return respBody;
  };
  
  //Step 2. Get accessible Web Service Connections by specifying a category name.
  var wsc = auto.util.env.getWebServiceConnections("ConfigurationManager");
  
  //Step 3. Get Session
  //You can pass arguments by using the plug-in input properties or you can specify them directly in a script. For example, you can pass the device ID through the query parameters (queryParamMap).
  var request = {
    "requestMethod": "POST",
    "requestUrl": "/ConfigurationManager/v1/objects/storages/" + storageDeviceId + "/sessions",
    "requestHeaders": auto.util.http.toRawHeader({}),
    "authScheme": "basic",
    "connectionName": wsc[0].name,
    "productName": wsc[0].productName
  };
  var responseBody = configurationManagerCall(request);
  var token = responseBody.token;
  var sId = responseBody.sessionId;

  //Step 4. Call the API that is associated with your use case based on the session obtained in Step 3.
//When specifying the Authorization header for the request in the user program, specify "none" for authScheme.
  var headers = {
    "Authorization": "Session " + token,
  };
  var queryMap = {
    "poolType" : "DP"
  };
  var queryStr = auto.util.http.buildQuery(queryMap);
  request = {
    "requestMethod": "GET",
    "requestUrl": "/ConfigurationManager/v1/objects/storages/" + storageDeviceId + "/pools" + queryStr,
    "requestHeaders": auto.util.http.toRawHeader(headers),
    "authScheme": "none",
    "connectionName": wsc[0].name,
    "productName": wsc[0].productName
  };
  var ret = configurationManagerCall(request);

  //Final Step. Set the required information for the output property of the plug-in or return value.
  pluginProperties.out0 = ret.data[0].poolId;
  pluginProperties.out1 = ret.data[0].poolName;
  return ret;
}