Go to primary content
Oracle® Retail Job Orchestration and Scheduler Oracle® Retail Job Orchestration and Scheduler
Release 16.0.027
E94822-01
  Go To Table Of Contents
Contents

Previous
Previous
 
Next
Next
 

4 JOS Process Flow

A process flow is a composition of one or more activities. It is written in a DSL script that contains all the activities that make up a process from start to finish.

Process Flow

A process flow encapsulates a sequence of activities. An activity can be synchronous or asynchronous. In JOS, some of these activities may be invocations of batch jobs.

Figure 4-1 Process Flow

Surrounding text describes Figure 4-1 .

Process Flow Concepts

This section includes the following:

  • DSL (Domain Specific Language)

  • Process Variables

DSL (Domain Specific Language)

Process flow definition is specified in a Domain Specific Language (DSL) built on the top of Groovy. Since Groovy is build on the top of Java Virtual Machine (JVM), Groovy can understand Java and Groovy language constructs. So the process flow DSL can understand the DSL, Groovy, and Java language constructs.

A process is a list of activities. The keywords "begin", "end" and "activity" are the main DSL keywords used in process flow definition. These are described in detail below.

Begin Activity

The begin activity in the process flow definition appears as the first activity. There should be only one begin activity. This activity is intended to be the one used for any initialization needed for the process flow.

Activity

Activity has two parts, name and action. The name attribute is mandatory and should be used to give a unique name for the activity.

Action section is where the executable code should reside. Any Groovy or Java code can be coded in this section.

There can be one or more activities in a process.

End Activity

The end activity in process flow definition appears as the last activity. There should be only one end activity. This activity is intended to be the one used for any finalization needed for the process flow.

Process Variables

Variables used between activities can be created and stored in the processVariables map. The process engine also uses some of the variables for its own working in the process variable map. These variables are prefixed with "bdi_internal_". These variables must not be modified inside the DSL code.

Here is how you can use the process variable map for your own use.

// Set Variable

processVariables["VariableName"] = "Some Value"

// Use a variable value

def anotherVariable = processVariables["VariableName"]

External Variables

Some of the system level configuration values are available in the externalVariables map. These values are read-only. The process flow DSL can use these values, but should not attempt to change it.

For example:

externalVariables["rxmJobAdminBaseUrlUserAlias"]

Process Flow DSL

This section includes the following:

  • Process Flow DSL Characteristics

  • DSL Keywords

  • Process Flow API

  • Process Flow Variables

Process Flow DSL Characteristics

The section describes the characteristics of the process flow DSL.

  • Every process flow must have a name. The process flow name must match the filename that the process flow is saved into.

  • Process flows are written in DSL and saved as .flo files.

  • Process flow is made up of two special activities called "begin" and "end" and a group of user-defined activity nodes.

  • The begin and end activities will always run.

    • User-defined activity may or may not run based on SKIP or moveTo logic.

    • Every user-defined activity must have a unique name within a process flow.

    • The activity names are used to transfer control from one activity to another. Jumping to an activity is possible using the moveTo function.

    • Every activity has an action block that does the real work. Small amounts of Groovy/Java code can be put inside the action block.

    • Local variables can be defined within the action block.

    • Process variables are defined on top and are accessible to all activities within the process.

    • There are few implicit variables such as $activityName and $name.

    • Errors can be thrown using the error <some message> function.

    • Built-in conditional branching, looping, error handling.

    • Predefined functions for common tasks to reduce boilerplate code.

    • Built in REST service DSL can call service with just one line.

    • Services available to start/restart/monitor process flows programmatically.

    • Can handle chaining of process flows.

    • Service credential management framework built in.

    • Hybrid Cloud ready.

    • Built in activity SKIP functionality.

    • Built in activity HOLD and RELEASE functionality.

    • Built in bulk skip and Hold functionality.

    • Built in SPLIT and JOIN functionality between process flows.

      • SPLIT - one to many

      • JOIN - many to one

DSL Keywords

The tables below describe the following:

  • DSL Keywords

  • DSL Blacklisted Keywords

  • Process Flow API

  • Process Flow Variables

Table 4-1 DSL Keyword Descriptions

DSL Keywords Description

process

Identifies the process flow. Only one keyword in a process flow.

name

Used for naming processes and activities.

var

Used for initializing process variables.

begin

Begin activity block is the first activity in the DSL. It is mandatory and can be used for initialization.

activity

The executable component of the process flow. A process flow is composed of many activities.

action

Action section is where the executable code should reside. Any Groovy or Java code can be coded in this section.

on "okay" moveTo

Use these keywords inside an activity to move to another activity.

on "error" moveTo

Use these keywords inside an activity to move to error activity.

end

