Basic Robotic Process Template

If you're creating your first robotic process in Appian RPA, the basic template can help you get started. The basic template provides a generic representation of commonly used methods in a robotic process. These methods include processing a number of items, performing tasks before and after an item has been processed, and cleaning up your resource at the end of the process.

When you use a template to create your robotic process, you are provided with a zip file containing your source code and a pre-built workflow in the Robotic process configuration page. This page explains the contents of the workflow and the source code generated by the template.

Workflow

basic-robot-workflow

The basic template's workflow contains six actions: Init, Pre-Process, More items?, Process Item, Post-Process, and End. Similar to an Appian process model, each workflow has a start and end action. This is represented by the Init and End actions.

The rest of the actions are related to processing items. An item is a single element to be evaluated by the robotic process. Depending on the nature of your robotic processes, an item could be a person, an ID, a bank account, an invoice, a job identifier, etc.

It's common for a robotic process to iterate over many items. For example, process several employees, IDs, or bank accounts. To ensure each item has been processed, the workflow includes a loop. Loops utilize conditional actions to determine when all available items have been processed.

If you click the list icon 951644.png on any action, you'll see it is associated with a method. These methods are in the source code generated from the template. Within the source code, Appian has provided an outline of how you can configure each method.

Source code

The source code contains a class named BaseRobot that implements the IRobot interface and is annotated with @Robot. Every Appian RPA robotic process must have the IRobot interface and @Robot annotation to allow the Appian RPA API to identify the class as a robot.

BaseRobot includes several methods and attributes. Some of the methods are directly associated with workflow actions; however, the basic template also generates additional methods that are called by the platform to prepare a robotic process or clean up a resource after the process ends.

The class contains the following methods:

Method Description Associated Action
startUp() Always called by the platform prior to the execution of the actions in the workflow. -
start() Provides initial information to the process. Init
preProcess() Specifies any required steps that are needed before processing the items. Pre-Process
moreItems() Implements the workflow-guided loop. More items?
processItem() Processes and sets the result status of each item. Process Item
postProcess() Specifies any required steps that are needed after processing all the items. Post-Process
end() Provides any final information to the process. End
cleanUp() Always called by the platform after all workflow actions have been executed, regardless of the execution's results, or if any situation causes the robotic process to end. -
manageException() Addresses exception cases. This will be called by the platform when an uncaught exception is thrown explicitly by your code or implicitly. -

The following sections explain how to work with each of the methods and attributes provided in the template. In some areas of the template's source code, you will see comments that say TO DO. These areas indicate where you can add conditions or tasks to enhance your robotic process.

Attributes

The first few lines in the template's source code reference the attributes and a constant related to the robotic process:

  • PAUSE (line 38) is a constant that indicates the process should pause for 500 milliseconds, the equivalent of half a second. Since the working speed of a robotic process on an application is fast and continuous, and applications are designed for human use, the robotic process must adapt to the working speed of a human to avoid errors.
  • IJidokaServer (line 43) is responsible for communicating with the Appian RPA Server. The server is what communicates information to the console. This object notifies the server about the number of items to be processed and which item is being processed using the following attributes:
    • currentItemIndex (line 53) Index to control how many items have been processed. The server must receive this value as a 1-based index. For the first item, use 1.
    • currentItem (line 58) stores the current item and is represented by a string.
    • numberOfItems (line 63) stores the total number of items.
  • IClient (line 48) is responsible for making low-level operating system API calls. This object allows the robotic process to perform actions on a resource, regardless of its operating system.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
	/**
	 * Pause in milliseconds between actions to mimic human behavior.
	 */
	private static final int PAUSE = 500;

	/**
	 * Object to communicate with the server.
	 */
	private IJidokaServer< ? > server;
	
	/**
	 * Object for performing actions on the node.
	 */
	private IClient client;
	
	/**
	 * Current item index.
	 */
	private int currentItemIndex;
	
	/**
	 * Current item that will be set in every iteration of the loop.
	 */
	private String currentItem;

	/**
	 * Number of items.
	 */
	private int numberOfItems;
    

