Thursday, 10 February 2011

JRuby script to access Oracle Coherence MBean attributes

I found a ruby gem known as "jmx4r" to use JMX from JRuby. The aim here was to use that to display details of an MBean's attributes but found it not as easy as I thought it would be. Here are 2 ways I did that, to be honest using option 2 seemed the better way to do this.

Option 1

In this example here I have using Ruby to make dynamic method calls based on the attribute value.

require 'java'
require 'rubygems'
require 'jmx4r'

def display_array (meth)
  data = ""
  
  meth.call.send("each") do |x|
    data += "\n\t" + x.to_s
  end
  
  return data
end

def display_attribute_data(key, mbean)
  meth = mbean.method(key)
  data = ""
  s = meth.call.to_s
  if (/^\[Ljava.lang.String/.match(s))
    # we have a String[] array with data
    return display_array meth
  elsif (/^\[I/.match(s))
    return display_array meth
  else
    return s
  end

end

url = "service:jmx:rmi://localhost:3000/jndi/rmi://localhost:9000/server"
conn = JMX::MBean.establish_connection :url => url
    
mbean = JMX::MBean.find_by_name "Coherence:type=Cluster"

# display attributes key/values
mbean.attributes.each do |key, value|  
 puts "Name: #{key}, Value: #{display_attribute_data key, mbean}\n"
end

# puts "\n\n** PRETTY PRINT DISPLAY attributes/method descriptions ** \n"
#JMX::MBean.pretty_print "Coherence:type=Cluster", :url => url
Output

Name: local_member_id, Value: 2
Name: cluster_size, Value: 2
Name: license_mode, Value: Development
Name: members_departed, Value:
Name: refresh_time, Value: Thu Feb 10 14:40:21 EST 2011
Name: cluster_name, Value: cluster:0xC4DB
Name: running, Value: true
Name: oldest_member_id, Value: 1
Name: members, Value:
        Member(Id=1, Timestamp=2011-02-10 14:38:05.783, Address=10.187.114.243:8088, MachineId=50163, Location=machine:paslap-au,process:662
0, Role=CoherenceServer)
        Member(Id=2, Timestamp=2011-02-10 14:38:15.57, Address=10.187.114.243:8090, MachineId=50163, Location=machine:paslap-au,process:2992
, Role=TangosolNetMBeanConnector)
Name: version, Value: 3.6.0.0
Name: members_departure_count, Value: 0
Name: member_ids, Value:
        1
        2


Option 2

In this example I get a JAVA javax.management.ObjectName so I can easily obtain attribute values by name. In this example I don't make any effort to format the value for the attribute should it be an array type. I could easily just use the code I did in option 1 above.
require 'java'
require 'rubygems'
require 'jmx4r'

java_import 'javax.management.ObjectName'

def display_attribute_data(conn, object_name, attribute)  
  return conn.get_attribute object_name, attribute
end

url = "service:jmx:rmi://localhost:3000/jndi/rmi://localhost:9000/server"
conn = JMX::MBean.establish_connection :url => url
    
mbean = JMX::MBean.find_by_name "Coherence:type=Cluster"
object_name = ObjectName.new "Coherence:type=Cluster"

# display attributes key/values
mbean.attributes.each do |key, value|  
 puts "Name: #{value}, Value: #{display_attribute_data conn, object_name, value}\n"
end 
Output

Name: LocalMemberId, Value: 2
Name: ClusterSize, Value: 2
Name: LicenseMode, Value: Development
Name: MembersDeparted, Value: [Ljava.lang.String;@725967
Name: RefreshTime, Value: Thu Feb 10 14:41:25 EST 2011
Name: ClusterName, Value: cluster:0xC4DB
Name: Running, Value: true
Name: OldestMemberId, Value: 1
Name: Members, Value: [Ljava.lang.String;@6e3e5e
Name: Version, Value: 3.6.0.0
Name: MembersDepartureCount, Value: 0
Name: MemberIds, Value: [I@9b87f6

No comments: