carioca 0.1 → 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.
- 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
|