JavaScript Adapters
Overview
JavaScript adapters provide templates for connection to HTTP and SQL back-ends. It provides a set of services, called procedures and mobile apps can call these procedures by issuing AJAX requests.
Prerequisite: Make sure to read the Creating Java and JavaScript Adapters tutorial first.
File structure
The adapter-resources folder
The adapter-resources folder contains an XML configuration file. This configuration file describes the connectivity options and lists the procedures that are exposed to the application or other adapters.
<?xml version="1.0" encoding="UTF-8"?>
<mfp:adapter name="JavaScriptAdapter">
<displayName>JavaScriptAdapter</displayName>
<description>JavaScriptAdapter</description>
<connectivity>
<connectionPolicy>
...
</connectionPolicy>
</connectivity>
<procedure name="procedure1"></procedure>
<procedure name="procedure2"></procedure>
<property name="name" displayName="username" defaultValue="John" />
</mfp:adapter>
name
: Mandatory. The name of the adapter. This name must be unique within the PMF. It can contain alphanumeric characters and underscores, and must start with a letter. After you define and deploy an adapter, you cannot modify its name.- <displayName>: Optional. The name of the adapter that is displayed in the PMF Operations Console. If this element is not specified, the value of the name attribute is used instead.
- <description>: Optional. Additional information about the adapter. Displayed in the PMF Operations Console.
- <connectivity>: Mandatory. Defines the mechanism by which the adapter connects to the back-end application. It contains the <connectionPolicy> subelement.
- <connectionPolicy>: Mandatory. Defines connection properties. The structure of this subelement depends on the integration technology of the back-end application. For more information about <connectionPolicy>, see HTTP adapter <connectionPolicy> element and SQL adapter <connectionPolicy> element.
- <procedure>: Mandatory. Defines a process for accessing a service that is exposed by a back-end application.
name
: Mandatory. The name of the procedure. This name must be unique within the adapter. It can contain alphanumeric characters and underscores, and must start with a letter.audit
: Optional. Defines whether calls to the procedure are logged in the audit log. The following values are valid:true
: Calls to the procedure are logged in the audit log.false
: Default. Calls to the procedure are not logged in the audit log.
scope
: Optional. The security scope that protects the adapter resource procedure. The scope can be a string of one or more space-separated scope elements, or null to apply the default scope. A scope element can be a keyword that is mapped to a security check, or the name of a security check. The default scope isRegisteredClient
, which is a reserved PMF keyword. The default protection requires an access token for accessing the resource.
For more information about the PMF OAuth resource protection and how to configure resource protection for JavaScript adapter resources, see Protecting adapter resources.
When the value of thesecured
attribute isfalse
, thescope
attribute is ignored.secured
: Optional. Defines whether the adapter procedure is protected by the PMF security framework. The following values are valid:true
: Default. The procedure is protected. Calls to the procedure require a valid access token.false
. The procedure is not protected. Calls to the procedure do not require an access token. See Unprotected resources. When this value is set, thescope
attribute is ignored.
- <securityCheckDefinition>: Optional. Defines a security-check object. Learn more about security checks in the Creating a Security Checks tutorial.
property
: Optional. Declares a user-defined property. Learn more in the Custom properties section of this tutorial.
Close section
Custom properties
The adapter.xml file can also contain user-defined custom properties. The values that developers assign to them during the creation of the adapter can be overridden in the PMF Operations Console → [your adapter] → Configurations tab, without redeploying the adapter. User-defined properties can be read using the getPropertyValue API and then further customized at run time.
Note: The configuration properties elements must always be located below the <procedure> elements. In the example above we defined a <displayName> property with a default value, so it could be used later.
The <property> element takes the following attributes:
name
: The name of the property, as defined in the configuration class.defaultValue
: Overrides the default value defined in the configuration class.displayName
: optional, a friendly name to be displayed in the console.description
: optional, a description to be displayed in the console.type
: optional, ensures that the property is of a specific type such asinteger
,string
,boolean
or a list of valid values (for exampletype="['1','2','3']"
).
Pull and Push Configurations
Customized adapter properties can be shared using the adapter configuration file found in the Configuration files tab.
To do so, use the pull
and push
commands described below using either Maven or the PMF CLI. For the properties to be shared, you need to change the default values given to the properties.
Run the commands from the root folder of the adapter Maven project:
Maven
- To pull the configurations file
mvn adapter:configpull -DmfpfConfigFile=config.json
- To push the configurations file
mvn adapter:configpush -DmfpfConfigFile=config.json
PMF CLI
- To pull the configurations file
pmfdev adapter pull
- To push the configurations file
pmfdev adapter push
Pushing configurations to multiple servers
The pull and push commands can help to create various DevOps flows, where different values are required in adapters depending on the environment you’re at (DEV, QA, UAT, PRODUCTION).
Maven
Note above how by default you specify a config.json file. Create files with different names to address different targets.
PMF CLI
Use the –configFile or -c flag to specify a different configuration file than the default one:
pmfdev adapter pull -c [adapterProject]/alternate_config.json
Learn more in by using
pmfdev help adapter pull/push
.
The js folder
This folder contains the JavaScript implementation file of all the procedures that are declared in the adapter.xml file and there can be only one JavaScript file in a JavaScript adapter. It also contains zero, one, or more XSL files, which contain a transformation scheme for retrieved raw XML data. Data that is retrieved by an adapter can be returned raw or preprocessed by the adapter itself. In either case, it is presented to the application as a JSON object.
JavaScript adapter procedures
Procedures are declared in XML and are implemented with server-side JavaScript, for the following purposes:
- To provide adapter functions to the application
- To call back-end services to retrieve data or to perform actions
Each procedure that is declared in the adapter.xml file must have a corresponding function in the JavaScript file.
By using server-side JavaScript, a procedure can process the data before or after it calls the service. You can apply more filtering to retrieved data by using simple XSLT code.
JavaScript adapter procedures are implemented in JavaScript. However, because an adapter is a server-side entity, it is possible to use Java in the adapter code.
Using global variables
The PMF does not rely on HTTP sessions and each request may reach a different node. You should not rely on global variables to keep data from one request to the next.
Adapter response threshold
Adapter calls are not designed to return huge chunks of data because the adapter response is stored in PMF memory as a string. Thus, data that exceeds the amount of available memory might cause an out-of-memory exception and the failure of the adapter invocation. To prevent such failure, you configure a threshold value from which the PMF returns gzipped HTTP responses. The HTTP protocol has standard headers to support gzip compression. The client application must also be able to support gzip content in HTTP.
Server-side
In the PMF Operations Console, under Runtimes > Settings > GZIP compression threshold for adapter responses, set the desired threshold value. The default value is 20 KB.
Note: By saving the change in the PMF Operations Console, the change is effective immediately in the runtime.
Client-side
Ensure that you enable the client to parse a gzip response, by setting the value of the Accept-Encoding
header to gzip
in every client request.
Use the addHeader
method with your request variable, for example: request.addHeader("Accept-Encoding","gzip");
Server-side APIs
JavaScript adapters can use server-side APIs to perform operations that are related to PMF, such as calling other JavaScript adapters, logging to the server log, getting values of configuration properties, reporting activities to Analytics and getting the identity of the request issuer.
getPropertyValue
Use the MFP.Server.getPropertyValue(propertyName)
API to retrieve properties defined in the adapter.xml or in the PMF Operations Console:
MFP.Server.getPropertyValue("name");
getTokenIntrospectionData
Use the MFP.Server.getTokenIntrospectionData()
API to
To get the current User ID use:
function getAuthUserId(){
var securityContext = MFP.Server.getTokenIntrospectionData();
var user = securityContext.getAuthenticatedUser();
return "User ID: " + user.getId;
}
getAdapterName
Use the getAdapterName()
API to retrieve the adapter name.
invokeHttp
Use the MFP.Server.invokeHttp(options)
API in HTTP adapters.
You can see usage examples on the JavaScript HTTP Adapter tutorial.
invokeSQL
Use the MFP.Server.invokeSQLStatement(options)
and the MFP.Server.invokeSQLStoredProcedure(options)
APIs in SQL adapters.
You can see usage examples on the JavaScript SQL Adapter tutorial.
addResponseHeader
Use the MFP.Server.addResponseHeader(name,value)
API to add a new header(s) to the response:
MFP.Server.addResponseHeader("Expires","Sun, 5 October 2014 18:00:00 GMT");
getClientRequest
Use the MFP.Server.getClientRequest()
API to get a reference to the Java HttpServletRequest object that was used to invoke an adapter procedure:
var request = MFP.Server.getClientRequest();
var userAgent = request.getHeader("User-Agent");
invokeProcedure
Use the MFP.Server.invokeProcedure(invocationData)
to call other JavaScript adapters.
You can see usage examples on the Advanced Adapter Usage and Mashup tutorial.
Logging
The JavaScript API provides logging capabilities through the MFP.Logger class. It contains four functions that correspond to four standard logging levels.
You can see the server-side log collection tutorial for more information.