lorj 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.gitreview +4 -0
  4. data/Gemfile +25 -0
  5. data/Gemfile.lock +34 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +652 -0
  8. data/Rakefile +24 -0
  9. data/bin/cloud_test.rb +81 -0
  10. data/example/students_1/process/Students.rb +20 -0
  11. data/example/students_1/students.rb +16 -0
  12. data/example/students_2/process/Students.rb +27 -0
  13. data/example/students_2/students.rb +36 -0
  14. data/example/students_3/controller/yaml_students.rb +94 -0
  15. data/example/students_3/controller/yaml_students_controller.rb +123 -0
  16. data/example/students_3/process/students.rb +118 -0
  17. data/example/students_3/students.rb +93 -0
  18. data/example/students_4/controller/yaml_students.rb +82 -0
  19. data/example/students_4/controller/yaml_students_controller.rb +141 -0
  20. data/example/students_4/process/students.rb +112 -0
  21. data/example/students_4/students.rb +103 -0
  22. data/example/yaml_students/students.rb +78 -0
  23. data/example/yaml_students/yaml_students.rb +115 -0
  24. data/lib/concept.md +111 -0
  25. data/lib/core/core.rb +723 -0
  26. data/lib/core/definition.rb +505 -0
  27. data/lib/core/definition_internal.rb +338 -0
  28. data/lib/core/lorj-basecontroller.rb +90 -0
  29. data/lib/core/lorj-basedefinition.rb +1079 -0
  30. data/lib/core/lorj-baseprocess.rb +231 -0
  31. data/lib/core/lorj-data.rb +567 -0
  32. data/lib/core/lorj-keypath.rb +115 -0
  33. data/lib/core_process/CloudProcess.rb +334 -0
  34. data/lib/core_process/global_process.rb +406 -0
  35. data/lib/core_process/network_process.rb +603 -0
  36. data/lib/img/.directory +4 -0
  37. data/lib/img/account_data_access.png +0 -0
  38. data/lib/img/config_data_access.png +0 -0
  39. data/lib/img/forj-lib-concept.png +0 -0
  40. data/lib/lorj/version.rb +3 -0
  41. data/lib/lorj.rb +51 -0
  42. data/lib/prc-account.rb +339 -0
  43. data/lib/prc-config.rb +1023 -0
  44. data/lib/prc-logging.rb +183 -0
  45. data/lib/prc.rb +108 -0
  46. data/lib/providers/hpcloud/Hpcloud.rb +419 -0
  47. data/lib/providers/hpcloud/compute.rb +108 -0
  48. data/lib/providers/hpcloud/network.rb +117 -0
  49. data/lib/providers/hpcloud/security_groups.rb +67 -0
  50. data/lib/providers/mock/Mock.rb +141 -0
  51. data/lib/providers/openstack/Openstack.rb +47 -0
  52. data/lib/providers/templates/compute.rb +42 -0
  53. data/lib/providers/templates/core.rb +61 -0
  54. data/lib/providers/templates/network.rb +33 -0
  55. data/lorj-spec/defaults.yaml +26 -0
  56. data/lorj.gemspec +39 -0
  57. data/spec/forj-account_spec.rb +75 -0
  58. data/spec/forj-config_spec.rb +196 -0
  59. metadata +164 -0
data/lib/prc-config.rb ADDED
@@ -0,0 +1,1023 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+
19
+ require 'rubygems'
20
+ require 'yaml'
21
+
22
+ module Lorj
23
+
24
+ # Recursive Hash existence
25
+ # This function will returns the level of recursive hash was found.
26
+ # * *Args* :
27
+ # - +yVal+ : Hash of hashes (or recursive hash).
28
+ # - +p+ : Array of string or symbols. keys tree to follow and check existence in yVal.
29
+ #
30
+ # * *Returns* :
31
+ # - +integer+ : Represents how many keys was found in the recursive hash
32
+ #
33
+ # * *Raises* :
34
+ # No exceptions
35
+ #
36
+ # Example:
37
+ #
38
+ # yVal = { :test => {:test2 => 'value1', :test3 => 'value2'}, :test4 => 'value3'}
39
+ #
40
+ # yVal can be represented like:
41
+ #
42
+ # yVal:
43
+ # test:
44
+ # test2 = 'value1'
45
+ # test3 = 'value2'
46
+ # test4 = 'value3'
47
+ #
48
+ # so:
49
+ # rhExist?(yVal, :test) => 1 # test is found
50
+ # rhExist?(yVal, :test5) => 0 # no test5
51
+ # rhExist?(yVal, :test, :test2) => 2 # :test/:test2 tree is found
52
+ # rhExist?(yVal, :test, :test2, :test5) => 2 # :test/:test2 is found (value = 2), but :test5 was not found in this tree
53
+ # rhExist?(yVal, :test, :test5 ) => 1 # :test was found. but :test/:test5 tree was not found. so level 1, ok.
54
+ # rhExist?(yVal) => 0 # it is like searching for nothing...
55
+
56
+ def Lorj::rhExist?(yVal, *p)
57
+
58
+ if p.length() == 0
59
+ return 0
60
+ end
61
+ return 0 if yVal.class != Hash
62
+ p=p.flatten
63
+ if p.length() == 1
64
+ return 1 if yVal.key?(p[0])
65
+ return 0
66
+ end
67
+ return 0 if yVal.nil? or not yVal.key?(p[0])
68
+ ret = 0
69
+ ret = Lorj::rhExist?(yVal[p[0]], p.drop(1)) if yVal[p[0]].class == Hash
70
+ return 1 + ret
71
+ end
72
+
73
+ # Recursive Hash Get
74
+ # This function will returns the level of recursive hash was found.
75
+ # * *Args* :
76
+ # - +yVal+ : Hash of hashes (or recursive hash).
77
+ # - +p+ : Array of string or symbols. keys tree to follow and check existence in yVal.
78
+ #
79
+ # * *Returns* :
80
+ # - +value+ : Represents the data found in the tree. Can be of any type.
81
+ #
82
+ # * *Raises* :
83
+ # No exceptions
84
+ #
85
+ # Example:
86
+ #
87
+ # yVal = { :test => {:test2 => 'value1', :test3 => 'value2'}, :test4 => 'value3'}
88
+ #
89
+ # yVal can be represented like:
90
+ #
91
+ # yVal:
92
+ # test:
93
+ # test2 = 'value1'
94
+ # test3 = 'value2'
95
+ # test4 = 'value3'
96
+ #
97
+ # so:
98
+ # rhGet(yVal, :test) => {:test2 => 'value1', :test3 => 'value2'}
99
+ # rhGet(yVal, :test5) => nil
100
+ # rhGet(yVal, :test, :test2) => 'value1'
101
+ # rhGet(yVal, :test, :test2, :test5) => nil
102
+ # rhGet(yVal, :test, :test5 ) => nil
103
+ # rhGet(yVal) => nil
104
+ def Lorj::rhGet(yVal, *p)
105
+
106
+ return nil if yVal.class != Hash
107
+ p=p.flatten
108
+ if p.length() == 0 or not yVal
109
+ return yVal
110
+ end
111
+ if p.length() == 1
112
+ return yVal[p[0]] if yVal.key?(p[0])
113
+ return nil
114
+ end
115
+ return nil if not yVal
116
+ return Lorj::rhGet(yVal[p[0]], p.drop(1)) if yVal.key?(p[0])
117
+ nil
118
+ end
119
+
120
+ # Recursive Hash Set
121
+ # This function will build a recursive hash according to the '*p' key tree.
122
+ # if yVal is not nil, it will be updated.
123
+ #
124
+ # * *Args* :
125
+ # - +yVal+ : Hash of hashes (or recursive hash).
126
+ # - +p+ : Array of string or symbols. keys tree to follow and check existence in yVal.
127
+ #
128
+ # * *Returns* :
129
+ # - +value+ : the value set.
130
+ #
131
+ # * *Raises* :
132
+ # No exceptions
133
+ #
134
+ # Example:
135
+ #
136
+ # yVal = {}
137
+ #
138
+ # rhSet(yVal, :test) => nil
139
+ # # yVal = {}
140
+ #
141
+ # rhSet(yVal, :test5) => nil
142
+ # # yVal = {}
143
+ #
144
+ # rhSet(yVal, :test, :test2) => :test
145
+ # # yVal = {:test2 => :test}
146
+ #
147
+ # rhSet(yVal, :test, :test2, :test5) => :test
148
+ # # yVal = {:test2 => {:test5 => :test} }
149
+ #
150
+ # rhSet(yVal, :test, :test5 ) => :test
151
+ # # yVal = {:test2 => {:test5 => :test}, :test5 => :test }
152
+ #
153
+ # rhSet(yVal, 'blabla', :test2, 'text') => :test
154
+ # # yVal = {:test2 => {:test5 => :test, 'text' => 'blabla'}, :test5 => :test }
155
+ def Lorj::rhSet(yVal, value, *p)
156
+ if p.length() == 0
157
+ return yVal
158
+ end
159
+ p=p.flatten
160
+ if p.length() == 1
161
+ if not yVal.nil?
162
+ if not value.nil?
163
+ yVal[p[0]] = value
164
+ else
165
+ yVal.delete(p[0])
166
+ end
167
+ return yVal
168
+ end
169
+ #~ if value
170
+ ret = { p[0] => value }
171
+ #~ else
172
+ #~ ret = {}
173
+ #~ end
174
+ return ret
175
+ end
176
+ if not yVal.nil?
177
+ yVal[p[0]] = {} if not yVal[p[0]] or yVal[p[0]].class != Hash
178
+ ret=Lorj::rhSet(yVal[p[0]], value, p.drop(1))
179
+ return yVal
180
+ else
181
+ ret = Lorj::rhSet(nil, value, p.drop(1))
182
+ return { p[0] => ret }
183
+ end
184
+ end
185
+
186
+ # Move levels (default level 1) of tree keys to become symbol.
187
+ #
188
+ # * *Args* :
189
+ # - +yVal+ : Hash of hashes (or recursive hash).
190
+ # - +levels+: level of key tree to update.
191
+ # * *Returns* :
192
+ # - hash of hashes updated.
193
+ # * *Raises* :
194
+ # Nothing
195
+ def Lorj.rhKeyToSymbol(yVal, levels = 1)
196
+ return nil if yVal.nil? or yVal.class != Hash
197
+ yRes = {}
198
+ yVal.each { | key, value |
199
+ if key.class == String
200
+ if levels <= 1
201
+ yRes[key.to_sym] = value
202
+ else
203
+ yRes[key.to_sym] = rhKeyToSymbol(value, levels - 1)
204
+ end
205
+ else
206
+ if levels <= 1
207
+ yRes[key] = value
208
+ else
209
+ yRes[key] = rhKeyToSymbol(value, levels - 1)
210
+ end
211
+ end
212
+ }
213
+ yRes
214
+ end
215
+
216
+ # Check if levels of tree keys are all symbols.
217
+ #
218
+ # * *Args* :
219
+ # - +yVal+ : Hash of hashes (or recursive hash).
220
+ # - +levels+: level of key tree to update.
221
+ # * *Returns* :
222
+ # - true : one key path is not symbol.
223
+ # - false : all key path are symbols.
224
+ # * *Raises* :
225
+ # Nothing
226
+ def Lorj.rhKeyToSymbol?(yVal, levels = 1)
227
+ return false if yVal.nil? or yVal.class != Hash
228
+ yVal.each { | key, value |
229
+ if key.class == String
230
+ return true
231
+ end
232
+ if levels >1
233
+ res = rhKeyToSymbol?(value, levels - 1)
234
+ return true if res
235
+ end
236
+ }
237
+ false
238
+ end
239
+
240
+ # This class is the Application configuration class used by Lorj::Config
241
+ #
242
+ # It load a defaults.yaml file (path defined by PrcLib::app_defaults)
243
+ #
244
+ # defaults.yaml is divided in 3 sections:
245
+ #
246
+ # * :default: Contains a list of key = value
247
+ # * :setup: Contains :ask_step array
248
+ # - :ask_step: Array of group of keys/values to setup. Each group will be internally identified by a index starting at 0. parameters are as follow:
249
+ # - :desc: string to print out before group setup
250
+ # - :explanation: longer string to display after :desc:
251
+ # - :add: array of keys to add manually in the group.
252
+ #
253
+ # By default, thanks to data model dependency, the group is automatically populated.
254
+ #
255
+ # * :section: Contains a list of sections contains several key and attributes and eventually :default:
256
+ # This list of sections and keys will be used to build the account files with the lorj Lorj::Core::Setup function.
257
+ #
258
+ # - :default: This section define updatable data available from config.yaml. But will never be added in an account file.
259
+ # It contains a list of key and options.
260
+ #
261
+ # - :<aKey>: Possible options
262
+ # - :desc: default description for that <aKey>
263
+ #
264
+ # - :<aSectionName>: Name of the section which should contains a lis
265
+ # - :<aKeyName>: Name of the key to setup.
266
+ # - :desc: Description of that key, printed out at setup time.
267
+ # - :readonly: true if this key is not modifiable by a simple Lorj::Account::set function. false otherwise.
268
+ # - :account_exclusive: true if the key cannot be set as default from config.yaml or defaults.yaml.
269
+ # - :account: true to ask setup to ask this key to the user.
270
+ # - :validate: Ruby Regex to validate the end user input. Ex: !ruby/regexp /^\w?\w*$/
271
+ # - :default_value: default value proposed to the user.
272
+ # - :ask_step: Define the group number to attach the key to be asked. ex: 2
273
+ # - :list_values: Provide capabililities to get a list and choose from.
274
+ # - :query_type: Can be:
275
+ #
276
+ # ':query_call' to execute a query on flavor, query_params is empty for all.
277
+ #
278
+ # ':process_call' to execute a process function to get the values.
279
+ #
280
+ # ':controller_call' to execute a controller query.
281
+ #
282
+ # - :object:
283
+ #
284
+ # Used with :query_type=:query_call. object type symbol to query.
285
+ #
286
+ # - :query
287
+ #
288
+ # Used with :query_type=:process_call. process function name to call.
289
+ #
290
+ # - :query_call:
291
+ #
292
+ # Used with :query_type=:controller_call. Handler function to use. (query_e, create_e, ...)
293
+ #
294
+ # Used with :query_type=:process_call. Function name to call
295
+ #
296
+ # - :query_params:
297
+ #
298
+ # Used with :query_type=:query_call. Query hash defining filtering capabilities.
299
+ #
300
+ # Used with :query_type=:process_call. hParams data passed to the process function.
301
+ #
302
+ # - :value: fields to extract for the list of objects displayed.
303
+ # - :validate: if :list_strict, the value is limited to the possible values from the list
304
+
305
+ class Default
306
+
307
+ # @sDefaultsName='defaults.yaml'
308
+ # @yDefaults = defaults.yaml file data hash
309
+
310
+ # Load yaml documents (defaults)
311
+ # If config doesn't exist, it will be created, empty with 'defaults:' only
312
+
313
+ # class.exist?
314
+ #
315
+ #
316
+ # * *Args* :
317
+ # - ++ ->
318
+ # * *Returns* :
319
+ # -
320
+ # * *Raises* :
321
+ # - ++ ->
322
+ def self.exist?(key, section = :default)
323
+ key = key.to_sym if key.class == String
324
+ (Lorj::rhExist?(@@yDefaults, section, key) == 2)
325
+ end
326
+
327
+ #
328
+ #
329
+ # * *Args* :
330
+ # - ++ ->
331
+ # * *Returns* :
332
+ # -
333
+ # * *Raises* :
334
+ # - ++ ->
335
+ def self.get(key, section = :default)
336
+ key = key.to_sym if key.class == String
337
+ return(Lorj::rhGet(@@yDefaults, section, key)) if key
338
+ Lorj::rhGet(@@yDefaults, section) if not key
339
+ end
340
+
341
+ #
342
+ #
343
+ # * *Args* :
344
+ # - ++ ->
345
+ # * *Returns* :
346
+ # -
347
+ # * *Raises* :
348
+ # - ++ ->
349
+ def self.dump()
350
+ @@yDefaults
351
+ end
352
+
353
+ # Loop on Config metadata
354
+ #
355
+ #
356
+ # * *Args* :
357
+ # - ++ ->
358
+ # * *Returns* :
359
+ # -
360
+ # * *Raises* :
361
+ # - ++ ->
362
+ def self.meta_each
363
+ Lorj::rhGet(@@yDefaults, :sections).each { | section, hValue |
364
+ hValue.each { | key, value |
365
+ yield section, key, value
366
+ }
367
+ }
368
+ end
369
+
370
+ #
371
+ #
372
+ # * *Args* :
373
+ # - ++ ->
374
+ # * *Returns* :
375
+ # -
376
+ # * *Raises* :
377
+ # - ++ ->
378
+ def self.meta_exist?(key)
379
+ return nil if not key
380
+
381
+ key = key.to_sym if key.class == String
382
+
383
+ section = Lorj::rhGet(@@account_section_mapping, key)
384
+ Lorj::rhExist?(@@yDefaults, :sections, section, key) == 3
385
+ end
386
+
387
+ #
388
+ #
389
+ # * *Args* :
390
+ # - ++ ->
391
+ # * *Returns* :
392
+ # -
393
+ # * *Raises* :
394
+ # - ++ ->
395
+ def self.get_meta(key)
396
+ return nil if not key
397
+
398
+ key = key.to_sym if key.class == String
399
+ section = Lorj::rhGet(@@account_section_mapping, key)
400
+ Lorj::rhGet(@@yDefaults, :sections, section, key)
401
+ end
402
+
403
+ #
404
+ #
405
+ # * *Args* :
406
+ # - ++ ->
407
+ # * *Returns* :
408
+ # -
409
+ # * *Raises* :
410
+ # - ++ ->
411
+ def self.build_section_mapping
412
+
413
+ if Lorj::rhGet(@@yDefaults, :sections).nil?
414
+ PrcLib.warning("defaults.yaml do not defines :sections")
415
+ return nil
416
+ end
417
+
418
+ Lorj::rhGet(@@yDefaults, :sections).each { | section, hValue |
419
+ next if section == :default
420
+ hValue.each_key { | map_key |
421
+ PrcLib.fatal(1, "defaults.yaml: Duplicate entry between sections. '%s' defined in section '%s' already exists in section '%s'" % [map_key, section, Lorj::rhGet(@account_section_mapping, map_key) ])if Lorj::rhExist?(@account_section_mapping, map_key) != 0
422
+ Lorj::rhSet(@@account_section_mapping, section, map_key)
423
+ }
424
+ }
425
+ end
426
+
427
+ #
428
+ #
429
+ # * *Args* :
430
+ # - ++ ->
431
+ # * *Returns* :
432
+ # -
433
+ # * *Raises* :
434
+ # - ++ ->
435
+ def self.get_meta_section(key)
436
+ key = key.to_sym if key.class == String
437
+ Lorj::rhGet(@@account_section_mapping, key)
438
+ end
439
+
440
+ #
441
+ #
442
+ # * *Args* :
443
+ # - ++ ->
444
+ # * *Returns* :
445
+ # -
446
+ # * *Raises* :
447
+ # - ++ ->
448
+ def self.load()
449
+
450
+ @@account_section_mapping = {}
451
+ @@yDefaults = {}
452
+ @@sDefaultsName = nil
453
+
454
+ if not PrcLib.app_defaults
455
+ PrcLib.warning("PrcLib.app_defaults is not set. Application defaults won't be loaded.")
456
+ else
457
+ @@sDefaultsName = File.join(PrcLib.app_defaults,'defaults.yaml')
458
+
459
+ PrcLib.info("Reading default configuration '%s'..." % @@sDefaultsName)
460
+
461
+ @@yDefaults = YAML.load_file(@@sDefaultsName)
462
+
463
+ self.build_section_mapping
464
+ end
465
+ end
466
+
467
+ end
468
+
469
+
470
+ # Lorj::Config is a generic class for configuration management.
471
+ # It is used by lorj to get/set data
472
+ #
473
+ # lorj uses following function in different context:
474
+ #
475
+ # In your main:
476
+ # * Config.set : To set runtime depending on options given by the user (cli parameters for example)
477
+ # * Config.get : To get any kind of data, for example to test values.
478
+ # * Config.saveConfig : To save setting in local config. Use Lorj::Config::localSet to set this kind of data to save
479
+ # * Config.localSet : To set a local default data. If the main wanted to manage local config.
480
+ # * Config.meta_each : For example to display all data per section name, with values.
481
+ #
482
+ # In Process functions: The Config object is accessible as 'config'.
483
+ # * config.set : To set runtime data. Ex: adapt process runtime behavior.
484
+ # The best approach is to declare an obj_needs optional. lorj will set it in hParams.
485
+ # * config.get : To get data and adapt process behavior.
486
+ # The best approach is to declare an obj_needs optional and get the value from hParams.
487
+ #
488
+ # In Controller functions.
489
+ # Usually, the process has implemented everything.
490
+ # You should not use the config object. Thus, config object is not accessible.
491
+
492
+ class Config
493
+
494
+ # Internal Object variables:
495
+ #
496
+ # * @sConfigName= 'config.yaml'
497
+ # * @yRuntime = data in memory.
498
+ # * @yLocal = config.yaml file data hash.
499
+ # * @yObjConfig = Extra loaded data
500
+ # * Lorj::Default = Application defaults class
501
+
502
+ attr_reader :sConfigName
503
+
504
+ # Basic dump
505
+ #
506
+ # * *Args* :
507
+ # - +interms+ : Will be obsoleted shortly.
508
+ # * *Returns* :
509
+ # - hash of hashes.
510
+ # * *Raises* :
511
+ # nothing
512
+ def default_dump(interms = nil)
513
+ # Build a config hash.
514
+
515
+ res = {}
516
+ Lorj::Default.dump[:default].each_key { |key|
517
+ dump_key = exist?(key)
518
+ Lorj::rhSet(res, get(key), dump_key, key)
519
+ }
520
+ if Lorj::rhExist?(@yLocal, :default) == 1
521
+ @yLocal[:default].each_key { |key|
522
+ dump_key = exist?(key)
523
+ Lorj::rhSet(res, get(key), dump_key, key) if Lorj::rhExist?(res, dump_key, key) != 2
524
+ }
525
+ end
526
+ if interms
527
+ if interms.instance_of? Hash
528
+ @interms.each_key { | key|
529
+ dump_key = exist?(key)
530
+ Lorj::rhSet(res, get(key), dump_key, key) if Lorj::rhExist?(res, dump_key, key) != 2
531
+ }
532
+ elsif interms.instance_of? Array # Array of hash of hash
533
+ interms.each { | elem |
534
+ elem.each_key { | key|
535
+ dump_key = exist?(key)
536
+ Lorj::rhSet(res, get(key), dump_key, key) if Lorj::rhExist?(res, dump_key, key) != 2
537
+ }
538
+ }
539
+ end
540
+ end
541
+ @yRuntime.each_key { |key|
542
+ dump_key = exist?(key)
543
+ Lorj::rhSet(res, get(key), dump_key, key) if Lorj::rhExist?(res, dump_key, key) != 2
544
+ }
545
+
546
+ res
547
+ end
548
+
549
+ # Load yaml documents (defaults + config)
550
+ # If config doesn't exist, it will be created, empty with 'defaults:' only
551
+ #
552
+ #
553
+ # * *Args* :
554
+ # - +sConfigName+ : Config file name to use. By default, file path is built as PrcLib.data_path+'config.yaml'
555
+ # * *Returns* :
556
+ # -
557
+ # * *Raises* :
558
+ # - ++ ->
559
+ def initialize(sConfigName=nil)
560
+
561
+ Default.load() # Loading global application defaults
562
+
563
+ if PrcLib.data_path.nil?
564
+ PrcLib.fatal(1, 'Internal PrcLib.data_path was not set.')
565
+ end
566
+
567
+ sConfigDefaultName='config.yaml'
568
+
569
+ if sConfigName
570
+ if File.dirname(sConfigName) == '.'
571
+ sConfigName = File.join(PrcLib.data_path,sConfigName)
572
+ end
573
+ sConfigName = File.expand_path(sConfigName)
574
+ if not File.exists?(sConfigName)
575
+ PrcLib.warning("Config file '%s' doesn't exists. Using default one." % [sConfigName] )
576
+ @sConfigName = File.join(PrcLib.data_path,sConfigDefaultName)
577
+ else
578
+ @sConfigName = sConfigName
579
+ end
580
+ else
581
+ @sConfigName = File.join(PrcLib.data_path,sConfigDefaultName)
582
+ end
583
+
584
+ PrcLib.ensure_dir_exists(File.dirname(@sConfigName))
585
+
586
+ if File.exists?(@sConfigName)
587
+ @yLocal = YAML.load_file(@sConfigName)
588
+ if Lorj::rhKeyToSymbol?(@yLocal, 2)
589
+ @yLocal = Lorj::rhKeyToSymbol(@yLocal, 2)
590
+ self.saveConfig()
591
+ end
592
+
593
+ else
594
+ @yLocal = { :default => nil }
595
+ # Write the empty file
596
+ PrcLib.info('Creating your default configuration file ...')
597
+ self.saveConfig()
598
+ end
599
+
600
+ @yRuntime = {}
601
+ @yObjConfig = {}
602
+ end
603
+
604
+ # Save the config.yaml file.
605
+ #
606
+ # * *Args* :
607
+ # nothing
608
+ # * *Returns* :
609
+ # - true/false
610
+ # * *Raises* :
611
+ # nothing
612
+ def saveConfig()
613
+ begin
614
+ File.open(@sConfigName, 'w') do |out|
615
+ YAML.dump(@yLocal, out)
616
+ end
617
+ rescue => e
618
+ Lorj.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
619
+ return false
620
+ end
621
+ PrcLib.info('Configuration file "%s" updated.' % @sConfigName)
622
+ return true
623
+ end
624
+
625
+ # Save extra data to a file. Will be obsoleted.
626
+ #
627
+ # * *Args* :
628
+ # - +sFile+ : File name to use for saving data.
629
+ # - +section+ : Section name where to find the key structure to save.
630
+ # - +name+ : key structure name found in section to save.
631
+ # * *Returns* :
632
+ # - true/false
633
+ # * *Raises* :
634
+ # nothing
635
+ def extraSave(sFile, section, name)
636
+ hVal = Lorj::rhGet(@yObjConfig, section, name)
637
+ if hVal
638
+ begin
639
+ File.open(sFile, 'w') do |out|
640
+ YAML.dump(hVal, out)
641
+ end
642
+ rescue => e
643
+ Lorj.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
644
+ return false
645
+ end
646
+ PrcLib.info('Configuration file "%s" updated.' % sFile)
647
+ return true
648
+ end
649
+ end
650
+
651
+ # Load extra data from a file. Will be obsoleted.
652
+ #
653
+ # * *Args* :
654
+ # - +sFile+ : File name to use for saving data.
655
+ # - +section+ : Section name where to find the key structure to save.
656
+ # - +name+ : key structure name found in section to save.
657
+ # * *Returns* :
658
+ # - key tree loaded.
659
+ # * *Raises* :
660
+ # nothing
661
+ def extraLoad(sFile, section, name)
662
+ if File.exists?(sFile)
663
+ hVal = YAML.load_file(sFile)
664
+ Lorj::rhSet(@yObjConfig, hVal, section, name)
665
+ hVal
666
+ end
667
+ end
668
+
669
+ # Check from Extra data existence of keys tree. Will be obsoleted.
670
+ #
671
+ # * *Args* :
672
+ # - +section+ -> Section Name
673
+ # - +name+ -> Key Name
674
+ # - +key+ -> key tree
675
+ # * *Returns* :
676
+ # - true or false
677
+ # * *Raises* :
678
+ # Nothing
679
+
680
+ def extraExist?(section, name, key = nil)
681
+ return nil if not section or not name
682
+
683
+ key = key.to_sym if key.class == String
684
+
685
+ return(Lorj::rhExist?(@yObjConfig, section, name) == 2) if not key
686
+ return(Lorj::rhExist?(@yObjConfig, section, name, key) == 3)
687
+ end
688
+
689
+ # Get from Extra data existence of keys tree. Will be obsoleted.
690
+ #
691
+ # * *Args* :
692
+ # - +section+ -> Section Name
693
+ # - +name+ -> Key Name
694
+ # - +key+ -> key tree
695
+ # - +default+ -> default value
696
+ # * *Returns* :
697
+ # - value found
698
+ # * *Raises* :
699
+ # Nothing
700
+
701
+ def extraGet(section, name, key = nil, default = nil)
702
+ return nil if not section or not name
703
+
704
+ key = key.to_sym if key.class == String
705
+ return default unless ExtraExist?(section, name, key)
706
+ return Lorj::rhGet(@yObjConfig, section, name, key) if key
707
+ Lorj::rhGet(@yObjConfig, section, name)
708
+ end
709
+
710
+ # Set to Extra data existence of keys tree. Will be obsoleted.
711
+ #
712
+ # * *Args* :
713
+ # - +section+ -> Section Name
714
+ # - +name+ -> Key Name
715
+ # - +key+ -> key tree
716
+ # - +value+ -> Value to set
717
+ # * *Returns* :
718
+ # - value set
719
+ # * *Raises* :
720
+ # Nothing
721
+ def extraSet(section, name, key, value)
722
+ key = key.to_sym if key.class == String
723
+ if key
724
+ Lorj::rhSet(@yObjConfig, value, section, name, key)
725
+ else
726
+ Lorj::rhSet(@yObjConfig, value, section, name)
727
+ end
728
+ end
729
+
730
+ # Function to set a runtime key/value, but remove it if value is nil.
731
+ # To set in config.yaml, use Lorj::Config::localSet
732
+ # To set on extra data, like account information, use Lorj::Config::ExtraSet
733
+ #
734
+ # * *Args* :
735
+ # - +key+ : key name. Can be an key tree (Array of keys).
736
+ # - +value+ : Value to set
737
+ # * *Returns* :
738
+ # - value set
739
+ # * *Raises* :
740
+ # Nothing
741
+ def set(key, value)
742
+
743
+ key = key.to_sym if key.class == String
744
+
745
+ return false if not([Symbol, Array].include?(key.class))
746
+
747
+ Lorj::rhSet(@yRuntime, value, key)
748
+ true
749
+ end
750
+
751
+ # Call set function
752
+ #
753
+ # * *Args* :
754
+ # - +key+ : key name. Can be an key tree (Array of keys).
755
+ # - +value+ : Value to set
756
+ # * *Returns* :
757
+ # - value set
758
+ # * *Raises* :
759
+ # Nothing
760
+ def []=(key, value)
761
+ set(key, value)
762
+ end
763
+
764
+ # Check if the key exist as a runtime data.
765
+ #
766
+ # * *Args* :
767
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of keys).
768
+ # * *Returns* :
769
+ # - true/false
770
+ # * *Raises* :
771
+ # Nothing
772
+
773
+ def runtimeExist?(key)
774
+ (Lorj::rhExist?(@yRuntime, key) == 1)
775
+ end
776
+
777
+ # Get exclusively the Runtime data.
778
+ # Internally used by get.
779
+ #
780
+ # * *Args* :
781
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of keys).
782
+ # * *Returns* :
783
+ # - key value.
784
+ # * *Raises* :
785
+ # Nothing
786
+
787
+ def runtimeGet(key)
788
+ Lorj::rhGet(@yRuntime, key) if runtimeExist?(key)
789
+ end
790
+
791
+ # Get function
792
+ # Will search over several places:
793
+ # * runtime - Call internal runtimeGet -
794
+ # * local config (config>yaml) - Call internal LocalGet -
795
+ # * application default (defaults.yaml) - Call Lorj::Default.get -
796
+ # * default
797
+ #
798
+ # key can be an array, a string (converted to a symbol) or a symbol.
799
+ #
800
+ # * *Args* :
801
+ # - +key+ : key name
802
+ # - +default+: Default value to set if not found.
803
+ # * *Returns* :
804
+ # value found or default
805
+ # * *Raises* :
806
+ # nothing
807
+
808
+ def get(key, default = nil)
809
+ key = key.to_sym if key.class == String
810
+ return nil if not([Symbol, Array].include?(key.class))
811
+ # If key is in runtime
812
+ return runtimeGet(key) if runtimeExist?(key)
813
+ # else key in local default config of default section.
814
+ return localGet(key) if localDefaultExist?(key)
815
+ # else key in application defaults
816
+ return Lorj::Default.get(key) if Lorj::Default.exist?(key)
817
+ # else default
818
+ default
819
+ end
820
+
821
+ # Call get function
822
+ #
823
+ # * *Args* :
824
+ # - +key+ : key name
825
+ # - +default+: Default value to set if not found.
826
+ # * *Returns* :
827
+ # value found or default
828
+ # * *Raises* :
829
+ # nothing
830
+
831
+ def [](key, default = nil)
832
+ get(key, default)
833
+ end
834
+
835
+ # Get Application data
836
+ # Used to get any kind of section available in the Application default.yaml.
837
+ #
838
+ # * *Args* :
839
+ # - +section+: section name to get the key.
840
+ # - +key+ : key name
841
+ # * *Returns* :
842
+ # value found
843
+ # * *Raises* :
844
+ # nothing
845
+ def getAppDefault(section, key = nil)
846
+
847
+ key = key.to_sym if key.class == String
848
+
849
+ Lorj::Default.get(key, section)
850
+ end
851
+
852
+ # Check where the get or [] is going to get the data
853
+ #
854
+ # * *Args* :
855
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
856
+ # - +interms+ : <b>Will be removed shortly!!!</b> Add intermediate hash to check
857
+ # * *Returns* :
858
+ # - false if no value found.
859
+ # - 'runtime' if found in runtime.
860
+ # - '%s' if found in intermediate. <b>Will be removed shortly!!!</b>
861
+ # - 'hash[%s]' if found in intermediate. <b>Will be removed shortly!!!</b>
862
+ # - 'hash' if found in intermediate. <b>Will be removed shortly!!!</b>
863
+ # - 'local' if get from local config (config.yaml)
864
+ # - 'default' if get from application default (defaults.yaml)
865
+ # -
866
+ # * *Raises* :
867
+ # nothing
868
+ def exist?(key, interms = nil)
869
+ key = key.to_sym if key.class == String
870
+
871
+ # Check data in intermediate hashes or array of hash. (like account data - key have to be identical)
872
+ return "runtime" if Lorj::rhExist?(@yRuntime, key) == 1
873
+ if interms
874
+ if interms.instance_of? Hash
875
+ return 'hash' if Lorj::rhExist?(interms, key) == 1
876
+ elsif interms.instance_of? Array # Array of hash
877
+ iCount = 0
878
+ interms.each { | elem |
879
+ if elem.class == Hash
880
+ elem.each { | hashkey, value |
881
+ return ("%s" % hashkey) if value.class == Hash and Lorj::rhExist?(elem, hashkey, key) == 2
882
+ return ("hash[%s]" % iCount) if value.class != Hash and Lorj::rhExist?(elem, hashkey) == 1
883
+ }
884
+ end
885
+ iCount += 1
886
+ }
887
+ end
888
+ end
889
+ return 'local' if localDefaultExist?(key)
890
+ # else key in application defaults
891
+ return 'default' if Lorj::Default.exist?(key)
892
+ false
893
+ end
894
+
895
+ #
896
+ # Function to check default keys existence(in section :default) from local config file only.
897
+ #
898
+ # * *Args* :
899
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
900
+ # * *Returns* :
901
+ # -
902
+ # * *Raises* :
903
+ # nothing
904
+ def localDefaultExist?(key)
905
+ localExist?(key)
906
+ end
907
+
908
+ # Function to check key existence from local config file only.
909
+ #
910
+ # * *Args* :
911
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
912
+ # - +section+ : Section name to test the key.
913
+ # * *Returns* :
914
+ # -
915
+ # * *Raises* :
916
+ # nothing
917
+ def localExist?(key, section = :default)
918
+
919
+ key = key.to_sym if key.class == String
920
+ return true if Lorj::rhExist?(@yLocal, section, key) == 2
921
+ false
922
+ end
923
+
924
+ # Function to set a key value in local config file only.
925
+ #
926
+ # * *Args* :
927
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
928
+ # - +value+ : Value to set
929
+ # - +section+ : Section name to test the key.
930
+ #
931
+ # * *Returns* :
932
+ # - Value set.
933
+ # * *Raises* :
934
+ # nothing
935
+ def localSet(key, value, section = :default)
936
+ key = key.to_sym if key.class == String
937
+ if not key or not value
938
+ return false
939
+ end
940
+ if @yLocal[section] == nil
941
+ @yLocal[section]={}
942
+ end
943
+ if @yLocal.has_key?(section)
944
+ @yLocal[section].merge!({key => value})
945
+ else
946
+ @yLocal.merge!(section => {key => value})
947
+ end
948
+ return true
949
+ end
950
+
951
+ # Function to Get a key value from local config file only.
952
+ #
953
+ # * *Args* :
954
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
955
+ # - +section+ : Section name to test the key.
956
+ # - +default+ : default value if not found.
957
+ #
958
+ # * *Returns* :
959
+ # - Value get or default.
960
+ # * *Raises* :
961
+ # nothing
962
+ def localGet(key, section = :default, default = nil)
963
+ key = key.to_sym if key.class == String
964
+
965
+ return default if Lorj::rhExist?(@yLocal, section, key) != 2
966
+ Lorj::rhGet(@yLocal, section, key)
967
+ end
968
+
969
+ # Function to Delete a key value in local config file only.
970
+ #
971
+ # * *Args* :
972
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
973
+ # - +section+ : Section name to test the key.
974
+ #
975
+ # * *Returns* :
976
+ # - true/false
977
+ # * *Raises* :
978
+ # nothing
979
+ def localDel(key, section = :default)
980
+ key = key.to_sym if key.class == String
981
+ if not key
982
+ return false
983
+ end
984
+ if not @yLocal.has_key?(section)
985
+ return false
986
+ end
987
+ @yLocal[section].delete(key)
988
+ return true
989
+ end
990
+
991
+ # Function to return in fatal error if a config data is nil. Help to control function requirement.
992
+ #
993
+ #
994
+ # * *Args* :
995
+ # - +key+ : Symbol/String(converted to symbol) key name to test.
996
+ # * *Returns* :
997
+ # nothing
998
+ # * *Raises* :
999
+ # - +fatal+ : Call to PrcLib.fatal to exit the application with error 1.
1000
+ def fatal_if_inexistent(key)
1001
+ PrcLib.fatal(1, "Internal error - %s: '%s' is missing" % [caller(), key]) if not self.get(key)
1002
+ end
1003
+
1004
+ # each loop on Application Account section/key (meta data).
1005
+ # This loop will extract data from :section of the application definition (defaults.yaml)
1006
+ # key identified as account exclusive (:account_exclusive = true) are not selected.
1007
+ #
1008
+ # * *Args* :
1009
+ # - ++ ->
1010
+ # * *Returns* :
1011
+ # -
1012
+ # * *Raises* :
1013
+ # - ++ ->
1014
+ def meta_each
1015
+ Lorj::Default.meta_each { |section, key, value|
1016
+ next if Lorj::rhGet(value, :account_exclusive)
1017
+ yield section, key, value
1018
+ }
1019
+ end
1020
+
1021
+ end
1022
+
1023
+ end