carioca 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env ruby
2
+ #---
3
+ # Author : Romain GEORGES
4
+ # type : gem component library
5
+ # obj : Carioca::Services Module
6
+ #---
7
+
8
+
9
+
10
+ module Carioca
11
+
12
+ # namespace Services for Registry AND buitlins
13
+ module Services
14
+ # class method returning full path in Carioca gem for builtin services files according to installed gem path.
15
+ # @note do not use directly for generale purpose (expert/hacks only)
16
+ # @param [String] _name the name of a service
17
+ # @return [String,false] the full path filename orfalse if not found
18
+ def Services::search_builtins(_name)
19
+ if Gem::Specification.respond_to?(:find_by_name)
20
+ begin
21
+ spec = Gem::Specification.find_by_name('carioca')
22
+ rescue LoadError
23
+ spec = nil
24
+ end
25
+ else
26
+ spec = Gem.searcher.find('carioca')
27
+ end
28
+ if spec then
29
+ if Gem::Specification.respond_to?(:find_by_name)
30
+
31
+ res = spec.lib_dirs_glob.split('/')
32
+ else
33
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
34
+ end
35
+ res.pop
36
+ services_path = res.join('/').concat('/lib/carioca/services')
37
+ else
38
+ services_path = "./lib/carioca/services"
39
+ end
40
+ _file ="#{services_path}/#{_name}.rb"
41
+ if ( File::exist? _file or File::exist? "lib/#{_file}" ) then
42
+ return _file
43
+ else
44
+ return false
45
+ end
46
+ end
47
+
48
+ # class method returning the path of a file in gem if exist or false
49
+ # @note do not use directly for generale purpose (expert/hacks only)
50
+ # @return [String|FalseClass] the full path of a service file
51
+ def Services::search_file_in_gem(_gem,_file)
52
+ if Gem::Specification.respond_to?(:find_by_name)
53
+ begin
54
+ spec = Gem::Specification.find_by_name(_gem)
55
+ rescue LoadError
56
+ spec = nil
57
+ end
58
+ else
59
+ spec = Gem.searcher.find(_gem)
60
+ end
61
+ if spec then
62
+ if Gem::Specification.respond_to?(:find_by_name)
63
+ res = spec.lib_dirs_glob.split('/')
64
+ else
65
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
66
+ end
67
+ res.pop
68
+ services_path = res.join('/').concat("/#{_file}")
69
+ return services_path if File::exist?(services_path)
70
+ return false
71
+ else
72
+ return false
73
+ end
74
+ end
75
+
76
+
77
+ # class method returning the [Carioca::Services::Registry]@list complement for builtins service found for a carioca gem version
78
+ # @note do not use directly for generale purpose (expert/hacks only)
79
+ # @return [Hash] the [Carioca::Services::Registry]@list complement
80
+ def Services::discover_builtins
81
+ if Gem::Specification.respond_to?(:find_by_name)
82
+ begin
83
+ spec = Gem::Specification.find_by_name('carioca')
84
+ rescue LoadError
85
+ spec = nil
86
+ end
87
+ else
88
+ spec = Gem.searcher.find('carioca')
89
+ end
90
+
91
+ if spec then
92
+ if Gem::Specification.respond_to?(:find_by_name)
93
+ res = spec.lib_dirs_glob.split('/')
94
+ else
95
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
96
+ end
97
+ res.pop
98
+ services_path = res.join('/').concat('/lib/carioca/services')
99
+ else
100
+ services_path = "./lib/carioca/services"
101
+ end
102
+
103
+ map = Dir["#{services_path}/*"]
104
+ map.delete_if { |item| not File::file?(item) }
105
+ map.delete_if { |item| File::basename(item) == 'logger.rb' }
106
+
107
+ res = {}
108
+ map.each do |file|
109
+ Services::validate_service(file,res)
110
+ end
111
+ return res
112
+ end
113
+
114
+ def Services::validate_service(file,res)
115
+ init_options = {}
116
+ if open(file).grep(/^# \$BUILTIN/).size > 0 then
117
+ service = open(file).grep(/# \$SERVICE/).first.split[2]
118
+ resource = open(file).grep(/# \$RESOURCE/).first.split[2]
119
+ desc = open(file).grep(/# \$DESCRIPTION/).first
120
+ desc = desc.split(' ')
121
+ desc.shift(2)
122
+ description= desc.join(' ')
123
+ open(file).grep(/# \$INIT_OPTIONS/).each do |opt|
124
+ prev = opt.split
125
+ init_options[prev[2].to_sym] = prev[4]
126
+ end
127
+ distributed = (open(file).grep(/# \$DISTRIBUTED/))? true : false
128
+ req = open(file).grep(/# \$REQUIRES/)
129
+ if req.empty? then
130
+ requires = []
131
+ else
132
+ requires = req.split
133
+ requires.shift
134
+ end
135
+
136
+ end
137
+ unless service.nil? or resource.nil? or description.nil? then
138
+ res[resource] = { :service => service, :type => :builtin, :description => description, :resource => resource}
139
+ res[resource][:init_options] = init_options unless init_options.empty?
140
+ end
141
+ end
142
+ end
143
+ end
@@ -17,14 +17,14 @@
17
17
 
18
18
  require 'rubygems'
19
19
  require 'methodic'
20
- require 'services'
20
+ require 'carioca/services'
21
21
  require 'yaml'
22
+ require 'drb/drb'
22
23
 
23
24
  # overwriting Hash class
24
25
  # @private
25
26
  class Hash
26
27
 
27
-
28
28
  # recursively transform Hash keys form String to Symbols
29
29
  # come from Rails code
30
30
  # exist in Ruby 2.0
@@ -61,7 +61,8 @@ module Carioca
61
61
  # @note please do not use Standalone ( dependancy of Configuration class )
62
62
  # @private
63
63
  class Settings < Hash
64
-
64
+
65
+
65
66
  # the name of the config file in YAML format
66
67
  attr_accessor :config_file
67
68
 
@@ -107,7 +108,7 @@ module Carioca
107
108
  # Service Configuration of Carioca
108
109
  class Configuration
109
110
 
110
-
111
+ include DRb::DRbUndumped
111
112
 
112
113
  # @example
113
114
  # config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
@@ -120,8 +121,10 @@ module Carioca
120
121
  # Configuration service constructor (open config)
121
122
  # @param [Hash] _options the params
122
123
  # @option _options [String] :config_file the filename of the config
123
- def initialize(_options = {})
124
- options = Methodic.get_options(_options)
124
+ def initialize(_opts = {})
125
+
126
+
127
+ options = Methodic.get_options(_opts)
125
128
  options.specify_default_value :config_file => "./.config"
126
129
  options.merge
127
130
  @settings = Carioca::Services::Settings.new(options)
@@ -46,7 +46,7 @@ module Carioca
46
46
  def method_missing(methodname, *args,&block)
47
47
  @log.debug("ProxyDebug") { "BEGIN CALL for mapped service #{@mapped_service} "}
48
48
  @log.debug("ProxyDebug") { "called: #{methodname} " }
49
- @log.debug("ProxyDebug") { "args : #{args}" }
49
+ @log.debug("ProxyDebug") { "args : #{args.join " "}" }
50
50
  if block_given? then
51
51
  @log.debug("ProxyDebug") { "block given" }
52
52
  a = @obj.send(methodname, *args,&block)
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+ require 'carioca'
4
+
5
+ $VERBOSE = nil
6
+ if Gem::Specification.respond_to?(:find_by_name)
7
+ begin
8
+ spec = Gem::Specification.find_by_name('carioca')
9
+ res = spec.lib_dirs_glob.split('/')
10
+ rescue LoadError
11
+ spec = nil
12
+ end
13
+ else
14
+ spec = Gem.searcher.find('carioca')
15
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
16
+ end
17
+
18
+ res.pop
19
+ tasks_path = res.join('/').concat('/lib/carioca/tasks/')
20
+
21
+
22
+ Dir["#{tasks_path}/*.rake"].each { |ext| load ext }
23
+
@@ -0,0 +1,11 @@
1
+ require 'carioca'
2
+ namespace :carioca do
3
+ desc "initialize Carioca Registry"
4
+ task :init_registry do
5
+ mkdir 'services'
6
+ carioca = Carioca::Services::Registry.init :name => 'services/registry.yml', :debug => true
7
+ carioca.discover_builtins
8
+ carioca.save!
9
+ puts "Carioca : Registry initialize in services/registry.yml (see /tmp/log.file for details)"
10
+ end
11
+ end
@@ -5,8 +5,19 @@ require 'carioca'
5
5
  $debug = true
6
6
 
7
7
  describe Carioca do
8
+
8
9
  before :all do
9
10
  FileUtils.rm_rf("/tmp/log.file")
11
+ File::unlink('/tmp/dorsal/ringserver.pid') if File::exist?('/tmp/dorsal/ringserver.pid')
12
+ File::unlink('/tmp/dorsal/service-distdummy.pid') if File::exist?('/tmp/dorsal/service-distdummy.pid')
13
+ pid = `ps aux|grep ruby|grep -v grep |grep 'Ultragreen Ring Server'|awk '{ print $2}'`
14
+ unless pid.empty? then
15
+ res = `kill -TERM #{pid.chomp}`
16
+ end
17
+ pid = `ps aux|grep ruby|grep -v grep |grep 'a dummy test service'|awk '{ print $2}'`
18
+ unless pid.empty? then
19
+ res = `kill -TERM #{pid.chomp}`
20
+ end
10
21
  $carioca = Carioca::Services::Registry.init :file => 'spec/config/services.registry', :debug => $debug
11
22
  end
12
23
 
@@ -65,12 +76,18 @@ describe Carioca do
65
76
  end
66
77
  end
67
78
 
79
+ context "#name (RW)" do
80
+ it { should respond_to :name }
81
+ it { should respond_to :name= }
82
+ it { $carioca.name.should be_an_instance_of String }
83
+ it { $carioca.name.should eq 'Carioca'}
84
+ end
68
85
 
69
86
  context "#list (RO)" do
70
87
  it { should respond_to :list }
71
88
  it { should_not respond_to :list= }
72
89
  it { subject.list.should be_an_instance_of Hash }
73
- it { $carioca.list.keys.sort.should eq ["configuration", "debug", "dummy", "logger", "uuid"] }
90
+ it { $carioca.list.keys.sort.should eq ["configuration", "debug", "distdummy","dorsal", "dummy", "logger", "uuid", "uuidbygemfile"] }
74
91
  end
75
92
 
76
93
  context "#loaded_services (RO)" do
@@ -113,7 +130,7 @@ describe Carioca do
113
130
  myservice.test 'titi'
114
131
  end
115
132
  it { subject.list.keys.should include "debug" }
116
- it "should log a proxy service log sequence" do
133
+ it "should log a proxy service log sequence", :if => $debug do
117
134
  open('/tmp/log.file').grep(/DEBUG -- ProxyDebug: BEGIN CALL for mapped service dummy/).size.should eq 1
118
135
  open('/tmp/log.file').grep(/DEBUG -- ProxyDebug: called: test/).size.should eq 1
119
136
  open('/tmp/log.file').grep(/DEBUG -- ProxyDebug: args : titi/).size.should eq 1
@@ -127,28 +144,30 @@ describe Carioca do
127
144
  $conf = subject.start_service :name => 'configuration'
128
145
  end
129
146
  it "should access flat settings" do
130
- $conf.settings.context1.key.should eq 'value'
147
+ $conf.settings.context1.key0.should eq 'value'
131
148
  $conf.settings.context1.node.key1 eq 'value1'
132
149
  $conf.settings.context1.node.key2 eq 'value2'
133
- $conf.settings.context2.key.should eq 'value'
150
+ $conf.settings.context2.key0.should eq 'value'
134
151
  $conf.settings.context2.node.key1 eq 'value3'
135
152
  $conf.settings.context2.node.key2 eq 'value4'
136
153
  end
137
154
  it "should access contextualized settings" do
138
155
  $conf = subject.restart_service :name => 'configuration', :params => { :context => 'context2' }
139
- $conf.settings.key.should eq 'value'
156
+ $conf.settings.key0.should eq 'value'
140
157
  $conf.settings.node.key1 eq 'value3'
141
158
  $conf.settings.node.key2 eq 'value4'
142
159
  end
143
160
  it "should access inherited settings from YAML" do
144
161
  $conf = subject.restart_service :name => 'configuration', :params => { :context => 'context3' }
145
- $conf.settings.key.should eq 'value'
162
+ $conf.settings.key0.should eq 'value'
146
163
  $conf.settings.node.key1 eq 'value3'
147
164
  $conf.settings.node.key2 eq 'value4'
148
165
  end
149
166
  it "should be possible to override a config value" do
150
167
  $conf.settings.node.key2 = 'value8'
151
168
  $conf.settings.node.key2.should eq 'value8'
169
+ $conf.settings[:node][:key2] = 'value6'
170
+ $conf.settings[:node][:key2].should eq 'value6'
152
171
  end
153
172
  it { $conf.should respond_to :config_file }
154
173
  it { $conf.should respond_to :config_file= }
@@ -157,6 +176,7 @@ describe Carioca do
157
176
  it "should be saved in other file" do
158
177
  $conf.config_file = '/tmp/.config'
159
178
  $conf.save!.should be_true
179
+
160
180
  end
161
181
  it "should stop the configuration service" do
162
182
  subject.stop_service({:name => 'configuration'}).should eq true
@@ -164,6 +184,7 @@ describe Carioca do
164
184
  end
165
185
 
166
186
  end
187
+
167
188
  context "External services" do
168
189
 
169
190
  it "should start a dummy service precised in registry YAML configuration" do
@@ -183,6 +204,44 @@ describe Carioca do
183
204
  it "should be possible to execute a method with the gem service" do
184
205
  $uuid.generate.should be_a_kind_of String
185
206
  end
207
+ it "should start a file in gem service precised by gem_file in registry YAML configuration" do
208
+ $uuidgemfile = subject.start_service :name => 'uuidbygemfile'
209
+ $uuidgemfile.should be_an_instance_of UUID
210
+ end
211
+ it { subject.list.keys.should include "uuidbygemfile" }
212
+ it { subject.loaded_services.keys.should include "uuidbygemfile" }
213
+ it "should be possible to execute a method with the gem_file service" do
214
+ $uuidgemfile.generate.should be_a_kind_of String
215
+ subject.stop_service :name => "uuidbygemfile"
216
+ end
217
+
218
+
219
+ context "Distributed service" do
220
+ it "should be possible to execute a distributed service" do
221
+ $dummy_dist = subject.start_service :name => 'distdummy'
222
+ end
223
+ it "should exist a processus Ring server" do
224
+ File::exist?('/tmp/dorsal/ringserver.pid').should be_true
225
+ pid = `ps aux|grep ruby|grep -v grep |grep 'Ultragreen Ring Server'|awk '{ print $2}'`
226
+ pid.should_not be_empty
227
+ end
228
+ it "should log if debug mode", :if => $debug do
229
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Starting new Ring Server/).size.should >= 1
230
+ end
231
+ it "should not log if debug mode", :unless => $debug do
232
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Starting new Ring Server/).size.should eq 0
233
+ end
234
+ it "should include 'distdummy' in @loaded_services.keys" do
235
+ subject.loaded_services.should include "distdummy"
236
+ end
237
+ it "should distdummy be a DRbObject" do
238
+ $dummy_dist.should be_a_kind_of DRb::DRbObject
239
+ end
240
+ it "should be possible to use test method of the distributed dummy service, and return 'OK'" do
241
+ $dummy_dist.test.should eq 'OK'
242
+ end
243
+ end
244
+
186
245
  end
187
246
  end
188
247
 
@@ -200,7 +259,7 @@ describe Carioca do
200
259
  open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dummy stopped/).size.should >= 1
201
260
  end
202
261
  it "should not log if debug mode", :unless => $debug do
203
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dummy stopped/).size.should = 0
262
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dummy stopped/).size.should eq 0
204
263
  end
205
264
  it "should return false if service not already running" do
206
265
  subject.stop_service({:name => 'dum'}).should eq false
@@ -209,7 +268,7 @@ describe Carioca do
209
268
  open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dum not loaded/).size.should >= 1
210
269
  end
211
270
  it "should not log if debug mode and service not loaded", :unless => $debug do
212
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dum not loaded/).size.should = 0
271
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Service dum not loaded/).size.should eq 0
213
272
  end
