Synchronous Executions Design Pattern

When you develop process models that execute robotic processes, you may want your process model to wait for the results of the robotic process before continuing. Currently, the robotic process executes asynchronously, so you have to wait for the robotic process to complete and retrieve the results separately before proceeding.

This page describes a design pattern to help you achieve synchronous execution between a robotic process within an Appian process model. In a future RPA release, we'll introduce a Smart Service to make this design seamless. In the meantime, Appian recommends using the pattern described below to develop a scalable and reusable solution for more synchronous execution between your robotic processes and Appian process models.

While you could use a polling pattern to continually check the status of the robotic process, this is not recommended because it could cause your process to reach the 1000-node limit and/or dramatically increase the size of your process history.

Goal

This pattern aims to help you develop a network of Appian objects to determine when a robotic process is complete. Most of these objects are reusable (as noted in the sections below), so you'll create them once and apply them to future robotic process and process model configurations.

Data passes between objects in the following ways:

  • The main process model will start the robotic process using an integration and wait for a message stating that the robotic process has completed.
  • On completion, the robotic process will call a web API to look up the process instance where it started from, which is listed in a process report.
  • The web API then starts a new process that will send a message to the original process.
  • Once the main process receives a message that the robotic process is complete, it will retrieve the results using an integration.

Design structure

To get started, you'll need to create a few objects. In the sections below, we include names for the objects. You can name the objects anything you'd like, but keep in mind that the code referencing the example object names will need to be updated as well if you change the names.

Some objects should be created at the same time, while others can be created in sequence. The steps below start with supporting objects that are needed to create the main process model, which executes the robotic process.

At the end of this pattern, you'll have the following objects in your application:

  • Process models (2), one representing the process model in your specific application that will incorporate the robotic process and one that will send the message that indicates the robotic process is complete.
  • Integrations (2) to execute and retrieve the results of the robotic process.
  • Connected system to authenticate the integrations.
  • Web API that the robotic process calls when it completes.
  • Process report to map the robotic process back to the original process that called it.
  • Constants (2) to reference the process model and process report used by the web API.
  • Group to set the security on all the other objects.

Step 1: Create group

Create a group named [App name] Service Account that will be used for securing the remaining objects. Later, we'll add the service account for your Appian RPA connected system to this group.

Step 2: Create process report

Create a process report that will look up the ID of the process instance that executed the given robotic process. To do this:

  1. In the Appian Designer, click New > Process Report to create a new Process Report object.
  2. Click the Duplicate existing process report option. Select the Active Processes report that comes out-of-the-box.
  3. After you click Save to create the new report, open it to edit.
  4. Remove the existing columns from the process report and create two new columns: one for the process instance ID (pp!id) and one for the execution ID (pv!executionId). The second column will be blank for any robotic processes from process models without this variable.

    It's important that this report only contain two columns. If additional columns exist, the query breaks in the web API (detailed below).

  5. Save your changes.
  6. Set the security on the process folder and/or knowledge center so that the group in step 1 you created has Viewer access.
  7. Create a constant that points to this process report so it can be referenced by the web API later on. In this pattern, we named this constant INSTANCE_EXECUTION_MAPPING_REPORT. Select Document for the constant type.

Step 3: Design the first process model

Next, create the process model designed to send a message to the main process model when the robotic process execution finishes.

Send Completion Message

This process is started by the notifyProcessOfCompletion web API (described below) and takes in a specific process instance ID to send a message to. The process ID is crucial here to ensure that the process-to-process message is targeted rather than just sending a massive message to any listening process model.

This process model contains three nodes: Start, Send Message, and End.

rpa-send-completion-msg-pm.png

  1. In the new process model, create a process variable called processInstance of type Number (Integer). Parameter should be set to Yes.
  2. Create a Send Message Event node. On the Data tab, in the DestinationProcessID row, map the Value to the processInstance process variable (=pv!processInstance).
  3. Set the security of the process model so that the group you created has Initiator access.

After your save the process model, create a constant called SEND_COMPLETION_MSG_PM pointing to it. You'll use this constant in the Web API.

Step 4: Create a Web API

Next, create the web API object. This web API is called during the cleanUp() method of the robotic process to notify the originating process that it has completed. It is designed to be generic, so that all the developer has to pass in is the execution ID and it will determine the correct process instance to send the message to.

  1. Create a Web API object called notifyProcessOfCompletion.
  2. Click Start process to build the API from a template. Alternatively, you can choose Create from scratch instead, just choose POST in the HTTP Method field.
  3. In the Endpoint field, type send-completion-msg.
  4. Click Create.

The code below uses two constants:

  • INSTANCE_EXECUTION_MAPPING_REPORT points to the process report you created in step 1. The report maps process instances with execution IDs.
  • SEND_COMPLETION_MSG_PM points to the Send Completion Message process model. The API initiates this process model when it receives a process ID as input.

