Metastorm BPM 9, like with earlier versions of the product provides the facility to extend BPM applications and integrate processes with other systems via scripts that execute on the BPM server itself. Up to the release of version 9, server side scripting could be performed using JScript, VBScript or JScript.NET, the latter of which allowed integration with the .NET framework. Version 9 now allows the developer to code in C#, the most popular of the .NET languages (C# is used in all examples here). This article looks to provide a very brief introduction to server side scripting in Metastorm BPM 9 and will cover how to create server side scripts, access your process data and how to execute a server side script from within a process. Knowledge of C# is required.
Before delving into the coding, its important to get a grasp on the core Metastorm namespaces and understand what namespaces are imported into each server side script and why. Each new server side script is created with a default set of ‘using’ statements (‘imports’ in JScript.NET) that are required for the script to execute correctly. To add a server side script to your project, right clicking the project name and select New > Server Script. A new script file will be added to your project called ServerScript1 and the script will open for editing. Take a look at the using statements at the top (yours will exclude my comments in green).
For the sake of clarity, we are refering to the metastorm project inventory items as project objects in this article. Not only because ‘object’ is a standard programming label/identifier for ‘things’ you code against (abstract representations of real world entities) but because at runtime, your project objects are seen as just that, .NET objects of classes in the Metastorm.Runtime.Models namespace. The class represents the process definition that you deploy to the BPM server, the objects represent the process instances.
One of the biggest fundamental and most obvious improvements in version 9 over version 7 is the object orientated design approach. Your data, regardless of its source (web services, database, LDAP etc) are represented as named business objects. Your processes have their own processData and processContext objects. Forms also have local data objects, all of which are available to use in your server side code. The introduction of looping constructs is no doubt a result of this new object orientated approach to process design.
Before jumping into the details of server side scripting in version 9 and how we can utilize and manipulate our metastorm objects using C#, I want to touch on the object model for a project. Essentially each project represents a namespace inside of the Metastorm.Runtime.Models name space, for example I’m using a project called RH_RootCases so the namespace would be Metastorm.Runtime.Models.RH_RootCases. This namespace contains the following (on the basis that you have added these to your project) and lists them by name (e.g. Form1,Process1 etc):
The most important property of the form class is probably the ‘Fields’ collection which can be accessed to return the fields and their values for use in your scripts. The following illustrates a few basic field and form business object related operations:
The connection represents the named object that connects to your data sources and contains the configuration information required for the connection. The configuration information is dependant on the type of connection you create, e.g. data link properties for database connections, URI and method/parameter specifics for a web services. The below is a simple example of how to access a database connections properties using the default Metastorm connection object:
Each of your processes has its own process data object. This object contains the values of your process variables which can be accessed via server side code. As well as the process data, there is also process context data available which contains values such as the folder ID, folder name, process instance creation date and the user name of the originator. The below illustrates some simple assignments from data found in the Process1 object (the default name for your first process):
As well as forms, connections and processes, you can access your other Server Side Scripts, which means you can create a very logical server side object model of your own allowing you maintain OOP design principles and to some extent patterns. One of my own personal problems with Metastorm 7 was its line by line syntax. Very large procedures would have lots of random Metastorm functions and assignments that were attached to stages and actions and there wasn’t really any true OOP style organization and ability to abstract out changeable code into their own objects. With 9, this has changed and so via the same Metatorm.Runtime.Models namespace, you can access each of your server side script files by name. Note however that you can set your own namespaces for server scripts, meaning that they will not be available via Metatorm.Runtime.Models, but via the namespace you set, which may for example be inline with a client standard namespace model, for example ‘company.application.logicalgrouping.scriptname’. If this is the case, just remember to use this namespace model to access your other server side scripts.
Custom Business Objects can also be accessed by your server scripts.
Getting Access to Objects
Now we know where to find our project objects, we need to ensure that our server side script can access the methods and properties of our project objects. Like with the old ‘ework’ object (eWork.Engine.ScriptObject) used in v7 which allowed access to integration wizard functions on the server side by passing it in as an argument, we need to do exactly the same thing here. The business objects you wish to work with inside of a server side method should be passed to the method as arguments. The type of the object being passed should be expressed, for example :
Now you can use the expression builder to assign the value of the script return. For the first action in my process, I’ve added an assignment activity called ‘getCase’ which will assign the return value to a process variable called ‘intCaseNo’. You can see from the below expression builder window that I call the script and then pass an instance of the RootCase object:
In order for the expression builder to be able to see and invoke your methods, the ‘Promote’ attribute must be used in the script to promote the method being called. This is accomplished by placing the attribute declaration just above the method name [Promote(PromotionTargets.ExpressionBuilder)]. Our previous script examples illustrate this. As well as exposing the script methods to the expression builder, you should ensure that the method is static so that no object instantiation is required and the class can just be called directly. Classes are static by default as they have all static members.
So, server side scripting is a relatively straight forward process in Metastorm BPM 9. A good knowledge of C# syntax is obviously a pre-requisite.