Accelerate the Value of Data

Overview of Workflow Customizations

Learn how to customize a workflow.

Define a New Business Process

Define a new business process and/or create custom JAR files to customize a workflow. For more information, see the Workflow Web-based Modeller.

Create Custom JAR Files

This section contains information about the requirements, resources, and steps for creating custom JAR files.

Required Resources
  • Java 11 is required if you want to create your own action, listener, or validator classes that will be packed in a JAR file.
  • The Workflow Service Public Repository helps you to create the customizations. Use the Out-of-the-box (OOTB) process definitions which are available on every tenant. For more information, see Workflow Service Public Repository.

Custom Workflow

There are two main types of tasks that are used in the workflow:
  1. User tasks
  2. Service tasks

User tasks represent steps in the workflow that will show up in the Inbox and require a user's action, such as data validation or profile approval.

Service tasks are steps in the workflow that are not displayed in the UI and do some programmatic action. These steps invoke a Java class that is written to do actions. Examples of such actions are deleting a profile, merging profiles, or editing attributes.

Roles and Security

Roles

Workflow requires users to have the workflow user role (ROLE_WORKFLOW) enabled.

All workflows are public, but if you are a workflow assignee you can take action on a workflow. Workflows can be applied to Profiles and Potential Matches. You can configure the workflow owner and assignee to receive email notifications on when tasks are assigned, approved, or rejected.

Workflow Management

You can use the Workflow Web-based Modeler to define and modify the business processes. You can import an existing BPMN XML file or create process definitions through the Workflow Web-based Modeler user interface and deploy the process definition to a specific tenant.

Workflow Service Public Repository

The Workflow Service Public Repository is available at: https://bitbucket.org/reltio-ondemand/workflow. This repository contains the following items:

  • Public API for Workflow Custom JARs
  • Source code of default Reltio service task delegates (Approve Change Request, Delete Entity, etc.)
  • Default process definitions that are available on every tenant
  • Samples of new/customized process definitions with Java source code of additional classes

Review the Readme files in the repository for information about using these resources.

Creating Custom JAR Files - Steps