"end" activity in process flow definition appears as the last activity. There should be only one "end " activity.


DSL Blacklisted Keywords – In the process definition, changes can be made in DSL (Domain Specific Language), Groovy, or Java. Since this file is essentially a program, it can be modified to cause damages (e.g., delete files from the system). We have introduced a list of keywords that are potentially dangerous to use. If a blacklist word is present in the DSL, application deployment will fail and an error will be written to the server log (examples - java, groovy, thread etc.)

Table 4-2 Process Flow API Descriptions

DSL API Usage Description

triggerProcess(def baseUrl, String processDslName, String credentials, String processParameters)

triggerProcess(externalVariables["url"], "ProcessABC", externalVariables["urlUserAlias"], "a=b,c=d")

Method to start a process from DSL. This method sends a POST request to Process Flow to start a process. It returns process

startOrRestartJob(def baseUrl, String jobName, String credentials)

startOrRestartJob(externalVariables["url"],"JobAbc", externalVariables["urlUserAlias"])

Method to start or restart a job in Job Admin. This method sends a POST request to a REST end point in Job Admin.

waitForJobCompletedOrFailed(def targetActivity, def url, String credentials, int waitMinutes=1)

waitForJobCompletedOrFailed("JobAbcActivity",externalVariables["url"] + "/resources/batch/jobs/JobAbc/" + processVariables["jobExecutionId"], externalVariables["urlUserAlias"])

Method to wait for job to be completed or to fail. This method checks the status of the job and waits until status is COMPLETED or FAILED.

waitForProcessInstancesToReachStatus(def processInstanceList, def targetStatus=PROCESS_COMPLETED, def logicalAndOrOr = LOGICAL_AND, int waitMinutes=1)

waitForProcessInstancesToReachStatus(["P~1", "Q~1"], PROCESS_COMPLETED, LOGICAL_OR)

Method to wait for other process instances to reach a status.

waitForProcessNamesToReachStatus(Map, processNameToNumberOfExecutionsAfterStartMarkerTime, LocalDateTime startMarkerTime, def targetStatus = PROCESS_COMPLETED, def logicalAndOrOr = LOGICAL_AND, def whichExecutionStatus = LAST_EXECUTION_STATUS, int waitMinutes = 1)

waitForProcessNamesToReachStatus([P:3, Q:3, R:3], now().minusDays(1), PROCESS_COMPLETED, LOGICAL_AND, LAST_EXECUTION_STATUS)

Method to wait for processes with names to reach a status.

persistGlobalUserData(String key, String value)

persistGlobalUserData("key", "value")

Method to persist data to be shared with other processes. Persists key value pairs in BDI_SYSTEM_OPTIONS table.

String findGlobalUserData(String key)

findGlobalUserData("key")

Gets value from BDI_SYSTEM_OPTIONS table for a given key.

Map findAllGlobalUserData(String key)

findAllGlobalUserData()

Returns a Map with all user data.

removeGlobalUserData(String key)

removeGlobalUserData("key")

Removes data for given key.

error

error "report my error"

Generate an error condition and jump to the end activity. Process will be marked as failed.

POST

POST[externalVariables.url]^externalVariables.urlUserAlias

def response = (POST[externalVariables.url] + customHttpHeaders & MediaType.APPLICATION_JSON_TYPE ^ BasicAuth.alias1 | MediaType.APPLICATION_JSON_TYPE) << {} as String

Method to make a POST call to a url.

externalVariables.url - URL system option key configured in System Options table

customHttpHeaders - [a:"b", c:"d"]

Use "+" to provide custom http headers

Use "&" to provide response media type

Use "^" to provide basic authentication alias. User name and password will be Base64 encoded by the API.

Use "|" to provide entity media type

Use "<<" to post data. The data will be in the format provided in entity media type.

GET

GET[externalVariables.url]^externalVariables.urlUserAlias

def response = (GET[externalVariables.url] + customHttpHeaders & MediaType.APPLICATION_JSON_TYPE ^ BasicAuth.alias1) as String

Method to make a GET call to a URL.

externalVariables.url - URL system option key configured in System Options table

customHttpHeaders - [a:"b", c:"d"]

Use "+" to provide custom http headers

Use "&" to provide response media type

Use "^" to provide basic authentication alias. User name and password will be Base64 encoded by the API

DELETE

DELETE[externalVariables.url]^externalVariables.urlUserAlias

def response = (DELETE[externalVariables.url] + customHttpHeaders & MediaType.APPLICATION_JSON_TYPE ^ BasicAuth.alias1) << {} as String

Method to make a DELETE call to a URL.

externalVariables.url - URL system option key configured in System Options table

customHttpHeaders - [a:"b", c:"d"]

Use "+" to provide custom http headers

Use "&" to provide response media type

Use "^" to provide basic authentication alias. User name and password will be Base64 encoded by the API

log.info

log.debug

log.error

log.debug "Activity Name: $activityName"

Adds information to log file.


Table 4-3 Process Flow Variables

Variables Implicit or Explicit Usage Examples Description

externalVariables

Implicit

def myVar = externalVariables['myKey']

These are global variables that apply to all process flows. It comes from System Options table. Installation specific key values will be here.

processVariables

Implicit

var([ "myVar1":"prq", "myVar2":"xyz", "myVar3":"mno" ])//get valuedef aVar = processVariables['myVar1']//put new valueprocessVariables['myVar2'] = "abc"

These are process level variables that can be shared by all activities. Process variables are automatically persisted. Restart of a process recovers the process variables to the right value where it left off in the previous run. These are the most common variables you should use. Process variables must be declared using the var key word.

Local variables

Explicit

action{ def a = "xyz" def i = 7 i++}

Any variables can be created with the action block and used as local variables. Local variables defined in one activity is not accessible in another activity.

Global external variables

Explicit

persistGlobalUserData("key1", "value1")def xyz = findGlobalUserData("key1")removeGlobalUserData("key1")

For inter process dynamic variable sharing one can persist new variable to DB.

activityName

Implicit

println "My activity is ${activityName}"

Current activity name.

name

Implicit

Println "My process name is ${processName}"

Current process name.

processExecutionId

Implicit

Println "Current process execution Id is ${processExecutionId}"

Current process execution Id


Process Flow Instrumentation

When the process engine executes the process flow, the before and after snapshots of the activity are recorded in the process schema.

The information is reported through the Process Flow Admin application. Process Flow Admin is a web application that provides a GUI to manage task workflows. This is useful for tracking the process flows as well as troubleshooting. The snapshots also help when restarting a failed process. From the schema, the process engine can recreate the context to execute a restart and can resume execution from the activity that failed in the previous run.

Sub-Processes

One process may invoke one or more processes asynchronously. All the processes may run at the same time.

In order to identify these sub-processes, they are named accordingly. Once invoked, the main process has no control over the sub-processes. Each of the processes will run in the same way, as they are invoked independently.

Process Schema

The process instrumentation captures the state of the process at the beginning and end of each activity. This information is persisted into the process schema. For each activity there will be two records, one for before the activity and the other for after the activity.

Table 4-4 Process Schema Table Descriptions

Table Name Description

BDI_PROCESS_DEFINITION

This table stores all the process flow definitions. It is loaded at deployment time.

BDI_PROCESS_EXEC_INSTANCE

This table tracks all the process flow executions. There is a row for each process flow execution.

BDI_ACTIVITY_EXEC_INSTANCE

This table tracks all the activity executions. There are two rows for each activity execution. One to store the before context, and one to store after context

BDI_ACTIVITY_DYNAMIC_CONFIG

This table stores the user runtime choices like SKIP, HOLD, and so on, at the activity level

BDI_SYSTEM_OPTIONS

This table has all the system level information like URLs, credential aliases, and so on.

BDI_EXTERNAL_VARIABLE

This table does temporary storage of variables during process execution.

BDI_PROCESS_CALL_STACK

This table stores call stack for processes


Process Restart

When the activities within a process flow fails, the process status is marked as failed. A failed (or stopped) process flow can be restarted. If there are multiple failed processes, only the latest failed instance can be restarted.


Note:

The restart is for an instance that has already run and failed. This is different from running a new instance of the process flow.

When a process flow is restarted, the system knows the activity that failed (or stopped) in the previous run. During the restart, the process engine will skip all the activities prior to the failed activity. It will restore the context for the activity and resume execution at the failed activity.

Process flow execution does not keep the activity history at the restart. It will overwrite the activity records upon restart.

Statuses

Each activity instance and the process instance maintain the status of execution in the process schema. Following are the possible values for Activities and Process.

At the begin activity, the process is marked as PROCESS_STARTED. If any activity fails, the process is marked as PROCESS_FAILED. After the end action is completed, the process is marked PROCESS_COMPLETED. A complete list of process flow statuses includes:

  • PROCESS_STARTED

  • PROCESS_FAILED

  • PROCESS_COMPLETED

  • PROCESS_STOPPING

  • PROCESS_STOPPED

Similar to process statuses, each activity has also a status. The values include:

  • ACTIVITY_STARTED

  • ACTIVITY_FAILED

  • ACTIVITY_COMPLETED

  • ACTIVITY_WAITING_DUE_TO_HOLD_STARTED

  • ACTIVITY_WAITING_DUE_TO_HOLD_COMPLETED

  • ACTIVITY_WAITING_DUE_TO_JOIN_STARTED

  • ACTIVITY_WAITING_DUE_TO_JOIN_COMPLETED

  • ACTIVITY_SKIPPED

  • ACTIVITY_STOPPING