startUp() method

The startUp() method can be used to verify conditions on your resource before executing the actions in your workflow. For example, you can verify if an application is available, determine the screen resolution, or verify that the robotic process can be executed. The startUp() method is also where you can initialize the different instances needed by the robotic process.

If this method is not implemented by the robotic process using the annotation @Override, the platform will call the default implementation present in the interface IRobot.

Within the source code, you'll see the following declarations:

  • @Override (line 65) tells the platform to ignore the default implementation listed in the IRobot interface and instead use the following implementation.
  • server = JidokaFactory.getServer(); (line 69) initializes IJidokaServer.
  • client = IClient.getInstance(this); (line 70) initializes IClient, where this refers to the class that implements the IRobot interface. From the template, this would be the class BaseRobot.
  • return true; (line 79) determines that the robotic process will not run until a condition returns true.

By itself, the return true element does not tell the robotic process to do anything. Instead, the template's source code indicates on lines 72-76 that this is where you can add a condition that will check your resource before running the robotic process. Since the template provides you with return true;, you want to add a condition that will return false if the condition impacts the robotic process's successful execution.

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
@Override
	public boolean startUp() {
		
		// Initialize modules
		server = JidokaFactory.getServer();
		client = IClient.getInstance(this);
		
		/*
		 * TODO: Here you can check any condition that could make the robot not work
		 * properly. In this case, you want to return 'false' so the robot doesn't
		 * continue the execution.
		 */
		
		// If there weren't any problems, the robot can continue
		return true;
	}

start() method

The start() method is used to define the initial actions of the workflow and is associated with the Init action. Since the template is designed to process items, this is where you can indicate the total number of items that will be processed.

  • server.debug("Robot initialized!"); (line 89) sends a log message of type debug to the server to indicate that the robotic process was correctly initialized.
  • client.typingPause(PAUSE); (line 95) indicates that the robotic process will pause after typing. Since it is using the PAUSE constant, there will be a 500 millisecond pause.
  • client.mousePause(PAUSE); (line 96) indicates that the robotic process will pause after using the mouse. Since it is using the PAUSE constant, there will be a 500 millisecond pause.
  • numberOfItems (line 102) indicates the number of items to process.

If you do not know the number of items to process at the beginning of your robotic process, you can indicate the number of items in a different method later on using the following code:

  • server.info("Generating items..."); (line 109) sends a log message of type info to the server to indicate that you are about to set the number of items to process.
  • server.setNumberOfItems(numberOfItems); (line 111) indicates the total number of items to process.
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	public void start() {
		
		server.debug("Robot initialized!");
		
		/*
		 * Set the standard pause after typing or using the mouse. This is not
		 * mandatory, but it is very usual.
		 */
		client.typingPause(PAUSE);
		client.mousePause(PAUSE);
		
		/*
		 * Get the number of items and save it. In this case, we're generating
		 * 10 items.
		 */
		numberOfItems = 10;
		
		/*
		 * TODO: If the number of items are known at this point, this is a good place to
		 * notify the server. Anyway, this number must be notified as soon as it is
		 * known.
		 */
		server.info("Generating items...");
		
		server.setNumberOfItems(numberOfItems);
	}

preProcess() method