214
273
  it "should return false if service :name is logger" do
215
274
  subject.stop_service({:name => 'logger'}).should eq false
@@ -218,9 +277,23 @@ describe Carioca do
218
277
  open('/tmp/log.file').grep(/DEBUG -- Carioca: Service logger can't be unloaded/).size.should >= 1
219
278
  end
220
279
  it "should not log if debug mode and service :name is logger", :unless => $debug do
221
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Service logger can't be unloaded/).size.should = 0
280
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Service logger can't be unloaded/).size.should eq 0
222
281
  end
223
282
 
283
+ context "Distributed Service" do
284
+ it "should be possible to stop a distributed service" do
285
+ $dummy_dist = subject.start_service :name => 'distdummy'
286
+ subject.stop_service({:name => 'distdummy'}).should be_true
287
+ end
288
+ it "should not exist forked daemon instance for this stopped service" do
289
+ pid = `ps aux|grep ruby|grep -v grep |grep 'a dummy test service'|awk '{ print $2}'`
290
+ pid.should be_empty
291
+ end
292
+ it "should not exist the pid file of this stopped services" do
293
+ File::exist?('/tmp/dorsal/service-distdummy.pid').should be_false
294
+ $dummy_dist = subject.start_service :name => 'distdummy'
295
+ end
296
+ end
224
297
 
225
298
  end
226
299
 
@@ -236,6 +309,16 @@ describe Carioca do
236
309
  it "should restart a service already loaded and log it" do
237
310
  $dummy = subject.restart_service :name => 'dummy'
238
311
  end
312
+
313
+ context "Distributed service" do
314
+ it "should ne possible to restart a distributed service" do
315
+ $dummy_dist = subject.restart_service :name => 'distdummy'
316
+ end
317
+ it "should log it if debug mode", :if => $debug do
318
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Restarting distributed service distdummy/).size.should eq 1
319
+ end
320
+ end
321
+
239
322
  it "should log it if debug mode", :if => $debug do
