lorj 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 (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