The preProcess() method allows you to list steps that must be completed before processing items. For example, you could add steps to open an application and log in. By default, the template calls server.info to send a log message of type info to the server to demonstrate the use of this method.

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    public void preProcess() {
   	/**
	 * Method for performing previous tasks before processing the items.
	 * 
	 * Associated with the {@code Pre-Process} action in the workflow.
	 */
	public void preProcess() {
		
		server.info("Method for performing previous tasks before processing the items");
		
		/*
		 * TODO: Here you can open applications or log in to the systems required for the
		 * automation.
		 */
	}

moreItems() method

The moreItems() method determines if the robotic process should evaluate another item or move to the next step in the workflow. This method implements the workflow-guided loop and is associated with a conditional action.

Unlike generic actions, conditional actions can only return string or boolean values because the values must match the output labels on your conditional workflow action. For example, if the moreItems() method returned a boolean value, there would only be two possible outputs for the condition and the output labels would be true and false.

However, the More Items? action in the template's workflow returns two outputs with the labels yes and no, so the method needs to return a string value. When the method returns a string, there can be two or more outputs, and the outputs must match the output labels.

The conditional action requires an if statement to determine which output to produce. In the template, if (currentItemIndex < numberOfItems) (line 139) states that, if the number of items that have been processed is less than the number of all items, return yes. If not, return no.

If the output is yes, more items will continue to be processed. Before processing, you must notify the server of the next item.

  • server.setCurrentItem() (line 148) tells the server which item is the current item being processed. This requires two parameters:
    • currentItemIndex is the 1-based item index of the total number of items to process.
    • currentItem is the identification of the item.

To identify the current item, the template provides the syntax currentItem = "itemKey_" + currentItemIndex; to concatenate the itemKey_ value and the index of the current item. Items would then be identified as itemKey_1, itemKey_2, itemKey_3, and so on.

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
   	/**
	 * Evaluates if there are items left to process.
	 * 
	 * Associated with the {@code More items?} action in the workflow.
	 * 
	 * @return String value of the workflow wire name of the path to take
	 */
	public String moreItems() {
		
		// If the index is lower than the number of items, there are items left to process
		if (currentItemIndex < numberOfItems) {
			
			// Increase the item
			currentItemIndex++;
			
			// Assign the new item to process
			currentItem = "itemKey_" + currentItemIndex;
			
			// Notify the server the new current item
			server.setCurrentItem(currentItemIndex, currentItem);
			
			return "yes";
		}
		
		return "no";
	}

processItem() method

The processItem() method evaluates and processes each item. The tasks associated with this method vary depending on what your item is. For example, say you need to transcribe a number of employee names into a document. Each employee name would be an item, and the processItem() method could have a task to write each name into Notepad.

When processing an item, it's possible that an error can occur or that certain items may need to be treated differently from others. To address these situations, Appian RPA allows for exception handling.

There are several exception classes, but since this template is related to item processing, you are provided with an exception specific to items.

  • JidokaItemException (line 171) is an exception class specific to handling items. This class indicates that an exception will occur if certain conditions are met. In the template, the exception is thrown when processing the third item. To indicate how the robotic process should proceed once the exception is thrown, you will call the manageExceptions() method at the end of your source code.
  • setCurrentItemResult() (line 176) determines the resulting status of the current item. Items can have a result of OK, Warn, Fail, or Ignore.
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
	/**
	 * In this method, each item is processed at a time.
	 * 
	 * Associated with the {@code Process Item} action in the workflow.
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public void processItem() throws Exception {
		
		/*
		 * Provoke an exception for the third item to show how exception handling works.
		 * This exception will be caught in the manageException method
		 */
		if (currentItemIndex == 3) {
			throw new JidokaItemException((IJidokaServer<Serializable>) server,
					"Exception thrown for the 3rd item");
		}
		
		// Set the result for the current item
		setCurrentItemResult();
	}

To determine which status an item will return, the template uses the setCurrentItemResult() method. Here, the method evaluates the results of a random number between 0 and 1. If the result is 1, the resulting status is OK. If the result is 0, the status is Warn.

To send the results to the server and see them in the console, you would use the following methods:

  • setCurrentItemResultToWarn() (line 191) sets the current item result to Warn. This accepts a string parameter where you can add a description of the processing result.
  • setCurrentItemResultToOK() (line 195) sets the current item result to OK. This accepts a String parameter where you can add a description of the processing result.
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    /**
	 * Set the current item to OK or WARN with a probability of 50%.
	 */
	private void setCurrentItemResult() {
		
		// Calculate a random integer between 0 and 1
		Random rd = new Random();
		int n = rd.nextInt(2);
		
		if (n == 0) {
			
			// The current item will be WARN when the random number is equal to 0
			server.setCurrentItemResultToWarn("Warning randomly calculated!");
		} else {
			
			// The current item will be OK when the random number is equal to 1
			server.setCurrentItemResultToOK("OK randomly calculated!");
		}
		
	}

