19 May 2006

Using Groovy for System Management

I've been funking around with Groovy in some of my spare time recently. My unabashed opinion is that Groovy is a wonderful scripting language since it enables me to use all the aspects of my favourite programming language in a very dynamic away.

One of my work mates, The Tugman(tm) -- made mention that Groovy has something called a GroovyMBean. Since I tend to work with the runtime and management areas of OC4J, I thought I'd check it out.

Turns out that the GroovyMBean provides a lovely little proxy over a MBean running on a server, enabling the MBean as if it was a standard object inside of Groovy. The GroovyMBean delegates all the calls made to it through to the underlying MBean it is wrappering.

Well that sounded quite interesting. But what's more interesting is the possibility that this opens up for the configuration and administration of OracleAS/OC4J 10.1.3.

How so?

Well OC4J and OracleAS 10.1.3 use MBeans for a lot of the actual server configuration and management tasks, as well as providing MBeans for all of the standard J2EE applications and artifacts. In fact, the management console in 10.1.3 (Application Server Control) uses JMX and the set of MBeans provided by OC4J to actually perform all of the operations it exposes in the GUI.

Thus armed with the GroovyMBean, it should be possible perform system and application administration and configuration tasks.

After a bit of playing around with it, it turns out it really IS possible to do.

As a simple illustation, here's an example of a script which displays the details of the JDK which is running an instance of OracleAS

client = new OC4JClient()
client.connect("localhost","23791","oc4jadmin","welcome1")

helper = client.helper

println "\n--> Access JVM MBean"
jvm = helper.createGroovyMBean("oc4j:J2EEServer=standalone,j2eeType=JVM,name=single")

println "\n--> Print selected attributes from JVM MBean"
println ""
println " JVM Vendor : $jvm.javaVendor"
println " JVM Version : $jvm.javaVersion"


Which when run shows:

--> Access JVM MBean

--> Print selected attributes from JVM MBean

JVM Vendor : Sun Microsystems Inc.
JVM Version : 1.5.0_04


This Groovy script simply establishes a connection to the MBeanServer running in the specified OracleAS instance, creates a GroovyMBean for the specified MBean and then displays some attributes from the MBean.

A close look at the script shows the use of two additional classes I developed when developing scripts.

  • OC4JClient -- this class makes establishing the connection to the MBeanServer running OracleAS/OC4J instance breeze. All you need to do is tell it where to connect to the server and a username and password to use. It will take care of all the details of creating the required JMX remote connection.

  • OC4JMBeanHelper -- this is the object type returned from client.helper property. The OC4JMBeanHelper provides a set of convenience methods for working with the set of OC4J System MBeans, for creating GroovyMBeans, etc.
While these additional classes are certainly not required, using them does reduce the amount of work required to work with the MBeans, reducing it down to simple scripting calls.

This is a simple illustation of a Groovy management script, but don't let it fool you. The exact same concepts can be applied using any of the OracleAS/OC4J MBeans to build up more powerful and wide ranging administration scripts.

As a further simple example, lets say you want to find out the running status of all the applications deployed to an OracleAS/OC4J instance. With groovy this is as simple as the below.

client = new OC4JClient()
client.connect("localhost","23791","oc4jadmin","welcome1")
helper = client.helper

// Print a header
30.times { print "----" }
print "\nName "
9.times { print "\t" }
println "State \t Startup \t"
30.times { print "----" }
println ""

// List all the application MBeans and print their state and startimes
for (String item : helper.AllApplicationMBeanNames ) {
app = helper.createGroovyMBean(item)
println "\n$app.objectName \t" + helper.decodeState(app.state) +"\t "+ new Date(app.startTime)
}
30.times { print "----" }
println ""

client.close()


Which when executed shows:
-------------------------------------------------------------------------------------------------------------
Name State Startup
-------------------------------------------------------------------------------------------------------------

oc4j:j2eeType=J2EEApplication,name=archer,J2EEServer=standalone RUNNING Fri May 19 11:19:02 CST 2006

oc4j:j2eeType=J2EEApplication,name=ascontrol,J2EEServer=standalone RUNNING Fri May 19 11:19:02 CST 2006

oc4j:j2eeType=J2EEApplication,name=default,J2EEServer=standalone RUNNING Fri May 19 11:19:01 CST 2006

