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 +1 -1
- data/README.md +29 -0
- data/Rakefile +1 -1
- data/lib/jmx/dynamic_mbean.rb +51 -31
- data/lib/jmx/version.rb +1 -1
- data/test/jmx_attribute_test.rb +4 -1
- data/test/jmx_client_test.rb +0 -2
- data/test/jmx_server_test.rb +72 -34
- metadata +3 -4
- data/README.txt +0 -29
data/Manifest.txt
CHANGED
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.
|
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
|
data/lib/jmx/dynamic_mbean.rb
CHANGED
@@ -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
|
113
|
-
|
114
|
-
operations <<
|
115
|
-
|
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
|
-
|
119
|
-
|
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
|
-
|
123
|
-
|
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(
|
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
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
151
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
224
|
+
metadata[:op].return_type = type
|
206
225
|
end
|
207
226
|
|
208
227
|
# Thread local storage for the derived bean
|
209
|
-
def self.
|
210
|
-
|
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.
|
216
|
-
attributes = self.class.
|
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
data/test/jmx_attribute_test.rb
CHANGED
@@ -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
|
|
data/test/jmx_client_test.rb
CHANGED
data/test/jmx_server_test.rb
CHANGED
@@ -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
|
-
|
62
|
-
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
assert_equal("
|
72
|
-
|
73
|
-
|
74
|
-
bean.
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
+
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-
|
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.
|
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
|