sap apim java script policy
java proxy
java object
---------
<!–- Use case: Remove forward slash from incoming URL present at the end using a library function in a different script file --> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns='http://www.sap.com/apimgmt'> <IncludeURL>jsc://lib.js</IncludeURL> <ResourceURL>jsc://maincode.js</ResourceURL> </Javascript> <!–- =====Content of lib.js ==== --> //Trims the last chars from the string function trimEnd(value, searchChar){ if (value.charAt(value.length - 1) == searchChar) { value = value.substr(0, value.length - 1); } return value; } <!–- ======= Contents of maincode.js ==== --> //Returns the proxy path suffix by escaping the trailing ‘/’ function getTrimmedPathSuffix(){ return trimEnd(context.getVariable("proxy.pathsuffix"),'/'); } context.setVariable("trimmedPathSuffix", getTrimmedPathSuffix());
Elements and Attributes | Description |
---|---|
timeLimit (required) | Specifies the maximum time (in milliseconds) that the script is permitted to execute. |
ResourceURL (required) | Specifies the JavaScript resource (file). This is the main code file from which the execution begins. Syntax: <ResourceURL>jsc://example-javascript.js</ResourceURL> |
IncludeURL (optional) | Specifies a JavaScript library to be loaded as dependency. Store libraries under /APIProxy/FileResources/<policy name>.js in your API proxy bundle. The scripts are evaluated in the order in which they are listed in the policy. Syntax: <IncludeURL>jsc://my-javascript-URL.js</IncludeURL> |
Display name (optional) | Labels the policy in the management UI proxy editor with a different, natural-language name. If you skip this element, the value of the name attribute is applied to the policy. Syntax: <DisplayName>Policy-Display-Name</DisplayName> |
Error Name | Cause |
---|---|
ScriptExecutionFailed | A runtime error occurred in the JavaScript code. See the fault string for details. |
ScriptExecutionFailedLineNumber | An error occurred in the JavaScript code. See the fault string for details. |
ScriptSecurityError | A security error occurred when the JavaScript executed. See the fault string for details. |
WrongResourceType | In the <ResourceURL> and <IncludeURL> elements, you must refer to a JavaScript file correctly using the jsc resource type. For example, here is the correct way to refer to the JavaScript file in the policy: <ResourceURL>jsc://JavaScript-1.js</ResourceURL> |
NoResourceForURL | The <ResourceURL> and <IncludeURL> elements refer to a JavaScript file that does not exist. |
ScriptCompilationFailed | An error occurred during compilation of the JavaScript code. Refer to the error message for details. |
InvalidResourceUrlFormat | This error occurs when the format of the resource URL specified within the <ResourceURL> or the <IncludeURL> element of the JavaScript policy is invalid, resulting in the deployment of the API proxy to fail. |
InvalidResourceUrlReference | This error occurs when the <ResourceURL> or the <IncludeURL> elements refer to a JavaScript file that does not exist, resulting in the deployment of the API proxy to fail. |
Variable Set | Where | Example |
---|---|---|
[prefix].[policy_name].failed | The [prefix] is javascript. The [policy_name] is the name of the policy that threw the error. | javascript.JavaScript-1.failed = true |
fault.[error_name] | [error_name] is the specific error name to check for as listed in the table above. | fault.name Matches "ScriptExecutionFailed" |
----
ava Script Object Model
This topic describes JavaScript model for API Management. JavaScript model enables you to use the JavaScript policy to add custom JavaScript to an API proxy.
API Management JavaScript object model defines objects that can be used in a JavaScript code executing within an API proxy flow. Objects defined by the JavaScript object model are within the scope of the API proxy flow. On executing the JavaScript, a scope is created and within the scope, the following object references are created: context, request, response, and crypto. You can also use a print function for debugging purpose.
Context Object
- Scope: Global; available throughout the API Proxy flow.
- Child objects: proxyRequest, proxyResponse, targetRequest, and targetResponse.
Child objects are scoped to the ambient request and response, either the proxy request and response or the target request and response. For example, if the JavaScript policy executes in the proxy endpoint part of the flow, then the context.proxyRequest and context.proxyResponse objects are in scope. If the JavaScript runs in a target flow, then the context.targetRequest and context.targetResponse objects are in scope.
Following table describes context objects and its children:Context objects Name Description Properties context A wrapper for the message processing pipeline context and the request and response Flows that are executed by the ProxyEndpoint and TargetEndpoint. flow, session context.proxyRequest An object that represents the inbound request message to the ProxyEndpoint (from the requesting app to the API proxy) headers, query parameters, method, body, url context.targetRequest An object that represents the outbound request message from the TargetEndpoint (from the API proxy to the back end service). headers, query parameters, method, body, url context.targetResponse An object that represents the inbound target response message (from the backend service to the API proxy) headers, content, status context.proxyResponse An object that represents the outbound proxy response message (from the API proxy to the requesting app) headers, content, status Context.flow The name of the current flow. Context.session A map of name/value pairs that you can use to pass objects between two different steps executing in the same context. For example: context.session['key'] = 123. context.*Request child objects
Each HTTP transaction executing in an API Proxy, creates two request message objects:- Inbound: Request from client.
- Outbound: Request generated by API Proxy and submitted to the backend target.
context.*Request child object properties Property Name Description url The url property is a read/write convenience property that combines scheme, host, port, path, and query parameters for the targetRequest.
The complete URL of the request is composed of the following properties:
protocol: The protocol of the URL (for example, HTTP, HTTPS)
port: The port (for example: 80, 443)
host: The host of the URL (for example, www.example.com)
path: The path of the URI (for example, /v1/mocktarget)
When getting url, a URL is returned in the following format:
protocol://host:port/path?queryParams
Examples:
context.targetRequest.url = 'http://www.example.com/path?q1=1'context.targetRequest.protocol ='https';headers HTTP request headers as a mapping of String => List
Examples:
For this HTTP request:
POST /v1/blogs HTTP/1.1 Host: api.example.com Content-Type: application/json Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z
The following JavaScript:
context.proxyRequest.headers['Content-Type']; context.proxyRequest.headers['Authorization'];
returns the following values:application/json Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z
queryParams The request message query parameters as a mapping of String => List.
Examples: "?city=PaloAlto&city=NewYork"
can be accessed as:
context.proxyRequest.queryParams['city']; // == 'PaloAlto' context.proxyRequest.queryParams['city'][0] // == 'PaloAlto' context.proxyRequest.queryParams['city'][1]; // == 'NewYork' context.proxyRequest.queryParams['city'].length(); // == 2
method The HTTP verb (GET, POST, PUT, DELETE. PATCH, etc.) associated with the request
Examples:
For this request:
POST /v1/blogs HTTP/1.1 Host: api.example.com Content-Type: application/json Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z
The following JavaScript:
context.proxyRequest.method;
returns the following value
POST
body The message body (payload) of the HTTP request.
The request body has the following members:
context.targetRequest.body.asXML;
context.targetRequest.body.asJSON;
context.targetRequest.body.asForm;
Examples:
For an XML body:
<customer number='1'> <name>Fred<name/> <customer/>
To access the elements of the XML object as follows:
var name = context.targetRequest.body.asXML.name;
To access XML attributes, use the @ notation.
var number = context.targetRequest.body.asXML.@number;
For a JSON request body:
{ "a": 1 , "b" : "2" }
var a = context.proxyRequest.body.asJSON.a; // == 1 var b = context.proxyRequest.body.asJSON.b; // == 2
To read form parameters:
"vehicle=Car&vehicle=Truck" v0 = context.proxyRequest.body.asForm['vehicle'][0]; v1 = context.proxyRequest.body.asForm['vehicle'][1];
context.*Response child objects
Each HTTP transaction executing in an API Proxy, creates two response message objects:- Inbound: Response from the backend service.
- Outbound: Response sent to client.
context.*Response object properties Property Name Description headers The HTTP headers of the response message as a mapping of String => List.
Example:
var cookie = context.targetResponse.headers['Set-Cookie'];
status The status code with status message as a property. Both status code and status message are available as properties.
Example:
var status = context.targetResponse.status.code; // 200
var msg = context.targetResponse.status.message; // "OK"
content The HTTP body (payload content) of the response message.
Response content has the following members:
context.targetResponse.content.asXML;
context.targetResponse.content.asJSON;
- Context object methods
Methods Method Name Description Syntax context.getVariable() Retrieves the value of a predefined or custom variable. context.getVariable("variable-name"); context.setVariable() Sets the value for a custom variable or for any predefined variables. context.setVariable("variable-name", value); context.removeVariable() Removes a variable from the context. context.removeVariable('variable-name');
Request and Response objects
The request and response objects are "shorthand" references to the ambient request and response, either the proxy request and response or the target request and response. The objects these variables refer to depend upon the context in which the JavaScript policy executes. If the JavaScript runs in the flow of a proxy endpoint, then the request and response variables refer to context.proxyRequest and context.ProxyResponse. If the JavaScript runs in a target flow, then the variables refer to the context.targetRequest and context.targetResponse.
Crypto Object
Scope: Global
- Hash objects supported by crypto:
- SHA-1: You can create SHA-1 objects, update them, and convert them to hex and base64 values.
- Create an SHA-1 object
var_sah1 = crypto.getSHA1();
- Update an SHA-1 object
_sha512.update(value);
- Return the SHA-1 object as a hex string
var _hashed_token = _sha1.digest();
- Return the SHA-1 object as a base64 string
var _hashed_token = _sha1.digest64();
- Create an SHA-1 object
- SHA-256: You can create SHA-256 objects, update them, and convert them to hex and base64 values.
- Create an SHA-256 object
var _sha256 = crypto.getSHA256();
- Update an SHA-256 object
_sha256.update(value);
- Return the SHA-256 object as a hex string
var _hashed_token = _sha256.digest();
- Return the SHA-256 object as a base64 string
var _hashed_token = _sha256.digest64();
- Create an SHA-256 object
- SHA-512 : You can create SHA-512 objects, update them, and convert them to hex and base64 values.
- Create an SHA-512 object
var _sha512 = crypto.getSHA512();
- Update an SHA-512 object
_sha512.update(value);
- Return the SHA-512 object as a hex string
var _hashed_token = _sha512.digest();
- Return the SHA-512 object as a base64 string
var _hashed_token = _sha512.digest64();
- Create an SHA-512 object
- MD5: You can create MD5 objects, update them, and convert them to hex and base64 values.
- Create an MD5 object
var _md5 = crypto.getmd5();
- Update an MD5 object
_md5 .update(value);
- Return the MD5 object as a hex string
var _hashed_token = _md5.digest();
- Return the MD5 object as a base64 string
var _hashed_token = _md5.digest64();
- Create an MD5 object
- Crypto date/time support: The crypto object supports date/time formatting patterns.
crypto.dateFormat() returns a date in the string format.
Syntax:
crypto.dateFormat(format, [timezone], [time])The following table shows the parameters and examples of Crypto date/time support:Parameter Description Example format (string) The underlying implementation for this parameter is java.text.SimpleDateFormat, for example: 'YYYY-MM-DD HH:mm:ss.SSS' Get the current time, down to milliseconds: var _now = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS'); timezone (string, optional) The underlying implementation for this parameter is java.util.TimeZone. Default: UTC Get the current time for Pacific Time Zone:var _pst = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST'); time (number, optional) A Unix timestamp value to format. Default: current time Get the value of ten seconds from current time: var _timeNow = Number(context.getVariable('system.timestamp'));var ten_seconds = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST', _timeNow + 10 * 1000);
try { //get values to use with hash functions var salt = context.getVariable("salt") || 'SomeHardCodedSalt'; var host = context.getVariable("request.header.Host"); var unhashed_token = ""; var _timeNow = Number(context.getVariable('system.timestamp')); var now = crypto.dateFormat('YYYY-MM-DD HH:mm:ss.SSS','PST', _timeNow); unhashed_token = "|" + now + "|" + host //generate a hash with the unhashedToken: var sha512 = crypto.getSHA512(); sha512.update(salt); sha512.update(unhashed_token); //convert to base64 var base64_token = sha512.digest64(); // set headers context.setVariable("request.header.now", now); context.setVariable("request.header.token", base64_token); } catch(e) { throw 'Error in Javascript'; }
The print() function
Using http Client
The http Client object is exposed to custom Java Script code through the JavaScript object model. To attach custom JavaScript to an API proxy, you use the Java Script policy. When the policy runs, the custom JavaScript code executes.
The httpClient object is useful for developing composite services or mashups. For example, you can consolidate multiple backend calls into a single API method. This object is commonly used as an alternative to the Service Callout policy.
httpClient Reference
HTTP Client exposes two methods: get() and send()
httpClient.get()
Usage: var exchangeObj = httpClient.get(url);
Return: method returns an exchange object. This object has no properties, and it exposes the following methods:
- isError(): (boolean) Returns true if the httpClient was unable to connect to the server. HTTP status codes 4xx and 5xx result in isError() false, as the connection completed and a valid response code was returned. If isError() returns true, then a call to getResponse() returns the JavaScript undefined.
- isSuccess(): (boolean) Returns true if the send was complete and successful.
- isComplete(): (boolean) Returns true if the request is complete.
- waitForComplete(): Pauses the thread until the request is complete (by success or error).
- getResponse(): (object) Returns the response object if the httpClient.send() was complete and successful.
- getError(): (string) If the call to httpClient.send() resulted in an error, returns the error message as a string.
- httpClient.send()
Usage: var request = new Request(url, operation, headers); var exchangeObj = httpClient.send(request);
Returns: A call to httpClient.send() returns an exchange object.
---