jmx 0.5 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  Manifest.txt
2
2
  Rakefile
3
- README.txt
3
+ README.md
4
4
  LICENSE.txt
5
5
  lib/jmx
6
6
  lib/jmx.rb
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # JMX
2
+
3
+ ## DESCRIPTION:
4
+
5
+ JMX is a library which allows you to access JMX MBeans as a client or create
6
+ your own MBeans as a Ruby class.
7
+
8
+ ## FEATURES/PROBLEMS:
9
+
10
+ * Use '-J-Dcom.sun.management.jmxremote' to make jruby process accessible from a jruby command-line
11
+
12
+ ## SYNOPSIS:
13
+
14
+ Connect to same JVM as client script and look at Memory MBean
15
+
16
+ require 'jmx'
17
+
18
+ client = JMX.simple_connect(:port => 9999)
19
+
20
+ memory = client["java.lang:type=Memory"]
21
+ puts memory.attributes
22
+
23
+ ## REQUIREMENTS:
24
+
25
+ * JRuby
26
+
27
+ ## INSTALL:
28
+
29
+ * jruby -S gem install jmx
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- MANIFEST = FileList["Manifest.txt", "Rakefile", "README.txt", "LICENSE.txt", "lib/**/*", "samples/*","test/**/*"]
1
+ MANIFEST = FileList["Manifest.txt", "Rakefile", "README.md", "LICENSE.txt", "lib/**/*", "samples/*","test/**/*"]
2
2
 
3
3
  file "Manifest.txt" => :manifest
4
4
  task :manifest do
@@ -109,67 +109,86 @@ class RubyDynamicMBean
109
109
  # TODO: preserve any original method_added?
110
110
  # TODO: Error handling here when it all goes wrong?
111
111
  def self.method_added(name) #:nodoc:
112
- return if local_hash[:op].nil?
113
- local_hash[:op].name = name
114
- operations << local_hash[:op].to_jmx
115
- local_hash[:op] = nil
112
+ return if metadata[:op].nil?
113
+ metadata[:op].name = name
114
+ operations << metadata[:op].to_jmx
115
+ metadata[:op] = nil
116
116
  end
117
117
 
118
- def self.attributes #:nodoc:
119
- local_hash[:attrs] ||= []
118
+ # All attributes in this class
119
+ def self.attributes
120
+ metadata[:attrs] ||= []
121
+ end
122
+
123
+ # All attributes up the inheritance chain
124
+ def self.all_attributes
125
+ ancestors.inject([]) do |sum, clazz|
126
+ sum.concat(clazz.attributes) if clazz.respond_to? :attributes
127
+ sum
128
+ end
129
+ end
130
+
131
+ # All operations up the inheritance chain
132
+ def self.all_operations
133
+ ancestors.inject([]) do |sum, clazz|
134
+ sum.concat(clazz.operations) if clazz.respond_to? :operations
135
+ sum
136
+ end
120
137
  end
121
138
 
122
- def self.operations #:nodoc:
123
- local_hash[:ops] ||= []
139
+ # All operations in this class
140
+ def self.operations
141
+ metadata[:ops] ||= []
124
142
  end
125
143
 
126
- def self.define_getter(name, type)
144
+ def self.define_getter(name, type, reader)
127
145
  # FIXME: Our to_java_type needs to do something saner
128
146
  java_type = begin; to_java_type(type); rescue; nil; end
129
147
  value_proc = java_type ? proc { |value| java_type.new value } : proc { |value| Java.ruby_to_java value }
130
148
 
149
+ reader = name.to_s unless reader
150
+ attr_reader reader unless instance_methods.include?(reader)
131
151
  define_method("jmx_get_#{name.downcase}") do
132
- javax.management.Attribute.new name, value_proc.call(instance_variable_get('@' + name))
152
+ javax.management.Attribute.new name, value_proc.call(__send__(reader))
133
153
  end
134
154
  end
135
155
 
136
- def self.define_setter(name, type)
156
+ def self.define_setter(name, type, writer)
137
157
  value_converter = JMX::JavaTypeAware.to_ruby(type)
138
158
 
