Thursday, October 2, 2008

Make WLST scripts more flexible with Python's Getopt

My impression is that the audience of people who are learning and using the WebLogic Scripting Tool are not experienced Python programmers (I'm not, either). That's unfortunate, because Python (and Jython) have a lot of capabilities that can enhance your WLST scripts.

A natural "first script" in WLST probably hardcodes all the values that you might pass as command-line parameters in an ordinary shell script or Java class. Doing that limits the flexibility of your script, forcing you to modify it each time you need to change it's behavior slightly.

The solution is to use the Python getopt module, which works similarly to the feature available in Unix shell scripts. It also adds "long options", which the Perl getopt module provides.

For instance, the following is the beginning of a sample script that might be used to create a JMS module in a domain. Instead of hardcoding the parameters into the script, they're expected to be passed in on the command line. If any errors occur while gathering the command-line arguments, the "usage()" method is called, and the script exits.

import sys
import os
from java.lang import System

import getopt

def usage():
print "Usage:"
print "createJMSModule [-n] -u user -c credential -h host -p port -s serverName -m moduleName [-d subDeploymentName] -j jmsServerName"

try:
opts, args = getopt.getopt(sys.argv[1:], "nu:c:h:p:s:m:d:j:",
["user=", "credential=", "host=", "port=",
"targetServerName=", "moduleName=",
"subDeploymentName=", "jmsServerName="])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)

reallyDoIt = true
user = ''
credential = ''
host = ''
port = ''
targetServerName = ''
moduleName = ''
subDeploymentName = 'DeployToJMSServer'
jmsServerName = ''

for opt, arg in opts:
if opt == "-n":
reallyDoIt = false
elif opt == "-u":
user = arg
elif opt == "-c":
credential = arg
elif opt == "-h":
host = arg
elif opt == "-p":
port = arg
elif opt == "-s":
targetServerName = arg
elif opt == "-m":
moduleName = arg
elif opt == "-d":
subDeploymentName = arg
elif opt == "-j":
jmsServerName = arg

if user == "":
print "Missing \"-u user\" parameter."
usage()
sys.exit(2)
elif credential == "":
print "Missing \"-c credential\" parameter."
usage()
sys.exit(2)
elif host == "":
print "Missing \"-h host\" parameter."
usage()
sys.exit(2)
elif port == "":
print "Missing \"-p port\" parameter."
usage()
sys.exit(2)
elif targetServerName == "":
print "Missing \"-s serverName\" parameter."
usage()
sys.exit(2)
elif moduleName == "":
print "Missing \"-m moduleName\" parameter."
usage()
sys.exit(2)
elif jmsServerName == "":
print "Missing \"-j jmsServerName\" parameter."
usage()
sys.exit(2)

print "Got all the required parameters"


Calling WLST scripts from the shell requires actually calling the "wlst" application, and passing your script, and the additional command line parameters, as arguments to "wlst". For instance, this is the skeleton of a Bash script file (use Cygwin on Windows) that could be used to call this script. I assume that WEBLOGIC_HOME points to your WebLogic installation (like "c:/bea/weblogic92") and WLST_SCRIPTS_HOME points to your repository of scripts for execution.

#! /bin/bash
$WEBLOGIC_HOME/common/bin/wlst.cmd $WLST_SCRIPTS_HOME/src/samplegetopt.py "$@"

This would produce output like this (output in versions besides 9.2.2 might vary slightly):

% ./samplegetopt -n -u weblogic -c password -h somehost.somenet.com -p 8001 -s joe -m blow -j jmsserver

CLASSPATH=C:\bea\...

PATH=C:\bea\...

Your environment has been set.

CLASSPATH=C:\bea\...

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

Got all the required parameters

8 comments:

Brian Bouchard said...

Thanks for this post David. This is exactly what I've been looking for..

Brock Mills said...

Even better, you can run wlst as a straight jython app and get the wlst interpreter out of the way altogether

There's a couple of tricks (classpaths, some missing wlst functions etc) but it is well worth the effort as you can use classes and the like


http://satya-ghattu.blogspot.com/2006/01/wlst-as-jython-module_06.html

Greg said...

Just avoid using option '-i', it would be "eaten" by WLST interpreter!

By the way, the URL Brock Mills mentionned has moved to http://ghattus.com/2006/01/06/wlst-as-a-jython-module/.

path2progress said...

Hey David,
Great post. I want to know how we can use properties file insteadof the command line parameters?
I want to create around 50 queues and want to write a WLST that will read from the properties file and do the stuff. Any hints? clues?
loadProperties doesn't help. I am looking for soemthing that will allow me to iterate thru the properties and create queues in a loop.
Any help in this regard would be much appreciated.
Thanks in advance.

Unknown said...

I suggest you ask about this on the relevant Oracle forum that focuses on WLST issues: .

subbareddy said...

Subba

I got the following issue when i copy n pasted the above code in test.py and attemted to run in eclipse as Run AS - Python Run. Please help me out to fix the issue. Thanks in advance..

Traceback (most recent call last):
File "C:\Documents and Settings\cgontla.APAC\CAF_Workspace1\test_Python\src\com\example\test2.py", line 3, in
from java.lang import System
ImportError: No module named java.lang

Unknown said...

Well, yes, that's because this technically is a Jython script, not Python. Pure Python knows nothing about Java.

Unknown said...

Thanks David. This post Helped in running WLST in cygwin