oc4j:j2eeType=J2EEApplication,name=exploded,J2EEServer=standalone RUNNING Fri May 19 11:19:02 CST 2006

oc4j:j2eeType=J2EEApplication,name=system,J2EEServer=standalone RUNNING Fri May 19 11:19:00 CST 2006
-------------------------------------------------------------------------------------------------------------


Now want to see the configured users for each application?


client = new OC4JClient()
client.connect("localhost","23791","oc4jadmin","welcome1")
helper = client.helper

sysname = helper.getMBeanNameForJ2EEApplication("system")
sysapp = helper.createGroovyMBean(sysname)

println "System Users"
for(user in sysapp.users) {
println " $user.name"
}
client.close()


Which shows:
System Users
JtaAdmin
steve
oc4jadmin
anonymous
j2ee


The way I see it is that given administrators have common and/or regular tasks to perform, with type of direct scripting access to the OC4J System MBeans it provides them with the ability to capture those tasks in scripts.

Which can then be executed when needed, stored in a SCCS for posterity, shared with other users and administrators, etc.

I'll be posting a lot more about this over the coming weeks and plan to put the helper classes, some more detailed documentation and a set of starter scripts onto OTN over the next few weeks.

9 comments:

Archana said...

Hi Steave,
I am new to JMX. Few questions on MBean.
1- Can we configure no. of concurrent connections to JMXConnectionServer ?If so how?
2- What would one need to use connector architecture for remote accessibility. Can we not use normal API for this purpose ?
3-Does OC4J 10.1.3 supports JMX Remoting API ?
Thanks in advance,
archana shukla

buttso said...

gday Archana --
1. The MBeanServer running in OC4J does not need to be configured with a separate concurrent connection setting. The connector we use is via our ORMI protocol, so we just use connections available from the ORMI pool.

2. I'm not sure what you are asking, sorry.

3. Yes OC4J 10.1.3 supports the JMX remote API (JSR160).

SEA Dawg said...

Hi

I'm new to JMX and Groovy and read with interest what you're doing with the two. Would it be possible to create a Groovy script that for example would fully automate the creation and configuring of an OC4J instance, and then deploy an EAR of WAR file?

How could I go about putiing together the basics that would allow me to do this.

Also how would I set about crafting a class similar to the OC4JClient class (which I haven't seen) - which libraries would the class draw on for example?

Many thanks/Rgds/Zane

Richard Shu said...

I have the need to automate OC4J instance management remotely too, and would like to see "some more detailed documentation and a set of starter scripts", but not sure where I can find that. Can you shed some light on it? Thanks a lot.

Chris Gilbert said...

Hi,

This looks really useful for me too - I'm about to undertake a project on improving our monitoring of application and database servers for our customers, and so I'm looking at a more simple way to use JMX to do this, and groovy scripts seem appropriate.

It would also be useful for the upgrade tool our software uses. Is there any chance you could send me the sample classes you talk about here, or direct me to the right place on OTN?

You can send it to disciple3d at gmx dot co dot uk.

Thanks very much.

Chris

Buttso said...

Hey Chris -- I can send you the code helpers I have. It's not complete work and I haven't looked at it for a while, but you're welcome to it. The OC4JHelper class has quite a few methods to help make working with the OC4J MBean hierarchy a little more straightforward.

I recently did some work with WebLogic Server and Groovy and found that since I didn't have the helper class I ended up just doing a bunch of manual JMX queries using ObjectNames of the form to work with the MBean type I needed.

-steve-

Thomas said...

Thanks Steve, I'd appreciate that. I am not really a developer, I'm actually a DBA, so I always feel very over my head in programming this sort of thing, so anything that makes it simpler helps a lot!

thanks,

Chris

Brett said...

Is it possible to get the OC4J helper classes?

Anonymous said...

Hi Buttso,

This is quite interesting article. You said in your article"
In fact, the management console in 10.1.3 (Application Server Control) uses JMX and the set of MBeans provided by OC4J to actually perform all of the operations it exposes in the GUI."

I am new to use JMX and groovy.
I will appreciate you kind help if you can give me any sample code or example that can serve above purpose as you have explained.

With Regards,NV