139
- define_method("jmx_set_#{name.downcase}") do |value|
140
- instance_variable_set '@' + name, value_converter.call(value)
141
- end
159
+ writer = name.to_s + '=' unless writer
160
+ attr_writer name.to_s unless instance_methods.include?(writer)
161
+ define_method("jmx_set_#{name.downcase}") do |value|
162
+ __send__ writer, value_converter.call(value)
163
+ end
142
164
  end
143
165
 
144
166
  # the <tt>rw_attribute</tt> method is used to declare a JMX read write attribute. See the +JavaSimpleTypes+
145
167
  # module for more information about acceptable types usage:
146
168
  # rw_attribute :attribute_name, :string, "Description displayed in a JMX console"
147
- def self.rw_attribute(name, type, description)
169
+ def self.rw_attribute(name, type, description, reader=nil, writer=nil)
148
170
  name = name.to_s
149
171
  attributes << JMX::Attribute.new(name, type, description, true, true).to_jmx
150
- attr_accessor name
151
- define_getter name, type
152
- define_setter name, type
172
+ define_getter name, type, reader
173
+ define_setter name, type, writer
153
174
  end
154
175
 
155
176
  # the <tt>r_attribute</tt> method is used to declare a JMX read only attribute. See the +JavaSimpleTypes+
156
177
  # module for more information about acceptable types usage:
157
178
  # r_attribute :attribute_name, :string, "Description displayed in a JMX console"
158
- def self.r_attribute(name, type, description)
179
+ def self.r_attribute(name, type, description, reader=nil)
159
180
  name = name.to_s
160
181
  attributes << JMX::Attribute.new(name, type, description, true, false).to_jmx
161
- attr_reader name
162
- define_getter name, type
182
+ define_getter name, type, reader
163
183
  end
164
184
 
165
185
  # the <tt>w_attribute</tt> method is used to declare a JMX write only attribute. See the +JavaSimpleTypes+
166
186
  # module for more information about acceptable types usage:
167
187
  # w_attribute :attribute_name, :string, "Description displayed in a JMX console"
168
- def self.w_attribute(name, type, description)
188
+ def self.w_attribute(name, type, description, writer=nil)
169
189
  name = name.to_s
170
190
  attributes << JMX::Attribute.new(name, type, description, false, true).to_jmx
171
- attr_writer name
172
- define_setter name, type
191
+ define_setter name, type, writer
173
192
  end
174
193
 
175
194
  # Use the operation method to declare the start of an operation
@@ -182,7 +201,7 @@ class RubyDynamicMBean
182
201
  #++
183
202
  def self.operation(description)
184
203
  # Wait to error check until method_added so we can know method name
185
- local_hash[:op] = JMX::Operation.new description
204
+ metadata[:op] = JMX::Operation.new description
186
205
  end
187
206
 
188
207
  # Used to declare a parameter (you can declare more than one in succession) that
@@ -192,7 +211,7 @@ class RubyDynamicMBean
192
211
  # def start
193
212
  # end
194
213
  def self.parameter(type, name=nil, description=nil)
195
- local_hash[:op].parameters << JMX::Parameter.new(type, name, description)
214
+ metadata[:op].parameters << JMX::Parameter.new(type, name, description)
196
215
  end
197
216
 
198
217
  # Used to declare the return type of the operation
@@ -202,18 +221,19 @@ class RubyDynamicMBean
202
221
  # def set_name
203
222
  # end
204
223
  def self.returns(type)
205
- local_hash[:op].return_type = type
224
+ metadata[:op].return_type = type
206
225
  end
207
226
 
208
227
  # Thread local storage for the derived bean
209
- def self.local_hash
210
- Thread.current[self.name] ||= {}
228
+ def self.metadata
229
+ @@metadata ||= {}
230
+ @@metadata[object_id] ||= {}
211
231
  end
212
232
 
213
233
  # when creating a dynamic MBean we need to provide it with a name and a description.
214
234
  def initialize(name, description)
215
- operations = self.class.operations.to_java MBeanOperationInfo
216
- attributes = self.class.attributes.to_java MBeanAttributeInfo
235
+ operations = self.class.all_operations.to_java MBeanOperationInfo
236
+ attributes = self.class.all_attributes.to_java MBeanAttributeInfo
217
237
  @info = MBeanInfo.new name, description, attributes, nil, operations, nil
