jmx 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Thomas E Enebo <enebo@acm.org>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,13 @@
1
+ Manifest.txt
2
+ Rakefile
3
+ README.txt
4
+ LICENSE.txt
5
+ lib/jmx
6
+ lib/jmx/dynamic_mbean.rb
7
+ lib/jmx/server.rb
8
+ lib/jmx/version.rb
9
+ lib/jmx.rb
10
+ lib/rmi.rb
11
+ samples/memory.rb
12
+ test/jmx_client_test.rb
13
+ test/jmx_server_test.rb
data/README.txt 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
+ 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
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ MANIFEST = FileList["Manifest.txt", "Rakefile", "README.txt", "LICENSE.txt", "lib/**/*", "samples/*","test/**/*"]
2
+
3
+ file "Manifest.txt" => :manifest
4
+ task :manifest do
5
+ File.open("Manifest.txt", "w") {|f| MANIFEST.each {|n| f << "#{n}\n"} }
6
+ end
7
+ Rake::Task['manifest'].invoke # Always regen manifest, so Hoe has up-to-date list of files
8
+
9
+ $LOAD_PATH << 'lib'
10
+ require 'jmx/version'
11
+ begin
12
+ require 'hoe'
13
+ Hoe.new("jmx", JMX::VERSION) do |p|
14
+ p.rubyforge_name = "jruby-extras"
15
+ p.url = "http://jruby-extras.rubyforge.org/jmx"
16
+ p.author = "Thomas Enebo"
17
+ p.email = "enebo@acm.org"
18
+ p.summary = "Package for interacting/creating Java Management Extensions"
19
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
20
+ p.description = "Install this gem and require 'jmx' to load the library."
21
+ end.spec.dependencies.delete_if { |dep| dep.name == "hoe" }
22
+ rescue LoadError
23
+ puts "You need Hoe installed to be able to package this gem"
24
+ rescue => e
25
+ p e.backtrace
26
+ puts "ignoring error while loading hoe: #{e.to_s}"
27
+ end
data/lib/jmx.rb ADDED
@@ -0,0 +1,210 @@
1
+ include Java
2
+
3
+ require 'rmi'
4
+ require 'jmx/dynamic_mbean'
5
+ require 'jmx/server'
6
+
7
+ import java.util.ArrayList
8
+ import javax.management.Attribute
9
+ import javax.management.DynamicMBean
10
+ import javax.management.MBeanInfo
11
+ import javax.management.ObjectName
12
+
13
+ class ObjectName
14
+ def [](key)
15
+ get_key_property(key.to_s)
16
+ end
17
+
18
+ def info(server)
19
+ server.getMBeanInfo(self)
20
+ end
21
+ end
22
+
23
+ module javax::management::openmbean::CompositeData
24
+ include Enumerable
25
+
26
+ def [](key)
27
+ get(key.to_s)
28
+ end
29
+
30
+ def method_missing(name, *args)
31
+ self[name]
32
+ end
33
+
34
+ def each
35
+ get_composite_type.key_set.each { |key| yield key }
36
+ end
37
+
38
+ def each_pair
39
+ get_composite_type.key_set.each { |key| yield key, get(key) }
40
+ end
41
+ end
42
+
43
+ module JMX
44
+ ##
45
+ # Connect to a MBeanServer
46
+ # opts can contain several values
47
+ # :host - The hostname where the server resides (def: localhost)
48
+ # :port - Which port the server resides at (def: 8686)
49
+ # :url_path - path part of JMXServerURL (def: /jmxrmi)
50
+ # :user - User to connect as (optional)
51
+ # :password - Password for user (optional)
52
+ def self.connect(opts = {})
53
+ host = opts[:host] || 'localhost'
54
+ port = opts[:port] || 8686
55
+ url_path = opts[:url_path] || "/jmxrmi"
56
+ url = "service:jmx:rmi:///jndi/rmi://#{host}:#{port}#{url_path}"
57
+
58
+ if opts[:user]
59
+ JMX::MBeanServer.new url, opts[:user], opts[:password]
60
+ else
61
+ JMX::MBeanServer.new url
62
+ end
63
+ end
64
+
65
+ ##
66
+ # sad little simple server setup so you can connect up to it.
67
+ #
68
+ def self.simple_server(opts = {})
69
+ port = opts[:port] || 8686
70
+ url_path = opts[:url_path] || "/jmxrmi"
71
+ url = "service:jmx:rmi:///jndi/rmi://localhost:#{port}#{url_path}"
72
+ $registry = RMIRegistry.new port
73
+ @connector = JMX::MBeanServerConnector.new(url, JMX::MBeanServer.new).start
74
+ end
75
+
76
+ # Holder for beans created from retrieval (namespace protection [tm]).
77
+ # This also gives MBeans nicer names when inspected
78
+ module MBeans
79
+ ##
80
+ # Create modules in this namespace for each package in the Java fully
81
+ # qualified name and return the deepest module along with the Java class
82
+ # name back to the caller.
83
+ def self.parent_for(java_class_fqn)
84
+ java_class_fqn.split(".").inject(MBeans) do |parent, segment|
85
+ # Note: We are boned if java class name is lower cased
86
+ return [parent, segment] if segment =~ /^[A-Z]/
87
+
88
+ segment.capitalize!
89
+ unless parent.const_defined? segment
90
+ parent.const_set segment, Module.new
91
+ else
92
+ parent.const_get segment
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+
99
+ # Create a Ruby proxy based on the MBean represented by the object_name
100
+ class MBeanProxy
101
+ # Generate a friendly Ruby proxy for the MBean represented by object_name
102
+ def self.generate(server, object_name)
103
+ parent, class_name = MBeans.parent_for object_name.info(server).class_name
104
+
105
+ if parent.const_defined? class_name
106
+ proxy = parent.const_get(class_name)
107
+ else
108
+ proxy = Class.new MBeanProxy
109
+ parent.const_set class_name, proxy
110
+ end
111
+
112
+ proxy.new(server, object_name)
113
+ end
114
+
115
+ def initialize(server, object_name)
116
+ @server, @object_name = server, object_name
117
+ @info = @server.getMBeanInfo(@object_name)
118
+
119
+ define_attributes
120
+ define_operations
121
+ end
122
+
123
+ def attributes
124
+ @attributes ||= @info.attributes.inject([]) { |s,attr| s << attr.name }
125
+ end
126
+
127
+ def operations
128
+ @operations ||= @info.operations.inject([]) { |s,op| s << op.name }
129
+ end
130
+
131
+ # Get MBean attribute specified by name
132
+ def [](name)
133
+ @server.getAttribute @object_name, name.to_s
134
+ end
135
+
136
+ # Set MBean attribute specified by name to value
137
+ def []=(name, value)
138
+ @server.setAttribute @object_name, Attribute.new(name.to_s, value)
139
+ end
140
+
141
+ def add_notification_listener(filter=nil, handback=nil, &listener)
142
+ @server.addNotificationListener @object_name, listener, filter, handback
143
+ end
144
+
145
+ def remove_notification_listener(listener)
146
+ @server.removeNotificationListener @object_name, listener
147
+ end
148
+
149
+ def method_missing(name, *args)
150
+ puts "Invoking: #{name}, #{args}"
151
+ java_args = java_args(args)
152
+ @server.invoke @object_name, name.to_s, java_args, java_types(java_args)
153
+ end
154
+
155
+ private
156
+
157
+ # Define ruby friendly methods for attributes. For odd attribute names or names
158
+ # that you want to call with the actual attribute name you can call aref/aset
159
+ def define_attributes
160
+ @info.attributes.each do |attr|
161
+ rname = underscore(attr.name)
162
+ self.class.__send__(:define_method, rname) { self[attr.name] } if attr.readable?
163
+ self.class.__send__(:define_method, rname + "=") {|v| self[attr.name] = v } if attr.writable?
164
+ end
165
+ end
166
+
167
+ def define_operations
168
+ @info.operations.each do |op|
169
+ self.class.__send__(:define_method, op.name) do |*args|
170
+ jargs = java_args(op.signature, args)
171
+ @server.invoke @object_name, op.name, jargs, java_types(jargs)
172
+ end
173
+ end
174
+ end
175
+
176
+ # Given the signature and the parameters supplied do these signatures match.
177
+ # Repackage these parameters as Java objects in a primitive object array.
178
+ def java_args(signature, params)
179
+ return nil if params.nil?
180
+
181
+ i = 0
182
+ params.map do |param|
183
+ required_type = JavaClass.for_name(signature[i].get_type)
184
+ java_arg = Java.ruby_to_java(param)
185
+
186
+ if (param.kind_of? Array)
187
+ java_arg = param.inject(ArrayList.new) {|l, element| l << element }
188
+ end
189
+
190
+ arg_type = java_arg.java_class
191
+
192
+ raise TypeError.new("parameter #{signature[i].name} expected to be #{required_type}, but was #{arg_type}") if !required_type.assignable_from? arg_type
193
+ i = i + 1
194
+
195
+ java_arg
196
+ end.to_java(:object)
197
+ end
198
+
199
+ # Convert a collection of java objects to their Java class name equivalents
200
+ def java_types(params)
201
+ return nil if params.nil?
202
+
203
+ params.map {|e| params.java_class.name }.to_java(:string)
204
+ end
205
+
206
+ def underscore(string)
207
+ string.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,101 @@
1
+ module JMX
2
+ import javax.management.MBeanParameterInfo
3
+ import javax.management.MBeanOperationInfo
4
+ import javax.management.MBeanInfo
5
+
6
+ module JavaTypeAware
7
+ SIMPLE_TYPES = {
8
+ :int => 'java.lang.Integer',
9
+ :list => 'java.util.List',
10
+ :long => 'java.lang.Long',
11
+ :map => 'java.util.Map',
12
+ :set => 'java.util.Set',
13
+ :string => 'java.lang.String',
14
+ :void => 'java.lang.Void'
15
+ }
16
+
17
+ def to_java_type(type_name)
18
+ SIMPLE_TYPES[type_name] || type_name
19
+ end
20
+ end
21
+
22
+ class Parameter
23
+ include JavaTypeAware
24
+
25
+ def initialize(type, name, description)
26
+ @type, @name, @description = type, name, description
27
+ end
28
+
29
+ def to_jmx
30
+ MBeanParameterInfo.new @name.to_s, to_java_type(@type), @description
31
+ end
32
+ end
33
+
34
+ class Operation < Struct.new(:description, :parameters, :return_type, :name, :impact)
35
+ include JavaTypeAware
36
+
37
+ def initialize(description)
38
+ super
39
+ self.parameters, self.impact, self.description = [], MBeanOperationInfo::UNKNOWN, description
40
+ end
41
+
42
+ def to_jmx
43
+ java_parameters = parameters.map { |parameter| parameter.to_jmx }
44
+ MBeanOperationInfo.new name.to_s, description, java_parameters.to_java(javax.management.MBeanParameterInfo), to_java_type(return_type), impact
45
+ end
46
+ end
47
+ end
48
+
49
+ class RubyDynamicMBean
50
+ import javax.management.MBeanOperationInfo
51
+
52
+ # TODO: preserve any original method_added?
53
+ # TODO: Error handling here when it all goes wrong?
54
+ def self.method_added(name)
55
+ return if Thread.current[:op].nil?
56
+ Thread.current[:op].name = name
57
+ operations << Thread.current[:op].to_jmx
58
+ Thread.current[:op] = nil
59
+ end
60
+
61
+ def self.attributes
62
+ Thread.current[:attrs] ||= []
63
+ end
64
+
65
+ def self.operations
66
+ Thread.current[:ops] ||= []
67
+ end
68
+
69
+ # Last operation wins if more than one
70
+ def self.operation(description)
71
+ include DynamicMBean
72
+
73
+ # Wait to error check until method_added so we can know method name
74
+ Thread.current[:op] = JMX::Operation.new description
75
+ end
76
+
77
+ def self.parameter(type, name=nil, description=nil)
78
+ Thread.current[:op].parameters << JMX::Parameter.new(type, name, description)
79
+ end
80
+
81
+ def self.returns(type)
82
+ Thread.current[:op].return_type = type
83
+ end
84
+
85
+ def initialize(name, description)
86
+ operations = self.class.operations.to_java(MBeanOperationInfo)
87
+ @info = MBeanInfo.new name, description, nil, nil, operations, nil
88
+ end
89
+
90
+ def getAttribute(attribute); $stderr.puts "getAttribute"; end
91
+ def getAttributes(attributes); $stderr.puts "getAttributes"; end
92
+ def getMBeanInfo; @info; end
93
+ def invoke(actionName, params=nil, signature=nil)
94
+ send(actionName, *params)
95
+ end
96
+ def setAttribute(attribute); $stderr.puts "setAttribute"; end
97
+ def setAttributes(attributes); $stderr.puts "setAttributes"; end
98
+ def to_s; toString; end
99
+ def inspect; toString; end
100
+ def toString; "#@info.class_name: #@info.description"; end
101
+ end
data/lib/jmx/server.rb ADDED
@@ -0,0 +1,117 @@
1
+ module JMX
2
+ # Represents both MBeanServer and MBeanServerConnection
3
+ class MBeanServer
4
+ import javax.management.Attribute
5
+ import javax.management.MBeanServerFactory
6
+ import javax.management.remote.JMXConnectorFactory
7
+ import javax.management.remote.JMXServiceURL
8
+
9
+ attr_accessor :server
10
+ @@classes = {}
11
+
12
+ def initialize(location=nil, username=nil, password=nil)
13
+ if (location)
14
+ env = username ?
15
+ {"jmx.remote.credentials" => [username, password].to_java(:string)} :
16
+ nil
17
+ url = JMXServiceURL.new location
18
+ @server = JMXConnectorFactory.connect(url, env).getMBeanServerConnection
19
+ else
20
+ @server = java.lang.management.ManagementFactory.getPlatformMBeanServer
21
+ #@server = MBeanServerFactory.createMBeanServer
22
+ end
23
+ end
24
+
25
+ def [](object_name)
26
+ name = make_object_name object_name
27
+
28
+ unless @server.isRegistered(name)
29
+ raise NoSuchBeanError.new("No name: #{object_name}")
30
+ end
31
+
32
+ #### TODO: Why?
33
+ @server.getObjectInstance name
34
+ MBeanProxy.generate(@server, name)
35
+ end
36
+
37
+ def []=(class_name, object_name)
38
+ name = make_object_name object_name
39
+
40
+ @server.createMBean class_name, name, nil, nil
41
+
42
+ MBeanProxy.generate(@server, name)
43
+ end
44
+
45
+ def default_domain
46
+ @server.getDefaultDomain
47
+ end
48
+
49
+ def domains
50
+ @server.domains
51
+ end
52
+
53
+ def mbean_count
54
+ @server.getMBeanCount
55
+ end
56
+
57
+ def query_names(name=nil, query=nil)
58
+ object_name = name.nil? ? nil : make_object_name(name)
59
+
60
+ @server.query_names(object_name, query)
61
+ end
62
+
63
+ def register_mbean(object, object_name)
64
+ name = make_object_name object_name
65
+
66
+ @server.registerMBean(object, name)
67
+
68
+ MBeanProxy.generate(@server, name)
69
+ end
70
+
71
+ def self.find(agent_id=nil)
72
+ MBeanServerFactory.findMBeanServer(agent_id)
73
+ end
74
+
75
+ private
76
+
77
+ def make_object_name(object_name)
78
+ return object_name if object_name.kind_of? ObjectName
79
+
80
+ ObjectName.new object_name
81
+ rescue
82
+ raise ArgumentError.new("Invalid ObjectName #{$!.message}")
83
+ end
84
+ end
85
+
86
+ class NoSuchBeanError < RuntimeError
87
+ end
88
+
89
+ class MBeanServerConnector
90
+ import javax.management.remote.JMXServiceURL
91
+ import javax.management.remote.JMXConnectorServerFactory
92
+
93
+ def initialize(location, server)
94
+ @url = JMXServiceURL.new location
95
+ @server = JMXConnectorServerFactory.newJMXConnectorServer @url, nil, server.server
96
+
97
+ if block_given?
98
+ start
99
+ yield
100
+ stop
101
+ end
102
+ end
103
+
104
+ def active?
105
+ @server.isActive
106
+ end
107
+
108
+ def start
109
+ @server.start
110
+ self
111
+ end
112
+
113
+ def stop
114
+ @server.stop if active?
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,3 @@
1
+ module JMX
2
+ VERSION = "0.1"
3
+ end
data/lib/rmi.rb ADDED
@@ -0,0 +1,21 @@
1
+ include Java
2
+
3
+ import java.rmi.registry.LocateRegistry
4
+ import java.rmi.registry.Registry
5
+ import java.rmi.server.UnicastRemoteObject
6
+
7
+ class RMIRegistry
8
+ def initialize(port = Registry::REGISTRY_PORT)
9
+ start(port)
10
+ end
11
+
12
+ def start(port)
13
+ @registry = LocateRegistry.createRegistry port
14
+
15
+ end
16
+
17
+ def stop
18
+ UnicastRemoteObject.unexportObject @registry, true
19
+ end
20
+ end
21
+
data/samples/memory.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'jmx'
2
+
3
+ def in_mb(value)
4
+ format "%0.2f Mb" % (value.to_f / (1024 * 1024))
5
+ end
6
+
7
+ server = JMX.simple_server
8
+ client = JMX.connect
9
+ memory = client["java.lang:type=Memory"]
10
+
11
+ Thread.new do
12
+ puts "Enter 'gc' to garbage collect or anything else to quit"
13
+ while (command = gets.chomp)
14
+ break if command != "gc"
15
+ memory.gc
16
+ end
17
+
18
+ server.stop
19
+ exit 0
20
+ end
21
+
22
+ while (true)
23
+ heap = in_mb(memory.heap_memory_usage.used)
24
+ non_heap = in_mb(memory.non_heap_memory_usage.used)
25
+
26
+ puts "Heap: #{heap}, Non-Heap: #{non_heap}"
27
+ sleep(2)
28
+ end
29
+
@@ -0,0 +1,88 @@
1
+ # In order to run these tests you must be running GFv2
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
4
+
5
+ require 'test/unit'
6
+ require 'rmi'
7
+ require 'jmx'
8
+
9
+ PORT = 9999
10
+ $registry = RMIRegistry.new PORT
11
+
12
+ class JMXConnectorClientTest < Test::Unit::TestCase
13
+ URL = "service:jmx:rmi:///jndi/rmi://localhost:#{PORT}/jmxrmi"
14
+
15
+ def setup
16
+ @connector = JMX::MBeanServerConnector.new(URL, JMX::MBeanServer.new)
17
+ @connector.start
18
+ @client = JMX::connect(:port => PORT)
19
+ end
20
+
21
+ def teardown
22
+ @connector.stop
23
+ end
24
+
25
+ def test_invalid_mbean_name
26
+ assert_raises(ArgumentError) { @client["::::::"] }
27
+ end
28
+
29
+ def test_get_mbean
30
+ memory = @client["java.lang:type=Memory"]
31
+
32
+ assert_not_nil memory, "Could not acquire memory mbean"
33
+
34
+ # Attr form
35
+ heap = memory[:HeapMemoryUsage]
36
+ assert_not_nil heap
37
+ assert(heap[:used] > 0, "No heap used? Impossible!")
38
+
39
+ # underscored form
40
+ heap = memory.heap_memory_usage
41
+ assert_not_nil heap
42
+ assert(heap.used > 0, "No heap used? Impossible!")
43
+ end
44
+
45
+ def test_set_mbean
46
+ memory = @client["java.lang:type=Memory"]
47
+ original_verbose = memory.verbose
48
+ memory.verbose = !original_verbose
49
+ assert(memory.verbose != original_verbose, "Could not change verbose")
50
+
51
+ memory[:Verbose] = original_verbose
52
+ assert(memory[:Verbose] == original_verbose, "Could not change back verbose")
53
+ end
54
+
55
+ def test_attributes
56
+ memory = @client["java.lang:type=Memory"]
57
+ assert(memory.attributes.include?("HeapMemoryUsage"), "HeapMemoryUsage not found")
58
+ end
59
+
60
+ def test_operations
61
+ memory = @client["java.lang:type=Memory"]
62
+ assert(memory.operations.include?("gc"), "gc not found")
63
+ end
64
+
65
+
66
+ def test_simple_operation
67
+ memory = @client["java.lang:type=Memory"]
68
+
69
+ heap1 = memory[:HeapMemoryUsage][:used]
70
+ memory.gc
71
+ heap2 = memory[:HeapMemoryUsage][:used]
72
+
73
+ assert(heap1.to_i >= heap2.to_i, "GC did not collect")
74
+ end
75
+
76
+ def test_query_names
77
+ names = @client.query_names("java.lang:type=MemoryPool,*")
78
+ assert(names.size > 0, "No memory pools. Impossible!")
79
+
80
+ a_memory_pool_bean = @client[names.to_array[0]]
81
+ assert_not_nil a_memory_pool_bean, "Name must resolve to something"
82
+
83
+ usage = a_memory_pool_bean[:Usage]
84
+ assert_not_nil usage, "Memory pools have usage"
85
+
86
+ assert_not_nil usage[:used], "Some memory is used"
87
+ end
88
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
7
+
8
+ require 'test/unit'
9
+ require 'rmi'
10
+ require 'jmx'
11
+
12
+ class MyDynamicMBean < RubyDynamicMBean
13
+ operation "Doubles a value"
14
+ parameter :int, "a", "Value to double"
15
+ returns :int
16
+ def double(a)
17
+ a + a
18
+ end
19
+
20
+ operation "Doubles a string"
21
+ parameter :string, "a", "Value to double"
22
+ returns :string
23
+ def string_double(a)
24
+ a + a
25
+ end
26
+
27
+ operation "Give me foo"
28
+ returns :string
29
+ def foo
30
+ "foo"
31
+ end
32
+
33
+ operation "Concatentates a list"
34
+ parameter :list, "list", "List to concatenate"
35
+ returns :string
36
+ def concat(list)
37
+ list.inject("") { |memo, element| memo << element.to_s }
38
+ end
39
+ end
40
+
41
+ class JMXServerTest < Test::Unit::TestCase
42
+ PORT = 9999
43
+ URL = "service:jmx:rmi:///jndi/rmi://localhost:#{PORT}/jmxrmi"
44
+
45
+ def setup
46
+ @registry = RMIRegistry.new PORT
47
+ @server = JMX::MBeanServer.new
48
+ @connector = JMX::MBeanServerConnector.new(URL, @server)
49
+ @connector.start
50
+ @client = JMX::connect(:port => PORT)
51
+ end
52
+
53
+ def teardown
54
+ @connector.stop
55
+ @registry.stop
56
+ end
57
+
58
+ def test_ruby_mbean
59
+ dyna = MyDynamicMBean.new("domain.MySuperBean", "Heh")
60
+ domain = @server.default_domain
61
+ @server.register_mbean dyna, "#{domain}:type=MyDynamicMBean"
62
+
63
+ # Get bean from client connector connection
64
+ bean = @client["#{domain}:type=MyDynamicMBean"]
65
+ assert_equal("foo", bean.foo)
66
+ assert_equal(6, bean.double(3))
67
+ assert_raise(TypeError) { puts bean.double("HEH") }
68
+ assert_equal("hehheh", bean.string_double("heh"))
69
+ assert_equal("123", bean.concat([1,2,3]))
70
+ end
71
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jmx
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Enebo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-06 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Install this gem and require 'jmx' to load the library.
17
+ email: enebo@acm.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - Manifest.txt
24
+ - README.txt
25
+ - LICENSE.txt
26
+ files:
27
+ - Manifest.txt
28
+ - Rakefile
29
+ - README.txt
30
+ - LICENSE.txt
31
+ - lib/jmx
32
+ - lib/jmx/dynamic_mbean.rb
33
+ - lib/jmx/server.rb
34
+ - lib/jmx/version.rb
35
+ - lib/jmx.rb
36
+ - lib/rmi.rb
37
+ - samples/memory.rb
38
+ - test/jmx_client_test.rb
39
+ - test/jmx_server_test.rb
40
+ has_rdoc: true
41
+ homepage: http://jruby-extras.rubyforge.org/jmx
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --main
45
+ - README.txt
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project: jruby-extras
63
+ rubygems_version: 1.0.1
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: Package for interacting/creating Java Management Extensions
67
+ test_files: []
68
+