postProcess() method

The postProcess() method allows you to list steps that must be completed after all items are done being processed. For example, you can add steps to close an application and log out. By default, the template calls server.info (line 207) to send a log message of type info to the server to demonstrate the use of this method.

200
201
202
203
204
205
206
207
208
209
210
211
212
213
    /**
	 * Method for performing tasks after the items have been processed.
	 * 
	 * Associated with the {@code Post-Process} action in the workflow.
	 */
	public void postProcess() {
		
		server.info("Method for performing tasks after the items have been processed");
		
		/*
		 * TODO: Here you can close the applications or log out the systems opened
		 * before the items processing.
		 */
	}

end() method

The end() method is used to define the final actions of the workflow and is associated with the End action. By default, the template calls server.debug (line 221) to send a log message of type debug to indicate the robotic process has finished.

220
221
222
    public void end() {
        server.debug("Robot finished!");
    }

cleanUp() method

The cleanUp() method is always invoked by the platform when all actions in the workflow have finished their execution, or if the process ended with errors or failed.

The purpose of this method is to leave the resource in the same state it was before the robotic process started its execution. This is where you can add tasks to clean up the resource, like closing an application or logging out. Earlier in the template, it was recommended to add these tasks in the postProcess() method. As a best practice, you should add these tasks in private methods and call them both from the postProcess() and cleanUp() methods in case the process ends with errors or fails.

The cleanUp() method also returns output files that can be downloaded directly from the robotic process execution page. To send files to the server, this method must return an array of strings referring to the local paths of the generated files.

If this method is not implemented by the robotic process using the annotation @Override, the platform will call the default implementation present in the interface IRobot.

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  @Override
    public String[] cleanUp() throws Exception {
        
        /*
         * To do: since this method is called when the execution ends, no matter if it
         * ended well or not, this is where you can assure the node is left in the same 
         * state it was before the execution started. 
         */
        
        server.info("Cleaning up...");
        
        /*
         * To do: If the execution must return any files, it has to be done here. To do 
         * so, you have to return the paths to each file as a String array.
         */
        
        return new String[0];
    }

manageException() method

The manageException() method is implicitly called by the platform whenever an exception is thrown during the execution and it is not explicitly caught in the rest of the code. You can modify this method to determine how an exception should be handled and processed.

If this method is not implemented by the robotic process using the annotation @Override, the platform will call the default implementation present in the interface IRobot.

  • @Override (line 244) tells the platform to ignore the default implementation listed in the IRobot interface and instead use the following implementation.
  • manageException(String action, Exception exception) (line 245) is invoked whenever an action throws an exception without catching it. It passes the method name associated to the action and the chain of exceptions as parameters. To find a specific exception, you will need to search for it.
  • server.warn(exception.getMessage(), exception) (line 248) sends a log message of type Warn to the server to indicate an exception was thrown. It also includes the stack trace which will appear in the execution page.
  • ExceptionUtils (line 259) is a third-party dependency from Apache Commons. This reviews the chain of exceptions received as a parameter from manageException to see if it contains the exception JidokaItemException.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  @Override
    public String manageException(String action, Exception exception) throws Exception {
        
        // Optionally, we send the exception to the execution log
        server.warn(exception.getMessage(), exception);
        
        if (ExceptionUtils.indexOfThrowable(exception, JidokaItemException.class) >= 0) {
            server.setCurrentItemResultToWarn("Exception processing the item!");
            return "moreItems";
        }
        
        // Unknown exception. Throw it
        throw exception;
    }

For more information on exception handling, review the Client module.

Open in Github

On This Page

FEEDBACK