PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/jmx4r.rb

http://jmx4r.googlecode.com/
Ruby | 182 lines | 111 code | 18 blank | 53 comment | 10 complexity | d9284b2640515e8fe39e10b8b7080fe1 MD5 | raw file
Possible License(s): Apache-2.0
  1. # Copyright 2007 Jeff Mesnil (http://jmesnil.net)
  2. require 'java'
  3. class String
  4. # Transform a CamelCase String to a snake_case String.
  5. #--
  6. # Code has been taken from ActiveRecord
  7. def snake_case
  8. self.to_s.gsub(/::/, '/').
  9. gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
  10. gsub(/([a-z\d])([A-Z])/,'\1_\2').
  11. tr("-", "_").
  12. downcase
  13. end
  14. end
  15. module JMX
  16. require 'open_data_helper'
  17. require 'jruby'
  18. class MBean
  19. include_class 'java.util.HashMap'
  20. include_class 'javax.management.Attribute'
  21. include_class 'javax.management.ObjectName'
  22. include_class 'javax.management.remote.JMXConnector'
  23. include_class 'javax.management.remote.JMXConnectorFactory'
  24. include_class 'javax.management.remote.JMXServiceURL'
  25. JThread = java.lang.Thread
  26. attr_reader :object_name, :operations, :attributes
  27. # Creates a new MBean.
  28. #
  29. # object_name:: a string corresponding to a valid ObjectName
  30. # mbsc:: a connection to a MBean server. If none is passed,
  31. # use the global connection created by
  32. # MBean.establish_connection
  33. def initialize(object_name, mbsc=nil)
  34. @mbsc = mbsc || @@mbsc
  35. @object_name = object_name
  36. info = @mbsc.getMBeanInfo @object_name
  37. @attributes = Hash.new
  38. info.attributes.each do | mbean_attr |
  39. @attributes[mbean_attr.name.snake_case] = mbean_attr.name
  40. self.class.instance_eval do
  41. define_method mbean_attr.name.snake_case do
  42. @mbsc.getAttribute @object_name, "#{mbean_attr.name}"
  43. end
  44. end
  45. if mbean_attr.isWritable
  46. self.class.instance_eval do
  47. define_method "#{mbean_attr.name.snake_case}=" do |value|
  48. attr = Attribute.new mbean_attr.name, value
  49. @mbsc.setAttribute @object_name, attr
  50. end
  51. end
  52. end
  53. end
  54. @operations = Hash.new
  55. info.operations.each do |mbean_op|
  56. param_types = mbean_op.signature.map {|param| param.type}
  57. @operations[mbean_op.name.snake_case] = [mbean_op.name, param_types]
  58. end
  59. end
  60. def method_missing(method, *args, &block) #:nodoc:
  61. if @operations.keys.include?(method.to_s)
  62. op_name, param_types = @operations[method.to_s]
  63. @mbsc.invoke @object_name,
  64. op_name,
  65. args.to_java(:Object),
  66. param_types.to_java(:String)
  67. else
  68. super
  69. end
  70. end
  71. @@mbsc = nil
  72. # establish a connection to a remote MBean server which will
  73. # be used by all subsequent MBeans.
  74. #
  75. # See MBean.create_connection for a list of the keys that are
  76. # accepted in arguments.
  77. #
  78. # Examples
  79. #
  80. # JMX::MBean.establish_connection :port => "node23", :port => 1090
  81. # JMX::MBean.establish_connection :port => "node23", :username => "jeff", :password => "secret"
  82. def self.establish_connection(args={})
  83. @@mbsc ||= create_connection args
  84. end
  85. def self.remove_connection(args={})
  86. @@mbsc = nil
  87. end
  88. def self.connection(args={})
  89. if args.has_key? :host or args.has_key? :port
  90. return create_connection(args)
  91. else
  92. MBean.establish_connection(args) unless @@mbsc
  93. return @@mbsc
  94. end
  95. end
  96. # Create a connection to a remote MBean server.
  97. #
  98. # The args accepts 4 keys:
  99. #
  100. # [:host] the host of the MBean server (defaults to "localhost")
  101. # [:port] the port of the MBean server (defaults to 3000)
  102. # [:username] the name of the user (if the MBean server requires authentication).
  103. # No default
  104. # [:password] the password of the user (if the MBean server requires authentication).
  105. # No default
  106. # [:credentials] custom credentials (if the MBean server requires authentication).
  107. # No default. It has precedence over :username and :password (i.e. if
  108. # :credentials is specified, :username & :password are ignored)
  109. #
  110. def self.create_connection(args={})
  111. host= args[:host] || "localhost"
  112. port = args[:port] || 3000
  113. username = args[:username]
  114. password = args[:password]
  115. credentials = args[:credentials]
  116. url = "service:jmx:rmi:///jndi/rmi://#{host}:#{port}/jmxrmi"
  117. unless credentials
  118. if !username.nil? and username.length > 0
  119. user_password_credentials = [username, password]
  120. credentials = user_password_credentials.to_java(:String)
  121. end
  122. end
  123. env = HashMap.new
  124. env.put(JMXConnector::CREDENTIALS, credentials) if credentials
  125. # the context class loader is set to JRuby's classloader when
  126. # creating the JMX Connection so that classes loaded using
  127. # JRuby "require" (and not from its classpath) can also be
  128. # accessed (see issue #6)
  129. begin
  130. context_class_loader = JThread.current_thread.context_class_loader
  131. JThread.current_thread.context_class_loader = JRuby.runtime.getJRubyClassLoader
  132. connector = JMXConnectorFactory::connect JMXServiceURL.new(url), env
  133. connector.getMBeanServerConnection
  134. ensure
  135. # ... and we reset the previous context class loader
  136. JThread.current_thread.context_class_loader = context_class_loader
  137. end
  138. end
  139. # Returns an array of MBeans corresponding to all the MBeans
  140. # registered for the ObjectName passed in parameter (which may be
  141. # a pattern).
  142. #
  143. # The args accepts the same keys than #create_connection and an
  144. # additional one:
  145. #
  146. # [:connection] a MBean server connection (as returned by #create_connection)
  147. # No default. It has precedence over :host and :port (i.e if
  148. # :connection is specified, :host and :port are ignored)
  149. #
  150. def self.find_all_by_name(name, args={})
  151. object_name = ObjectName.new(name)
  152. mbsc = args[:connection] || MBean.connection(args)
  153. object_names = mbsc.queryNames(object_name, nil)
  154. object_names.map { |on| MBean.new(on, mbsc) }
  155. end
  156. # Same as #find_all_by_name but the ObjectName passed in parameter
  157. # can not be a pattern.
  158. # Only one single MBean is returned.
  159. def self.find_by_name(name, args={})
  160. mbsc = args[:connection] || MBean.connection(args)
  161. MBean.new ObjectName.new(name), mbsc
  162. end
  163. end
  164. end