carioca 0.1 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +3 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +4 -0
- data/README.md +236 -0
- data/carioca.gemspec +2 -2
- data/doc/manual.rdoc +192 -3
- data/lib/carioca.rb +277 -187
- data/lib/carioca_private.rb +100 -0
- data/lib/services.rb +58 -2
- data/lib/services/configuration.rb +150 -18
- data/lib/services/debug.rb +15 -12
- data/lib/services/logger.rb +18 -12
- data/spec/carioca_spec.rb +157 -19
- data/spec/config/services.registry +14 -14
- data/spec/samples/dummy.rb +1 -1
- data/spec/samples/otherdummy.rb +10 -0
- data/spec/samples/requireddummy.rb +10 -0
- data/ultragreen_roodi_coding_convention.yml +1 -1
- metadata +10 -7
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#---
|
3
|
+
# Author : Romain GEORGES
|
4
|
+
# type : gem component library
|
5
|
+
# obj : Carioca Private Module (mixin for Carioca::Services::Registry)
|
6
|
+
#---
|
7
|
+
|
8
|
+
# private methods to mixin Carioca::Services::Registry
|
9
|
+
# @private
|
10
|
+
module PrivateMethodsCariocaServicesRegistry
|
11
|
+
|
12
|
+
|
13
|
+
# private initializer
|
14
|
+
def initialize(_options)
|
15
|
+
@logger_not_in_reg = false
|
16
|
+
@debug = _options[:debug]
|
17
|
+
@registry_filename = _options[:file]
|
18
|
+
@list = Hash::new
|
19
|
+
load if File::exist?(@registry_filename)
|
20
|
+
unless @list.include?('logger') then
|
21
|
+
self.register_service({:name => 'logger',
|
22
|
+
:service => 'Carioca::Services::InternalLogger',
|
23
|
+
:resource => 'logger',
|
24
|
+
:description => "The standard ruby Logger internal wrapper Service",
|
25
|
+
:type => :builtin,
|
26
|
+
:init_options => { :target => "/tmp/log.file"}})
|
27
|
+
@logger_not_in_reg = true
|
28
|
+
end
|
29
|
+
@loaded_services = Hash::new
|
30
|
+
# preload logger service
|
31
|
+
@log = self.start_service :name => 'logger'
|
32
|
+
@log.level =(@debug)? Logger::DEBUG : Logger::INFO
|
33
|
+
@log.debug('Carioca') { "Registry started, service logger preloaded" }
|
34
|
+
@log.debug('Carioca') { "Logger registered, not in configured registry" } if @logger_not_in_reg
|
35
|
+
end
|
36
|
+
|
37
|
+
# verify dependancies in services structure
|
38
|
+
# in @list from a service defition
|
39
|
+
# in _options and start it if needed
|
40
|
+
def verify_requires_dependancies(_options)
|
41
|
+
_name = _options[:shortname]
|
42
|
+
if @list[_name].include?(:requires) then
|
43
|
+
@list[_name][:requires].each do |service|
|
44
|
+
raise RegistryError::new 'Missing Required depedancy #{service}' unless @list.keys.include? service
|
45
|
+
unless @loaded_services.include?(service) then
|
46
|
+
@log.debug('Carioca') { "Registry dependancy found and not loaded : #{service}" }
|
47
|
+
restart_service :name => service
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# require file for a service
|
54
|
+
# from a service definition in _options
|
55
|
+
def require_service(_options)
|
56
|
+
_name = _options[:shortname]
|
57
|
+
sym = ":#{@list[_name][:service].split('::').last}"
|
58
|
+
case @list[_name][:type]
|
59
|
+
when :file then
|
60
|
+
require @list[_name][:resource]
|
61
|
+
when :builtin then
|
62
|
+
_file = Carioca::Services::search_builtins _name
|
63
|
+
if _file then
|
64
|
+
require _file
|
65
|
+
else
|
66
|
+
raise RegistryError::new("Config failed")
|
67
|
+
end
|
68
|
+
when :gem then
|
69
|
+
eval("require '#{@list[_name][:resource]}'")
|
70
|
+
else
|
71
|
+
raise RegistryError::new("Config failed")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# instanciate Object from class defintion of a service defined in
|
76
|
+
# the service definition in _options
|
77
|
+
def instanciate_service(_options)
|
78
|
+
|
79
|
+
_name = _options[:shortname]
|
80
|
+
@list[_name][:init_options].merge! _options[:params] unless _options[:params].nil?
|
81
|
+
if @list[_name][:init_options].nil? then
|
82
|
+
eval("@loaded_services[_options[:name]] = #{@list[_name][:service]}::new")
|
83
|
+
else
|
84
|
+
eval("@loaded_services[_options[:name]] = #{@list[_name][:service]}::new(@list[_name][:init_options])")
|
85
|
+
end
|
86
|
+
@log.debug('Carioca') { "Service #{_options[:name]} started" } if @log
|
87
|
+
return @loaded_services[_options[:name]]
|
88
|
+
end
|
89
|
+
|
90
|
+
# call the garbage method of a service if exist and
|
91
|
+
# Delete from the loaded services list
|
92
|
+
def kill_service(_name)
|
93
|
+
@loaded_services[_name].garbage if @loaded_services[_name].respond_to? :garbage
|
94
|
+
@loaded_services.delete(_name)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
end # end of PrivateMethodsCariocaServicesRegistry
|
99
|
+
|
100
|
+
|
data/lib/services.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#---
|
3
|
+
# Author : Romain GEORGES
|
4
|
+
# type : gem component library
|
5
|
+
# obj : Carioca::Services Module
|
6
|
+
#---
|
7
|
+
|
8
|
+
|
9
|
+
|
1
10
|
module Carioca
|
11
|
+
|
12
|
+
# namespace Services for Registry AND buitlins
|
2
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
|
3
18
|
def Services::search_builtins(_name)
|
4
19
|
asearch = Gem.searcher
|
5
20
|
spec = asearch.find('carioca')
|
@@ -17,10 +32,51 @@ module Carioca
|
|
17
32
|
return false
|
18
33
|
end
|
19
34
|
end
|
35
|
+
|
36
|
+
# class method returning the [Carioca::Services::Registry]@list complement for builtins service found for a carioca gem version
|
37
|
+
# @note do not use directly for generale purpose (expert/hacks only)
|
38
|
+
# @return [Hash] the [Carioca::Services::Registry]@list complement
|
39
|
+
def Services::discover_builtins
|
20
40
|
|
21
|
-
|
22
|
-
|
41
|
+
asearch = Gem.searcher
|
42
|
+
spec = asearch.find('carioca')
|
43
|
+
if spec then
|
44
|
+
res = asearch.lib_dirs_for(spec).split('/')
|
45
|
+
res.pop
|
46
|
+
services_path = res.join('/').concat('/lib/services')
|
47
|
+
else
|
48
|
+
services_path = "lib/services"
|
49
|
+
end
|
50
|
+
|
51
|
+
map = Dir["#{services_path}/*"]
|
52
|
+
map.delete_if { |item| not File::file?(item) }
|
53
|
+
map.delete_if { |item| File::basename(item) == 'logger.rb' }
|
23
54
|
|
55
|
+
res = {}
|
56
|
+
map.each do |file|
|
57
|
+
Services::validate_service(file,res)
|
58
|
+
end
|
59
|
+
return res
|
60
|
+
end
|
24
61
|
|
62
|
+
def Services::validate_service(file,res)
|
63
|
+
init_options = {}
|
64
|
+
if open(file).grep(/^# \$BUILTIN/).size > 0 then
|
65
|
+
service = open(file).grep(/# \$SERVICE/).first.split[2]
|
66
|
+
resource = open(file).grep(/# \$RESOURCE/).first.split[2]
|
67
|
+
desc = open(file).grep(/# \$DESCRIPTION/).first
|
68
|
+
desc = desc.split(' ')
|
69
|
+
desc.shift(2)
|
70
|
+
description= desc.join(' ')
|
71
|
+
open(file).grep(/# \$INIT_OPTIONS/).each do |opt|
|
72
|
+
prev = opt.split
|
73
|
+
init_options[prev[2].to_sym] = prev[4]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
unless service.nil? or resource.nil? or description.nil? then
|
77
|
+
res[resource] = { :service => service, :type => :builtin, :description => description, :resource => resource}
|
78
|
+
res[resource][:init_options] = init_options unless init_options.empty?
|
79
|
+
end
|
80
|
+
end
|
25
81
|
end
|
26
82
|
end
|
@@ -1,4 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# $BUILTIN
|
3
|
+
# $NAME configuration
|
4
|
+
# $SERVICE Carioca::Services::Configuration
|
5
|
+
# $RESOURCE configuration
|
6
|
+
# $DESCRIPTION The Carioca Configuration Service
|
7
|
+
# $INIT_OPTIONS config_file => ./.config
|
8
|
+
|
2
9
|
# Copyright Ultragreen (c) 2005
|
3
10
|
#---
|
4
11
|
# Author : Romain GEORGES
|
@@ -11,41 +18,166 @@
|
|
11
18
|
require 'rubygems'
|
12
19
|
require 'methodic'
|
13
20
|
require 'services'
|
21
|
+
require 'yaml'
|
22
|
+
|
23
|
+
# overwriting Hash class
|
24
|
+
# @private
|
25
|
+
class Hash
|
26
|
+
|
27
|
+
|
28
|
+
# recursively transform Hash keys form String to Symbols
|
29
|
+
# come from Rails code
|
30
|
+
# exist in Ruby 2.0
|
31
|
+
def deep_symbolize
|
32
|
+
target = dup
|
33
|
+
target.inject({}) do |memo, (key, value)|
|
34
|
+
value = value.deep_symbolize if value.is_a?(Hash)
|
35
|
+
memo[key.to_sym] = value
|
36
|
+
memo
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# pretty accessor for hash record
|
41
|
+
# like ahash[:key] => ahash.key
|
42
|
+
# r/w accessor
|
43
|
+
def method_missing(name, *args, &block)
|
44
|
+
if name.to_s =~ /(.+)=$/
|
45
|
+
self[$1.to_sym] = args.first
|
46
|
+
else
|
47
|
+
self[name.to_sym]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
14
55
|
|
15
56
|
module Carioca
|
57
|
+
|
16
58
|
module Services
|
17
|
-
|
18
|
-
class
|
59
|
+
|
60
|
+
# settings Hash record utilities class
|
61
|
+
# @note please do not use Standalone ( dependancy of Configuration class )
|
62
|
+
# @private
|
63
|
+
class Settings < Hash
|
64
|
+
|
65
|
+
# the name of the config file in YAML format
|
66
|
+
attr_accessor :config_file
|
67
|
+
|
68
|
+
# constructor (pre-open the config file in YAML)
|
69
|
+
# @param [Hash] options the options records
|
70
|
+
# @option options [String] :config_file (REQUIRED) the name of the config file
|
71
|
+
# @option options [String] :context a context (root) name to bind in YAML Structure
|
72
|
+
def initialize(options = {})
|
73
|
+
@config_file = options[:config_file]
|
74
|
+
newsets = {}
|
75
|
+
if File::exist?(@config_file) then
|
76
|
+
newsets = YAML::load_file(@config_file).deep_symbolize
|
77
|
+
newsets = newsets[options[:context].to_sym] if options[:context] && newsets[options[:context].to_sym]
|
78
|
+
deep_merge!(self, newsets)
|
79
|
+
end
|
80
|
+
end
|
19
81
|
|
82
|
+
# save the Hash(self) in the file named by @config_file
|
83
|
+
# @return [TrueClass,FalseClass] true if save! successfull
|
84
|
+
def save!
|
85
|
+
res = false
|
86
|
+
File.open(@config_file, "w") do |f|
|
87
|
+
res = true if f.write(self.to_yaml)
|
88
|
+
end
|
89
|
+
return res
|
90
|
+
end
|
91
|
+
|
92
|
+
|
20
93
|
private
|
21
|
-
#
|
22
|
-
|
23
|
-
|
24
|
-
|
94
|
+
# full recursive merger for hash
|
95
|
+
def deep_merge!(target, data)
|
96
|
+
merger = proc{|key, v1, v2|
|
97
|
+
Settings === v1 && Settings === v2 ? v1.merge(v2, &merger) : v2 }
|
98
|
+
target.merge! data, &merger
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
# Service Configuration of Carioca
|
108
|
+
class Configuration
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
# @example
|
113
|
+
# config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
|
114
|
+
# p config.config_file
|
115
|
+
# config_file = 'newfilename'
|
116
|
+
# @attr_reader [String] the filename of the YAML struct
|
117
|
+
attr_accessor :settings
|
118
|
+
|
119
|
+
|
120
|
+
# Configuration service constructor (open config)
|
121
|
+
# @param [Hash] _options the params
|
122
|
+
# @option _options [String] :config_file the filename of the config
|
123
|
+
def initialize(_options = {})
|
25
124
|
options = Methodic.get_options(_options)
|
26
|
-
options.
|
27
|
-
options.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
125
|
+
options.specify_default_value :config_file => "./.config"
|
126
|
+
options.merge
|
127
|
+
@settings = Carioca::Services::Settings.new(options)
|
33
128
|
end
|
34
129
|
|
35
|
-
|
36
|
-
|
130
|
+
# Proxy to @settings.save!
|
131
|
+
# save the Hash(self) in the file named by @config_file
|
132
|
+
# @return [TrueClass,FalseClass] true if save! successfull
|
133
|
+
# @example usage
|
134
|
+
# config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
|
135
|
+
# config.config_file = 'newfile'
|
136
|
+
# config.save!
|
137
|
+
def save!
|
138
|
+
@settings.save!
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# reading wrapper to @settings.config_file accessor
|
143
|
+
# @return [String] @config_file the file name
|
144
|
+
# @example usage
|
145
|
+
# config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
|
146
|
+
# p config.config_file
|
147
|
+
def config_file
|
148
|
+
@settings.config_file
|
149
|
+
end
|
150
|
+
|
151
|
+
# writting wrapper to @settings.config_file accessor
|
152
|
+
# @param [String] name the file name
|
153
|
+
# @example usage
|
154
|
+
# config = Carioca::Services::Configuration::new :config_file => 'afilename', :context => 'production'
|
155
|
+
# config.config_file = 'newfile'
|
156
|
+
def config_file=(name)
|
157
|
+
@settings.config_file = name
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
# garbage service hook
|
162
|
+
# @note close the logger
|
163
|
+
# @note call by Carioca::Services::Registry#close
|
164
|
+
def garbage
|
165
|
+
@settings = nil
|
166
|
+
return true
|
37
167
|
end
|
38
168
|
|
39
169
|
end
|
40
170
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
171
|
end
|
45
172
|
|
46
173
|
|
174
|
+
|
175
|
+
|
176
|
+
|
47
177
|
# interactive hacks
|
48
178
|
if $0 == __FILE__ then
|
179
|
+
conf =Carioca::Services::Configuration::new :config_file => 'spec/config/.config'
|
180
|
+
p conf
|
49
181
|
puts "#{File::basename(__FILE__)}:"
|
50
182
|
puts 'this is a RUBY library file'
|
51
183
|
puts "Copyright (c) Ultragreen"
|
data/lib/services/debug.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# $BUILTIN
|
3
|
+
# $NAME debug
|
4
|
+
# $SERVICE Carioca::Services::ProxyDebug
|
5
|
+
# $RESOURCE debug
|
6
|
+
# $DESCRIPTION Proxy class debugger Service for Carioca
|
2
7
|
# Copyright Ultragreen (c) 2012
|
3
8
|
#---
|
4
9
|
# Author : Romain GEORGES
|
@@ -14,14 +19,18 @@ require 'methodic'
|
|
14
19
|
module Carioca
|
15
20
|
module Services
|
16
21
|
|
17
|
-
# standard RAA dependency
|
18
|
-
|
19
22
|
|
23
|
+
# Service Debug of Carioca
|
24
|
+
# Proxy Class Debug for devs
|
20
25
|
class ProxyDebug
|
21
26
|
|
27
|
+
# ProxyDebug service constructor (has a class proxy => so a service proxy)
|
28
|
+
# @param [Hash] _options the params
|
29
|
+
# @option _options [String] :service the name of the service you want to proxyfying
|
30
|
+
# @option _options [Hash] :params the params of the proxyfied service
|
22
31
|
def initialize(_options)
|
23
32
|
options = Methodic.get_options(_options)
|
24
|
-
options.specify_classes_of :service => String
|
33
|
+
options.specify_classes_of :service => String
|
25
34
|
options.specify_presence_of([:service])
|
26
35
|
options.validate!
|
27
36
|
if options[:params] then
|
@@ -33,26 +42,24 @@ module Carioca
|
|
33
42
|
@mapped_service = options[:service]
|
34
43
|
end
|
35
44
|
|
45
|
+
# method_missing overload to make the class proxy efficient
|
36
46
|
def method_missing(methodname, *args,&block)
|
37
47
|
@log.debug("ProxyDebug") { "BEGIN CALL for mapped service #{@mapped_service} "}
|
38
48
|
@log.debug("ProxyDebug") { "called: #{methodname} " }
|
39
49
|
@log.debug("ProxyDebug") { "args : #{args}" }
|
40
|
-
|
41
50
|
if block_given? then
|
42
51
|
@log.debug("ProxyDebug") { "block given" }
|
43
52
|
a = @obj.send(methodname, *args,&block)
|
44
53
|
else
|
45
|
-
|
46
54
|
a = @obj.send(methodname, *args)
|
47
55
|
end
|
48
|
-
|
49
56
|
@log.debug("ProxyDebug") { "=> returned: #{a} " }
|
50
57
|
@log.debug("ProxyDebug") { 'END CALL' }
|
51
58
|
return a
|
52
59
|
end
|
60
|
+
|
61
|
+
|
53
62
|
end
|
54
|
-
|
55
|
-
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
@@ -61,10 +68,6 @@ if $0 == __FILE__ then
|
|
61
68
|
puts "#{File::basename(__FILE__)}:"
|
62
69
|
puts 'this is a RUBY library file'
|
63
70
|
puts "Copyright (c) Ultragreen"
|
64
|
-
puts "Version : #{Agents::LIB_VERSION}"
|
65
|
-
puts "Author : #{Agents::AUTHOR}"
|
66
|
-
puts "Date release : #{Agents::DATE}"
|
67
|
-
puts "Observation : #{Agents::OBS}"
|
68
71
|
end
|
69
72
|
|
70
73
|
|
data/lib/services/logger.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# $BUILTIN
|
3
|
+
# $NAME logger
|
4
|
+
# $SERVICE Carioca::Services::InternalLogger
|
5
|
+
# $RESOURCE logger
|
6
|
+
# $DESCRIPTION The standard ruby Logger internal wrapper Service for Carioca
|
7
|
+
# $INIT_OPTIONS target => /tmp/log.file
|
2
8
|
# Copyright Ultragreen (c) 2005
|
3
9
|
#---
|
4
10
|
# Author : Romain GEORGES
|
@@ -7,31 +13,31 @@
|
|
7
13
|
#---
|
8
14
|
# $Id$
|
9
15
|
|
10
|
-
|
11
16
|
require 'rubygems'
|
12
17
|
require 'logger'
|
13
18
|
require 'methodic'
|
14
19
|
|
15
20
|
module Carioca
|
16
21
|
module Services
|
17
|
-
|
22
|
+
|
23
|
+
# Service Logger (InternalLogger) of Carioca,
|
24
|
+
# @note integrally based on Logger from logger Gem
|
18
25
|
class InternalLogger < Logger
|
19
26
|
|
20
27
|
private
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
28
|
+
|
29
|
+
# logger service constructor (open log)
|
30
|
+
# @param [Hash] _options the params
|
31
|
+
# @option _options [String] :target the filename where to log
|
32
|
+
def initialize(_options = {})
|
25
33
|
options = Methodic.get_options(_options)
|
26
|
-
options.
|
27
|
-
options.
|
28
|
-
|
34
|
+
options.specify_default_value :target => STDOUT
|
35
|
+
options.merge
|
29
36
|
super(options[:target])
|
30
|
-
|
31
|
-
|
32
|
-
|
33
37
|
end
|
34
38
|
|
39
|
+
# garbage service hook
|
40
|
+
# @note close the logger
|
35
41
|
def garbage
|
36
42
|
self.close
|
37
43
|
end
|