rboss 0.1.0

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.
Files changed (51) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +1 -0
  4. data/bin/jboss-profile +90 -0
  5. data/bin/twiddle +230 -0
  6. data/examples/jboss_profile/jbb_profile_1.yaml +32 -0
  7. data/examples/jboss_profile/jbb_profile_2.yaml +32 -0
  8. data/examples/jboss_profile/jboss_profile.yaml +7 -0
  9. data/examples/monitor/simple_monitor.rb +61 -0
  10. data/lib/rboss.rb +25 -0
  11. data/lib/rboss/component_processor.rb +177 -0
  12. data/lib/rboss/components/component.rb +52 -0
  13. data/lib/rboss/components/datasource.rb +198 -0
  14. data/lib/rboss/components/deploy_folder.rb +104 -0
  15. data/lib/rboss/components/hypersonic_replacer.rb +58 -0
  16. data/lib/rboss/components/jbossweb.rb +117 -0
  17. data/lib/rboss/components/jmx.rb +88 -0
  18. data/lib/rboss/components/mod_cluster.rb +81 -0
  19. data/lib/rboss/components/org/6.0/deploy_folder.rb +33 -0
  20. data/lib/rboss/components/org/jmx.rb +59 -0
  21. data/lib/rboss/components/profile_folder.rb +44 -0
  22. data/lib/rboss/components/resource.rb +53 -0
  23. data/lib/rboss/components/run_conf.rb +90 -0
  24. data/lib/rboss/components/run_conf.yaml +22 -0
  25. data/lib/rboss/components/service_script.rb +55 -0
  26. data/lib/rboss/components/slimming.rb +124 -0
  27. data/lib/rboss/components/soa-p/hypersonic_replacer.rb +79 -0
  28. data/lib/rboss/components/soa-p/jmx.rb +47 -0
  29. data/lib/rboss/components/xadatasource.rb +67 -0
  30. data/lib/rboss/file_processor.rb +107 -0
  31. data/lib/rboss/jboss_path.rb +53 -0
  32. data/lib/rboss/jboss_profile.rb +344 -0
  33. data/lib/rboss/resources/jboss_init_redhat.sh.erb +140 -0
  34. data/lib/rboss/resources/mod_cluster.sar/META-INF/mod_cluster-jboss-beans.xml +282 -0
  35. data/lib/rboss/resources/mod_cluster.sar/mod_cluster-1.1.2.Final.jar +0 -0
  36. data/lib/rboss/resources/run.conf.erb +62 -0
  37. data/lib/rboss/twiddle.rb +25 -0
  38. data/lib/rboss/twiddle/base_monitor.rb +57 -0
  39. data/lib/rboss/twiddle/mbean.rb +82 -0
  40. data/lib/rboss/twiddle/monitor.rb +144 -0
  41. data/lib/rboss/twiddle/scanner.rb +92 -0
  42. data/lib/rboss/twiddle/twiddle.rb +71 -0
  43. data/lib/rboss/utils.rb +33 -0
  44. data/lib/rboss/version.rb +25 -0
  45. data/rboss.gemspec +20 -0
  46. data/test/datasource_test.rb +211 -0
  47. data/test/deploy_folder_test.rb +126 -0
  48. data/test/mbean_test.rb +53 -0
  49. data/test/test_helper.rb +124 -0
  50. data/test/test_suite.rb +35 -0
  51. metadata +109 -0
