Best Practices for Configuring Groovy Scripts Based Survivorship and Agreement Rules

In this topic we discuss the best practices for configuring groovy scripts.

  • If you configure your implementation to use Groovy Scripts for Set Master rules, merges aren't processed until a valid Set Master script has been deployed.

  • Any survivorship rules written using the Manage Survivorship Rules setup task which uses the Oracle Business Rules framework, continues to function if you don't enable groovy script survivorship rules.

  • For a given survivorship process type, such as Set Master or Agreement Rules, you can either use Groovy script or Oracle Business Rules. You can't combine the two frameworks for a single process type. For example you can't define one Set Master rule using Groovy Script and another Set Master rule using Oracle Business rules.

  • You can combine Oracle Business Rules and Groovy script between different survivorship process types, such as using Oracle Business Rules for Set Master logic and Groovy script for Set Attribute logic.

  • For best performance with attribute survivorship processing, try to use attribute source confidence as much as possible for your Set Attribute survivorship logic.

  • Merge request processing may handle very large volumes of records, so groovy scripts should be as fast and efficient as possible. Avoid using newView() functions and web service calls unless absolutely necessary; and if necessary, assure that these types of operations will be fast and reliable.

  • Select one of the Use source confidence Attribute Selection Type options from the Manage Customer Data Management Options setup page.

  • If needed, use Groovy script along with your source confidence configuration to handle exception scenarios.

Overview of Groovy Scripting Functions

Groovy Script support for configuring survivorship and agreement rules is based on a specific set of functions that let you interact with the data records in the context of a merge request. These functions are of the following categories:

  • Functions that let you inspect the records in the merge requests

  • Functions that let you define the result of the merge request

These categories of specialized functions help you to create survivorship and agreement rules using standard Groovy Script syntax and operations.

Input Functions

These functions provide the data that your survivorship and agreement rules evaluate. Generally, these functions are called at the beginning of your script to instantiate the information required to determine the proper merge process outputs.

getRuleType()

This function lets you determine the functional context of the script. This function returns SetAttribute, SetMaster, or Agreement depending on which type of script calls it. It's generally not necessary to programmatically determine the rule type because the script types are presented as distinct functions within the Application Composer Data Quality Rules task. But there may be cases where it's helpful for logging or testing.

getObjectType()

This function lets you determine what type of party the merge request is processing. This function returns PERSON or ORGANIZATION depending on which type of script calls it. It's generally not necessary to programmatically determine the object type because the scripts for Persons and Organizations are clearly differentiated as distinct functions within the Application Composer Data Quality Rules task. But there may be cases where it's helpful for logging or testing.

getMaster()

This function lets you access the data record that has been identified as the master record for the merge request. The function is called without parameters and it returns a single Row object that contains the details of the master record. The following example shows a typical usage of this function:

 def rowMaster = getMaster();
  def masterName = rowMaster.getAttribute("OrganizationName");
  // etc...

getNonMasters()

This function lets you access the set of data records that have been identified as the non-master records for the merge request because the merge process inactivates them. This function is called without parameters and it returns a list of row objects consisting of one list entry for each non-master record. It's important to note that the getNonMasters list isn't an ADF recordset object. ADF recordset functions such as reset() and first() don't work with the list. The following example shows a typical usage of this function:

 getNonMasters()
def rowNonMasters = getNonMasters();
   def nonmasterName;
   for (nonmaster in rowNonMasters) {
       nonmasterName = nonmaster.getAttribute("OrganizationName"); }
   // etc...
 

getRows()

This function lets you access the full set of customer records for the merge request, which is the union of the master and non-master sets of rows. This function is called without parameters and it returns a list of row objects consisting of one list entry for each non-master record. Like the getNonMasters function, it's important to note that the getRows list isn't an ADF recordset object. ADF recordset functions such as reset() and first() don't work with the list. The following example shows a typical usage of this function:

def rowDuplicates = getRows()
   def duplicateName;
   for (duplicate in rowDuplicates) {
      duplicateName = duplicate.getAttribute("OrganizationName"); }
    // etc...

getSourceInfo(Row row, String attributeName)

This function lets you access information about which source system provided the current value of an attribute for a given master or non-master row. This function is called using the following parameters:

  • A row object for the non-master or master row of interest

  • The name of a source-confidence configured attribute

This function returns a source information record for the attribute in question. The structure of the source information record is as follows:

Attribute

Definition

Example

RecordId

The party ID of the person or organization record referenced by the row object parameter.

300100184760397

AttributeName

The name of the attribute parameter.

OrganizationName

AttributeValue

The current value of the attribute on the row.

Pinnacle Systems

Source

The code of the registered source system for the attribute value.

RNOW

SourceConfidenceLevel

The configured attribute source confidence value of the given attribute for the given source system.

90

SourceUpdateDate

The time stamp when the person or organization record was updated with the current value.

1/24/2020 11:48:03 PM

Note: The getSourceInfo function is only available for attributes that have been configured with source system confidence using the Manage Source System Confidence setup task.

The following example shows a typical usage of this function:

    def rowDuplicates = getRows();
    def rowSource;
    def bestSource;
    def bestValue;
    bestSource = getSourceInfo(rowDuplicates[0],"OrganizationName");
    for (row in rowDuplicates) {
      rowSource = getSourceInfo(row,"OrganizationName");
      if(rowSource.SourceConfidenceLevel > bestSource.SourceConfidenceLevel) {
        bestSource = rowSource;
      }  
    }
    bestValue = bestSource.AttributeValue;

Output Functions

Output functions create the final behavior of the merge process based on the logic of a survivorship or agreement rule script. Generally, these functions are called at the end of the script after the data provided by the input functions has been evaluated with scripted logic.