240
323
  open('/tmp/log.file').grep(/DEBUG -- Carioca: Restarting service dummy/).size.should eq 1
241
324
  end
@@ -275,7 +358,7 @@ describe Carioca do
275
358
  it "should add a new service" do
276
359
  subject.register_service :name => 'otherdummy',
277
360
  :type => :file,
278
- :resource => 'spec/samples/otherdummy.rb',
361
+ :resource => './spec/samples/otherdummy.rb',
279
362
  :service =>'ExternalServices::OtherDummy',
280
363
  :description => 'An other Dummy Service',
281
364
  :requires => ['requireddummy']
@@ -286,15 +369,15 @@ describe Carioca do
286
369
  it "should follow requires when started" do
287
370
  subject.register_service :name => 'requireddummy',
288
371
  :type => :file,
289
- :resource => 'spec/samples/requireddummy.rb',
372
+ :resource => './spec/samples/requireddummy.rb',
290
373
  :service =>'ExternalServices::RequiredDummy',
291
374
  :description => 'An other Dummy Service'
292
375
  subject.start_service :name => 'otherdummy'
293
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Registry dependancy found and not loaded : requireddummy/).size.should eq 1
376
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Registry dependancy found and not loaded : requireddummy/).size.should eq 1 if $debug
294
377
  subject.loaded_services.keys.should include 'requireddummy'
