Appendix F. Scripting Reference

Table of Contents
F.1. Scripting Configuration
F.2. Examples
F.3. Function Reference
F.4. Places to Trigger Scripts
F.5. Variables Available in Scripts
F.6. Debugging OpenIDM Scripts

Scripting allows you to customize various aspects of OpenIDM functionality, for example, by providing custom logic between source and target mappings, defining correlation rules, filters, and triggers, and so on.

F.1. Scripting Configuration

You define scripts using script objects, which can either include the code directly in the configuration, or call an external file that contains the script.

Custom scripts should be placed in the script/ folder for your project, for example path/to/openidm/script/. Do not modify or remove the script files located in path/to/openidm/bin/defaults/script/. This folder contains the default scripts that are required to run specific services. Scripts in this folder are not guaranteed to remain constant between product releases.

{
  "type" : "text/javascript",
  "source": string
}
        

or

{
  "type" : "text/javascript",
  "file" : file location
}
        
type

string, required

Specifies the type of script to be executed. Currently, OpenIDM supports only"text/javascript".

source

string, required if file is not specified

Specifies the source code of the script to be executed.

file

string, required if source is not specified

Specifies the file containing the source code of the script to execute.

F.2. Examples

The following example (included in the sync.json file) returns true if the employeeType is equal to external, otherwise returns false. This script can be useful during reconciliation to establish whether the source object should be a part of the reconciliation, or ignored.

"validTarget": {
   "type" : "text/javascript",
   "source": "target.employeeType == 'external'"
}
        

The following example (included in the sync.json file) sets the __PASSWORD__ attribute to defaultpwd when OpenIDM creates a target object.

"onCreate" : {
  "type" : "text/javascript",
  "source": "target.__PASSWORD__ = 'defaultpwd'"
}
        

The following example (included in the router.json file) shows a trigger to create Solaris home directories using a script. The script is located in a file, /path/to/openidm/script/createUnixHomeDir.js.

{
  "filters" : [ {
    "pattern" : "^system/solaris/account$",
    "methods" : [ "create" ],
    "onResponse" : {
      "type" : "text/javascript",
      "file" : "script/createUnixHomeDir.js"
    }
  } ]
}
        

F.3. Function Reference

Functions (access to managed objects, system objects, and configuration objects) within OpenIDM are accessible to scripts via the openidm object, which is included in the top-level scope provided to each script.

OpenIDM also provides a logger object to access SLF4J facilities. The following code shows an example:

logger.info("Parameters passed in: {} {} {}", param1, param2, param3);
        

To set the log level, use org.forgerock.openidm.script.javascript.JavaScript.level in openidm/conf/logging.properties.

F.3.1. openidm.create(id, value)

This function creates a new resource object.

Parameters
id

string

The identifier of the object to be created.

value

object

The value of the object to be created.

Returns
  • The created OpenIDM resource object.

Throws
  • An exception is thrown if the object could not be created.

F.3.2. openidm.patch(id, rev, value)

This function performs a partial modification of a managed object. Unlike the update function, only the modified attributes are provided, not the entire object.

Parameters
id

string

The identifier of the object to be updated.

rev

string

The revision of the object to be updated, or null if the object is not subject to revision control.

value

object

The value of the modifications to be applied to the object.

Returns
  • The modified OpenIDM resource object.

Throws
  • An exception is thrown if the object could not be updated.

F.3.3. openidm.read(id)

This function reads and returns an OpenIDM resource object.

Parameters
id

string

The identifier of the object to be read.

Returns
  • The read OpenIDM resource object, or null if not found.

F.3.4. openidm.update(id, rev, value)

This function updates a resource object.

Parameters
id

string

The identifier of the resource object to be updated.

rev

string

The revision of the object to be updated, or null if the object is not subject to revision control.

value

object

The value of the object to be updated.

Returns
  • The modified OpenIDM resource object.

