appendix-scripting.xml revision 7b85693a3ced68e4f3697280b999a5a710b7a17d
<?xml version="1.0" encoding="UTF-8"?>
<!--
! CCPL HEADER START
!
! This work is licensed under the Creative Commons
! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
! To view a copy of this license, visit
! or send a letter to Creative Commons, 444 Castro Street,
! Suite 900, Mountain View, California, 94041, USA.
!
! You can also obtain a copy of the license at
! See the License for the specific language governing permissions
! and limitations under the License.
!
! If applicable, add the following below this CCPL HEADER, with the fields
! enclosed by brackets "[]" replaced with your own identifying information:
! Portions Copyright [yyyy] [name of copyright owner]
!
! CCPL HEADER END
!
! Copyright 2011-2014 ForgeRock AS
!
-->
<appendix xml:id="appendix-scripting"
version="5.0"
xml:lang="en"
xmlns="http://docbook.org/ns/docbook"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Scripting Reference</title>
<indexterm>
<primary>Scripting</primary>
</indexterm>
<para>
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.
</para>
<para>
OpenIDM ${docTargetVersion} supports scripts written in JavaScript and
Groovy. OpenIDM configures script options in the
</para>
<section xml:id="scripting-configuration">
<title>Scripting Configuration</title>
<para>
OpenIDM includes several default scripts in the following directory:
or remove any of the scripts in this directory, as OpenIDM needs these
scripts to run specific services. Scripts in this folder are not guaranteed
to remain constant between product releases.
</para>
<para>
If you develop custom scripts, copy them to the <literal>script/</literal>
directory for your project, such as
</para>
<section xml:id="script-json">
<title>Script Configuration File</title>
<para>
OpenIDM ${docTargetVersion} includes a script configuration file
in the <filename>conf/</filename> directory,
xlink:href="integrators-guide#config-default-directories">
<citetitle>Default and Custom Configuration Directories</citetitle>
</link>.
</para>
<para>
The properties shown in the default version of the
</para>
<variablelist>
<varlistentry>
<term>properties</term>
<listitem>
<para>
Additional custom properties.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ECMAScript</term>
<listitem>
<para>
JavaScript is an ECMAScript language.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
See <xref linkend="debugging-scripts" />
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Minimum time after which a script can be recompiled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Specifies a log level for Groovy scripts.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Defines the encoding format for Groovy scripts.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Specifies the output directory.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Specifies the output bytecode.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Defines directories with Groovy class files.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Specifies the verbosity of stack traces.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Sets debugging status.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Sets number of non-fatal errors before aborting a compilation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Defines the file extension for a Groovy script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Defines the base class for the script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Allows a script to be recompiled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Minimum time between when Groovy scripts can be compiled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Defines whether a Groovy indy test can be used.
</para>
</listitem>
</varlistentry>
<varlistentry>
<listitem>
<para>
Notes whether Groovy Abstract Syntax Transformations (AST)s are
disabled.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
discussed in the section on <link xlink:show="new"
xlink:role="http://docbook.org/xlink/role/olink"
xlink:href="integrators-guide#config-default-directories">
<citetitle>Default and Custom Configuration Directories</citetitle></link>.
</para>
</section>
<section xml:id="script-call">
<title>Calling A Script From Another Configuration File</title>
<programlisting language="javascript">
{
"type" : "text/javascript",
"source": <replaceable>string</replaceable>
} </programlisting>
<para>or</para>
<programlisting language="javascript">
{
"type" : "text/javascript",
"file" : <replaceable>file location</replaceable>
} </programlisting>
<variablelist>
<varlistentry>
<term>type</term>
<listitem>
<para>string, required</para>
<para>
Specifies the type of script to be executed. Supported types include
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>source</term>
<listitem>
<para>string, required if file is not specified</para>
<para>
Specifies the source code of the script to be executed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>file</term>
<listitem>
<para>string, required if source is not specified</para>
<para>
Specifies the file containing the source code of the script to execute.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
<section xml:id="scripting-example">
<title>Examples</title>
<para>
returns <literal>true</literal> if the <literal>employeeType</literal> is
equal to <literal>external</literal>, otherwise returns
<literal>false</literal>. This script can be useful during reconciliation to
establish whether the source object should be a part of the reconciliation,
or ignored.
</para>
<programlisting language="javascript">
"validTarget": {
"type" : "text/javascript",
"source": "target.employeeType == 'external'"
} </programlisting>
<para>
sets the <literal>__PASSWORD__</literal> attribute to
<literal>defaultpwd</literal> when OpenIDM creates a target object.
</para>
<programlisting language="javascript">
"onCreate" : {
"type" : "text/javascript",
"source": "target.__PASSWORD__ = 'defaultpwd'"
} </programlisting>
<para>
file) shows a trigger to create Solaris home directories using a script. The
script is located in a file,
</para>
<programlisting language="javascript">
{
"filters" : [ {
"methods" : [ "create" ],
"onResponse" : {
"type" : "text/javascript",
"file" : "script/createUnixHomeDir.js"
}
} ]
} </programlisting>
</section>
<section xml:id="function-ref">
<title>Function Reference</title>
<indexterm>
<primary>Objects</primary>
<secondary>Script access</secondary>
</indexterm>
<indexterm>
<primary>Scripting</primary>
<secondary>Functions</secondary>
</indexterm>
<para>
Functions (access to managed objects, system objects, and configuration
objects) within OpenIDM are accessible to scripts via the
<literal>openidm</literal> object, which is included in the top-level scope
provided to each script.
</para>
<para>
OpenIDM also provides a <literal>logger</literal> object to access SLF4J
facilities. The following code shows an example:
</para>
<programlisting language="javascript">
logger.info("Parameters passed in: {} {} {}", param1, param2, param3);
</programlisting>
<para>To set the log level, use
</para>
<section xml:id="function-create">
<para>This function creates a new resource object.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>container</term>
<listitem>
<para>string</para>
<para>
The resource container in which the object will be
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>
The identifier of the object to be created, if the
client is supplying the ID. If the server should
generate an ID, pass null here.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>value</term>
<listitem>
<para>object</para>
<para>The value of the object to be created.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The created OpenIDM resource object.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be created.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-patch">
<para>This function performs a partial modification of a managed
object. Unlike the <literal>update</literal> function, only the
modified attributes are provided, not the entire object.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the object to be updated.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>rev</term>
<listitem>
<para>string</para>
<para>The revision of the object to be updated, or
<literal>null</literal> if the object is not subject
to revision control.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>value</term>
<listitem>
<para>object</para>
<para>The value of the modifications to be applied to
the object.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The modified OpenIDM resource object.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be updated.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-read">
<para>This function reads and returns an OpenIDM resource object.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the object to be read.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The read OpenIDM resource object, or <literal>null</literal>
if not found.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-update">
<para>This function updates a resource object.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the resource object to be updated.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>rev</term>
<listitem>
<para>string</para>
<para>The revision of the object to be updated, or
<literal>null</literal> if the object is not subject to revision control.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>value</term>
<listitem>
<para>object</para>
<para>The value of the object to be updated.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The modified OpenIDM resource object.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be updated.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-delete">
<para>This function deletes a resource object.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the object to be deleted.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>rev</term>
<listitem>
<para>string</para>
<para>The revision of the object to be deleted, or
<literal>null</literal> if the object is not subject to revision control.
</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A <literal>null</literal> value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be deleted.
</para>
</listitem>
</itemizedlist>
<para>Note that <literal>delete</literal> 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:
</para>
<programlisting language="javascript">
</programlisting>
results in an error similar to the following:
</para>
<screen>
</screen>
</section>
<section xml:id="function-query">
<para>This function performs a query on the specified OpenIDM resource object.
</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the object to perform the query on.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>An object containing the query ID and its parameters.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The result of the query. A query result includes the following
parameters:
</para>
<variablelist>
<varlistentry>
<term>"query-time-ms"</term>
<listitem>
<para>The time, in milliseconds, that OpenIDM took to process
the query.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>"conversion-time-ms"</term>
<listitem>
<para>(For an OrientDB repository only) the time, in
milliseconds, taken to convert the data to a JSON object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>"result"</term>
<listitem>
<para>The list of entries retrieved by the query. The result
includes the revision (<literal>"_rev"</literal>) of the
entry and any other properties that were requested in the
query.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>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
<literal>select _openidm_id, userName, email from managed_user,</literal>.
</para>
<programlisting language="javascript">
{
"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
}
</programlisting>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the given query could not be processed.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-action">
<para>This function performs an action on the specified OpenIDM resource
object.
</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>id</term>
<listitem>
<para>string</para>
<para>The identifier of the object on which the action should be
performed.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>An object containing the parameters to pass to the action.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>value</term>
<listitem>
<para>object</para>
<para>A value that can be provided to the action for processing.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The result of the action. May be <literal>null</literal> if
no result is provided.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the given action could not be executed
for any reason.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-encrypt">
<para>This function encrypts a value.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>value</term>
<listitem>
<para>any</para>
<para>The value to be encrypted.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>cipher</term>
<listitem>
<para>string</para>
<para>The cipher with which to encrypt the value, using the form
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>alias</term>
<listitem>
<para>string</para>
<para>The key alias in the keystore with which to encrypt the node.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>The value, encrypted with the specified cipher and key.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be encrypted for any
reason.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-decrypt">
<para>This function decrypts a value.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>value</term>
<listitem>
<para>any</para>
<para>The value to be decrypted.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A deep copy of the value, with any encrypted value decrypted.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the object could not be decrypted for any
reason.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-logger-debug">
<para>Logs a message at DEBUG level.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>message</term>
<listitem>
<para>string</para>
<para>The message format to log. Params replace <literal>{}</literal>
in your message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>Arguments to include in the message.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A <literal>null</literal> value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the message could not be logged.</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-logger-error">
<para>Logs a message at ERROR level.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>message</term>
<listitem>
<para>string</para>
<para>The message format to log. Params replace <literal>{}</literal>
in your message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>Arguments to include in the message.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A <literal>null</literal> value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the message could not be logged.</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-logger-info">
<para>Logs a message at INFO level.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>message</term>
<listitem>
<para>string</para>
<para>The message format to log. Params replace
<literal>{}</literal>
in your message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>Arguments to include in the message.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A
<literal>null</literal>
value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the message could not be logged.</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-logger-trace">
<para>Logs a message at TRACE level.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>message</term>
<listitem>
<para>string</para>
<para>The message format to log. Params replace
<literal>{}</literal>
in your message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>Arguments to include in the message.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A
<literal>null</literal>
value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the message could not be logged.</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="function-logger-warn">
<para>Logs a message at WARN level.</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term>message</term>
<listitem>
<para>string</para>
<para>The message format to log. Params replace
<literal>{}</literal>
in your message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>params</term>
<listitem>
<para>object</para>
<para>Arguments to include in the message.</para>
</listitem>
</varlistentry>
</variablelist>
<itemizedlist>
<title>Returns</title>
<listitem>
<para>A <literal>null</literal> value if successful.
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<title>Throws</title>
<listitem>
<para>An exception is thrown if the message could not be logged.</para>
</listitem>
</itemizedlist>
</section>
</section>
<section xml:id="script-places">
<title>Places to Trigger Scripts</title>
<para>Scripts can be triggered at different places, by different events.
</para>
<variablelist>
<varlistentry>
</term>
<listitem>
<variablelist>
<varlistentry>
<term>Triggered by situation</term>
<listitem>
<para>onCreate, onUpdate, onDelete, onLink, onUnlink</para>
</listitem>
</varlistentry>
<!-- what of postCreate, postUpdate, postDelete? -->
<varlistentry>
<term>Object filter</term>
<listitem>
<para>vaildSource, validTarget</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Correlating objects</term>
<listitem>
<para>correlationQuery</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Triggered on any reconciliation</term>
<listitem>
<para>result</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Scripts inside properties</term>
<listitem>
<para>condition, transform</para>
per hook. If multiple scripts are defined for the same hook, only the last
one is kept.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
</term>
<listitem>
<para>onCreate, onRead, onUpdate, onDelete, onValidate,
onRetrieve, onStore, postCreate, postUpdate, and postDelete
</para>
per hook. If multiple scripts are defined for the same hook, only the last
one is kept.
</para>
</listitem>
</varlistentry>
<varlistentry>
</term>
<listitem>
<para>onRequest, onResponse, onFailure</para>
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="script-variables">
<title>Variables Available in Scripts</title>
<para>The variables that are available to scripts depend on the triggers
that launch the script. The following section outlines the available
variables, per trigger.
</para>
<variablelist>
<varlistentry>
<term>condition</term>
<listitem>
<para>object</para>
</listitem>
</varlistentry>
<varlistentry>
<term>correlationQuery</term>
<listitem>
<para>source</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Custom endpoint scripts</term>
<listitem>
<para>request</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onCreate, postCreate</term>
<listitem>
<para>object, source, target</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onDelete, postDelete</term>
<listitem>
<para>object</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onLink</term>
<listitem>
<para>source, target</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onRead</term>
<listitem>
<para>object</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onRetrieve</term>
<listitem>
<para>object (when called from either an object or a
property storage trigger); property (only when
called from a property storage trigger)</para>
<para>
As a property, returns the modified property values from the
script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onStore</term>
<listitem>
<para>object, property</para>
<para>
As a property, returns the modified property values from the
script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onUnlink</term>
<listitem>
<para>source, target</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onUpdate, postUpdate</term>
<listitem>
<para>oldObject, newObject</para>
</listitem>
</varlistentry>
<varlistentry>
<term>onValidate</term>
<listitem>
<para>object, property</para>
</listitem>
</varlistentry>
<varlistentry>
<term>propertyName</term>
<listitem>
<para>
Name of the property that is changed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>result</term>
<listitem>
<para>source, target</para>
</listitem>
</varlistentry>
<varlistentry>
<term>synchronization situation scripts</term>
<listitem>
the synchronization operation in progress. This variable can
be used for asynchronous callbacks to execute the action at
a later stage.</para>
<para><literal>sourceAction</literal> - a boolean that
indicates whether the situation was assessed during the source phase</para>
<para><literal>source</literal> (if found)</para>
<para><literal>target</literal> (if found)</para>
<para>The properties from the configured script object.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>taskScanner</term>
<listitem>
<para>input, objectID</para>
</listitem>
</varlistentry>
<varlistentry>
<term>transform</term>
<listitem>
<para>source</para>
</listitem>
</varlistentry>
<varlistentry>
<term>validSource</term>
<listitem>
<para>source</para>
</listitem>
</varlistentry>
<varlistentry>
<term>validTarget</term>
<listitem>
<para>target</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="debugging-scripts">
<title>Debugging OpenIDM JavaScripts</title>
<para>
OpenIDM includes Eclipse JSDT libraries so you can use Eclipse to debug
your OpenIDM JavaScripts during development.
</para>
<procedure xml:id="enable-debugging">
<title>To Enable Debugging</title>
<para>
Follow these steps to enable debugging using Eclipse.
</para>
<step>
<para>
Install the environment to support JavaScript development in either of
the following ways.
</para>
<stepalternatives>
<step>
<para>
Download and install Eclipse IDE for JavaScript Web Developers from
xlink:show="new">Eclipse download page</link>.
</para>
</step>
<step>
<para>
xlink:show="new">JavaScript Development Tools</link> to your existing
Eclipse installation.
</para>
</step>
</stepalternatives>
</step>
<step>
<para>
Create an empty JavaScript project called <literal>External JavaScript
Source</literal> in Eclipse.
</para>
<para>
Eclipse then uses the <filename>External JavaScript Source</filename>
directory in the default workspace location to store sources that it
downloads from OpenIDM.
</para>
</step>
<step>
<para>
Stop OpenIDM.
</para>
</step>
<step>
<para>
debugging.
</para>
<substeps>
<step>
<para>
Uncomment and edit the following line.
</para>
<programlisting>
#openidm.script.javascript.debug=transport=socket,suspend=y,address=9888,trace=true
</programlisting>
<para>
Here <literal>suspend=y</literal> prevents OpenIDM from starting until
the remote JavaScript debugger has connected. You might therefore
choose to set this to <literal>suspend=n</literal>.
</para>
</step>
<step>
<para>
Uncomment and edit the following line.
</para>
<programlisting>
</programlisting>
<para>
to match the absolute path to this folder including the trailing
<literal>/</literal> character. On Windows, also use forward slashes,
</para>
<para>
Each time OpenIDM loads a new script, it then creates or overwrites
the file in the <filename>External JavaScript Source</filename>
directory. Before toggling breakpoints, be sure to refresh the source
manually in Eclipse so you have the latest version.
</para>
</step>
</substeps>
</step>
<!-- Fix for OPENIDM-566: JavaScript debugger configuration description refinement -->
<step>
<para>Prepare the Eclipse debugger to allow you to set breakpoints.</para>
<para>In the Eclipse Debug perspective, select the Breakpoints tab, and
then click the Add Script Load Breakpoint icon to open the list of
scripts.
</para>
<para>In the Add Script Load Breakpoint window, select your scripts, and
then click OK.
</para>
</step>
<step>
<para>Start OpenIDM, and connect the debugger.</para>
<para>To create a new debug, configuration click Run > Debug
Configurations... > Remote JavaScript > New button, and then set
the port to 9888 as shown above.
</para>
</step>
</procedure>
</section>
</appendix>