All the runtime statuses are persisted in the process schema at runtime when the DSL is executed.

Implementing a JOS Flow

The following steps show how to implement a JOS Flow.

  1. Download JosProcessFlow<version>ForAll16.x.xApps_eng_ga.zip and unzip the file.

  2. Create a process flow DSL file that stitches the jobs. DSL is Groovy based and Groovy or Java code can be used with in action block. See the following sample of DSL.

  3. Copy the DSL files to jos-process-home/setup-data/dsl/flows-in-scope folder.

  4. Run the deployer script in the jos-process-home/bin folder to deploy the JOS Process flow.

Activity Features

This section includes the following activity features:

Skip Activity

Activities in a process flow can be skipped by setting the skip activity flag through the Process Flow Configurations screen or REST endpoint. The skip flag can be set to expire, based on date and time. If the expiration date is not provided, then that activity will be skipped until the skip flag is removed. When an activity is set to skip, the process flow engine skips that activity and runs the next activity in the flow.

Figure 4-2 Process Flow Configurations Screen

Surrounding text describes Figure 4-2 .

REST Endpoint to Set the Skip Activity Flag

/batch/processes/<processName>/activities/<activityName>?skip=true

Hold/Release Activity

Activities in a process flow can be paused by setting the hold activity flag through the Process Flow Configurations screen or REST endpoint. The hold flag can be set to expire, based on date and time. If the expiration date is not provided, then that activity will be paused until the hold flag is removed. When an activity is set to hold, the process flow engine waits on that activity until the hold flag is removed or the time has expired.

REST Endpoint to Set the Hold Activity Flag

/batch/processes/<processName>/activities/<activityName>?hold=true

Bulk Skip/Hold

Bulk skip or hold allows you to set a skip and/or hold flag for a list of activities in multiple process flows.


Note:

Verify the updates in the BDI_ACTIVITY_DYNAMIC_CONFIG table.
 
                REST Endpoint: /batch/processes/skip-or-hold
                POST Data:
                {"processActivities": [
                        {"processName" : "…", 
                        "activityName": "…", 
                        "skip" : true,   false if not specified
                        "hold" : false,  false if not specified 
                        "actionExpiryDate" : "optional",
                         "comments" : "optional"
                        },
                        {…}
                     ]
}
                

Curl Command to Set Bulk Skip/Hold

curl -i --user processadmin:processadmin1 -X POST -H "Content-Type:application/json" http://host:port/bdi-process-flow/resources/batch/processes/skip-or-hold -d '{"processActivities": [
{"processName" : "OrgHier_Fnd_ProcessFlow_From_RMS", "activityName": "OrgHier_Fnd_ExtractorActivity", "skip":true},
{"processName" : "DiffGrp_Fnd_ProcessFlow_From_RMS", "activityName": "Activity1", "skip":true}
,{"processName" : "DiffGrp_Fnd_ProcessFlow_From_RMS", "activityName": "Activity2", "skip":true}
]
}'

Output

{"processActivities":[{"actionResult":"OK","activityName":"OrgHier_Fnd_ExtractorActivity","processName":"OrgHier_Fnd_ProcessFlow_From_RMS"},{"actionResult":"OK","activityName":"Activity1","processName":"DiffGrp_Fnd_ProcessFlow_From_RMS"},{"actionResult":"OK","activityName":"Activity2","processName":"DiffGrp_Fnd_ProcessFlow_From_RMS"}],"netResponse":"SUCCESS"}

Callback Service

The Process Flow engine can be configured to call a rest service at each activity. This is useful if the process flow is invoked by an external system (typically a workflow system) and the system wants to be informed of the progress of each activity. This callback can be configured declaratively or programmatically as needed.

The external system will have to implement the CallBack Service that will allow it to receive information from the JOS process flow. The external system can call the process flow, passing the context information as process flow parameters. The process flow will pass the information back when it makes the CallBack Service call.

How to Start Process Flow with Input Parameters

To start a JOS process flow, the user must a REST service call to the URL