To create custom JAR files:

  1. Customize the Listener.
    1. Create a new Java file. For example, CustomTaskStartEventListener.java.
    2. Implement the WorkflowTaskListener interface to create listeners of specific user tasks.
    3. Implement the WorkflowExecutionListener interface to create listeners of specific service tasks. Examples of implementations can be found in the workflow-custom folder of the Workflow Service Public Repository.

      Business Process Model and Notation (BPMN), which is the standard language for process applications. For more information, see Business Process Model and Notation

    4. Open the BPMN diagram in Workflow Modeler. For more information, see the Workflow Web-based Modeler.
    5. Change the classpath of the listener implementation. Select a task to be modified, open the Listeners tab, and edit the Java Class attribute value:

      Example:

      <userTask> 
          ... 
              <activiti:taskListener event="create" class="com.reltio.workflow.activiti.service.CustomTaskStartEventListener">
          ...
      </userTask>
    6. Publish the updated BPMN diagram.
  2. Customize the validator.
    1. Create a new Java file (for example CustomPotentialMatchTaskValidator.java). You can create a new file from a copy of one of the example validator files.
    2. Open the BPMN diagram in the Workflow Modeler. (See the Workflow Web-based Modeler topic for more information .)
    3. Change the classpath of the validator implementation. Select a task to be modified, open the Form tab, and edit the Default Value of the Validator form field.
      Example:
      <userTask>
       ...
        <activiti:formProperty id="validator" name="Validator" type="string" writable="false" 
      default="com.reltio.workflow.activiti.service.validator.CustomPotentialMatchTaskValidator">
      ...
      </userTask>
    4. Publish the updated BPMN diagram. For details see Workflow Configuration Guide.
      Note: You must be assigned the ROLE_WORKFLOW_MANAGER role to publish process definitions.
      Example
      By default, PotentialMatchTaskValidator service task logs errors and info messages using the Logger mechanism. Suppose we need to get log info output also to the console. For this purpose, we create a new Java class (e.g. CustomPotentialMatchTaskValidator) as a copy of the out-of-the-box class PotentialMatchTaskValidator. In the CustomPotentialMatchTaskValidator class, we add SOUT statements for errors and info messages:
      
      public boolean doValidate(TaskValidationInfo taskInfo) throws InvalidTaskException 
      {
        ("Validating task with objectURIs "+taskInfo.getObjectUris()); // Customization (SOUT statement added)
        if (isCoupleOfObjectUris(taskInfo.getObjectUris())) {
          boolean isMerged = false;
          //Check if already merged
          try {
            isMerged = isAlreadyMerged(taskInfo);
          } catch (InvalidUriException ex) {
            logger.error(ex.getMessage(), ex);
            throw new InvalidTaskException(ex.getMessage());
          } catch (ReltioInvalidRequestException ex) {
            logger.error(ex.getMessage(), ex);              
            throw new InvalidTaskException("Invalid task as object uris is invalid: " + taskInfo.getObjectUris());
          }
          if (isMerged) 
           {
            ("Invalid Task"); // Customization (SOUT statement added)
            logger.info("Invalid task as the entities are already merged: " + taskInfo.getObjectUris());
            throw new InvalidTaskException("Invalid task as the entities are already merged: " + taskInfo.getObjectUris());
          }
        } else 
         {
          ("Invalid Task"); // Customization (SOUT statement added)
          logger.info("Invalid task as there are not 2 uris : " + taskInfo.getObjectUris());
          throw new InvalidTaskException("Invalid task as there are not 2 uris : " + taskInfo.getObjectUris());
        }
        ("Valid Task"); // Customization (SOUT statement added)
        return true;
      }

      Result:

      In CustomPotentialMatchTaskValidator, the logging mechanism is extended with log info output to the console.

  3. Customize the service task.
    1. Create a new Java file (for example, CustomDeleteInsteadOfMerge.java) for custom Service Task implementation. Out-of-the-box service task implementations are:
    2. Push the code to the BitBucket repository that was granted to you. For details see Custom JAR Deployment.
    3. Open the BPMN diagram in the Workflow Modeler.
    4. Change the classpath of the service task implementation. Select the service task to be modified, open the Main config tab, and edit the Java Class field value.
      Example:
      <serviceTask id="MergeService" 
                  name="Merge Service" 
                  activiti:class="com.reltio.workflow.activiti.service.CustomDeleteInsteadOfMerge">
      </serviceTask>
    5. Publish the updated BPMN diagram.

      Example:

      By default, the Merge service task merges two entities by their objectURIs. If we need a service task that will delete both such entities, we create a new Java class (for example: CustomDeleteInsteadOfMerge) as a copy of the out-of-the-box class Merge. In the Merge class, we get two entities and merge them using the POST {TenantURL}/{entityURI1}/sameAs?URI='{entityURI2}' API:
      
      String objectUrisStr = (String) delegateExecution.getEngineServices().getRuntimeService().getVariable(delegateExecution.getProcessInstanceId(), Constants.OBJECTURIS);
      List<String> objectURIs = Arrays.asList(StringUtils.split(objectUrisStr,","));
      String entityURI1 = objectURIs.get(0);
      String entityURI2 = objectURIs.get(1);
       
      // Merging entities
      String url = Utility.generateTenantUrl(EnvironmentURL,tenantId) + "/" + entityURI1 + "/sameAs?URI=" + entityURI2;
      logger.debug(url);
      String responseJson = reltioService.invokeApi(accessToken, url, Constants.POST, "");
      ObjectMapper objectMapper = new ObjectMapper();
      Map<String,String> responseMap = objectMapper.readValue(responseJson, Map.class);
      if(responseMap.containsKey("severity")) {
        logger.error((String) responseMap.get("errorMessage"));
        // throw new Exception((String) responseMap.get("errorMessage"));
        throw new Exception(responseJson);
        } logger.debug(responseJson);
      In the new CustomDeleteInsteadOfMerge class, we get two entities and delete them one by one using the DELETE {TenantURL}/{entity object URI} API:
      
      String objectUrisStr = (String) delegateExecution.getEngineServices().getRuntimeService().getVariable(delegateExecution.getProcessInstanceId(), Constants.OBJECTURIS);
      List<String> objectURIs = Arrays.asList(StringUtils.split(objectUrisStr,","));
      String entityURI1 = objectURIs.get(0);
      String entityURI2 = objectURIs.get(1);
       
      //Deleting entities
      for(String objectURI: objectURIs){
        String url = EnvironmentURL+"/reltio/api/" + tenantId + "/" + objectURI;
        String responseJson = reltioService.invokeApi(accessToken,url,Constants.DELETE,"");
        ObjectMapper objectMapper = new ObjectMapper();
        ReltioResponse reltioResponse = objectMapper.readValue(responseJson, ReltioResponse.class);
        if(reltioResponse.getStatus()==null || !reltioResponse.getStatus().equals(Constants.SUCCESS)) {
          logger.error(reltioResponse.getErrorCode().toString() + ": "+reltioResponse.getErrorMessage());
          // throw new Exception(reltioResponse.getErrorCode().toString() + ": "+reltioResponse.getErrorMessage());
          throw new Exception(responseJson);
        }
      }

      Result:

      In CustomDeleteInsteadOfMerge, the logic is now customized so that the two entities are deleted one by one (instead of being merged, as in Merge).

  4. Ensure that the Unit/Integration tests cover at least 70% of your code. For more information, see topic Custom workflow review checklist.
  5. Finally, once the automatic checks in the Reltio Workflow Development Pipeline are executed, you will receive a notification either to fix something or to let you know that your code was approved.

  6. In case you need to fix something, you will repeat this process (pushing the new changes) until you get the final approval.

  7. Once you've been notified that your code is approved, navigateto the Workflow Modeler and select the JAR view.

    Note: The review process takes 1 business day and usually, only 1 round of review is required. Please plan the deployment schedule accordingly.
  8. In the Workflow Modeler, you can register the JAR file or deploy process definition.
  9. Select the JAR files tab on the left panel.
  10. From the list of custom workflows that are yet to be deployed, select the custom workflow that you want to deploy.
  11. Hover your mouse pointer over the custom workflow and select Register to register the JAR file. For more information, see topic Overview of JAR files .
    Note: To view the list of custom workflows and register them here, you must use the bitbucket pipeline for code development.
