Download (all) Scripts from Maximo / ICD to your Eclipse Project

In one of my last blogs I showed a very nice way how to upload Jython scripts from Eclipse to your Maximo / ICD environment. Now what about the situation that you already have a Maximo / ICD environment with tons of scripts in it? In this blog I will show you a simple way how you can include all these scripts to your Eclipse project within 15 minutes. This will also include the first comment lines needed for the later upload.

To achieve our goal the following steps are needed:

  • Setup an application export in the Autoscript application
  • Download a XML File including all scripts
  • Run a Jython script to extract all the unique scripts

Setup an application export in the Autoscript application

The application export will be configured using the “Object Structures” application. Launch:

Go To > Integration > Object Structures

In the Object Structures application search for the “MXSCRIPT” Object Structure and open it.

Selection_018

After opening select an action:

Select Action > Add/Modify Application Export Support

 

Menu_020

In the dialog box create a new row in the table using the values shown here:

Selection_021

Press OK. The export support now has been created. Next step is to grant the security rights to the user group which should use the tool. In my example I will grant the rights to the maxadmin group. Goto the following Menu:

Go To > Security > Security Groups

Now perform the following steps:

  1. Search and open the security group you want to grant the rights to.
  2. Change to the “Applications” Tab.
  3. Filter for the Application “Automation Scripts” and select the record.
  4. In the Options for Automation Scripts section enable the option “Application Export”.Selection_022
  5. Save the Security Group.
  6. Logoff and Logon again to Maximo / ICD. Be sure that all your user sessions are successfully logged of – otherwise the settings will not be activated.

Download a XML File including all scripts

To download a XML File which includes all scripts in your system you have to go to the Automation Scripts application.

Go To > System Configuration > Plattform Configuration > Automation Scripts

If the previous step worked correctly you should now see a new Icon in the iconbar Selection_023for the application export. Before you press this button you have to search for the scripts to export. If all scripts should be exported just press enter in the search field. Now press the icon.

In the “Application Export” Dialog you just can take all settings and press “OK”.

Selection_024

The XML File now will be downloaded to the download directory of your browser on your local PC.

Run a Jython script to extract all the unique scripts

First of all you have to have a project setup in Eclipse where you would like to store your downloaded scripts. This chapter requires a complete project-setup using Eclipse, Jython and PyDev like described in this blog. Copy the downloaded XML file to this directory and name it scripts.xml.

Now create a Jython script with the following code:

#AUTOSCRIPT:EXPORTSCRIPTS
#DESCRIPTION:Script to export all Jython Scripts on a Server
#LOGLEVEL:ERROR

from java.io import File
from org.jdom.input import SAXBuilder

xmlFile = File("scripts.xml")
builder = SAXBuilder()

document = builder.build(xmlFile)
wrap = document.getRootElement()
ns = wrap.getNamespace()
rootNode = wrap.getChild("MXSCRIPTSet", ns)

liste = rootNode.getChildren("AUTOSCRIPT",ns)
for i in range(0,liste.size()):
    node = liste.get(i)
    scriptName = node.getChildText("AUTOSCRIPT",ns)
    scriptDesc = node.getChildText("DESCRIPTION",ns)
    scriptVersion = node.getChildText("VERSION",ns)
    scriptDebug = node.getChildText("LOGLEVEL",ns)
    scriptCode = node.getChildText("SOURCE",ns).encode('utf-8')
    
    scriptFile = open(scriptName + ".py","w")
    scriptFile.write("#AUTOSCRIPT: " + scriptName + "\n")
    scriptFile.write("#DESCRIPTION:" + scriptDesc + "\n")
    scriptFile.write("#VERSION:    " + scriptVersion + "\n")
    scriptFile.write("#LOGLEVEL:   " + scriptDebug + "\n")
    scriptFile.write(scriptCode)
    scriptFile.close()

This scripts requires the Java JDOM Class. Please ensure that the jdom.jar file is included in your PYTHONPATH. You can check this by right-click on your Eclipse project and select the “Properties” Menu. Check under “PyDev – PYTHONPATH” if jdom.jar is existent. If not use the “Add zip/jar/egg” Button to add it.

Selection_025

Remark: If you don’t have a local version of jdom.jar you can find one on your Maximo / ICD Server in the following directory: %WEBSPHERE _DIR%\AppServer\profiles\ctgAppSrv01\installedApps\ctgCell01\MAXIMO.ear\lib

Everything is prepared now. You can run the Script now from Eclipse using the Run Icon Arrow  Selection_009 and then the following menu:

Menu_026

Hopefully after a refresh of your project/folder (F5) you will see a bunch of new scripts! Congratulations!

Read Maximo system properties in a Jython script

It is a good practise to store all properties like usernames, passwords, Url’s, etc in the Maximo System Properties. User defined properties can be defined in addition to all the tons of existing system properties. You will find the properties application under

System Configuration –> Plattform Configuration –> System Properties

To define a new property just click “New Row” in the Global Properties section:

properties1

The usage of these properties in a Jython script is quit easy. To read and print the new “custom.username” property the following script can be used:

from psdi.server import MXServer
configData = MXServer.getMXServer().getSystemProperties()
maxProperty = configData.getProperty("custom.username")
print maxProperty

properties2

When tested in the Maximo Script editor the script should print out the username “bigadmin”. If you get a no output at StdOut or “None” you should verify if you made a live refresh of the property data.

Selecting specific Mbo’s using Relationships and Where Clauses

A very common scenario is that you would like to get an instance of a MboSet with not all records included, but only a subset. Spoken in SQL you would like to apply a where clause to limit the number of records you get as a result in a MboSet. In this article I will show you different ways on how you can achieve this.

  1. Usage of relationships

A very common pattern is to just use relationships when you initialize your MboSet. I have shown such a pattern in this article. You can easily define the where clause directly in the relationship and you will only get the records based on the where clause.

  1. Adding a Where-Clause to an existing MboSet

It is quit handy to add a Where-Clause to an existing MboSet. The following code example will show this scenario:

woset = session.getMboSet('WORKORDER')
woset.setWhere("WONUM = '2009'")
woset.reset()
wo = woset.moveFirst()
if wo is not None:
    print "Workorder ",wo.getString("WONUM")

At the beginning you initialize a MboSet returning all Workorder’s in the system. In line 2 you append a Where-Clause to the result set. When you have used a relationship with an existing where clauses in it the new where clause will be appended. The woset.reset() method call in line 3 is required to “execute” the where clause and update the result set in woset. The rest of the script just shows the first record.

  1. Building a temporary relationship

This is one of my favorite patterns which can help you make life much easier. When you develop your script you will not always have the perfect relationship for navigation defined in the system. So you can either define a new relationship in database configuration or you can do this step directly from your Jython script. You define a new relationship just to be used temporarily in your script with no impact to the rest of the system.

The syntax based on the JavaDoc is:

public MboSetRemote getMboSet(java.lang.String name,
                              java.lang.String objectName,
                              java.lang.String relationship)
                    throws MXException, java.rmi.RemoteException

A real example statement to get all worklog entries for a specific workorder could look like this:

worklogset = wo.getMboSet("$TEMPREL1", "WORKLOG", "RECORDKEY='2009'")

$TEMPREL1 – An unique identifier for the relationship. It needs to be unique and for this reason it is good practice to start the name with a dollar sign.

WORKLOG – The database object which should be queried using any provided where clause.

RECORDKEY=’2009’ – The where clause to be applied to reset the MboSet of interest.

Adding Mbo records to a MboSet

In this blog I will show you in detail how to add new Mbo records to a MboSet.

The easy pattern

To do so we will directly start with a simple code example:

woset = session.getMboSet('WORKORDER')
wo = woset.add()
if wo is not None:
    wo.setValue("DESCRIPTION","New Testworkorder")
    wo.setValue("WOPRIORITY", 10)
 
    # Only save if necessary (e.g. Script executed via RMI)
    woset.save()

This is the simplest form of adding a record. At the beginning we need to have a MboSet object stored to the woset variable.
By using the add method woset.add() a new record will be added to an existing MboSet. The record is added at the beginning of the MboSet. If you would like to add the new record to the end of the existing set you can use the woset.addAtEnd() method.

Very important is line 3 to check if we really have created a new object instance. Without that check our wo.setValue(..) method calls would result in Null Pointer exceptions. The wo.setValue method is quite easy to use to set the individual fields in the MboSet. The good thing at this method is that it does not differentiate between datatypes.

The woset.save() method call is a bit special and need some explanation. Depending on the way you run your script you should or should not save the MboSet at the end:

  • In general no saving on object & attribute launchpoints
  • In general no saving in workflow actions
  • In general save in RMI Scripting, in direct invocation or when you act on a dialog button.

But as you can imagine there is no rule without exceptions and you eventually have to trial and error to find the correct usage.

Add Mbo records to multiple MboSet’s using transactions

In the previous example we just added a single record to a single Mbo. What if we wan’t to a add an additional Worklog entry to the new Workorder. What about transaction processing. We only want to create the Workorder together with the worklog entry or fail both. The following script shows such an example:

woset = session.getMboSet('WORKORDER')
wo = woset.add()
if wo is not None:
    wo.setValue("DESCRIPTION","New Testworkorder 3")
    wo.setValue("WOPRIORITY", 10)
 
    worklogset = wo.getMboSet("WORKLOGAPPT")
    worklog = worklogset.add()
    if worklog is not None:
        worklog.setValue("DESCRIPTION", "WLOG Descr.")
        woset.save()
        print "Workorder " + wo.getString("WONUM")  + " created !"

This example is quite similar to the first one. The difference is that we navigate from our newly created workorder Mbo to a Worklog MboSet via a predefined relationship. Using a relationship at this point automatically holds together the two MboSets via a transaction. There is nothing else via have to do to create this kind of dependency! Cool, isn’t it?

The next line to mention is the woset.save() statement. You could ask: “Why do we do not save the Workorder object?” My answer is: “Save the object you want! Since both MboSet objects are linked by a relationship it doesn’t matter which object you save. The result is the same!”

Setting up Eclipse for Maximo / ICD Jython development

Introduction

When you start developing Jython scripts in context of Maximo & ICD the first question is where to edit the scripts. The provided editor in the Web-interface of the product can only be seen as a “Paste-In” area, since it absolutely lacks any needed development features. Better alternatives at this point can be the usage of more professional editors like UltraEdit or Notepad++. If you only want to develop a small set of short Jython scripts this can be a starting point for you. If you plan to do a bit more development I would highly encourage the usage of a professional development environment. In this article I would like to show you how you can set up the Eclipse platform to perfectly act as a Maximo & ICD development environment. I will guarantee you that the benefits of this platform over time are major, even if it is a bit work to setup at the beginning.

Required Software

So before we start let’s figure out, which software is needed for the installation:

  • Eclipse Luna (Download) (64 Bit)
  • Java JRE or SDK V1.7 or V1.8 (64 Bit) *** please see notices below
  • Jython Interpreter V2.5.2 (Download) – Even it is quit old – this is the used Version in the product.

Notices on Java:
For the development of Jython scripts the used JRE or SDK is really important. For Maximo/SCCD 7.5.x (TPAE 7.5) you need at least a JRE Level of Version 1.6 for Maximo 7.6 (TPAE 7.6) you need at least a JRE Level Version 1.7. I personally always try to use the IBM Java in the version 1.7 and set the JRE Compliance level to 1.6 if needed. I will show you later on how to set this – don’t care for the moment.

The download of the IBM Java is a bit tricky to find. The base download page is can be found here. For Windows you need to download the complete “IBM Development Package for Eclipse”, extract it and take out the JRE directory. You should use Version 5.0 64-bit which includes Java 7.1 (1.7).

Installing the Prerequisites

The installation of the software is described in this section.

  1. Eclipse installation

For Eclipse no special installation is required. It basically only needs to be extracted to a folder of your choose. On the first start you can select the folder where you would like to store your eclipse workspace (data-directory).

  1. Java JRE (optional – you may use your system JRE)

Depending on the Java Version you have to either run a setup program or just copy some files. The installed Java does not have to be the system Java! This is important to know if you use different software on your computer which requires a certain version of Java.

If you use the “IBM Development Package for Eclipse” just extract the “ibm_sdk71” subfolder to a folder on your local harddisk for later usage.

  1. Jython 2.5.2 Installation

Jython Installation is quit straight forward using the setup program. During installation you are asked for the Java Home directory where you should be careful to select the one provided by the Java JRE Installation.

 

Configuration of the Java Environment (optional)

At this point we need to set up the correct Java Environment Eclipse should use.

  1. In Eclipse go to “Window –> Preferences”.
  2. In the left navigation pane go to “Java –> Installed JRE’s”. In the window on the right you should see the currently installed JRE selected. If you have installed an additional JRE and want to make this the default JRE select the Add button on the right.
  3. Select “Standard VM” and “Next…”
  4. The next screen requires the definition of the new JRE. If you select the correct installation directory for your JRE home the rest of the Fields should be filled in automatically:
    eclipsejre1
  5. After selecting “Finish” a new SDK is available. The SDK which is checked and bold is the default SDK.

At the end the right Java compiler must be selected:

  • Maximo 6: Java 1.4
  • Maximo 7: Java 1.5
  • Maximo 7.5.x: Java 1.6
  • Maximo 7.6: Java 1.7

Set it in Eclipse preferences: Windows –> Preferences –> Java –> Compiler  –> Compile compliance level.

eclipsejre2

Installing the maximo.ear

The maximo.ear contains most of the Java method’s to operate on all kinds of Mbo’s and MboSet’s within TPAE. One of the best features of using Eclipse in comparison to a simple text editor is, that we can include the businessobjects JAR file from your Maximo/ICD installation and that we have some syntax checking and input features for these classes. I will show you in a later post how we can utilize these features to make our life easier.

The best way to make the JAR file available is to create an own project in Eclipse for the referenced Java libraries.

  • Select “File –> New –> Java Project” in the Eclipse Workbench with the name “MaximoLibs”.
  • Copy [SMPDIR]\maximo\deployment\default\maximo.ear from your admin workstation into the new project.
  • Extract the following files from the maximo.ear file:
    • jar
    • war and extract the content to a directory named maximouiweb
    • lib/*.jar files to a directory lib
  • Refresh the project tree in Eclipse (F5). Your project should now looks like follow:
    eclipsejre3

Installing the PyDev Plug-In in Eclipse

After the initial start of Eclipse and the selection of a workspace directory you find yourself in the Welcome screen, which should be closed using the “Workbench” symbol in the upper right corner.

To install PyDev select the Menu “Help à Install new Software…”

  1. Enter the text http://pydev.org/updates into the Work with text box.
  2. Select only the PyDev checkbox
    pydev1
  3. Press the Next Button…
  4. You get the Installation Details displayed where you also can press “Next”
  5. Accept the License and press “Finish”. The installation starts.
  6. At the end of the installation you are asked to restart Eclipse. Please answer with “Yes”.

Configuring PyDev in Eclipse

To configure PyDev perform the following steps:

  1. After Restart, click Window and then click Preferences.
  2. Find the entry “Jython Interpreter” as shown in the picture and select “New…”
    pydev2
  1. Enter “Jython 2.5.2” as the Interpreter Name and find the jython.jar file from your previous Jython installation. Select “OK”.
    pydev3
  2. The configuration starts. Select OK in the dialog which appears.

At the End your Jython Interpreter Configuration should look similar to this one:

pydev4

Create a new PyDev project

Now create a new PyDev project where you can store you Jython sources.

  • Select: File –> New –> Project
  • Select the wizard PyDev Project and select Next
  • Enter a project Name and select the correct Project Type Jython and the Grammar Version 2.5 with your defined Interpreter.
    eclipsejre4
  • Press Finish.

You get a question if the associated PyDev perspective should be opened. Select Yes.

Congratulations you have your first Python/Jython project. There is still one little piece missing…

Referencing the Maximo Java libraries

In a previous step we have extracted the Maximo related Java libraries. To use them in our Jython project we need to reference them.

  • Right click to your new project in the PyDev Package Explorer window and select properties.
  • In the property window select the option “PyDev – PYTHONPATH”
  • Select the tab “External Libraries”.
  • Using the “Add zip/jar/egg” button you can add all required libraries from the referenced project. At least the businessobjects.jar file should be added, but all other jar files could be added in addition. At the end your configuration looks like this:
    pydev5

Creating your first Jython Script

To create the first Jython script right click on your newly created project and select New –> File in the Popup Menu. Select a filename of your choose with the extension “.py” and click on Finish.

You are asked for the Default Eclipse preferences for PyDev. Just click ok.

You are now ready to create your first Jython script, but this is a story for another post.

Using RMI from a Jython Script

The Remote Method Invocation (RMI) Interface of TPAE allows to connect from an external program to TPAE. Using RMI business objects can be red, written and updated by the control of a Jython script. To use RMI Scripting a current version of Jython has to be installed on the system where the script should be executed.

The script then connects to the RMI Port of TPAE which is by default Port 1099 (Maximo up to Version 6) or 13400 (Maximo 7 and higher). This port can be changed using the mxe.registry.port property. The following picture shows the concept:

RMI Base concept

Based on this knowledge we can develope our first RMI Script, which only connects to the MX Server and after that disconnects:

import psdi.util.MXSession as MXSession

session = MXSession.getSession()
session.setHost('192.168.158.135:13400/MXServer')
session.setUserName('maxadmin')
session.setPassword('maxadmin')
session.connect()

# ... Do your stuff here ...

session.disconnect()

One word to the Path “MXServer” in the setHost() function call. This has to be the name, which is provided in the Maximo Properties in the parameter mxe.name. This means, that you can have several RMI listeners for multiple Maximo installations on the same host (e.g. mx.name = MXTest, mx.name = MXProd).

In a second step the script can be extended to correctly handle error situations. To achive this you can utilize the Jython error handling functionality:

try:
# perform some task that may raise an exception

except Exception, value:
# perform some exception handling

finally:
# perform tasks that must always be completed (Will be performed before the exception is # raised.)

The new connection section of the script now looks as follows:

import psdi.util.MXSession as MXSession
from psdi.util import MXException

try:
    session = MXSession.getSession()
    session.setHost('192.168.158.135:13400/MXServer')
    session.setUserName('maxadmin')
    session.setPassword('maxadmin')
    session.connect()

except MXException, conex:
    print 'conex.getErrorGroup()     :',conex.getErrorGroup()
    print 'conex.getErrorKey()       :',conex.getErrorKey()
    print 'conex.getDetail()         :',conex.getDetail()
    print 'conex.getDisplayMessage() :',conex.getDisplayMessage()
    exit

# ... Do your stuff here ...

TPAE Scripting customization points

In this blog I will shortly document the different ways a Jython script can be triggered in TPAE. The following launch points and invocation methods are available to start a script:

Launch points

A launch point is a configuration objects which triggers an automation script if a certain condition occurs. When a launch point is deactivated, the script associated with that launch point does not run. The The following launch point types can be defined in TPAE:

Object Launch Point

  • Execute scripts on MBO events such as init, add, update, or delete (TPAE 7.5)
  • Starting from TPAE 7.6 this kind of Launch Point has a much more fine granular configuration.
  • Execute the script on:
    • Initialize Value: executed when the MBO is initialized
    • Validate Application: executed when the MBO is validated against business rules, but is not yet saved in the Database
    • Allow Object Creation: Indicates whether Maximo business objects can be created.
    • Allow Object Deletion: Indicates whether Maximo business objects can be deleted.
    • Save: executed in the process of saving the MBO. In this case more fine granular specifications about the execution time (before Save, after Save, After Commit) can be made.

Attribute Launch Point

  • Execute scripts based on the change of an attribute. This type of launchpoint is used for field validations or other actions.
  • Starting from TPAE 7.6 this kind of Launch Point has a much more fine granular configuration.
  • Execute the script on:
    • Initialize access restriction: Sets the access level for the attribute’s field. (Example: Read/Write to Read only)
    • Initialize value: Sets the initial value for the attribute’s field.
    • Validate: Checks whether the value in the attribute’s field is valid.
    • Retrieve list: Retrieves a list of valid values for the attribute’s field. For example, in an invoice, you can set up the supplier field to return a list of approved vendors.
    • Run action: Runs an action that is based on the value that is in the field.
  • Example can be found here

Action Launch Point

  • Execute scripts in the context of workflow/escalation actions
  • Execute scripts in the context of a Menu or Button (Sample here)

Custom condition Launch Point

  • Workflow conditions and conditional expressions can be utilized by Custom condition launch point

Other Methods

Manually Run from Scripting Application

  • Run a script without any launchpoint defined. (Sample here)

Remote Method Invocation (RMI)

  • Runs scripts from outside TPAE. See here for further details.

Interfaces (starting from Maximo 7.6)

  • Runs in context of Integration Framework to convert data