295
378
  subject.loaded_services.keys.should include 'otherdummy'
296
379
  end
297
- it "should raise Argument error if :type is not :gem, :file or :builtin" do
380
+ it "should raise Argument error if :type is not :gem, :file, :gem_file or :builtin" do
298
381
  lambda { subject.register_service :name => 'otherdummy',
299
382
  :type => :error,
300
383
  :resource => 'spec/samples/otherdummy.rb',
@@ -336,14 +419,20 @@ describe Carioca do
336
419
  it "should not log a registry closing notification if not debug mode", :unless => $debug do
337
420
  open('/tmp/log.file').grep(/DEBUG -- Carioca: closing Registry .../).size.should eq 0
338
421
  end
422
+ it "should log a distributed service killing notification if debug mode", :if => $debug do
423
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Killing distributed Service distdummy./).size.should >= 1
424
+ end
425
+ it "should not log a distributed service killing notification if not debug mode", :unless => $debug do
426
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Killing distributed Service distdummy./).size.should eq 0
427
+ end
339
428
  it "should log a stopping notification for each services if debug mode", :if => $debug do
340
- ['debug','uuid'].each do |service|
341
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Stopping service #{service} .../).size.should eq 1
429
+ ['debug','uuid','dorsal','dummy','dummy_one','requireddummy','otherdummy'].each do |service|
430
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Service #{service} stopped/).size.should >= 1
342
431
  end
343
432
  end
344
433
  it "should not log a stopping notification for each services if not debug mode", :unless => $debug do
345
- ['debug','uuid'].each do |service|
346
- open('/tmp/log.file').grep(/DEBUG -- Carioca: Stopping service #{service} .../).size.should eq 0
434
+ ['debug','uuid','dorsal','dummy','dummy_one','requireddummy','otherdummy'].each do |service|
435
+ open('/tmp/log.file').grep(/DEBUG -- Carioca: Service #{service} stopped/).size.should eq 0
347
436
  end
348
437
  end
349
438
  it "should log a registry closing confirmation if debug mode", :if => $debug do
@@ -355,6 +444,8 @@ describe Carioca do
355
444
  it "should loaded services empty" do
356
445
  subject.loaded_services.empty?.should eq true
357
446
  end
447
+ context "Distributed service" do
448
+ end
358
449
  end
359
450
  end
360
451
  end