In the Workflow Modeler, the JAR files tab also displays custom workflows that are already deployed. You can un-register them from this tab.

Perform Local Debugging

Customers and partners developing custom Java classes for listeners, validators, and service tasks can benefit from the capability to debug Workflow Adapter custom classes on a local machine with the Hub running in the Reltio Connected Cloud. This section contains information about how to enable local debugging and information about how to debug a custom listener class locally.

Enabling Local Debugging

To enable local debugging, you must configure the environment to set up the Workflow Adapter locally.

After you configure the environment, you can perform local debugging through the UI or through the API.

API

You can perform local debugging through Workflow API requests executed against the locally installed Workflow Adapter. For more information, see the Workflow API.

User Interface (UI)

You can perform local debugging through the UI configured to work with the locally installed Workflow Adapter. Complete the following steps to enable local debugging through the UI.

  1. Set up HTTPS on the local machine. For more information, see Enabling SSL for workflow.
  2. Complete the following steps to configure the path to the Workflow Adapter in the UI configuration per tenant to work with the Workflow Adapter on the local machine.
    1. Open Console > UI Modeler.

      From the left navigation menu, select Import/Export UI Config Files.

      For more information, see Export and Import of UI Configuration Files.

    2. Select the com.reltio.plugins.workflow.json file.

      For more information, see Export and Import of UI Configuration Files.

    3. Download a copy of the file and make the following changes to the file.
      1. Save an unedited back up copy of this file before you start local debugging.
      2. Specify a local path for workflowPath. Make sure that the workflow path matches you local settings.

      Example:

      {
         ...
          "extensions": [
              {
                  "point": "com.reltio.plugins.ui.configuration",
                  "id": "com.reltio.plugins.workflow.configuration",
                  "workflowPath": "https://localhost:8443/workflow-adapter/",
                  "stepsColors" :{
                  },
                  "enabled": true
              },
             ...
          ]
      }
      Important: As the Hub requires HTTPS for connections, make sure the path contains https://. Ensure that you have the HTTPS protocol enabled on your local machine. This change of UI configuration will affect all other users of the same tenant.
    4. Upload and replace the UI config file.
    5. Publish the updated file.

      For more information on uploading, replacing, and publishing the file, see Importing UI Configuration Files.

  3. Verify that the Hub is configured with the localhost. In your browser, open a network activity monitoring tool (for example, in Google Chrome which is available in Developer Tools > Network) and find the Request URL value for Workflow.

    Example:

    Example: Debugging a Custom Listener Class Locally

    [In this example, we are going to create a custom listener and debug it on a local machine. Suppose we have a Delete Profile Review Workflow and a user task assigned as shown in the image below:

    When a task reviewer changes the assignee (for example reassigns the task to another user), the Listener on assignment of task can send out an email notification. The out-of-the-box implementation of the TaskAssignmentEventListener listener sends an email notification to the new assignee.

Local Debugging Process

  1. In your Java IDE, open the Workflow project, go to Java sources (bpms > activiti > src > main > java) and open TaskAssignmentEventListener.java (classpath: com.reltio.workflow.activiti.service.TaskAssignmentEventListener).
  2. Set a breakpoint on taskAssignmentEvent (notice the breakpoint icon in the gutter area of the editor) and run the application.

  3. In the Hub, reassign the Recommend for Delete task to a different user.
  4. In the IDE, wait for the breakpoint hit, then stop the application. If the execution continues, we will observe the out-of-the-box behavior, such as an email notification sent to the assignee.
  5. Edit TaskAssignmentEventListener.java and add taskAssignmentEvent2 where email notification addressee is owner.

  6. Run the application.
    Note: It may take about one minute for the application to restart.
  7. In the Hub, reassign the Recommend for Delete task to a different user.
  8. In the IDE, wait for the breakpoint hit. When the breakpoint is hit, continue execution.
  9. Check the mailboxes of the assignee and task owner to verify that they both have received the email notification.