After you've created the object, use the following expression to configure the web API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
a!localVariables(
  local!processId: index(
    a!queryProcessAnalytics(
      report: cons!INSTANCE_EXECUTION_MAPPING_REPORT,
      query: a!query(
        /* Filter the query results by the execution ID */
        filter: a!queryFilter(field: "c1", operator: "=", value: http!request.body),
        pagingInfo: a!pagingInfo(1, 1)
      )
    ).data,
    /* Index to recieve only the process instance ID */
    "c0",
    {}
  ),
  if(
    length(local!processId)=0,
    /* If the query returned no results, there are no active processes waiting on that robotic process */
    a!httpResponse(
      statusCode: 200,
      headers: {
        a!httpHeader(name: "Content-Type", value: "application/json")
      },
      body: "There are no active processes to notify of the completion"
    ),
    /* Otherwise, start the process to send a message to the process instance */
    a!startProcess(
      processModel: cons!SEND_COMPLETION_MSG_PM,
      processParameters: {
        processInstance: local!processId
      },
      onSuccess: a!httpResponse(
        statusCode: 200,
        headers: {
          a!httpHeader(name: "Content-Type", value: "application/json")
        },
        body: a!toJson(
          fv!processInfo
        )
      ),
      onError: a!httpResponse(
        statusCode: 500,
        headers: {
          a!httpHeader(name: "Content-Type", value: "application/json")
        },
        body: a!toJson(
          {
            error: "There was an error starting the process"
          }
        )
      )
    )
  )
)

Finally, set the security of the web API so that the group you created has Viewer access.

Step 5: Create or edit the robotic process

Next, you'll need to update and deploy the robotic process code so it automatically sends a message to Appian when it's complete. This is done using the cleanUp() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public String[] cleanUp() throws Exception {

  /** The cleanUp() method ensures the resource is cleaned up at the end of the execution
   * regardless of whether it completes successfully or not. Therefore, the web API call
   * should be added to the cleanUp() method to guarantee that it will always be called
   * at the end of the robotic process.
   */

  // Constructs the execution ID to pass to the web API
  String executionId = server.getExecution(0).getRobotName() + "#" +
      server.getExecution(0).getCurrentExecution().getExecutionNumber();

  // Calls the notifyProcessOfCompletion web API and passes the execution ID
  IAppian appian = IAppian.getInstance(this);
  IWebApiRequest request = IWebApiRequestBuilderFactory.getFreshInstance()
      .post("send-completion-msg")
      .body(executionId)
      .build();
  IWebApiResponse response = appian.callWebApi(request);

  // Displays the result of the web API in the execution log for easy debugging
  server.info("Response body: " + new String(response.getBodyBytes()));
  
  return new String[0];
}

This method is designed to be reusable, so you could consider saving this modified version as a class to use across multiple robotic processes.

Step 6: Create connected system and integrations

Create a connected system for Appian RPA and use a service account to authenticate. Remember that the service account must have the appropriate tags in Appian RPA to run robotic processes on resources and must be in the application group you created for this to work correctly.

After you create the connected system, create two integrations using it:

  1. getExecutionResults: Retrieves the execution results for the given execution ID. You can decide whether you want this to be a reusable rule or not, since it can't really vary much between applications. In the integration, create a rule input called executionId (text) and add ri!executionId in the Execution Id field of the integration.
  2. executeRoboticProcess: Executes a robotic process. This isn't a generic object, but rather will be application specific based on the robotic process they're calling. In the integration, two rule inputs called onSuccess and onError (any type) appear automatically. In the Robotic Process field, select the process you want to execute.

You'll use both of these integrations in the Execute Robotic Process process model, described next.

Step 7: Create the main process model

Finally, create the process model that starts the robotic process and waits for the results.

Execute Robotic Process

This process model kicks off the robotic process execution, then listens for a message indicating the execution has been completed. It doesn't map to a reusable object, but represents a process model within a specific application that wants to integrate with a robotic process. You can think of this as the "main" process model.

This process model contains five nodes: Start, Execute Robotic Process, Receive Message, Get Results, and End.

rpa-execute-bot-pm.png

  1. In the new process model, create two process variables called executionId and status, both of type Text. Neither has a set value or other settings configured.
  2. Add a Call Integration Smart Service node and use the executeRoboticProcess integration. On the Data tab, configure a custom output called ac!Result.executionId. Save this output into the executionId process variable.
  3. Add a Receive Message Event node to wait for the bot to complete.
  4. Add a second Call Integration node and use the getExecutionResults integration. On the Data tab, add a new input called executionId. In the Value field, add the executionId process variable (=pv!executionId). Add a custom output called ac!Result.status. Save this output into the status process variable.
  5. Set the security on the process model so that the group you created has Viewer access.

Test it out

Once you have all objects configured and connected, you're ready to test. Use the Start Process for Debugging option in the Execute Robotic Process process model to get started.

If the process model doesn't proceed past the Receive Message Event, check these common issues:

  • Does your service account have the right permissions assigned? Remember that users, resources, and robotic processes need to share at least one permission in common to execute properly.
  • Is your integration fully set up? Open the executeRoboticProcess integration object to confirm the desired robotic process is selected.
  • Is your resource online? Make sure the desired resource is online and communicating with the Appian RPA Console and orchestration server.
  • Did the robotic process complete successfully, but didn't send a message back to the Send Completion Message process model? It could be that the process report isn't set up properly. In Appian RPA, go to the robotic process's execution log. If you see a line that says "Response body: There are no active processes to notify of the completion," check the process report to confirm that the robotic process execution id is properly matched with the process model instance.
Open in Github

On This Page

FEEDBACK