Technical Blog Post
An Overview of Automation Script Launch Points and Sequentially Ordered Automation Scripts
Since Automation Scripts were introduced in v7.5 and enhanced in v7.6, they became our best choice of customization most of the time. Besides a couple of rare situations which should be handled within JSPs or bean classes, Automation Scripts are used whenever we need to go beyond typical configurations.
If you are familiar with older versions of Maximo such as v6.x or v7.1, then you should also have some knowledge on Maximo Java framework and Maximo Business Objects (MBO classes, i.e. field, action, condition, integration processing classes etc.). In previous versions, we used to extend these business object classes and override their methods such as save(), initialize(), validate(), action(), etc. due to our specific needs. Now, we use object, attribute, action, condition or integration level Automation scripts in order to include further logic to the same methods.
One drawback of Automation Scripts is that Maximo does not provide a solution to run the scripts sequentially, instead it runs the scripts randomly. Of course there is a natural ordering for some events because the methods related to these events are executed in an order. This limitation might lead to undesirable results during multiple executions. You can read the tech note about multiple execution in random order following this link.
Let me explain the execution points, i.e. launch points, of Automation Scripts shortly. We mostly use object and attribute launch points which I prefer to mention last. I will begin with action, condition and integration launch points.
1) Action Launch Point
Maximo actions are mainly used in record processing components like workflow action nodes or escalation points. The screenshot below shows an Action Launch Point. This is a substitution for action classes and it basically works like standard Maximo actions.
2) Condition Launch Point
This launch point type is a substitution for condition classes and it basically works like standard Maximo conditional expressions. They are mainly used in security restrictions or workflow condition nodes. The screenshot below shows a Condition Launch Point.
3) Integration Launch Point
This launch point type is a substitution for integration processing classes and it basically works with Maximo Integration Framework components such as Object Structures, Publish Channels, Enterprise Services or Invocation Channels. They are executed when MIF processes inbound or outbound transactions. The screenshot below shows a Integration Launch Point.
4) Attribute Launch Point
This launch point type is a substitution for field classes and it basically works like extending field classes and overriding init(), initValue(), validate(), getList() or action() methods of them.
|Initialize Access Restriction||MboValueAdapter.init()||Called to initialize the field access restrictions|
|Initialize Value||MboValueAdapter.initValue()||Called to initialize the field value.|
|Validate||MboValueAdapter.validate()||Called to validate the data.|
|Retrieve List||MboValueAdapter.getList()||Get value list (if it has one)|
Called if the data is valid, to perform some action.
The screenshot below shows an Attribute Launch Point.
5) Object Launch Point
This launch point type is a substitution for object (MBO) classes and and it basically works like extending MBO classes and overriding init(), appValidate(), canAdd(), canDelete(), save(), toBeAdded(), toBeUpdated() or toBeDeleted() methods of them.
|Initialize Value||Mbo.init()||Called when the Mbo has been constructed and the field values have been initialized.|
|Validate Application||Mbo.appValidate()||Pre-save validation method.|
|Allow Object Creation||MboSet.canAdd()||Can an object be added to the collection?|
|Allow Object Deletion||Mbo.canDelete()||Can the object be deleted?|
|Save||Mbo.save()||Save the object and other linked objects.|
|Add?||Mbo.toBeAdded()||Is the Mbo to added to storage?|
|Update?||Mbo.toBeUpdated()||Is the Mbo to be updated in storage?|
|Delete?||Mbo.toBeDeleted()||Is the Mbo to be deleted from storage?|
I had mentioned that indeed there is some natural ordering of Automation Scripts coming from the original framework. For instance, typical order of execution for attributes is as follows:
1) Initialize Value - initValue()
2) Initialize Access Restriction - init()
3) Validate - validate()
4) Run Action - action()
5) Retrieve List - getList()
Now, how do we order Automation Scripts sequentially beyond the natural order coming from the framework? So, the question is what if we have multiple Automation Scripts on same level and we do not want them to run randomly. Actually, the solution is pretty straight forward and can be applied as follows:
1) Assume we are working on Work Orders and we want to have a sequential structure for SAVE method. Firstly, create an Group Action named WOSAVEACTS for instance.
2) Obviously we can add any kind of actions including Automation Script actions under this action group sequentially.
3) Then, create an Object level Automation Script with SAVE event for WORKORDER object in this case as below:
So, this script runs when a Work Order is saved and if we need to change any order of our actions or we need to add or remove some functions, we just modify the actions under WOSAVEACTS action group. We do not need to modify the same script to include new requirements, or create another one with the same level which will run in random order. It also gives us the flexibility to combine Maximo default actions with custom Automation script actions in any sequence we want. This is a simple and practical approach which reduces customizations to configurations.
NOTE: On the last step(3), a better alternative is to use an object relationship instead of using MXServer and where clause in the script. So, this step can be updated as follows:
3*) Then, via Database Configuration application create a relationship named WOSAVEACTION from WORKORDER to ACTION object as follows:
Now, create a more compact Object level Automation Script with SAVE event for WORKORDER object in this case as below: