Upload Jython Scripts from Eclipse to Maximo/ICD

In this post I would like to introduce a cool feature to upload your Jython scripts developed in Eclipse directly to Maximo/ICD without the need to jump to the scripting application and doing some copy/paste actions. To Archive this objective we will utilize the Integration Framework and will write a small Jython script to be called from Eclipse and utilizing this interface. I will show you step by step the different configuration steps.

This is a quit complex configuration to do and there are a lot of places to introduce errors so that the complete system will not work. Please post me your experiences with the configuration as a comment so I can improve this article over time.

Prerequisites

What are the prerequisites for our project:

  1. An Eclipse Installation with PyDev integrated where you develop your Jython Scripts
  2. A local Jython 2.x installation (which should normally already be in place). Please consider that we need a full installation and it is not enough to just have a copy of the jython.jar file since we need some standard Jython libraries for our project.
  3. Access to a Maximo/ICD System

The solution currently only has been tested with local authorization. The Upload script might need slight modifications for LDAP authorization (comments welcome :-).

The solution currently only supports http protocol. If you are using https the upload script might need some modifications.

Preparations Integration Framework in Maximo/ICD

Create a new Object Structure

We need to create an own Object Structure based on the existing MXScript Structure.

  1. Go to menu Integration → Object Structure and search the MXScript Object Structure.
  2. Duplicate the Object Structure (Select Action → Duplicate Object Structure)
    jythoneclupl1
  3. The new Object Structure should be called JYSCRIPT unless you want to edit the upload script later on.
  4. Remove the Source Object „AUTOSCRIPT/VARSThe configuration for the duplicated Object Structure should now look like this:jyecli02
  5. Select Action → Exclude/Include Fields
    Exclude all fields except the following ones:
    • AUTOSCRIPT
    • DESCRIPTION
    • LOGLEVEL
    • SCRIPTLANGUAGE
    • SOURCE
    • VERSION

Create an Enterprise Service

A new Enterprise Service must be created.

  1. Go to menu Integration → Enterprise Services
  2. Create a new Record and fill in the following fields only:
    jyecli03
  3. Save the Enterprise Services

Create an External System

A new External System must be created by the following steps:

  1. Go to menu Integration → External Systems
  2. Create a new Record and fill in the System Tab with the following values:
    jyecli04
  3. Be sure all fields are filled in as shown
  4. Select the tab “Enterprise Services” and create a connection to the previously created Enterprise service. For this select the “New Row” button. Fill in the new line as follows:
    jyecli05
  5. Be sure that the enabled box is checked.
  6. Save the External System. The configuration on the Maximo/ICD side is now finished.

 Configuration of the Eclipse Side

The configuration of Eclipse consist of two steps:

  • Prepare Upload Script
  • Create a “Run entry” in the Run configuration.

Prepare Upload Script

Take the following script and store it in a place of a Eclipse project. The project should have a valid Jython Runtime configured. Please have a look to this article for proper Eclipse setup if you are unsure.

#-------------------------------------------------------------
# AUTOSCRIPT:         UPLOADSCRIPT
# DESCRIPTION:        Script to upload Jython Scripts from
#                     Eclipse to Maximo / ICD
# AUTHOR:             Matthias Stroske
# Created             25.11.15
# VERSION:            1.0
# COPYRIGHT:          (c) Matthias Stroske
# MAXIMO/ICD Version: 7.5 and higher
#-------------------------------------------------------------
# History of Changes
#
# Ver  Date      Name               Description
# 1.0  01.10.15  Matthias Stroske   Initial Version
# 1.1  25.11.15  Matthias Stroske   Improved Parameter Handling
#
#-------------------------------------------------------------
 
import sys
import httplib
import base64
import string
import re
from xml.sax.saxutils import escape
 
def main():
    if len(sys.argv) < 5:
        print "USAGE: UploadScript.py <inDatei> <host> <user> <password>"
        sys.exit()
 
    inDatei = sys.argv[1]
    host = sys.argv[2]
    user = sys.argv[3]
    password = sys.argv[4]
     
    # Set Defaults as far as possible
    scriptName = None
    scriptDescription = None
    logLevel = "ERROR"
    version = "1.0"
 
    httpUrl = "http://" + host + "/meaweb/es/JYSCRIPT/JYSCRIPT"
 
    try:
        f = open(inDatei)
        fileContent = f.read()
    except Exception,ex:
        print ("Error reading the input file!")
        print ("Exception:" + str(ex))
    else:
        f.close
 
    firstLines = fileContent.split("\n", 15)
    for line in firstLines:
        matchObj = re.match(r'^#\s*DESCRIPTION:(.*)',line, re.I)
        if matchObj:
            scriptDescription = matchObj.group(1)
        matchObj = re.match(r'^#\s*AUTOSCRIPT:(.*)', line, re.I)
        if matchObj:
            scriptName = matchObj.group(1)
        matchObj = re.match(r'^#\s*LOGLEVEL:(.*)', line, re.I)
        if matchObj:
            logLevel = matchObj.group(1)
        # Simple Style
        matchObj = re.match(r'^#\s*VERSION:(.*)', line, re.I)
        if matchObj:
            version = matchObj.group(1)
        # CVS Style
        matchObj = re.match(r'^#\s*Revision:(.*)', line, re.I)
        if matchObj:
            version = matchObj.group(1)
             
 
    if scriptName is None or scriptDescription is None:
        print "ScriptName and ScriptDescription have to be specified in first Script Lines!"
        sys.exit()
 
    print "Script Name       = " + scriptName.strip()
    print "DESCRIPTION       = " + scriptDescription.strip()
    print "LOGLEVEL          = " + logLevel.strip()
    print "VERSION           = " + version.strip()
          
    message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    message += "<SyncJYSCRIPT xmlns=\"http://www.ibm.com/maximo\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
    message += "<JYSCRIPTSet>\n"
    message += "<AUTOSCRIPT>\n"
    message += "<AUTOSCRIPT>" + scriptName.strip() + "</AUTOSCRIPT>\n"
    message += "<DESCRIPTION>" + scriptDescription.strip() + "</DESCRIPTION>\n"
    message += "<LOGLEVEL>" + logLevel.strip() + "</LOGLEVEL>\n"
    message += "<SCRIPTLANGUAGE>jython</SCRIPTLANGUAGE>\n"
    message += "<VERSION>" + version.strip() + "</VERSION>\n"
    message += "<SOURCE>\n"
    message += escape(fileContent)
    #message += "pass\n"
    message += "</SOURCE>\n"
    message += "</AUTOSCRIPT>\n"
    message += "</JYSCRIPTSet>\n"
    message += "</SyncJYSCRIPT>\n"
    message += "\n"
 
    contentType = "application/soap+xml;charset=UTF-8;action=\"urn:processDocument\""
    auth = 'Basic ' + string.strip(base64.encodestring( user + ':' + password))
     
    webservice = httplib.HTTPConnection(host)
    #webservice.set_debuglevel(5) 
    headers = {"Content-type": contentType, "Content-Length": len(message), "Authorization": auth}
    webservice.request("POST", httpUrl, message, headers)
             
    # get the response
    res = webservice.getresponse()
     
    if res.status == 200:
        print "Script upload successful!"
    else:
        print "Script upload completed with RC = " + str(res.status)
     
    webservice.close()
    return
      
if __name__ == "__main__":
    main()

Eclipse External Tools configuration

To run the script in context of Eclipse you need to do an additional configuration step in Eclipse.

Find the following Icon in the Eclipse iconbar:   Selection_004

Select the little arrow beside the icon to expand the menu and select “External Tools Configurations…”

Menu_016

In the following Window fill in the Head section with the Name of the configuration.

Continue to fill in the  Main tab with the following values:

  • Location: The location of your locally installed Jython interpreter.
  • Working Directory: should be ${workspace_loc:/<ProjectName}
  • Arguments: 5 Arguments for the Jython interpreter to run.
    1. Name of Jython Upload Script: e.G. ${workspace_log:/Blog/UloadScript.py}
    2. Name of the Script to be uploaded: Best we can specify here is always: ${workspace_loc}${selected_resource_path}
    3. Maximo / ICD Host: IP Adress or Hostname of the Maximo Server
    4. Username in Maximo / ICD
    5. Password in Maximo / ICD  *** yes I know it is not good to store the PW in clear-text. With little modifications you could store it base64 encoded here if you modify the Jython script slightly.

Selection_017

Preparing your script and using the new tool

Preparing your script

To use the new tool your script must follow a little convention. The first 15 lines must include relevant information which are required to synchronize the script with Maximo/ICD.

#AUTOSCRIPT: UPLOADSCRIPT
#DESCRIPTION: PYTHON UPLOAD SCRIPT 2
#LOGLEVEL: ERROR
#VERSION: 1.0

This are fields which map to the appropriate fields in Maximo/ICD. The AUTOSCRIPT field is the Name of the Autoscript in Maximo/ICD. With the upload you can create new automation scripts, but you can not create or modify any launchpoints. When you change the DESCRIPTION,VERSION or LOGLEVEL field later on these fields are modified in Maximo/ICD.

I have created a base template for your code, which can be found in this blog.

Using the new Tool

To use the tool we assume, that you are now editing your custom Maximo/ICD Jython script with the information lines included and some Jython Code. From this place you just need to run the Upload Script by Clicking the Run external Symbol in the iconbar again. Selection_004 A script with the name you have chosen during configuration should appear in the drop down list.

After some second you will hopefully get a response “Script upload successful”  in the Console View of Eclipse. Otherwise you’ll get an error with the http Return Code.

Selection_046

I hope the solution will work in your environment!

9 comments

  • I tried the eclipse upload integration to maximo in your article.
    I was able to follow the steps.
    One thing to note is that we use https, so you may update article that the protocol may need to be tweeked.

    Also, it looks like the first argument to the script is the python script to upload. It was not clear to me that that was the argument. I entered first arguments as indicated in article and it tried to upload the upload script. Not sure why you would want to upload the upload script.

    I tried to run this an I get a connection refused. It seems to use http protocol and I know I have those ports open. I see JMS is used in the service. Do I need to open a different port for this method to work? Or is there some other item I need to enable to get this to work? Exclipse is installed on the maximo server.

    Here is the trace:
    Traceback (most recent call last):
    File “/root/workspace/Maximo/upload.py”, line 85, in
    main()
    File “/root/workspace/Maximo/upload.py”, line 75, in main
    webservice.request(“POST”, httpUrl, message, headers)
    File “/root/jython2.5.2/Lib/httplib.py”, line 866, in request
    self._send_request(method, url, body, headers)
    File “/root/jython2.5.2/Lib/httplib.py”, line 889, in _send_request
    self.endheaders()
    File “/root/jython2.5.2/Lib/httplib.py”, line 860, in endheaders
    self._send_output()
    File “/root/jython2.5.2/Lib/httplib.py”, line 732, in _send_output
    self.send(msg)
    File “/root/jython2.5.2/Lib/httplib.py”, line 699, in send
    self.connect()
    File “/root/jython2.5.2/Lib/httplib.py”, line 683, in connect
    raise socket.error, msg
    socket.error: (111, ‘Connection refused’)

    • The first argument makes sense when you are calling the upload script from within your Jython script you would like to upload to ICD/Maximo. This also means, when you are running the upload script while you edit the upload script this script will be uploaded. Unfortunately I made some errors in documenting the “Run Configurations” – it needs to be the “Run external Tools configuration” instead. This has been corrected in the Blog Post now.

      Your point regarding HTTPS is really valid. The script currently only supports http connections since I didn’t had a customer scenario with https so far. If you want you can try modifying the script by yourself. I think we have to change line 72 in the script (httplib.HTTPConnection). There is a httplib.HTTPSConnection method available in the Python httplib library. This call requires some more parameters and needs to be tested (maybe you do not need them at all). HTTPLib Reference can be found here: http://www.jython.org/docs/library/httplib.html

  • Very useful trick Matthias.
    I think you can use an OS service instead of a web service.
    This will simplify the setup since you will not need to define an external system and enterprice service but just the object structure.

  • I follwed your instructions and everythings seems to be ok. But when I run the script to upload a automationscript I get the response code 500 from the webservice. This means that there is a “Internal Server Error”.
    I don´t know what to do now. Do you have some tips about this problem? Is there something what I can analyze furthermore?

    • Server response code 500 is really very generic. One thing you could do is to verify the Maximo setup first. Try to open the following URL (replace the IP):

      http://192.168.158.127/meaweb/es/JYSCRIPT/JYSCRIPT

      If you get a message “Servlet is running. Please use HTTP POST to post data” then the Maximo setup seems to work correctly.

      Next thing you should doublecheck your Eclipse configuration… Is the External Tools configuration correctly? Has it the correct 4 parameters?

      I hope one of the points will solve your issue.

  • If any one wants to configure this with IntelliJ then
    In Settings Configure a New External Tool.
    1. In Program field give location to jython.bat
    2. In Parameters field give these parameters. (replace IP, user and password with your own settings.)
    $FileDir$\uploadScript.py $FileDir$\$FileName$ 127.0.0.1 user password
    3. In Working directory given Jython’s bin folder path

  • Excellent Article, Matthias,
    I followed steps till the end correctly and ran the program. But I get get error RC : 401.

    When I do the same thing is POSTMAN, I get an internal server error (500).

    Bruno, in his article says that we have to use MAXAUTH. Do you think we have do it the same in this sricpt as well?

    • I know that the script might have some issues in some kind of environments. Maybe it could be a try to change the authentication string from Basic authentication to a MAXAUTH property. I think it could be worth a test.