218
238
  end
219
239
 
data/lib/jmx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module JMX
2
- VERSION = "0.5"
2
+ VERSION = "0.6"
3
3
  end
@@ -20,6 +20,10 @@ class MyAttributeDynamicBean < RubyDynamicMBean
20
20
  def fetch_number_write_only
21
21
  @number_write_only
22
22
  end
23
+
24
+ def my_reader
25
+ 42
26
+ end
23
27
  end
24
28
 
25
29
 
@@ -74,6 +78,5 @@ class JMXAttributeTest < Test::Unit::TestCase
74
78
  assert_equal("red", @madb.name)
75
79
  assert_equal(3, @madb.fetch_number_write_only)
76
80
  end
77
-
78
81
  end
79
82
 
@@ -1,5 +1,3 @@
1
- # In order to run these tests you must be running GFv2
2
-
3
1
  $:.unshift File.join(File.dirname(__FILE__),'..','lib')
4
2
 
5
3
  require 'test/unit'
@@ -1,7 +1,3 @@
1
- #
2
- # To change this template, choose Tools | Templates
3
- # and open the template in the editor.
4
-
5
1
 
6
2
  $:.unshift File.join(File.dirname(__FILE__),'..','lib')
7
3
 
@@ -11,6 +7,9 @@ require 'jmx'
11
7
 
12
8
  class MyDynamicMBean < RubyDynamicMBean
13
9
  rw_attribute :name, :string, "My sample attribute"
10
+ r_attribute :explicit_reader, :int, "Sample int with writer", :my_reader
11
+ w_attribute :explicit_writer, :int, "Sample int with writer", :my_writer
12
+ rw_attribute :explicit_both, :int, "Sample int with writer", :my_read, :my_write
14
13
 
15
14
  operation "Doubles a value"
16
15
  parameter :int, "a", "Value to double"
@@ -38,6 +37,31 @@ class MyDynamicMBean < RubyDynamicMBean
38
37
  def concat(list)
39
38
  list.inject("") { |memo, element| memo << element.to_s }
40
39
  end
40
+
41
+ def my_reader
42
+ 42
43
+ end
44
+
45
+ def my_writer(value)
46
+ @name = value.to_s
47
+ end
48
+
49
+ def my_read
50
+ @frogger
51
+ end
52
+
53
+ def my_write(value)
54
+ @frogger = value
55
+ end
56
+ end
57
+
58
+ class MyExtendedDynamicMBean < MyDynamicMBean
59
+ operation "Triples a value"
60
+ parameter :int, "a", "Value to triple"
61
+ returns :int
62
+ def triple(a)
63
+ a + a + a
64
+ end
41
65
  end
42
66
 
43
67
  class JMXServerTest < Test::Unit::TestCase
@@ -50,42 +74,56 @@ class JMXServerTest < Test::Unit::TestCase
50
74
  @connector = JMX::MBeanServerConnector.new(URL, @server)
51
75
  @connector.start
52
76
  @client = JMX::connect(:port => PORT)
77
+ reg_mbean
53
78
  end
54
-
79
+
80
+ def reg_mbean
81
+ dyna = MyDynamicMBean.new("domain.MySuperBean", "Heh")
82
+ @domain = @server.default_domain
83
+ @server.register_mbean dyna, "#{@domain}:type=MyDynamicMBean"
84
+ @bean = @client["#{@domain}:type=MyDynamicMBean"]
85
+ end
86
+
87
+ def unreg_mbean
88
+ @server.unregister_mbean "#{@domain}:type=MyDynamicMBean"
89
+ end
90
+
55
91
  def teardown
56
92
  @connector.stop
57
93
  @registry.stop
94
+ unreg_mbean
58
95
  end
59
96
 
97
+
60
98
  def test_ruby_mbean
