Handlers are a combination of Ruby and XML that combine to perform a necessary function. Generally, this is one of the CRUD- Create, Retrieve, Update, Delete -functions, but there are cases of other functions such as data manipulation. Usually, if you need to build a handler, there is a handler like it already available on the Integrations section of community, so you don't need to start from scratch. Here we will go over the components of a handler, so that you will know what to modify to make the change(s) you need.
The handler directory (init.rb) contains the code that is run when the engine processes a node.
- xml output
The process directory (node.xml, info.xml) contains XML files for configuring properties of a task handler.
- Configuration values
- Node options (deferrable, visible, etc.)
- Node parameters
- Node results definition
- Handler XML input
The test directory (input.rb, output.xml) contains test cases run by the test harness.
- *_input.rb matches *.output.xml
- *_input.rb defines bindings
- *_output.xml defined expected results
The following images show the standard contents of a task handler package. The root of the handler directory should contain the three following subdirectories: handler, process, and test.
Unzipped directory of the kineticrequestceuserretrieve_v1 task handler
The handler directory contains the Ruby code that runs when the node is evaluated as well as any libraries that are used for integrations.
Contents of the handler directory
The process directory should contain the info.xml and node.xml files. These are used for configuring various properties of the task handler such as its name, description, parameters, results, etc.
Contents of the process directory
The test directory contains pairs of test files *input.rb and *output.xml, each of which represents a test case when running the test harness.
Contents of the test directory
The following images show some of the key pieces of code found within the init.rb file.
This image shows the class name of the handler, it is found at the very top of the init.rb file. This class name is important to the naming scheme of the handler. To derive the class name from the handler package name remove the underscores from the zip file name and capitalize the first letter of each word (including the v). For example kineticrequestceuserretrieve_v1.zip becomes KineticRequestCeUserRetrieveV1 (as below).
This image shows the initialize method. The initialize method is required to exist within the init.rb file and it is automatically called by the task engine when the node is processed. It is generally used to perform some kind of setup or staging for the rest of the handler's action. Here, we can see it is getting information from the node.xml file and assigning to @info_values and @parameters.
This image shows the execute method. The execute method is also required to exist within the init.rb file and is also automatically called by the task engine when the node is processed. Note that it is called after the initialize method. This method generally performs some kind of API interaction with an external resource. In this example, we:
- Build up the URL of the API to call
- Make the request to the API
- Get information from the results of the data that is returned
This method is responsible for returning the handler's results so they can be used later in the process. The results are defined immediately before the "end" keyword below.
Finally, this image shows the escape helper method.
As many and whatever appropriate helper functions can be defined.
This image shows the contents of the info.xml file. This file configures the task handler's configuration properties that are set when importing the task handler. Note that these are properties are defined system wide.
Here is an image of the configuration console showing how the values defined above are displayed when importing and configuring the task handler.
This image shows the top section of the node.xml file. Here basic properties of the task handler are defined like its name, description, whether it is deferrable or not, etc. The name and version must match the version/name in the file and the zip file name.
This piece of XML found within the node.xml file shows how the parameters of the node are defined. Each of the XML elements represents a single parameter that is displayed when configuring the node in the task builder. Within the elements there are several attributes that can be defined: id, label, tooltip, required, etc.
This piece of XML shows how the results of the node are defined. Each of the results simply needs a name to be defined. Note that these result definitions should match the structure of the result XML being returned in the task handler ruby code (shown above).
Note though that this does not stop you from passing additional parameters back in the ruby code. It is just that only results listed in the node.xml will be available for the workflow developers in the drop down list. Otherwise the developer will have to "just know" what is returned, which is generally not a good plan.
Finally, this image shows the XML data that the engine will pass to the task handler ruby code when the node is being processed. The XML structure shown is common for handlers interacting with Kinetic Request CE data but there are no constraints on how this XML should be organized. It is common for handlers of similar types to share the same XML structure so that code can be reused and simplified.
Repeatedly loading handlers into workflow constructed for their use, restarting the engine, and re-running the workflow or node is a time consuming way to test, so a local way to test is provided. The test harness is a tool that can be run on the desktop to test the execution of a handler. Two of the files within the handler structure are for use with the test harness.
This image shows the contents of the simple_input.rb file. This file is one of the two pieces necessary for defining a test case for the test harness. The purpose of this file is to essentially define all of the variables (bindings) that the task engine builds during normal processing. To determine which bindings to define in the simple input, simply look at the handler template in the node.xml (shown above). Anything with an @ symbol before the name is considered a binding variable.
This image shows the contents of the simple_output.xml file. This file is the second part of defining a test case. It is simply a chunk of XML data that defines what the test harness should expect a handler to return after running it. Note that this will look very similar to the results definition found in the node.xml but it will contain values within each of the result elements instead of being empty.