(http://<host>:<port>/bdi-process-flow/resources/batch/processes/operator/<processName>).

The call must be a POST call to the URL.

The process flow start call accepts HTTP query parameters. The format of the query parameters are as follows:

http://localhost:7001/bdi-process-flow/resources/batch/processes/<ProcessName>?processParameters=callerId=<value1>,correlationId=<value2>,callBackServiceDataDetail.<name1>=<value3>,callBackServiceDataDetail.<name2>=<value4>

Spaces are not allowed in query parameters and must be separated by commas.

For example:

http://localhost:7001/bdi-process-flow/resources/batch/processes/Abc_Process?processParameters=callerId=123,correlationId=abc,callBackServiceDataDetail.def=xyz,callBackServiceDataDetail.abc=123

The following is the context information that must be passed to the JOS process flow from the calling system.

  1. callerId - CallerId parameter is used to identify the invoker of process flow. In this case it is CAWA.

  2. correlationId - Correlation ID is the main identifier used by the calling system (CAWA) to tie the process flow Start call to the eventual CallBack Service call.

  3. callBackServiceDataDetail - <name>= These are additional key value pairs that may be required in the future as required by the caller.

All of the above parameters are optional. However, if the context is not passed, the caller may not be able to associate the invocation with the callback.

Call Back from the Process Flow

A method (invokeCallBackService) is available for the Process Flow DSL that will allow the process flow to call an external service. This service has following features:

  • The method internally invokes a REST call to the provided URL.

  • The method uses basic authentication for the rest call. The credentials for the method call must be available in the process flow.

  • The payload sent from process flow to the invoking application (CAWA) follows the contract as shown in the example in the next section. All of the values, other than keyValueEntryVo, are populated by the Process Flow engine. The DSL writer can modify the keyValueEntryVo before the callback to pass any custom values from the DSL to invoking application (CAWA).

  • The result of the callback REST service (in CAWA) must be a String value.

  • If the callback service invocation fails for any reason (such as a network issue), the process flow activity fails and the process flow is marked as failed.

How to Invoke the Callback Service Declaratively

Set up the callback URL in process flow system options. To configure a callback URL, you should add system options such as <serviceName>CallBackServiceUrl, for example, processCallBackServiceUrl.

  1. In the Process Flow Admin console, navigate to the Manage Configurations tab and the System Options sub-tab.

    Figure 4-3 Process Flow Admin Console Manage Configurations Tab

    Surrounding text describes Figure 4-3 .
  2. Scroll down to Create New System Options and enter System Option Name and System Option Value. The URL must be a valid ReST Service.

    Figure 4-4 Create New Systems Options Section

    Surrounding text describes Figure 4-4 .
  3. Click Save.

    Figure 4-5 Saved System Options

    Surrounding text describes Figure 4-5 .
  4. Set up the callback URL credential alias in the process flow. To add the callback URL credential alias, you must add credential alias such as <serviceName>CallBackServiceUrlUserAlias, for example, processCallBackServiceUrlUserAlias.

  5. In the Create New System Options section, select the Create Credentials check box.

    Figure 4-6 Create Credentials Check Box

    Surrounding text describes Figure 4-6 .
  6. Enter System Option Name, Username, and Password for the URL provided in the previous step. If the system option name for the URL is processCallBackServiceUrl, then the system option name for the credential must be processCallBackServiceUrlUserAlias.

    Figure 4-7 Entering URL Credentials

    Surrounding text describes Figure 4-7 .
  7. Click Save.

    Figure 4-8 System Option Name

    Surrounding text describes Figure 4-8 .

    Note:

    Credentials created through the UI are available after a server restart; however, after the redeployment of the application, the credentials must be created again.

  8. Navigate to the Manage Process Flow tab and select process flow, then go to Process Flow Configurations sub-tab.

  9. Select Callback check box for the activities you want callback to be enabled for. Select Callback URL from the drop-down list.

    Figure 4-9 Configuring Callback Activities

    Surrounding text describes Figure 4-9 .
  10. Click Save.

    Figure 4-10 Saved Callback Service URL

    Surrounding text describes Figure 4-10 .

How to Invoke the Callback Service Programmatically

From the Process Flow DSL activity, you can invoke the callback service, as shown in the examples below. The callBackServiceUrl and callBackServiceUrlUserAlias properties must be set up in the System Options inside process flow.

Example 1: Short Form

Add the following line inside the JOS process flow activity.

def retValue = invokeCallBackService(externalVariables.callBackServiceUrl, externalVariables.callBackServiceUrlUserAlias)

Example 2: Long Form

In the long form API, the callBackServiceData is an implicit parameter that is automatically defined, and the user can update it with additional data inside an activity if necessary.

Add the following line inside the JOS process flow activity.

//optionally update some data

callBackServiceData.keyValueEntryVo[0].key = "Some Key"

callBackServiceData.keyValueEntryVo[0].value = "Some Value"

def retValue =

invokeCallBackService(externalVariables.callBackServiceUrl, externalVariables.callBackServiceUrlUserAlias, callBackServiceData)

Callback Request Payload Structure

The JOS process flow will make a POST REST call to the callBackService URL, passing in the following payload. JSON is the default content type.

Figure 4-11 JSON Payload Contract

Surrounding text describes Figure 4-11 .

Figure 4-12 XML Payload Contract

Surrounding text describes Figure 4-12 .

Table 4-5 Call Back Service Scenarios

Activity Type Activity Action Callback Behavior Activity Status Sent by Callback Activity Status if Callback Fails

Any

None

Callback will be called after action part is complete.

ACTIVITY_COMPLETE or ACTIVITY_FAILED according to the action part success or failure.

ACTIVITY_FAILED

Skip

Callback will be called after action part is complete.

ACTIVITY_SKIPPED

ACTIVITY_FAILED

Hold

Callback will be called when hold is released and after the action part of the activity runs.

ACTIVITY_COMPLETE or ACTIVITY_FAILED according to the action part success or failure.

ACTIVITY_FAILED

Special Cases

startOrRestartJobActivity

None

Callback will be called as soon as the job start or restart call is complete.

ACTIVITY_COMPLETE if the job was started or restarted successfully. ACTIVITY_FAILED if the job was not started or restarted successfully.

ACTIVITY_FAILED

waitForJobCompletedOrFailed

None

Callback will be called after the Job status has reached complete or failed.

ACTIVITY_COMPLETE if the job was started or restarted successfully. ACTIVITY_FAILED the job failed.

ACTIVITY_FAILED

Restart Scenarios

startOrRestartJobActivity

None

Job will be started or restarted only if the Job was not started earlier or job failed. If the activity failed due to callback failure the job will not be started.

ACTIVITY_COMPLETE if the job was started or restarted successfully. ACTIVITY_FAILED if the job was not started or restarted successfully.

ACTIVITY_FAILED

waitForJobCompletedOrFailed

None

Callback will be called after checking the Job status, if it has reached complete or failed, otherwise process will wait for the job to reach complete or failed status.

ACTIVITY_COMPLETE if the job was started or restarted successfully. ACTIVITY_FAILEDif the job failed.

ACTIVITY_FAILED


Process Execution Trace

The Process Flow engine keeps track of process execution details in BDI_PROCESS_CALL_STACK_TRACE table. Also, in order for a sub-process to appear in the trace, the sub-process must be called with the new api as shown below.

triggerProcess(<Base URL>, <Sub Process Name>, <credentials>, <Process Parameter Map>)

Example:

triggerProcess("http://host:port/bdi-process-flow", "DiffGrp_Fnd_ProcessFlow_From_RMS", "userid:password", null)

REST end point to get process execution trace

http://<host>:<port>/bdi-process-flow/resources/telemetry/processes/execution-trace/{ProcessExectionId}

Sample Output

{
  "executionId": "Diff_Fnd_ProcessFlow_From_RMS~8e1c7c11-1302-409d-9102-c55fffbdc1ab",
  "executionName": "Diff_Fnd_ProcessFlow_From_RMS",
  "activityExecutionId": "",
  "url": "",
  "status": "PROCESS_COMPLETED",
  "duration": 0,
  "type": "PROCESS",
  "invocationTime": "2017-07-19T12:21:20.061-06:00",
  "children": [
    {
      "executionId": "ItemImage_Fnd_ProcessFlow_From_RMS~89f46519-50ab-4a51-a6fb-c6c5395afeca",
      "executionName": "ItemImage_Fnd_ProcessFlow_From_RMS",
      "activityExecutionId": "Activity2~a408b407-c4f0-4137-ba32-6ddd148f0838",
      "url": "http:\/\/msp8917:8001\/bdi-process-flow\/resources\/batch\/processes\/operator\/ItemImage_Fnd_ProcessFlow_From_RMS",
      "type": "PROCESS",
      "invocationTime": "2017-07-19T12:21:20.534-06:00",
      "children": [
      ]
    },
    {
      "executionId": "DiffGrp_Fnd_ProcessFlow_From_RMS~bb68a1ea-86a5-4108-aa58-b9e791d1fb8c",
      "executionName": "DiffGrp_Fnd_ProcessFlow_From_RMS",
      "activityExecutionId": "Activity1~602ad027-7946-4820-acd8-cf452f5fc937",
      "url": "http://host:port/bdi-process-flow/resources/batch/processes/operator/DiffGrp_Fnd_ProcessFlow_From_RMS",
      "type": "PROCESS",
      "invocationTime": "2017-07-19T12:21:20.296-06:00",
      "children": [
        {
          "executionId": "ItemHdr_Fnd_ProcessFlow_From_RMS~3886b39f-6268-4895-8e5e-300ded42665b",
          "executionName": "ItemHdr_Fnd_ProcessFlow_From_RMS",
          "activityExecutionId": "Activity2~8e9f9a6a-440a-41dd-a648-f4322102012b",
          "url": "http://host:port/bdi-process-flow/resources/batch/processes/operator/ItemHdr_Fnd_ProcessFlow_From_RMS",
          "type": "PROCESS",
          "invocationTime": "2017-07-19T12:21:20.705-06:00",
          "children": [
            
          ]
        },
        {
          "executionId": "InvAvailWh_Tx_ProcessFlow_From_RMS~6c462406-a991-4754-9d94-73628091114a",
          "executionName": "InvAvailWh_Tx_ProcessFlow_From_RMS",
          "activityExecutionId": "Activity1~e7f8e9fa-7ba6-4a51-81e2-bdcfe752c15e",
          "url": "http://host:port/bdi-process-flow/resources/batch/processes/operator/InvAvailWh_Tx_ProcessFlow_From_RMS",
          "type": "PROCESS",
          "invocationTime": "2017-07-19T12:21:20.538-06:00",
          "children": [
          ]
        }
      ]
    }
  ]
}

Process Metrics Service

Process Metrics provides an end point to produce metrics for processes that ran between "fromTime" and "toTime".

Path: /telemetry/processes

HTTP Method: GET

Parameters:

fromTime - Query parameter

toTime - Query parameter

Sample Response:

<process-runtime-monitoring-info>
    <data-requested-at>2017-10-09T10:24:27.848-06:00</data-requested-at>
    <data-requested-from-time>2017-03-01T00:00:00-06:00</data-requested-from-time>
    <data-requested-to-time>2017-08-01T00:00:00-06:00</data-requested-to-time>
    <process-server-runtime-info>
        <id>bdi-process</id>
        <app-status>RUNNING</app-status>
        <up-since>2017-10-09T10:22:34.498-06:00</up-since>
        <total-executions-count>16</total-executions-count>
        <successful-executions-count>8</successful-executions-count>
        <failed-executions-count>7</failed-executions-count>
        <process>
            <name>DiffGrp_Fnd_ProcessFlow_From_RMS</name>
            <slowest-run-duration>0.0</slowest-run-duration>
            <fastest-run-duration>120.0</fastest-run-duration>
            <avg-run-duration>60.2315</avg-run-duration>
            <executions>
                <exceution-count>1</exceution-count>
                <success-count>0</success-count>
                <failure-count>1</failure-count>
                <execution>
                    <execution-id>
DiffGrp_Fnd_ProcessFlow_From_RMS~650dba75-b632-42ea-963b-802c560d0c6b
</execution-id>
                    <status>PROCESS_FAILED</status>
                    <start-time>2017-05-17T14:39:32.489-06:00</start-time>
                    <end-time>2017-05-17T14:39:33.535-06:00</end-time>
                    <activity-exe>
                        <activity-exe-id>begin~2ac2bc4d-6233-41ac-a134-5fb73ebba275</activity-exe-id>
                        <name>begin</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_COMPLETED</status>
                    </activity-exe>
                    <activity-exe>
                        <activity-exe-id>
DiffGrp_Fnd_ExtractorActivity~035b6e78-411e-4868-b441-f2e79a3dba61
</activity-exe-id>
                        <name>DiffGrp_Fnd_ExtractorActivity</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_SKIPPED</status>
                    </activity-exe>
                    <activity-exe>
                        <activity-exe-id>
DiffGrp_Fnd_ExtractorStatusActivity~7d92a1c1-721a-416d-86ac-c412f9e49982
</activity-exe-id>
                        <name>DiffGrp_Fnd_ExtractorStatusActivity</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_SKIPPED</status>
                    </activity-exe>
                    <activity-exe>
                        <activity-exe-id>
DiffGrp_Fnd_GetDataSetIdActivity~423d19e3-8c9d-44b2-93b9-183f41cd0840
</activity-exe-id>
                        <name>DiffGrp_Fnd_GetDataSetIdActivity</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_SKIPPED</status>
                    </activity-exe>
                    <activity-exe>
                        <activity-exe-id>
DiffGrp_Fnd_DownloaderAndTransporterActivity~70bac2cb-c414-4be8-a5ab-0ef21fd2fc4d
</activity-exe-id>
                        <name>DiffGrp_Fnd_DownloaderAndTransporterActivity</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_FAILED</status>
                    </activity-exe>
                    <activity-exe>
                        <activity-exe-id>end~5c07a938-864b-4156-bab7-70b96bcb2d74</activity-exe-id>
                        <name>end</name>
                        <duration>0.0</duration>
                        <status>ACTIVITY_FAILED</status>
                    </activity-exe>
                </execution>
            </executions>
        </process>
    </process-server-runtime-info>
</process-runtime-monitoring-info>   

Process Security

The Process Flow application uses basic authentication to access the system. The user must belong to BdiProcessAdminGroup, BdiProcessOperatorGroup, or BdiProcessMonitorGroup to use the process flow REST services and process flow admin application.

There are two authorization roles designed for the process flow application: the Operator role and the Admin role. The Admin role has permissions to use all the functions provided by the process flow application. The Operator role has limited access compared to Admin, as identified in the table below. The Monitor role has the fewest access permissions.

Table 4-6 Authorization Roles

Service/Action Monitor Role Operator Role Admin Role

Update Process DSL

No

No

Yes

Start/Restart Process

No

Yes

Yes

Skip/Hold/Release

No

Yes

Yes

All other services

Yes

Yes

Yes


Process Customization

Seed Data

During the deployment of Process Flow, seed data gets loaded. Seed data files are located in "jos-process-home/setup-data/dml" folder. If seed data is changed, Process Flow needs to be reinstalled and redeployed. For loading seed data during redeployment, LOADSEEDDATA flag in BDI_SYSTEM_OPTIONS need to be set to TRUE.

Process DSL Reload

Along with seed data, the process DSL also gets loaded to BDI_PROCESS_DEFINITION table during the deployment time. Process DSLs are located in "jos-process-home/setup-data/dsl/flows-in-scope" folder. If you want to load DSLs again after DSLs are added or updated, Process Flow needs to be redeployed. For loading DSLs during the redeployment, LOADPROCESSDEF flag in BDI_SYSTEM_OPTIONS table need to be set to TRUE.

Deployment of Process Flow first time loads both seed data and process DSLs.

Redeployment loads seed data depending on the LOADSEEDDATA and LOADPROCESSDEF flag values.

Before redeployment make sure for every install/upgrade one needs to look at flows-in-scope i.e. /bdi-process-home/setup-data/dsl/flows-in-scope , to ensure they have the correct set of flows for that installation, each release would bring in functional changes and flows files define the primary functional definition of a BDI integration flow.

Perform the following procedure:

  1. Delete what was in scope before.

  2. Copy the latest flows for what you are trying to integrate.

  3. Deploy the application.

Table 4-7 Redeployment Scenarios

LOADSEEDDATA LOADPROCESSDEF Behavior

TRUE

TRUE

Loads both seed data and process DSLs

TRUE

FALSE

Loads seed data only

FALSE

TRUE

Loads process DSLs only

FALSE

FALSE

Does not load seed data and process DSLs


Troubleshooting

Since the process flow can be written in Groovy and DSL, it is prone to programming mistakes. Any custom DSL must be properly tested before deploying. The process flow engine can detect syntax errors only at runtime. So it is possible to load an incorrect process flow and fail during runtime.

At the end of an activity, the process engine invokes the next activity, depending on the result of activity execution (the "moveTo" statement). If you have empty activities (possibly because you commented out the existing invocation statements), make sure the activity result is valid.

If any activity fails, the process is marked as failed. So in case of process failure, examine the activity details to find out which activity failed. Once the failed activity is identified, the process variables can be inspected to look for any issues. The next step would be to look at the logs through the Process Flow Monitor application to see the details of the issue. Once the issue is fixed, either a restart or a new run of the process flow can be used, depending on the requirement.

Process Flow Did Not Start

To address this, verify the logs. It could be due to the missing Credentials Access permission, missing system credentials, or a missing system options or DSL parsing error.

Deleted Process Flow Still Listed in the UI

Deleting a process flow from jos-process-home does not delete it from the process flow application because the process flow application refers to the database entries. In order to delete a process flow from the JOS Process Flow application, the script DELETE_PROCESS_FLOW.sql(jos-process-home/setup-data/dml/) must be run in the JOS Schema.

Best Practices for Process Flow DSL

The following best practices for Process Flow DSL include:

  • Use naming conventions for process flows and activities in the process flow so that they are easily identified. It is recommended that the name of the process flow includes "Process" and the name of activities ends with "Activity".

  • Use the built-in startOrRestartJob method to start/restart a job in Job Admin.

  • Use the built-in waitForJobCompletedOrFailed method to wait until job is complete or failed.

  • Use the built-in triggerProcess to start a sub process.

  • Access system options through externalVariables.

  • Use processVariables to share variables between activities.

  • Use the built-in waitForProcessInstancesToReachStatus to wait for other process instances.

  • Use the built-in waitForProcessNamesToReachStatus to wait for other processes.

  • It is recommended to use flo as the extension for the process flow DSL file.

  • Use the built-in REST DSL to make rest calls.

  • Organize process flows as hierarchical parent child flows, where the parent manages the child flows.

  • Avoid using too many waitFor calls, as active threads can get blocked.