61
- dyna = MyDynamicMBean.new("domain.MySuperBean", "Heh")
62
- domain = @server.default_domain
63
- @server.register_mbean dyna, "#{domain}:type=MyDynamicMBean"
64
-
65
- # Get bean from client connector connection
66
- bean = @client["#{domain}:type=MyDynamicMBean"]
67
- assert_equal("foo", bean.foo)
68
- assert_equal(6, bean.double(3))
69
- assert_raise(TypeError) { puts bean.double("HEH") }
70
- assert_equal("hehheh", bean.string_double("heh"))
71
- assert_equal("123", bean.concat([1,2,3]))
72
-
73
- assert_nil(bean.name)
74
- bean.name = "Name"
75
- assert_equal("Name", bean.name)
76
- end
77
-
78
- def test_ruby_mbean_twice
79
- dyna = MyDynamicMBean.new("domain.MySuperBean", "Heh")
80
- domain = @server.default_domain
81
- @server.unregister_mbean "#{domain}:type=MyDynamicMBean"
82
- @server.register_mbean dyna, "#{domain}:type=MyDynamicMBean"
83
- # Get bean from client connector connection
84
- bean = @client["#{domain}:type=MyDynamicMBean"]
85
- assert_equal("foo", bean.foo)
86
- assert_equal(6, bean.double(3))
87
- assert_raise(TypeError) { puts bean.double("HEH") }
88
- assert_equal("hehheh", bean.string_double("heh"))
89
- assert_equal("123", bean.concat([1,2,3]))
99
+ assert_equal("foo", @bean.foo)
100
+ assert_equal(6, @bean.double(3))
101
+ assert_raise(TypeError) { puts @bean.double("HEH") }
102
+ assert_equal("hehheh", @bean.string_double("heh"))
103
+ assert_equal("123", @bean.concat([1,2,3]))
104
+ end
105
+
106
+ def test_ruby_mbean_attribtues
107
+ assert_nil(@bean.name)
108
+ @bean.name = "Name"
109
+ assert_equal("Name", @bean.name)
110
+
111
+ assert_equal(42, @bean.explicit_reader)
112
+ @bean.explicit_writer = 69
113
+ # explicit_writer changes attribute name as a side-effect
114
+ assert_equal("69", @bean.name)
115
+
116
+ @bean.explicit_both = 1
117
+ assert_equal(1, @bean.explicit_both)
118
+ end
119
+
120
+ def test_extended_mbean
121
+ dyna = MyExtendedDynamicMBean.new("domain.MySuperBean", "Heh")
122
+ @server.register_mbean dyna, "#{@domain}:type=MyExtendedDynamicMBean"
123
+ @bean = @client["#{@domain}:type=MyExtendedDynamicMBean"]
124
+
125
+ assert_equal(12, @bean.triple(4))
126
+
127
+ @server.unregister_mbean "#{@domain}:type=MyExtendedDynamicMBean"
90
128
  end
91
129
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: jmx
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: "0.5"
5
+ version: "0.6"
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas Enebo & Jay McGaffigan
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-18 00:00:00 -05:00
13
+ date: 2011-03-23 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -22,12 +22,11 @@ extensions: []
22
22
 
23
23
  extra_rdoc_files:
24
24
  - Manifest.txt
25
- - README.txt
26
25
  - LICENSE.txt
27
26
  files:
28
27
  - Manifest.txt
29
28
  - Rakefile
30
- - README.txt
29
+ - README.md
31
30
  - LICENSE.txt
32
31
  - lib/jmx.rb
33
32
  - lib/rmi.rb
data/README.txt DELETED
@@ -1,29 +0,0 @@
1
- = JMX
2
-
3
- == DESCRIPTION:
4
-
5
- JMX is a library which allows you to access JMX MBeans as a client or create
6
- your own MBeans as a Ruby class.
7
-
8
- http://jruby-extras.rubyforge.org/jmx/
9
-
10
- == FEATURES/PROBLEMS:
11
-
12
- * Use '-J-Dcom.sun.management.jmxremote' to make jruby process accessible from a jruby command-line
13
-
14
- == SYNOPSIS:
15
-
16
- require 'jmx'
17
-
18
- client = JMX.simple_connect(:port => 9999)
19
-
20
- memory = client["java.lang:type=Memory"]
21
- puts memory.attributes
22
-
23
- == REQUIREMENTS:
24
-
25
- * JRuby
26
-
27
- == INSTALL:
28
-
29
- * jruby -S gem install jmx