Throws
  • An exception is thrown if the object could not be updated.

F.3.5. openidm.delete(id, rev)

This function deletes a resource object.

Parameters
id

string

The identifier of the object to be deleted.

rev

string

The revision of the object to be deleted, or null if the object is not subject to revision control.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the object could not be deleted.

Note that delete is a reserved word in JavaScript and this function can therefore not be called in the usual manner. To call delete from a JavaScript, you must specify the call as shown in the following example:

openidm['delete']('managed/user/'+ user._id, user._rev)
            

Calling openidm.delete() directly from a JavaScript results in an error similar to the following:

                org.forgerock.openidm.script.ScriptException: missing name after . operator
            

F.3.6. openidm.query(id, params)

This function performs a query on the specified OpenIDM resource object.

Parameters
id

string

The identifier of the object to perform the query on.

params

object

An object containing the query ID and its parameters.

Returns
  • The result of the query. A query result includes the following parameters:

    "query-time-ms"

    The time, in milliseconds, that OpenIDM took to process the query.

    "conversion-time-ms"

    (For an OrientDB repository only) the time, in milliseconds, taken to convert the data to a JSON object.

    "result"

    The list of entries retrieved by the query. The result includes the revision ("_rev") of the entry and any other properties that were requested in the query.

    The following example shows the result of a custom query that requests the ID, user name, and email address of managed users in the repository. For an OrientDB repository, the query would be something like select _openidm_id, userName, email from managed_user,.

    {
      "conversion-time-ms": 0,
      "result": [
        {
          "email": "bjensen@example.com",
          "userName": "bjensen",
          "_rev": "0",
          "_id": "36bbb745-517f-4695-93d0-998e1e7065cf"
        },
        {
          "email": "scarter@example.com",
          "userName": "scarter",
          "_rev": "0",
          "_id": "cc3bf6f0-949e-4699-9b8e-8c78ce04a287"
        }
      ],
      "query-time-ms": 1
    }
                        
Throws
  • An exception is thrown if the given query could not be processed.

F.3.7. openidm.action(id, params, value)

This function performs an action on the specified OpenIDM resource object.

Parameters
id

string

The identifier of the object on which the action should be performed.

params

object

An object containing the parameters to pass to the action.

value

object

A value that can be provided to the action for processing.

Returns
  • The result of the action. May be null if no result is provided.

Throws
  • An exception is thrown if the given action could not be executed for any reason.

F.3.8. openidm.encrypt(value, cipher, alias)

This function encrypts a value.

Parameters
value

any

The value to be encrypted.

cipher

string

The cipher with which to encrypt the value, using the form "algorithm/mode/padding" or just "algorithm". Example: AES/ECB/PKCS5Padding.

alias

string

The key alias in the key store with which to encrypt the node.

Returns
  • The value, encrypted with the specified cipher and key.

Throws
  • An exception is thrown if the object could not be encrypted for any reason.

F.3.9. openidm.decrypt(value)

This function decrypts a value.

Parameters
value

any

The value to be decrypted.

Returns
  • A deep copy of the value, with any encrypted value decrypted.

Throws
  • An exception is thrown if the object could not be decrypted for any reason.

F.3.10. logger.debug(string message, object... params)

Logs a message at DEBUG level.

Parameters
message

string

The message format to log. Params replace {} in your message.

params

object

Arguments to include in the message.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the message could not be logged.

F.3.11. logger.error(string message, object... params)

Logs a message at ERROR level.

Parameters
message

string

The message format to log. Params replace {} in your message.

params

object

Arguments to include in the message.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the message could not be logged.

F.3.12. logger.info(string message, object... params)

Logs a message at INFO level.

Parameters
message

string

The message format to log. Params replace {} in your message.

params

object

Arguments to include in the message.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the message could not be logged.

F.3.13. logger.trace(string message, object... params)

Logs a message at TRACE level.

Parameters
message

string

The message format to log. Params replace {} in your message.

params

object

Arguments to include in the message.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the message could not be logged.

F.3.14. logger.warn(string message, object... params)

Logs a message at WARN level.

Parameters
message

string

The message format to log. Params replace {} in your message.

params

object

Arguments to include in the message.

Returns
  • A null value if successful.

Throws
  • An exception is thrown if the message could not be logged.

F.4. Places to Trigger Scripts

Scripts can be triggered at different places, by different events.

In openidm/conf/sync.json
Triggered by situation

onCreate, onUpdate, onDelete, onLink, onUnlink

Object filter

vaildSource, validTarget

Correlating objects

correlationQuery

Triggered on any reconciliation

result

Scripts inside properties

condition, transform

sync.json supports only one script per hook. If multiple scripts are defined for the same hook, only the last one is kept.

In openidm/conf/managed.json

onCreate, onRead, onUpdate, onDelete, onValidate, onRetrieve and onStore

managed.json supports only one script per hook. If multiple scripts are defined for the same hook, only the last one is kept.

In openidm/conf/router.json

onRequest, onResponse, onFailure

router.json supports multiple scripts per hook.

F.5. Variables Available in Scripts

The variables that are available to scripts depend on the triggers that launch the script. The following section outlines the available variables, per trigger.

condition

object

correlationQuery

source

Custom endpoint scripts

request

onCreate

object, source, target

onDelete

object

onLink

source, target

onRead

object

onRetrieve

object, property

onStore

object, property

onUnlink

source, target

onUpdate

oldObject, newObject

onValidate

object, property

result

source, target

synchronization situation scripts

recon.actionParam - the details of the synchronization operation in progress. This variable can be used for asynchronous callbacks to execute the action at a later stage.

sourceAction - a boolean that indicates whether the situation was assessed during the source phase

source (if found)

target (if found)

The properties from the configured script object.

taskScanner

input, objectID

transform

source

validSource

source

validTarget

target

F.6. Debugging OpenIDM Scripts

OpenIDM includes Eclipse JSDT libraries so you can use Eclipse to debug your OpenIDM scripts during development.

Procedure F.1. To Enable Debugging

Follow these steps to enable debugging using Eclipse.

  1. Install the environment to support JavaScript development in either of the following ways.

  2. Create an empty JavaScript project called External JavaScript Source in Eclipse.

    Eclipse then uses the External JavaScript Source directory in the default workspace location to store sources that it downloads from OpenIDM.

  3. Stop OpenIDM.

  4. Edit openidm/conf/boot/boot.properties to enable debugging.

    1. Uncomment and edit the following line.

      #openidm.script.javascript.debug=transport=socket,suspend=y,address=9888,trace=true
                              

      Here suspend=y prevents OpenIDM from starting until the remote JavaScript debugger has connected. You might therefore choose to set this to suspend=n.

    2. Uncomment and edit the following line.

      #openidm.script.javascript.sources=/Eclipse/workspace/External JavaScript Source/
                              

      Adjust /Eclipse/workspace/External JavaScript Source/ to match the absolute path to this folder including the trailing / character. On Windows, also use forward slashes, such asC:/Eclipse/workspace/External JavaScript Source/.

      Each time OpenIDM loads a new script, it then creates or overwrites the file in the External JavaScript Source directory. Before toggling breakpoints, be sure to refresh the source manually in Eclipse so you have the latest version.

  5. Prepare the Eclipse debugger to allow you to set breakpoints.

    In the Eclipse Debug perspective, select the Breakpoints tab, and then click the Add Script Load Breakpoint icon to open the list of scripts.

    In the Add Script Load Breakpoint window, select your scripts, and then click OK.

  6. Start OpenIDM, and connect the debugger.

    To create a new debug, configuration click Run > Debug Configurations... > Remote JavaScript > New button, and then set the port to 9888 as shown above.