- 03 Jun 2023
- 7 Minutes to read
- Print
- DarkLight
Studio Expressions
- Updated on 03 Jun 2023
- 7 Minutes to read
- Print
- DarkLight
Studio Expressions
Studio expressions operate within a Mozilla Rhino 1.7.12 run context, similar to RapidIdentity Connect Action Sets. That means you can use arbitrary JavaScript within Studio expressions, at the same ECMAScript level as RapidIdentity Connect.
Whereas Connect has a run context containing all of the available actions as well as special variables, like Global, Studio has its own unique set of variables available.
These variables will be listed below.
LOGGER Variable
The LOGGER
variable provides a handle on the Studio job logger. You can use the variable to print logs from a Studio expression. Supported methods include:
trace(object)
Emits a string version of the object
to the job log at TRACE
level if the job log level is at TRACE
.
Examples:
LOGGER.trace("Hello, world!")
LOGGER.trace("Source record key: " + SRC.recordKey[0])
LOGGER.trace(SRC.org)
LOGGER.trace(SRC.listRecords("org", null, 1000).length)
debug(object)
Emits a string version of the object
to the job log at DEBUG
level if the job log level is at DEBUG
or lower.
Examples:
LOGGER.debug("Hello, world!")
LOGGER.debug("Source record key: " + SRC.recordKey[0])
LOGGER.debug(SRC.org)
LOGGER.debug(SRC.listRecords("org", null, 1000).length)
info(object)
Emits a string version of the object
to the job log at INFO
level if the job log level is at INFO
or lower.
Examples:
LOGGER.info("Hello, world!")
LOGGER.info("Source record key: " + SRC.recordKey[0])
LOGGER.info(SRC.org)
LOGGER.info(SRC.listRecords("org", null, 1000).length)
warn(object)
Emits a string version of the object
to the job log at WARN
level if the job log level is at WARN
or lower.
Examples:
LOGGER.warn("Hello, world!")
LOGGER.warn("Source record key: " + SRC.recordKey[0])
LOGGER.warn(SRC.org)
LOGGER.warn(SRC.listRecords("org", null, 1000).length)
error(object)
Emits a string version of the object
to the job log at ERROR
level if the job log level is at ERROR
or lower.
Examples:
LOGGER.error("Hello, world!")
LOGGER.error("Source record key: " + SRC.recordKey[0])
LOGGER.error(SRC.org)
LOGGER.error(SRC.listRecords("org", null, 1000).length)
HASH Variable
The HASH
variable provides a handle on a hashing helper. Supported methods include:
crc32(toHash[, salt])
CRC32 is a not a secure hash function. Never use for sensitive use cases.
Takes a string toHash
and an optional salt
string and returns a CRC32 hash string (hex encoded).
Example:
HASH.crc32(SRC.recordKey[0])
md5(toHash[, salt])
MD5 is a not a secure hash function. Never use for sensitive use cases.
Takes a string toHash
and an optional salt
string and returns a MD5 hash string (Base64 encoded).
Example:
HASH.md5(SRC.recordKey[0])
sha1(toHash[, salt])
SHA-1 is a not a secure hash function. Never use for sensitive use cases.
Takes a string toHash
and an optional salt
string and returns a SHA-1 hash string (Base64 encoded).
Example:
HASH.sha1(SRC.recordKey[0])
sha256(toHash[, salt])
Takes a string toHash
and an optional salt
string and returns a SHA-256 hash string (Base64 encoded).
Example:
HASH.sha256(SRC.recordKey[0])
sha384(toHash[, salt])
Takes a string toHash
and an optional salt
string and returns a SHA-384 hash string (Base64 encoded).
Example:
HASH.sha384(SRC.recordKey[0])
sha512(toHash[, salt])
Takes a string toHash
and an optional salt
string and returns a SHA-512 hash string (Base64 encoded).
Example:
HASH.sha512(SRC.recordKey[0])
SRC Variable
The SRC
variable is a Studio Scriptable Record object. That means it functions as both:
A handle on the matched source record, if one was found
- One is always present unless this is a
delete
event. See Studio Mappings, Matching, and Event Governance for more information.
- One is always present unless this is a
A handle on the source namespace
We will cover Scriptable Record objects, including all allowed fields and methods, after introducing the other variable of this type.
(Deprecated) This variable may also be referenced as SOURCE
. Prefer SRC
.
DEST Variable
The DEST
variable is a Studio Scriptable Record object. That means it functions as both:
A handle on the matched destination record, if one was found
- One is always present unless this is a
create
event. See Studio Mappings, Matching, and Event Governance for more information.
- One is always present unless this is a
A handle on the destination namespace
Scriptable Records
As covered above, both SRC
and DEST
are instances of Scriptable Records. All Scriptable Records support the following methods:
get(fieldName)
The get
method on a record takes a fieldName
and returns an array containing the field values. The result array will be empty if no values could be found.
Examples:
// All three of the following return an array like ["<recordKey>"]
SRC.get("recordKey")
SRC["recordKey"]
SRC.recordKey // most idiomatic way
The same examples hold for DEST
. Note that if the record is not present (as is the case for SRC
on a delete event, or DEST
on a create event), the result will be an empty array.
Since the return value is an array, you often need to reference the first element to use the value in operations, e.g. SRC.recordKey[0]
to get the actual string value.
getRecord(id)
The getRecord
method can take an id
(i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in SRC["@id"][0])
and will return either the Scriptable Record that was found or null otherwise.
Example:
SRC.getRecord("13e285d1-2d40-43fb-b766-ee8cf8b1bd96")
getRecord(typeName, recordKey)
The getRecord
method can also take a typeName
(as shown in the Data Explorer or the Record Definition) and a recordKey value. It will return either the Scriptable Record that was found or null otherwise.
For an example, if the SRC
record is an ID Hub user, then you could do the following to get the associated ID Hub org, assuming at least one org is present on the user record:
SRC.getRecord("org", SRC.org[0])
getRecord(typeName, fieldName, fieldValue)
The getRecord
method can also take a typeName
(as shown in the Data Explorer or the Record Definition), fieldName
, and a fieldValue
to perform a search on a different field (the search will look up the record within the type where the given field is equal to the given value). It will return either the first such Scriptable Record that was found or null otherwise.
Example:
SRC.getRecord("org", "name", "Identity High School")
getRecords(ids)
The getRecords
method takes an array of ids
(i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in SRC["@id"][0])
and will return an array of Scriptable Records that match (an empty array will be returned if no matches are found).
Example:
SRC.getRecords(["13e285d1-2d40-43fb-b766-ee8cf8b1bd96", "39a1e87c-7f4a-412f-af7c-e11bd24ff3a1"])
getRecords(typeName, fieldName, fieldValue[, maxResults])
The getRecords
method can also take a typeName
(as shown in the Data Explorer or the Record Definition), fieldName
, and a fieldValue
to perform a search on a different field (the search will look up the records within the type where the given field is equal to the given value). It will return an array of Scriptable Records that match (an empty array will be returned if no matches are found).
Only the first three args (typeName
, fieldName
, and fieldValue
) are required.
If the maxResults
integer is supplied, then the result array will have, at most, maxResults
elements. The default value for maxResults
, if not specified, is 100.
Examples:
// pull back up to 100 user records from the specified org
SRC.getRecords("user", "org", "96ba55e0-7411-4769-b133-3e5755a968a9")
// pull back at most 1 user record from the specified org
SRC.getRecords("user", "org", "96ba55e0-7411-4769-b133-3e5755a968a9", 1)
listRecords(typeName[, filter, maxResults, orderBy, firstResultIndex])
The listRecords
method allows you to pull back an array of Scriptable Records matching complex criteria (similar to the Data Explorer). If no matching records are found, the result will be an empty array.
The only required argument is typeName
(as shown in the Data Explorer or the Record Definition).
Beyond that, any sublist of the following args can optionally be supplied:
filter
an optional filter string using the same syntax as the Data Explorer- Default: null, meaning all records, up to the
maxResults
limit will be supplied
- Default: null, meaning all records, up to the
maxResults
an optional integer limiting the result array size- Default: 1000
orderBy
an optional string specifying which field to order the results byNOTE:Do not use this unless you really need the results to be ordered, as there is an associated performance overhead with sorting records
- Default: null, meaning the results will be ordered by id (i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in
SRC["@id"][0]
)
- Default: null, meaning the results will be ordered by id (i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in
firstResultIndex
an optional integer specifying the index of the first record to skip to in the ordered result set (starting with 1, not 0)
Examples:
// pull back up to 1000 users
SRC.listRecords("user")
// pull back up to 1000 users with the given name Alice
SRC.listRecords("user", "givenName = Alice")
// pull back up to 2 users with the email asmith@idauto.edu
SRC.listRecords("user", "email = asmith@idauto.edu", 2)
// pull back up to 100 users ordered by givenName
SRC.listRecords("user", null, 100, "givenName")
// pull back the next page of 100 users ordered by givenName (i.e. the second set of 100)
SRC.listRecords("user", null, 100, "givenName", 100)
applyAccessGroups(records)
The applyAccessGroups
method takes an array of Scriptable Records and returns an array containing only the records that make it through any active, configured Access Groups. Note: this only actually does anything for the SRC
variable on a consumer mapping.
Example:
// pulls back up to 1000 org records from the source, then filters them using any
// configured Access Groups, returning only the orgs permitted by the Access Groups
SRC.applyAccessGroups(SRC.listRecords("org", null, 1000))