data/lib/rboss.rb ADDED
@@ -0,0 +1,25 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2011 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative "rboss/version"
24
+ require_relative "rboss/jboss_profile"
25
+ require_relative "rboss/twiddle"
@@ -0,0 +1,177 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2011 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ # A main class to process components based on a highly customizable set of parameters.
24
+ #
25
+ # 1. Creating a ComponentProcessor
26
+ # A ComponentProcessor needs a block that defines how to process a component. The block
27
+ # will receive the component type and the configuration.
28
+ #
29
+ # Example: ComponentProcessor::new do |component_type, configuration|
30
+ # component_type.new(configuration).process
31
+ # end
32
+ #
33
+ # 2. Registering a component
34
+ # Components need to be registered in the processor. The registration uses an id and a hash
35
+ # of parameters described bellow:
36
+ #
37
+ # :type => the type of the component. Only components with a defined type will be passed to the processor block
38
+ #
39
+ # :multiple_instances => a flag to indicate if this component can be added more than once
40
+ # :priority => a number defining a priority for this component to be processed
41
+ #
42
+ # :enabled => a flag to indicate if this component is enabled for processing by default
43
+ #
44
+ # :defaults => a hash containing the default config parameters for this component (only if the configuration is a Hash)
45
+ #
46
+ # :send_config => a hash for sending the configurations at process time to another component (only if the configuration
47
+ # is a Hash).
48
+ #
49
+ # The configuration keys are sending using the pattern :to_$COMPONENT_ID and supports key overriding
50
+ # Example:
51
+ # :send_config => {
52
+ # :to_bar_service => {
53
+ # :foo => :bar
54
+ # }
55
+ # :to_foo_service => [:foo]
56
+ # }
57
+ # The :foo config will be moved to the component :bar_service using :bar as the configuration key and to the component
58
+ # :foo_service using the same name as the key.
59
+ #
60
+ # :move_config => the same as for :send_config, but the configurations moved will not be passed to the block for this
61
+ # component.
62
+ #
63
+ # 3. Adding a component
64
+ #
65
+ # A component should be added by add method. You only need to specify the component id and the configuration (if needed).
66
+ # When a component is added, it will be processed for sending or moving configurations and, if the component has a type,
67
+ # it will be passed to the block for processing.
68
+ #
69
+ # author: Marcelo Guimarães <ataxexe@gmail.com>
70
+ class ComponentProcessor
71
+
72
+ def initialize &block
73
+ @process = block
74
+ @process ||= lambda { |type, config| type.new(config).process }
75
+ end
76
+
77
+ # Register a component using the given id (which must be used for adding it to process) and parameters
78
+ def register component_id, params
79
+ params = {
80
+ :type => nil,
81
+ :multiple_instances => false,
82
+ :priority => 0,
83
+ :enabled => false,
84
+ :defaults => {}
85
+ }.merge! params
86
+ @components ||= {}
87
+ params[:configs] ||= [] if params[:multiple_instances]
88
+ @components[component_id] = params unless @components.has_key? component_id
89
+ end
90
+
91
+ def add component_id, config = {}
92
+ registered_component = @components[component_id]
93
+ return unless registered_component
94
+ defaults = registered_component[:defaults]
95
+ registered_component[:enabled] = true
96
+ config = defaults.merge config if config.is_a? Hash
97
+ if registered_component[:multiple_instances]
98
+ registered_component[:configs] << config
99
+ else
100
+ registered_component[:config] = config
101
+ end
102
+ propagate_configs registered_component
103
+ end
104
+
105
+ def defaults component_id, defaults
106
+ registered_component = @components[component_id]
107
+ registered_component[:defaults] = defaults if registered_component
108
+ end
109
+
110
+ def process_components
111
+ enabled_components = @components.find_all {|component_id, params| params[:enabled]}
112
+ (enabled_components.sort_by { |key, value| value[:priority] }).each do |key, component|
113
+ process_component component
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ def process_component component
120
+ return unless component[:type]
121
+ if component[:multiple_instances]
122
+ component[:configs].each do |config|
123
+ @process.call component[:type], config
124
+ end
125
+ else
126
+ config = component[:config]
127
+ config ||= component[:defaults]
128
+ @process.call component[:type], config
129
+ end
130
+ end
131
+
132
+ def propagate_configs component
133
+ #TODO refactor this -----------------------------------
134
+ if component[:send_config] and component[:config].is_a? Hash
135
+ component[:send_config].each do |to, keys|
136
+ destination = to.to_s.gsub(/^to_/, '').to_sym
137
+ config = {}
138
+ if keys.is_a? Array
139
+ keys.each do |key|
140
+ config[key] = component[:config][key] if component[:config].has_key? key
141
+ end
142
+ elsif keys.is_a? Hash
143
+ keys.each do |k, v|
144
+ config[v] = component[:config][k] if component[:config].has_key? k
145
+ end
146
+ end
147
+ send_config destination, config
148
+ end
149
+ end
150
+ if component[:move_config] and component[:config].is_a? Hash
151
+ component[:move_config].each do |to, keys|
152
+ destination = to.to_s.gsub(/^to_/, '').to_sym
153
+ config = {}
154
+ if keys.is_a? Array
155
+ keys.each do |key|
156
+ config[key] = component[:config].delete key if component[:config].has_key? key
157
+ end
158
+ elsif keys.is_a? Hash
159
+ keys.each do |k, v|
160
+ config[v] = component[:config].delete k if component[:config].has_key? k
161
+ end
162
+ end
163
+ send_config destination, config, :enable_component => true
164
+ end
165
+ end
166
+ #------------------------------------------------------
167
+ end
168
+
169
+ def send_config component_id, config, opts = {}
170
+ component = @components[component_id]
171
+ component[:defaults] ||= {}
172
+ component_config = @components[component_id][:defaults]
173
+ component_config.merge! config
174
+ component[:enabled] = true if opts[:enable_component]
175
+ end
176
+
177
+ end
@@ -0,0 +1,52 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2011 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative "../file_processor"
24
+ require_relative "../jboss_path"
25
+ require_relative "../utils"
26
+
27
+ module JBoss
28
+
29
+ # A base helper module for JBoss Components
30
+ #
31
+ # author: Marcelo Guimarães <ataxexe@gmail.com>
32
+ module Component
33
+
34
+ def initialize jboss, logger, config
35
+ @jboss = jboss
36
+ @logger = logger
37
+ config = defaults.merge! config if self.respond_to? :defaults
38
+ configure(config)
39
+ end
40
+
41
+ def configure config
42
+ @config = config
43
+ end
44
+
45
+ # Creates a FileProcessor using the same logger and
46
+ # jboss path as the variable
47
+ def new_file_processor
48
+ FileProcessor::new :logger => @logger, :var => @jboss
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,198 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2011 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative "component"
24
+
25
+ require "logger"
26
+ require "rexml/document"
27
+
28
+ include REXML
29
+
30
+ module JBoss
31
+
32
+ # A class to configure a JBoss Datasource.
33
+ #
34
+ # For converting the property (if it is a Symbol), the above rules are used taking by example a
35
+ # value ":database_url":
36
+ # a. The value "database_url"
37
+ # b. The value "database-url"
38
+ # c. The value "DatabaseUrl"
39
+ # d. The value "DATABASE_URL"
40
+ #
41
+ # The key for finding the correct datasource is the configuration attribute :type, which is used
42
+ # to search in $JBOSS_HOME/docs/examples/jca for the file.
43
+ #
44
+ # Any key that is not found in the datasource template will be added. If it is a Symbol, the underlines will be
45
+ # converted to hyphens.
46
+ #
47
+ # For saving the file, the configuration :name will be used in the form "${name}-ds.xml".
48
+ #
49
+ # Configuration:
50
+ #
51
+ # :folder => a folder where this datasource will be saved (default: $JBOSS_HOME/server/$CONFIG/deploy)
52
+ # if a relative path is given, it will be appended to default value
53
+ # :encrypt => a flag to indicate if the password should be encrypted (default: false)
54
+ # :type => the type of the datasource
55
+ # :name => a name for saving the file (default: :type)
56
+ # :attributes => a Hash with the attributes that will be changed in template (the only required is :jndi_name)
57
+ # Any attribute that is not present in datasource xml will be created using this template: <key>value</key>.
58
+ #
59
+ # author: Marcelo Guimarães <ataxexe@gmail.com>
60
+ class Datasource
61
+ include Component
62
+
63
+ attr_accessor :jndi_name, :attributes, :type, :name
64
+
65
+ def defaults
66
+ {
67
+ :folder => "#{@jboss.profile}/deploy",
68
+ :encrypt => false,
69
+ :attributes => {}
70
+ }
71
+ end
72
+
73
+ def configure config
74
+ config[:type] = :mssql if config[:type].to_s == "sqlserver"
75
+ @type = config[:type].to_s.gsub /_/, '-'
76
+ @name = config[:name]
77
+ @name ||= @type.to_s
78
+ @folder = config[:folder].to_s
79
+ @folder = "#{@jboss.profile}/#{@folder}" unless @folder.start_with? '/'
80
+ @attributes = config[:attributes]
81
+ @encrypt = config[:encrypt]
82
+ @jndi_name = @attributes.delete :jndi_name
83
+ end
84
+
85
+ def process
86
+ if @encrypt
87
+ @user = @attributes.delete :user
88
+ @user = @attributes.delete :user_name unless @user
89
+ @password = encrypt @attributes.delete :password
90
+ end
91
+ processor = new_file_processor
92
+ processor.with "#{@jboss.home}/docs/examples/jca/#{@type}-ds.xml", :xml do |action|
93
+ action.to_process do |xml, jboss|
94
+ element = XPath.first xml, "//jndi-name"
95
+ element.text = @jndi_name
96
+ configure_datasource xml
97
+
98
+ if @encrypt
99
+ security_domain = Element::new "security-domain"
100
+ security_domain.text = @name
101
+
102
+ xml.root.elements[1] << security_domain
103
+ end
104
+ action.copy_to "#{@folder}/#{@name}-ds.xml"
105
+ xml
106
+ end
107
+ end
108
+ @logger.info "Creating datasource #{@name}"
109
+ processor.process
110
+ if @encrypt
111
+ create_login_module
112
+ create_login_config
113
+ end
114
+ end
115
+
116
+ def find xml, key
117
+ if key.is_a? Symbol
118
+ key = key.to_s
119
+ [key, key.gsub(/_/, '-'), key.camelize, key.upcase].each do |k|
120
+ element = XPath.first xml, yield(k)
121
+ return element if element
122
+ end
123
+ else
124
+ XPath.first xml, yield(key)
125
+ end
126
+ nil
127
+ end
128
+
129
+ def configure_datasource xml
130
+ if @encrypt
131
+ xml.root.delete_element "//user-name"
132
+ xml.root.delete_element "//password"
133
+ @service = "LocalTxCM"
134
+ end
135
+ @attributes.each do |key, value|
136
+ element = find(xml, key) { |k| "//#{k}" }
137
+
138
+ if element
139
+ element.text = value
140
+ else
141
+ insert_attribute xml, key, value
142
+ end
143
+ end
144
+ end
145
+
146
+ def insert_attribute xml, key, value
147
+ if key.is_a? Symbol
148
+ element = Element::new key.to_s.gsub /_/, '-'
149
+ else
150
+ element = Element::new key
151
+ end
152
+ element.text = value
153
+ xml.root.elements[1] << element
154
+ end
155
+
156
+ def create_login_config
157
+ File.open("#{@folder}/#{@name}.login-module.xml", 'w+') { |f| f.write @login_module }
158
+ end
159
+
160
+ def create_login_module
161
+ @login_module = Document::new <<XML
162
+ <policy>
163
+ <application-policy name='#{@name}'>
164
+ <authentication>
165
+ <login-module code='org.jboss.resource.security.SecureIdentityLoginModule' flag='required'>
166
+ <module-option name='username'>#{@user}</module-option>
167
+ <module-option name='password'>#{@password}</module-option>
168
+ <module-option name='managedConnectionFactoryName'>jboss.jca:name=#{@jndi_name},service=#{@service}</module-option>
169
+ </login-module>
170
+ </authentication>
171
+ </application-policy>
172
+ </policy>
173
+ XML
174
+ end
175
+
176
+ def jboss_logging_lib_path
177
+ %W{#{@jboss.home}/client/jboss-logging-spi.jar #{@jboss.home}/client/jboss-logging.jar}.each do |path|
178
+ return path if File.exist? path
179
+ end
180
+ end
181
+
182
+ def jbosssx_lib_path
183
+ %W{#{@jboss.home}/lib/jbosssx.jar #{@jboss.home}/common/lib/jbosssx.jar}.each do |path|
184
+ return path if File.exist? path
185
+ end
186
+ end
187
+
188
+ # Encrypts the given password using the SecureIdentityLoginModule
189
+ def encrypt password
190
+ cmd = "java -cp #{jboss_logging_lib_path}:#{jbosssx_lib_path} org.jboss.resource.security.SecureIdentityLoginModule #{password}"
191
+ @logger.debug cmd
192
+ encrypted = `#{cmd}`
193
+ encrypted.chomp.split(/:/)[1].strip
194
+ end
195
+
196
+ end
197
+
198
+ end