Permalink
Browse files

Add attribute support for MBean (patch by Jay McGaffigan)

git-svn-id: svn+ssh://rubyforge.org/var/svn/jruby-extras/trunk/jmx@1043 8ba958d5-0c1a-0410-94a6-a65dfc1b28a6
  • Loading branch information...
1 parent 8709ec0 commit 6956ec297066b872d72735d8da3555112faa9643 enebo committed Jul 6, 2008
Showing with 119 additions and 16 deletions.
  1. +3 −2 Manifest.txt
  2. +113 −13 lib/jmx/dynamic_mbean.rb
  3. +1 −1 lib/jmx/version.rb
  4. +2 −0 nbproject/project.properties
View
@@ -3,11 +3,12 @@ Rakefile
README.txt
LICENSE.txt
lib/jmx
-lib/jmx.rb
-lib/rmi.rb
lib/jmx/dynamic_mbean.rb
lib/jmx/server.rb
lib/jmx/version.rb
+lib/jmx.rb
+lib/rmi.rb
samples/memory.rb
+test/jmx_attribute_test.rb
test/jmx_client_test.rb
test/jmx_server_test.rb
@@ -1,21 +1,28 @@
module JMX
import javax.management.MBeanParameterInfo
import javax.management.MBeanOperationInfo
+ import javax.management.MBeanAttributeInfo
import javax.management.MBeanInfo
module JavaTypeAware
SIMPLE_TYPES = {
- :int => 'java.lang.Integer',
- :list => 'java.util.List',
- :long => 'java.lang.Long',
- :map => 'java.util.Map',
- :set => 'java.util.Set',
- :string => 'java.lang.String',
- :void => 'java.lang.Void'
+ :int => ['java.lang.Integer', lambda {|param| param.to_i}],
+ :list => ['java.util.List', lambda {|param| param.to_a}],
+ :long => ['java.lang.Long', lambda {|param| param.to_i}],
+ :float => ['java.lang.Float', lambda {|param| param.to_f}],
+ :map => ['java.util.Map', lambda {|param| param}],
+ :set => ['java.util.Set', lambda {|param| param}],
+ :string => ['java.lang.String', lambda {|param| "'#{param.to_s}'"}],
+ :void => ['java.lang.Void', lambda {|param| nil}]
}
def to_java_type(type_name)
- SIMPLE_TYPES[type_name] || type_name
+ SIMPLE_TYPES[type_name][0] || type_name
+ end
+ #TODO: I'm not sure this is strictly needed, but funky things can happen if you
+ # are expecting your attributes (from the ruby side) to be ruby types and they are java types.
+ def to_ruby(type_name)
+ SIMPLE_TYPES[type_name][1] || lambda {|param| param}
end
end
@@ -44,10 +51,31 @@ def to_jmx
MBeanOperationInfo.new name.to_s, description, java_parameters.to_java(javax.management.MBeanParameterInfo), to_java_type(return_type), impact
end
end
+
+
+ class Attribute < Struct.new(:name, :type, :description, :is_reader, :is_writer, :is_iser)
+ include JavaTypeAware
+
+ def initialize(name, type, description, is_rdr, is_wrtr)
+ super
+ self.description, self.type, self.name = description, type, name
+ self.is_reader,self.is_writer, self.is_iser = is_rdr, is_wrtr, false
+ end
+
+ def to_jmx
+ MBeanAttributeInfo.new(name.to_s, to_java_type(type), description, is_reader, is_writer, is_iser)
+ end
+ end
end
+
+=begin rdoc
+ Inherit from this class to create your own ruby based dynamic MBean
+=end
class RubyDynamicMBean
import javax.management.MBeanOperationInfo
+ import javax.management.MBeanAttributeInfo
+ include JMX::JavaTypeAware
# TODO: preserve any original method_added?
# TODO: Error handling here when it all goes wrong?
@@ -66,6 +94,61 @@ def self.operations
Thread.current[:ops] ||= []
end
+ #methods used to create an attribute. They are modeled on the attrib_accessor
+ # patterns of creating getters and setters in ruby
+ def self.rw_attribute(name, type, description)
+ #QUESTION: Is this here to ensure that our type implements the interface?
+ include DynamicMBean
+ attributes << JMX::Attribute.new(name, type, description, true, true).to_jmx
+ attr_accessor name
+ #create a "java" oriented accessor method
+ define_method("jmx_get_#{name.to_s.downcase}") do
+ begin
+ #attempt conversion
+ java_type = to_java_type(type)
+ value = eval "#{java_type}.new(@#{name.to_s})"
+ rescue
+ #otherwise turn it into a java Object type for now.
+ value = eval "Java.ruby_to_java(@#{name.to_s})"
+ end
+ attribute = javax.management.Attribute.new(name.to_s, value)
+ end
+
+ define_method("jmx_set_#{name.to_s.downcase}") do |value|
+ blck = to_ruby(type)
+ eval "@#{name.to_s} = #{blck.call(value)}"
+ end
+
+ end
+ # used to create a read only attribute
+ def self.r_attribute(name, type, description)
+ include DynamicMBean
+ attributes << JMX::Attribute.new(name, type, description, true, false).to_jmx
+ attr_reader name
+ #create a "java" oriented accessor method
+ define_method("jmx_get_#{name.to_s.downcase}") do
+ begin
+ #attempt conversion
+ java_type = to_java_type(type)
+ value = eval "#{java_type}.new(@#{name.to_s})"
+ rescue
+ #otherwise turn it into a java Object type for now.
+ value = eval "Java.ruby_to_java(@#{name.to_s})"
+ end
+ attribute = javax.management.Attribute.new(name.to_s, value)
+ end
+ end
+ # used to create a read only attribute
+ def self.w_attribute(name, type, description)
+ include DynamicMBean
+ attributes << JMX::Attribute.new(name, type, description, false, true).to_jmx
+ attr_writer name
+ define_method("jmx_set_#{name.to_s.downcase}") do |value|
+ blck = to_ruby(type)
+ eval "@#{name.to_s} = #{blck.call(value)}"
+ end
+ end
+
# Last operation wins if more than one
def self.operation(description)
include DynamicMBean
@@ -84,17 +167,34 @@ def self.returns(type)
def initialize(name, description)
operations = self.class.operations.to_java(MBeanOperationInfo)
- @info = MBeanInfo.new name, description, nil, nil, operations, nil
+ attributes = self.class.attributes.to_java(MBeanAttributeInfo)
+ @info = MBeanInfo.new name, description, attributes, nil, operations, nil
end
- def getAttribute(attribute); $stderr.puts "getAttribute"; end
- def getAttributes(attributes); $stderr.puts "getAttributes"; end
+ def getAttribute(attribute)
+ send("jmx_get_"+attribute.downcase)
+ end
+
+ def getAttributes(attributes)
+ attrs = javax.management.AttributeList.new
+ attributes.each { |attribute| attrs.add(getAttribute(attribute)) }
+ attrs
+ end
+
def getMBeanInfo; @info; end
+
def invoke(actionName, params=nil, signature=nil)
send(actionName, *params)
end
- def setAttribute(attribute); $stderr.puts "setAttribute"; end
- def setAttributes(attributes); $stderr.puts "setAttributes"; end
+
+ def setAttribute(attribute)
+ send("jmx_set_#{attribute.name.downcase}", attribute.value)
+ end
+
+ def setAttributes(attributes)
+ attributes.each { |attribute| setAttribute attribute}
+ end
+
def to_s; toString; end
def inspect; toString; end
def toString; "#@info.class_name: #@info.description"; end
View
@@ -1,3 +1,3 @@
module JMX
- VERSION = "0.1"
+ VERSION = "0.2"
end
@@ -1,4 +1,6 @@
+javac.classpath=
main.file=main.rb
+ruby.includejava=false
source.encoding=UTF-8
src.dir=lib
test.src.dir=test

0 comments on commit 6956ec2

Please sign in to comment.