selectMaster(Row row)

This function is used in Contact Set Master and Account Set Master scripts to specify which record from the merge request should be retained as the master record after the merge. This function takes a data Row instance as its only parameter, and whatever row is passed to the function is the record that's retained as the master. All other records in the merge request are inactivated during merge processing. The following example shows a typical usage of this function:

...
    def masterRow = rowDuplicates[0];
    for (row in rowDuplicates) {
      if row.LastUpdateDate > masterRow.LastUpdateDate {
        masterRow = row;
      }
    }
    selectMaster(masterRow);

selectAttribute(String attributeName, Row row)

This function is used in Contact Set Attributes and Account Set Attributes scripts to define which attribute value instances from across the records in the merge should be used to build the master record. This function takes the name of an attribute and a Row instance as its parameters. The value for the given parameter that's found in the given row is retained on the master record. This function is logically equivalent to using the Duplicate Resolution override flow to select the source record for a given attribute. The following example shows the syntax of this function:

    def rowDuplicates = getRows();
    def bestSourceRow;
    def fieldName = "OrganizationName";
    rowBestSource = rowDuplicates[0];
    for (row in rowDuplicates) {
       if(getSourceInfo(row, fieldName).SourceConfidenceLevel > getSourceInfo(rowBestSource, fieldName).SourceConfidenceLevel) {
          rowBestSource = row;}
    }
    selectAttribute(fieldName, rowBestSource);

overrideAttribute(String attributeName, Object attributeValue)

This function is used in Contact Set Attribute and Account Set Attribute rules to specify an attribute value for the master record, which can't be derived in the normal fashion from the records in the merge request. This function takes the name of an attribute and the value for the attribute as its parameters and sets the final value of the master record's given field to the given value. This function is logically equivalent to using the Duplicate Resolution Override flow to enter your own value for a given attribute.

Note: Ensure that the value's data type and format are correct because this function sets an externally-defined value.

The following example shows the syntax for this function:

def fieldName = "OrganizationName";
    def fieldValue = "Pinnacle Systems";
    overrideAttribute(fieldName, fieldValue);

This function is used in Contact Agreement Rule and Account Agreement Rule scripts to veto a merge request if a specified set of conditions are observed in the merge request's records. This function takes a single parameter which defines the rejection message that's displayed on the merge request if the rejection criteria are met. The following example shows the syntax for this function:

def rowNonMasters = getNonMasters;
    for (row in rowNonMasters) {
        if (row.value != null) {
            rejectRequest("Unable to merge contacts that have this value");}
    }

Evaluating the Data

Once you have called the appropriate functions, your survivorship or agreement rules script need to evaluate the data to determine the correct merge result. This evaluation process uses standard Groovy Script operators and functions. For more information about Groovy scripts, see the Oracle Applications Cloud Groovy Scripting Reference guide.

Putting It Together

You can generally follow this pattern in groovy scripting:

  1. Call Input Functions

  2. Evaluate the Data

  3. Call Output Functions

To further illustrate this concept, the following is a simple script to determine the master record for a merge request based on the most recent Last Updated Date from the records:

/* Input Functions: call getRows() to initialize a list of the party records in the merge request and then
define a variable to designate the Master record and set it to the first record in the list of Rows */
    def rowDuplicates = getRows();  
    def masterRow = rowDuplicates[0]; 
/* Evaluate the Data: iterate through the list of records to determine if the current list item 
was more recently updated than whatever record has been designated the master.  If the current record was more recently updated, 
promote it to become the new Master */
    for (row in rowDuplicates) {
      if (row.LastUpdateDate > masterRow.LastUpdateDate) {
        masterRow = row; 
      }
    }
/* Call Output Functions: use the selectMaster() function to dictate which record from the merge set 
should become the master */
    selectMaster(masterRow);

Best Practices for Groovy Scripting

Consider the following points when planning and configuring your survivorship and agreement rules using groovy scripts:

  • The Rows returned by the getRows(), getNonMasters(), and getMaster() functions is a standard Groovy Script list object, not an Oracle ADF recordset object. You must use standard Groovy methods for traversing the recordset such as for (item in list) instead of ADF functions such as reset(), first(), or hasNext().

  • The responses of the getRows(), getNonMasters(), or getMaster() functions are cached for each script execution. So the data state of row objects of your scripts don't show any changes within the scope of a script execution.

  • The result of a Set Master script is reflected in the response to getNonMasters() or getMaster() functions called in Set Attribute or Agreement Rules scripts.

  • You can't access the Resolution Request header object in your survivorship scripts. The only supported means for initializing data objects in your scripts are the input functions described in this topic.

  • The selectAttribute() and overrideAttribute() functions can be used on top-level attributes of the Row object. Fields that contain embedded child record collections can't be manipulated with these functions.

  • You can interact with custom attributes and custom child objects by using the API name for the attribute or object that was specified when the custom entity was created in Application Composer.

  • The script fragments provided in this topic are intended to illustrate the syntax and usage of the Input and Output functions. Refer to the Sample Scripts section for examples of complete scripts.

  • Some Best Practices for writing Groovy Scripts are available in the Performance Best Practices for Using Scripts section of Performance Best Practices for Extending Oracle CX Sales and Fusion Service (Doc ID 2170121.1) on My Oracle Support: https://support.oracle.com/epmos/faces/DocumentDisplay?id=2170121.1

  • The Groovy Script survivorship and agreement rule templates should only be used to configure Set Master, Attribute Survivorship and Agreement rules. Use of these templates for general processing extension or automation isn't supported and may cause incorrect or unpredictable behavior.