lorj 0.2.0 → 1.0.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +46 -0
  4. data/Gemfile +15 -15
  5. data/README.md +22 -17
  6. data/Rakefile +12 -2
  7. data/bin/cloud_test.rb +13 -65
  8. data/example/students_1/process/students.rb +39 -0
  9. data/example/students_1/students.rb +22 -5
  10. data/example/students_2/process/students.rb +48 -0
  11. data/example/students_2/students.rb +39 -16
  12. data/example/students_3/controller/yaml_students.rb +50 -43
  13. data/example/students_3/controller/yaml_students_controller.rb +100 -87
  14. data/example/students_3/process/students.rb +161 -97
  15. data/example/students_3/students.rb +85 -56
  16. data/example/yaml_students/students.rb +40 -40
  17. data/example/yaml_students/yaml_students.rb +103 -90
  18. data/lib/core/core.rb +356 -696
  19. data/lib/core/core_controller.rb +227 -0
  20. data/lib/core/core_internal.rb +339 -0
  21. data/lib/core/core_model.rb +328 -0
  22. data/lib/core/core_object_data.rb +330 -0
  23. data/lib/core/core_object_params.rb +230 -0
  24. data/lib/core/core_process.rb +391 -0
  25. data/lib/core/core_process_setup.rb +353 -0
  26. data/lib/core/core_setup_ask.rb +241 -0
  27. data/lib/core/core_setup_encrypt.rb +146 -0
  28. data/lib/core/core_setup_init.rb +229 -0
  29. data/lib/core/core_setup_list.rb +160 -0
  30. data/lib/core/definition.rb +647 -469
  31. data/lib/core/definition_internal.rb +264 -308
  32. data/lib/core/lorj_basecontroller.rb +95 -0
  33. data/lib/core/lorj_basedefinition.rb +307 -0
  34. data/lib/core/lorj_baseprocess.rb +265 -0
  35. data/lib/core/lorj_data.rb +583 -0
  36. data/lib/core/lorj_keypath.rb +119 -0
  37. data/lib/core_process/cloud/process/common.rb +63 -0
  38. data/lib/core_process/cloud/process/connection.rb +93 -0
  39. data/lib/core_process/cloud/process/external_network.rb +94 -0
  40. data/lib/core_process/cloud/process/flavor.rb +99 -0
  41. data/lib/core_process/cloud/process/images.rb +87 -0
  42. data/lib/core_process/cloud/process/internet_network.rb +34 -0
  43. data/lib/core_process/cloud/process/internet_server.rb +30 -0
  44. data/lib/core_process/cloud/process/keypairs.rb +276 -0
  45. data/lib/core_process/cloud/process/network.rb +108 -0
  46. data/lib/core_process/cloud/process/public_ip.rb +100 -0
  47. data/lib/core_process/cloud/process/router.rb +260 -0
  48. data/lib/core_process/cloud/process/rules.rb +120 -0
  49. data/lib/core_process/cloud/process/security_groups.rb +121 -0
  50. data/lib/core_process/cloud/process/server.rb +127 -0
  51. data/lib/core_process/cloud/process/server_log.rb +35 -0
  52. data/lib/core_process/cloud/process/subnetwork.rb +108 -0
  53. data/lib/core_process/cloud_process.rb +30 -0
  54. data/lib/logging.rb +298 -0
  55. data/lib/lorj/version.rb +18 -1
  56. data/lib/lorj.rb +58 -18
  57. data/lib/lorj_account.rb +556 -0
  58. data/lib/lorj_config.rb +468 -0
  59. data/lib/lorj_defaults.rb +278 -0
  60. data/lib/prc.rb +136 -104
  61. data/lib/prc_base_config.rb +285 -0
  62. data/lib/prc_core_config.rb +878 -0
  63. data/lib/prc_section_config.rb +57 -0
  64. data/lib/providers/hpcloud/compute.rb +81 -93
  65. data/lib/providers/hpcloud/hpcloud.rb +462 -0
  66. data/lib/providers/hpcloud/network.rb +96 -98
  67. data/lib/providers/hpcloud/security_groups.rb +41 -40
  68. data/lib/providers/mock/mock.rb +144 -0
  69. data/lib/providers/openstack/openstack.rb +45 -0
  70. data/lib/providers/templates/compute.rb +21 -23
  71. data/lib/providers/templates/mycloud.rb +72 -0
  72. data/lib/providers/templates/network.rb +11 -12
  73. data/lib/rh.rb +339 -0
  74. data/lorj-spec/defaults.yaml +4 -0
  75. data/lorj.gemspec +6 -0
  76. data/spec/00_lorj_log_spec.rb +53 -0
  77. data/spec/01_hash_rh_spec.rb +243 -0
  78. data/spec/02_prc_base_config_spec.rb +216 -0
  79. data/spec/04_prc_core_config_spec.rb +83 -0
  80. data/spec/11_lorj_config_spec.rb +263 -0
  81. data/spec/12_lorj_account_spec.rb +181 -0
  82. metadata +76 -28
  83. data/Gemfile.lock +0 -37
  84. data/example/students_1/process/Students.rb +0 -20
  85. data/example/students_2/process/Students.rb +0 -27
  86. data/example/students_4/controller/yaml_students.rb +0 -82
  87. data/example/students_4/controller/yaml_students_controller.rb +0 -141
  88. data/example/students_4/process/students.rb +0 -112
  89. data/example/students_4/students.rb +0 -103
  90. data/lib/core/lorj-basecontroller.rb +0 -90
  91. data/lib/core/lorj-basedefinition.rb +0 -1139
  92. data/lib/core/lorj-baseprocess.rb +0 -236
  93. data/lib/core/lorj-data.rb +0 -567
  94. data/lib/core/lorj-keypath.rb +0 -115
  95. data/lib/core_process/CloudProcess.rb +0 -337
  96. data/lib/core_process/global_process.rb +0 -502
  97. data/lib/core_process/network_process.rb +0 -605
  98. data/lib/prc-account.rb +0 -339
  99. data/lib/prc-config.rb +0 -1030
  100. data/lib/prc-logging.rb +0 -261
  101. data/lib/providers/hpcloud/Hpcloud.rb +0 -426
  102. data/lib/providers/mock/Mock.rb +0 -141
  103. data/lib/providers/openstack/Openstack.rb +0 -47
  104. data/lib/providers/templates/core.rb +0 -61
  105. data/spec/forj-account_spec.rb +0 -75
  106. data/spec/forj-config_spec.rb +0 -196
data/lib/core/core.rb CHANGED
@@ -15,708 +15,368 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ # rubocop: disable Metrics/AbcSize
19
+
18
20
  # Module Lorj which contains several classes.
19
21
  #
20
22
  # Those classes describes :
21
23
  # - processes (BaseProcess) : How to create/delete/edit/query object.
22
- # - controler (BaseControler) : If a provider is defined, define how will do object creation/etc...
23
- # - definition(BaseDefinition): Functions to declare objects, query/data mapping and setup
24
+ # - controler (BaseControler) : If a provider is defined, define how will do
25
+ # object creation/etc...
26
+ # - definition(BaseDefinition): Functions to declare objects, query/data mapping
27
+ # and setup
24
28
  # this task to make it to work.
25
-
26
29
  module Lorj
27
-
28
- # Internal Lorj function to debug lorj.
29
- #
30
- # * *Args* :
31
- # - +iLevel+ : value between 1 to 5. Setting 5 is the most verbose!
32
- # - +sMsg+ : Array of string or symbols. keys tree to follow and check existence in yVal.
33
- #
34
- # * *Returns* :
35
- # - nothing
36
- #
37
- # * *Raises* :
38
- # No exceptions
39
- def Lorj::debug(iLevel, sMsg)
40
- if iLevel <= PrcLib.core_level
41
- PrcLib.debug("-%s- %s" % [iLevel, sMsg])
42
- end
43
- end
44
-
45
- # Internal PrcError class object derived from RuntimeError.
46
- # Internally used with raise.
47
- # Used to identify the error origin, while an error is thrown.
48
- class PrcError < RuntimeError
49
- attr_reader :ForjMsg
50
-
51
- def initialize(message = nil)
52
- @ForjMsg = message
53
- end
54
- end
55
-
56
-
57
- # This is the main lorj class.
58
- # It interfaces your main code with the full lorj system as shown in the concept document.
59
- # It give you access to the lorj model object designed by your process.
60
- #
61
- # When you start using it, your main must be as simple as you can, as you will need to move
62
- # most of your application logic to the process.
63
- # Your application can have several lorj objects running in your code, depending of your needs.
64
- #
65
- # The main things is that you can move most of your process management, usually in your code/modules
66
- # to be part of the lorj process, make it controller independant, and gains in
67
- # implementing several controllers to change the way to implement but not the process
68
- # you used to build your application!
69
- #
70
- # Then, your application contributors can build their own controller and extend your solution!
71
- #
72
- # Here an example of creating a CloudServer, using CloudCore (derived from Core).
73
- # CloudCore introduces lorj predefined CloudProcess used by forj cli.
74
- #
75
- # oCloud = Lorj::CloudCore.new(oConfig, 'myhpcloud')
76
- # oConfig.set(:server_name,'myservername')
77
- # oCloud.Create(:server)
78
- #
79
- # Another basic example (See example directory)
80
- #
81
- # oConfig = Lorj::Account.new()
82
- # oPrc = Lorj::Core.new(oConfig, 'mySqlAccount')
83
- # oCloud.Create(:student, { :student_name => "Robert Redford"})
84
- #
85
- # See BaseProcess to check how you can write a process and what kind of functions
86
- # are available for your process to be kept controller independant.
87
- #
88
- # See BaseController to see how you can write a controller and what kind of functions
89
- # are available to deal with the implementation API you need to use.
90
- class Core
91
-
92
- # Public access to a config object.
93
- # A config object can be any kind of class which should provide at least following functions:
94
- #
95
- # - get(*key, default=nil) and [*key] : function to get a value from a key. default is a value to get if not found.
96
- # - set(*key, value) or [*key, value]= : function to set a value to a key.
97
- # Ex: From processes, you can set a runtime data with:
98
- #
99
- # config.set(key, value)
100
- #
101
- # OR
102
- #
103
- # config[key] = value
104
- #
105
- # - exist?(*key) : function which return false if not found, or any other value if found.
106
- # Ex: From processes, you can get a data (runtime/account/config.yaml or defaults.yaml) with:
107
- #
108
- # config.get(key)
109
- #
110
- # OR
111
- #
112
- # config[key]
113
- #
114
- # For each functions, *key is a list of value, which becomes an array in the function.
115
- # It should accept to manage the key tree (hash of hashes)
116
- #
117
- # Currently lorj comes with Lorj::Config or Lorj::Account.
118
- # Thoses classes defines at least those 5 functions. And more.
119
- attr_reader :config
120
-
121
- # Core parameters are:
122
- # oForjConfig : Optional. An instance of a configuration system which *HAVE* to provide get/set/exist?/[]/[]=
123
- #
124
- # processClass: Array of string or symbol, or string or symbol. Is the path or name of one or more ProcessClass to use.
125
- # This class is dynamically loaded and derived from BaseProcess class.
126
- # It loads the Process class content from a file '$CORE_PROCESS_PATH/<sProcessClass>.rb'
127
- # If sProcessClass is a file path, this file will be loaded as a ruby include.
128
- #
129
- # <sProcessClass>.rb file name is case sensible and respect RUBY Class name convention
130
- #
131
- # sControllerClass: Optional. string or symbol. Is the path or name of ControllerClass to use.
132
- # This class is dynamically loaded and derived from BaseController class.
133
- # It loads the Controler class content from a file '$PROVIDER_PATH/<sControllerClass>.rb'
134
- #
135
- # The provider can redefine partially or totally some processes
136
- # Lorj::Core will load those redefinition from file:
137
- # $PROVIDER_PATH/<sControlerClass>Process.rb'
138
- #
139
- # <sControllerClass>.rb or <sControllerClass>Process.rb file name is case sensible and respect RUBY Class name convention
140
-
141
- def initialize(oForjConfig = nil, processesClass = nil, sControllerClass = nil)
142
- # Loading ProcessClass
143
- # Create Process derived from respectively BaseProcess
144
-
145
- PrcLib.core_level = 0 if PrcLib.core_level.nil?
146
-
147
- if oForjConfig.nil?
148
- @config = Lorj::Config.new()
149
- oForjConfig = @config
150
- Lorj.debug(2, "Using an internal Lorj::Config object.")
151
- else
152
- @config = oForjConfig
153
- end
154
-
155
-
156
- if processesClass.nil?
157
- aProcessesClass = []
158
- elsif not processesClass.is_a?(Array)
159
- aProcessesClass = [processesClass]
160
- else
161
- aProcessesClass = processesClass
162
- end
163
-
164
- cBaseProcess = BaseProcess
165
- cProcessClass = nil
166
-
167
- aProcessesClass.each { | sProcessClass |
168
- Lorj.debug(1, "Loading Process '%s'" % sProcessClass)
169
-
170
- # And load the content from the <sProcessClass>.rb
171
- if sProcessClass.is_a?(Symbol)
172
- # Ensure file and processName is capitalized
173
- sProcessClass = sProcessClass.to_s
174
- sProcessClass = sProcessClass.capitalize if (/[A-Z]/ =~ sProcessClass.to_s) != 0
175
- sFile = File.join(PrcLib.process_path, sProcessClass + '.rb')
176
- else
177
- if sProcessClass.include?('/')
178
- # Consider a path to the process file. File name is the name of the class.
179
- # We accept filename not capitalized.
180
- sPath = File.dirname(File.expand_path(sProcessClass))
181
- sFile = File.basename(sProcessClass)
182
- file = File.basename(sProcessClass)
183
- file['.rb'] = '' if file['.rb']
184
- sProcessClass = file
185
- sProcessClass = sProcessClass.capitalize if (/[A-Z]/ =~ sProcessClass) != 0
186
- mFound = sProcessClass.scan(/_[a-z]/)
187
- if mFound
188
- mFound.each { | str |
189
- sProcessClass[str] = str[1].capitalize
190
- }
191
- end
192
- else
193
- sPath = PrcLib.process_path
194
- sProcessClass = sProcessClass.capitalize if (/[A-Z]/ =~ sProcessClass) != 0
195
- sFile = sProcessClass + '.rb'
196
- end
197
- # Ensure process name is capitalized
198
- sFile = File.join(sPath, sFile)
199
- end
200
- if File.exists?(sFile)
201
- cNewClass = Class.new(cBaseProcess)
202
- sProcessClass = "%sProcess" % sProcessClass if not /Process$/ =~ sProcessClass
203
- Lorj.debug(1, "Declaring Process '%s'" % sProcessClass)
204
- cBaseProcess = Object.const_set(sProcessClass, cNewClass)
205
- cProcessClass = sProcessClass
206
- BaseDefinition.current_process(cBaseProcess)
207
- load sFile
208
- else
209
- PrcLib.warning("Process file definition '%s' is missing. " % sFile)
210
- end
211
- }
212
-
213
- if sControllerClass
214
- Lorj.debug(1, "Loading Controller/definition '%s'" % sControllerClass)
215
- # Add Provider Object -------------
216
- if sControllerClass.is_a?(Symbol)
217
- sPath = File.join(PrcLib.controller_path, sControllerClass.to_s)
218
- sControllerClass = sControllerClass.to_s.capitalize if (/[A-Z]/ =~ sControllerClass.to_s) != 0
219
- sFile = sControllerClass.to_s + '.rb'
220
- else
221
- if sControllerClass.include?('/')
222
- # Consider a path to the process file. File name is the name of the class.
223
- sPath = File.dirname(File.expand_path(sControllerClass))
224
- sFile = File.basename(sControllerClass)
225
- file = File.basename(sControllerClass)
226
- file = file.capitalize if (/[A-Z]/ =~ file) != 0
227
- file['.rb'] = '' if file['.rb']
228
- sControllerClass = file
229
- sControllerClass = sControllerClass.capitalize if (/[A-Z]/ =~ sControllerClass) != 0
230
- mFound = sControllerClass.scan(/_[a-z]/)
231
- if mFound
232
- mFound.each { | str |
233
- sControllerClass[str] = str[1].capitalize
234
- }
235
- end
236
- else
237
- sPath = File.join(PrcLib.controller_path, sControllerClass)
238
- sControllerClass = sControllerClass.capitalize if (/[A-Z]/ =~ sControllerClass) != 0
239
- sFile = sControllerClass + '.rb'
240
- end
241
- end
242
- sFile = File.join(sPath, sFile)
243
-
244
- # Initialize an empty class derived from BaseDefinition.
245
- # This to ensure provider Class will be derived from this Base Class
246
- # If this class is derived from a different Class, ruby will raise an error.
247
-
248
- # Create Definition and Controler derived from respectively BaseDefinition and BaseControler
249
- cBaseDefinition = Class.new(BaseDefinition)
250
- # Finally, name that class!
251
- Lorj.debug(2, "Declaring Definition '%s'" % sControllerClass)
252
- Object.const_set sControllerClass, cBaseDefinition
253
-
254
- cBaseControler = Class.new(BaseController)
255
- Lorj.debug(2, "Declaring Controller '%s'" % [sControllerClass + 'Controller'])
256
- Object.const_set sControllerClass + 'Controller', cBaseControler
257
-
258
- # Loading Provider base file. This file should load a class
259
- # which have the same name as the file.
260
- if File.exists?(sFile)
261
- load sFile
262
- else
263
- raise Lorj::PrcError.new(), "Provider file definition '%s' is missing. Cannot go on" % sFile
264
- end
265
-
266
- # Identify Provider Classes. Search for
267
- # - Definition Class (sControllerClass) - Contains ForjClass Object
268
- # - Controller Class (sControllerClass + 'Controller') - Provider Cloud controler object
269
-
270
- # Search for Definition Class
271
- begin
272
- # Get it from Objects
273
- oDefClass = Object.const_get(sControllerClass)
274
- rescue
275
- raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % sControllerClass
276
- end
277
-
278
- # Search for Controler Class
279
- # - Process Class (sControllerClass + 'Process') - Provider Process object if defined
280
- begin
281
- # Get the same one suffixed with 'Provider' from Objects
282
- oCoreObjectControllerClass = Object.const_get(sControllerClass + 'Controller')
283
- rescue
284
- raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % sControllerClass + 'Controller'
285
- end
286
-
287
- # Then, we create an BaseCloud Object with 2 objects joined:
288
- # ForjAccount and a BaseControler Object type
289
-
290
-
291
- else
292
- oCoreObjectControllerClass = nil
293
- oDefClass = BaseDefinition
294
- end
295
-
296
- # Add Process management object ---------------
297
- unless cProcessClass.nil?
298
- begin
299
- oBaseProcessDefClass = Object.const_get(cProcessClass)
300
- rescue
301
- raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % cProcessClass
302
- end
303
- else
304
- raise Lorj::PrcError.new(), 'Lorj::Core: No valid process loaded. Aborting.'
305
- end
306
- # Ex: Hpcloud(ForjAccount, HpcloudProvider)
307
- if oCoreObjectControllerClass
308
- @oCoreObject = oDefClass.new(oForjConfig, oBaseProcessDefClass.new(), oCoreObjectControllerClass.new())
309
- else
310
- @oCoreObject = oDefClass.new(oForjConfig, oBaseProcessDefClass.new())
311
- end
312
-
313
- end
314
-
315
- # a wrapper to Create call. Use this function for code readibility.
316
- #
317
- # * *Args* :
318
- # - +oCloudObj+ : Name of the object to initialize.
319
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
320
- # If you use this variable, any other runtime config defined
321
- # by the Data model will be cleaned before
322
- #
323
- # * *Returns* :
324
- # - +Lorj::Data+ : Represents the Object initialized.
325
- #
326
- # * *Raises* :
327
- # No exceptions
328
-
329
- def Connect(oCloudObj, hConfig = {})
330
- return nil if not oCloudObj or not @oCoreObject
331
- @oCoreObject.Create(oCloudObj, hConfig)
332
- end
333
-
334
- # Execute the creation process to create the object `oCloudObj`.
335
- # The creation process can add any kind of complexity to
336
- # get the a memory representation of the object manipulated during creation process.
337
- # This means that a creation process can be (non exhaustive list of possibilities)
338
- # - a connection initialization
339
- # - an internal memory data structure, like hash, array, ruby object...
340
- # - a get or create logic
341
- # - ...
342
- #
343
- # * *Args* :
344
- # - +oCloudObj+ : Name of the object to initialize.
345
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
346
- # If you use this variable, any other runtime config defined
347
- # by the Data model will be cleaned before
348
- #
349
- # * *Returns* :
350
- # - +Lorj::Data+ : Represents the Object initialized.
351
- #
352
- # * *Raises* :
353
- # No exceptions
354
- def Create(oCloudObj, hConfig = {})
355
- return nil if not oCloudObj or not @oCoreObject
356
- @oCoreObject.Create(oCloudObj, hConfig)
357
- end
358
-
359
- # a wrapper to Create call. Use this function for code readibility.
360
- #
361
- # * *Args* :
362
- # - +oCloudObj+ : Name of the object to initialize.
363
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
364
- # If you use this variable, any other runtime config defined
365
- # by the Data model will be cleaned before
366
- #
367
- # * *Returns* :
368
- # - +Lorj::Data+ : Represents the Object initialized.
369
- #
370
- # * *Raises* :
371
- # No exceptions
372
-
373
- def GetOrCreate(oCloudObj, hConfig = {})
374
- return nil if not oCloudObj or not @oCoreObject
375
- @oCoreObject.Create(oCloudObj, hConfig)
30
+ # This is the main lorj class.
31
+ # It interfaces your main code with the full lorj system as shown in the
32
+ # concept document.
33
+ # It give you access to the lorj model object designed by your process.
34
+ #
35
+ # When you start using it, your main must be as simple as you can, as you will
36
+ # need to move most of your application logic to the process.
37
+ # Your application can have several lorj objects running in your code,
38
+ # depending of your needs.
39
+ #
40
+ # The main things is that you can move most of your process management,
41
+ # usually in your code/modules to be part of the lorj process, make it
42
+ # controller independant, and gains in implementing several controllers to
43
+ # change the way to implement but not the process, you used to build your
44
+ # application!
45
+ #
46
+ # Then, your application contributors can build their own controller and
47
+ # extend your solution!
48
+ #
49
+ # Here an example of creating a CloudServer, using CloudCore
50
+ # (derived from Core).
51
+ # CloudCore introduces lorj predefined CloudProcess used by forj cli.
52
+ #
53
+ # oCloud = Lorj::CloudCore.new(oConfig, 'myhpcloud')
54
+ # oConfig.set(:server_name,'myservername')
55
+ # oCloud.Create(:server)
56
+ #
57
+ # Another basic example (See example directory)
58
+ #
59
+ # oConfig = Lorj::Account.new()
60
+ # oPrc = Lorj::Core.new(oConfig, 'mySqlAccount')
61
+ # oCloud.Create(:student, { :student_name => "Robert Redford"})
62
+ #
63
+ # See BaseProcess to check how you can write a process and what kind of
64
+ # functions are available for your process to be kept controller independant.
65
+ #
66
+ # See BaseController to see how you can write a controller and what kind of
67
+ # functions are available to deal with the implementation API you need to use.
68
+ class Core
69
+ # Public access to a config object.
70
+ # A config object can be any kind of class which should provide at least
71
+ # following functions:
72
+ #
73
+ # - get(*key, default=nil) and [*key] : function to get a value from a key.
74
+ # default is a value to get if not
75
+ # found.
76
+ # - set(*key, value) or [*key, value]= : function to set a value to a key.
77
+ # Ex: From processes, you can set a runtime data with:
78
+ #
79
+ # config.set(key, value)
80
+ #
81
+ # OR
82
+ #
83
+ # config[key] = value
84
+ #
85
+ # - exist?(*key) : function which return false if not
86
+ # found, or any other value if found.
87
+ # Ex: From processes, you can get a data (runtime/account/config.yaml or
88
+ # defaults.yaml) with:
89
+ #
90
+ # config.get(key)
91
+ #
92
+ # OR
93
+ #
94
+ # config[key]
95
+ #
96
+ # For each functions, *key is a list of value, which becomes an array in the
97
+ # function.
98
+ # It should accept to manage the key tree (hash of hashes)
99
+ #
100
+ # Currently lorj comes with Lorj::Config or Lorj::Account.
101
+ # Thoses classes defines at least those 5 functions. And more.
102
+ attr_reader :config
103
+
104
+ # a wrapper to Create call. Use this function for code readibility.
105
+ #
106
+ # * *Args* :
107
+ # - +oCloudObj+ : Name of the object to initialize.
108
+ # - +hConfig+ : Hash of hashes containing data required to initialize
109
+ # the object.
110
+ # If you use this variable, any other runtime config defined
111
+ # by the Data model will be cleaned before
112
+ #
113
+ # * *Returns* :
114
+ # - +Lorj::Data+ : Represents the Object initialized.
115
+ #
116
+ # * *Raises* :
117
+ # No exceptions
118
+
119
+ def connect(oCloudObj, hConfig = {})
120
+ return nil if !oCloudObj || !@core_object
121
+ @core_object.process_create(oCloudObj, hConfig)
122
+ end
123
+
124
+ # Execute the creation process to create the object `oCloudObj`.
125
+ # The creation process can add any kind of complexity to
126
+ # get the a memory representation of the object manipulated during creation
127
+ # process.
128
+ # This means that a creation process can be (non exhaustive list of
129
+ # possibilities)
130
+ # - a connection initialization
131
+ # - an internal memory data structure, like hash, array, ruby object...
132
+ # - a get or create logic
133
+ # - ...
134
+ #
135
+ # * *Args* :
136
+ # - +oCloudObj+ : Name of the object to initialize.
137
+ # - +hConfig+ : Hash of hashes containing data required to initialize
138
+ # the object.
139
+ # If you use this variable, any other runtime config defined
140
+ # by the Data model will be cleaned before
141
+ #
142
+ # * *Returns* :
143
+ # - +Lorj::Data+ : Represents the Object initialized.
144
+ #
145
+ # * *Raises* :
146
+ # No exceptions
147
+ def create(oCloudObj, hConfig = {})
148
+ return nil if !oCloudObj || !@core_object
149
+ @core_object.process_create(oCloudObj, hConfig)
150
+ end
151
+
152
+ # a wrapper to Create call. Use this function for code readibility.
153
+ #
154
+ # * *Args* :
155
+ # - +oCloudObj+ : Name of the object to initialize.
156
+ # - +hConfig+ : Hash of hashes containing data required to initialize
157
+ # the object.
158
+ # If you use this variable, any other runtime config defined
159
+ # by the Data model will be cleaned before
160
+ #
161
+ # * *Returns* :
162
+ # - +Lorj::Data+ : Represents the Object initialized.
163
+ #
164
+ # * *Raises* :
165
+ # No exceptions
166
+
167
+ def get_or_create(oCloudObj, hConfig = {})
168
+ return nil if !oCloudObj || !@core_object
169
+ @core_object.process_create(oCloudObj, hConfig)
170
+ end
171
+
172
+ # Execution of the delete process for the `oCloudObj` object.
173
+ # It requires the object to be loaded in lorj Lorj::Data objects cache.
174
+ # You can use `Create` or `Get` functions to load this object.
175
+ #
176
+ # * *Args* :
177
+ # - +oCloudObj+ : Name of the object to initialize.
178
+ # - +hConfig+ : Hash of hashes containing data required to initialize
179
+ # the object.
180
+ # If you use this variable, any other runtime config defined
181
+ # by the Data model will be cleaned before
182
+ #
183
+ # * *Returns* :
184
+ # - +Lorj::Data+ : Represents the Object initialized.
185
+ #
186
+ # * *Raises* :
187
+ # No exceptions
188
+
189
+ def delete(oCloudObj, hConfig = {})
190
+ return nil if !oCloudObj || !@core_object
191
+
192
+ @core_object.process_delete(oCloudObj, hConfig)
193
+ end
194
+
195
+ # Execution of the Query process for the `oCloudObj` object.
196
+ #
197
+ # * *Args* :
198
+ # - +oCloudObj+ : Name of the object to initialize.
199
+ # - +sQuery+ : Hash representing the query filter.
200
+ # - +hConfig+ : Hash of hashes containing data required to initialize
201
+ # the object.
202
+ # If you use this variable, any other runtime config defined
203
+ # by the Data model will be cleaned before
204
+ #
205
+ # * *Returns* :
206
+ # - +Lorj::Data+ : Represents the Object initialized.
207
+ #
208
+ # * *Raises* :
209
+ # No exceptions
210
+
211
+ def query(oCloudObj, sQuery, hConfig = {})
212
+ return nil if !oCloudObj || !@core_object
213
+
214
+ @core_object.process_query(oCloudObj, sQuery, hConfig)
215
+ end
216
+
217
+ # Execution of the Get process for the `oCloudObj` object.
218
+ #
219
+ # * *Args* :
220
+ # - +oCloudObj+ : Name of the object to initialize.
221
+ # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data
222
+ # object.
223
+ # - +hConfig+ : Hash of hashes containing data required to initialize
224
+ # the object.
225
+ # If you use this variable, any other runtime config defined
226
+ # by the Data model will be cleaned before
227
+ #
228
+ # * *Returns* :
229
+ # - +Lorj::Data+ : Represents the Object initialized.
230
+ #
231
+ # * *Raises* :
232
+ # No exceptions
233
+
234
+ def get(oCloudObj, sId, hConfig = {})
235
+ return nil if !oCloudObj || !@core_object || sId.nil?
236
+
237
+ @core_object.process_get(oCloudObj, sId, hConfig)
238
+ end
239
+
240
+ # Execution of the Update process for the `oCloudObj` object.
241
+ # Usually, the Controller object data is updated by the process
242
+ # (BaseController::set_attr)
243
+ # then it should call a controller_update to really update the data in the
244
+ # controller.
245
+ #
246
+ # * *Args* :
247
+ # - +oCloudObj+ : Name of the object to initialize.
248
+ # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data
249
+ # object.
250
+ # - +hConfig+ : Hash of hashes containing data required to initialize
251
+ # the object.
252
+ # If you use this variable, any other runtime config defined
253
+ # by the Data model will be cleaned before
254
+ #
255
+ # * *Returns* :
256
+ # - +Lorj::Data+ : Represents the Object initialized.
257
+ #
258
+ # * *Raises* :
259
+ # No exceptions
260
+
261
+ def update(oCloudObj, hConfig = {})
262
+ return nil if !oCloudObj || !@core_object
263
+
264
+ @core_object.process_update(oCloudObj, hConfig)
265
+ end
266
+
267
+ # Function used to ask users about setting up his account.
268
+ #
269
+ # * *Args* :
270
+ # - +oCloudObj+ : Name of the object to initialize.
271
+ # - +sAccountName+ : Account file name. If not set, Config[:account_name]
272
+ # is used.
273
+ # If you use this variable, any other runtime config defined
274
+ # by the Data model will be cleaned before
275
+ #
276
+ # * *Returns* :
277
+ # - +Lorj::Data+ : Represents the Object initialized.
278
+ #
279
+ # * *Raises* :
280
+ # No exceptions
281
+
282
+ def setup(oCloudObj, sAccountName = nil)
283
+ return nil if !oCloudObj || !@core_object
284
+ @core_object.process_setup(oCloudObj, sAccountName)
285
+ end
286
+
287
+ # Core parameters are:
288
+ # the_config : Optional. An instance of a configuration system which *HAVE*
289
+ # to provide get/set/exist?/[]/[]=
290
+ #
291
+ # processClass: Array of string or symbol, or string or symbol. Is the path
292
+ # or name of one or more ProcessClass to use.
293
+ # This class is dynamically loaded and derived from BaseProcess class.
294
+ # It loads the Process class content from a file
295
+ # '$CORE_PROCESS_PATH/<process_class>.rb'
296
+ # If process_class is a file path, this file will be loaded as a ruby
297
+ # include.
298
+ #
299
+ # <process_class>.rb file name is case sensible and respect RUBY Class
300
+ # name convention
301
+ #
302
+ # controller_class: Optional. string or symbol. Is the path or name of
303
+ # ControllerClass to use.
304
+ # This class is dynamically loaded and derived from BaseController class.
305
+ # It loads the Controler class content from a file
306
+ # '$PROVIDER_PATH/<controller_class>.rb'
307
+ #
308
+ # The provider can redefine partially or totally some processes
309
+ # Lorj::Core will load those redefinition from file:
310
+ # $PROVIDER_PATH/<controller_class>Process.rb'
311
+ #
312
+ # <controller_class>.rb or <controller_class>Process.rb file name is case
313
+ # sensible and respect RUBY Class name convention
314
+ def initialize(the_config = nil, the_process_class = nil,
315
+ controller_class = nil)
316
+ # Loading ProcessClass
317
+ # Create Process derived from respectively BaseProcess
318
+ PrcLib.core_level = 0 if PrcLib.core_level.nil?
319
+
320
+ init_core_config(the_config)
321
+
322
+ model = initialize_model
323
+
324
+ # Load Application processes
325
+ init_processes(model, the_process_class)
326
+
327
+ fail Lorj::PrcError.new, 'Lorj::Core: No valid process loaded. '\
328
+ 'Aborting.' if model[:process_class].nil?
329
+
330
+ # Load Controller and Controller processes.
331
+ init_controller(model, controller_class) if controller_class
332
+
333
+ # Create Core object with the application model loaded
334
+ # (processes & controller)
335
+ initialize_core_object(model)
336
+ PrcLib.model.clear_heap
337
+ end
338
+ end
339
+
340
+ # This class based on generic Core, defines a Cloud Process to use.
341
+ class CloudCore < Core
342
+ def initialize(oConfig, sAccount = nil, aProcesses = [])
343
+ config_account = init_config(oConfig, sAccount)
344
+
345
+ process_list = [:CloudProcess]
346
+
347
+ controller_mod = config_account.get(:provider_name)
348
+ fail Lorj::PrcError.new, 'Provider_name not set. Unable to create'\
349
+ ' instance CloudCore.' if controller_mod.nil?
350
+
351
+ init_controller_mod(process_list, controller_mod)
352
+
353
+ super(config_account, process_list.concat(aProcesses), controller_mod)
354
+ end
355
+
356
+ private
357
+
358
+ def init_config(oConfig, sAccount)
359
+ if !oConfig.is_a?(Lorj::Account)
360
+ config_account = oConfig
361
+ else
362
+ config_account = Lorj::Account.new(oConfig)
363
+
364
+ config_account.ac_load(sAccount) unless sAccount.nil?
376
365
  end
377
-
378
- # Execution of the delete process for the `oCloudObj` object.
379
- # It requires the object to be loaded in lorj Lorj::Data objects cache.
380
- # You can use `Create` or `Get` functions to load this object.
381
- #
382
- # * *Args* :
383
- # - +oCloudObj+ : Name of the object to initialize.
384
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
385
- # If you use this variable, any other runtime config defined
386
- # by the Data model will be cleaned before
387
- #
388
- # * *Returns* :
389
- # - +Lorj::Data+ : Represents the Object initialized.
390
- #
391
- # * *Raises* :
392
- # No exceptions
393
-
394
- def Delete(oCloudObj, hConfig = {})
395
- return nil if not oCloudObj or not @oCoreObject
396
-
397
- @oCoreObject.Delete(oCloudObj, hConfig)
398
- end
399
-
400
- # Execution of the Query process for the `oCloudObj` object.
401
- #
402
- # * *Args* :
403
- # - +oCloudObj+ : Name of the object to initialize.
404
- # - +sQuery+ : Hash representing the query filter.
405
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
406
- # If you use this variable, any other runtime config defined
407
- # by the Data model will be cleaned before
408
- #
409
- # * *Returns* :
410
- # - +Lorj::Data+ : Represents the Object initialized.
411
- #
412
- # * *Raises* :
413
- # No exceptions
414
-
415
- def Query(oCloudObj, sQuery, hConfig = {})
416
- return nil if not oCloudObj or not @oCoreObject
417
-
418
- @oCoreObject.Query(oCloudObj, sQuery, hConfig)
366
+ config_account
367
+ end
368
+
369
+ def init_controller_mod(process_list, controller_mod)
370
+ # TODO: Support for process full path, instead of predefined one.
371
+ controller_process_mod = File.join(PrcLib.controller_path, controller_mod,
372
+ controller_mod.capitalize +
373
+ 'Process.rb')
374
+ if File.exist?(controller_process_mod)
375
+ process_list << controller_process_mod
376
+ else
377
+ Lorj.debug(1, format("No Provider process defined. File '%s' not "\
378
+ 'found.', controller_process_mod))
419
379
  end
420
-
421
- # Execution of the Get process for the `oCloudObj` object.
422
- #
423
- # * *Args* :
424
- # - +oCloudObj+ : Name of the object to initialize.
425
- # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data object.
426
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
427
- # If you use this variable, any other runtime config defined
428
- # by the Data model will be cleaned before
429
- #
430
- # * *Returns* :
431
- # - +Lorj::Data+ : Represents the Object initialized.
432
- #
433
- # * *Raises* :
434
- # No exceptions
435
-
436
- def Get(oCloudObj, sId, hConfig = {})
437
- return nil if not oCloudObj or not @oCoreObject or sId.nil?
438
-
439
- @oCoreObject.Get(oCloudObj, sId, hConfig)
440
- end
441
-
442
- # Execution of the Update process for the `oCloudObj` object.
443
- # Usually, the Controller object data is updated by the process (BaseController::set_attr)
444
- # then it should call a controller_update to really update the data in the controller.
445
- #
446
- # * *Args* :
447
- # - +oCloudObj+ : Name of the object to initialize.
448
- # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data object.
449
- # - +hConfig+ : Hash of hashes containing data required to initialize the object.
450
- # If you use this variable, any other runtime config defined
451
- # by the Data model will be cleaned before
452
- #
453
- # * *Returns* :
454
- # - +Lorj::Data+ : Represents the Object initialized.
455
- #
456
- # * *Raises* :
457
- # No exceptions
458
-
459
- def Update(oCloudObj, hConfig = {})
460
- return nil if not oCloudObj or not @oCoreObject
461
-
462
- @oCoreObject.Update(oCloudObj, hConfig)
463
- end
464
-
465
- # Function used to ask users about setting up his account.
466
- #
467
- # * *Args* :
468
- # - +oCloudObj+ : Name of the object to initialize.
469
- # - +sAccountName+ : Account file name. If not set, Config[:account_name] is used.
470
- # If you use this variable, any other runtime config defined
471
- # by the Data model will be cleaned before
472
- #
473
- # * *Returns* :
474
- # - +Lorj::Data+ : Represents the Object initialized.
475
- #
476
- # * *Raises* :
477
- # No exceptions
478
-
479
- def Setup(oCloudObj, sAccountName = nil)
480
- return nil if not oCloudObj or not @oCoreObject
481
- @oCoreObject.Setup(oCloudObj, sAccountName)
482
- end
483
- end
484
-
485
- # This class based on generic Core, defines a Cloud Process to use.
486
- class CloudCore < Core
487
- def initialize(oConfig, sAccount = nil, aProcesses = [])
488
-
489
- unless oConfig.is_a?(Lorj::Account)
490
- oForjAccount = Lorj::Account.new(oConfig)
491
- unless sAccount.nil?
492
- oForjAccount.ac_load(sAccount)
493
- end
494
- else
495
- oForjAccount = oConfig
496
- end
497
- aProcessList = [:CloudProcess]
498
-
499
- sControllerMod = oForjAccount.get(:provider_name)
500
- raise Lorj::PrcError.new(), "Provider_name not set. Unable to create instance CloudCore." if sControllerMod.nil?
501
-
502
- sControllerProcessMod = File.join(PrcLib.controller_path, sControllerMod, sControllerMod.capitalize + "Process.rb")
503
- if File.exist?(sControllerProcessMod)
504
- aProcessList << sControllerProcessMod
505
- else
506
- Lorj.debug(1, "No Provider process defined. File '%s' not found." % sControllerProcessMod)
507
- end
508
-
509
- super(oForjAccount, aProcessList.concat(aProcesses), sControllerMod)
510
- end
511
- end
512
-
513
- # Represents a list of key/value pairs
514
- # if the value is a Lorj::Data(data or list), the key will be the Lorj::Data type.
515
- #
516
- #
517
- #
518
- # Used by
519
- # - BaseDefinition to get a Lorj::Data cache.
520
- # - Process create/query/update/delete/get to build the hParams
521
- # The object behavior is adapted to the process usage
522
- # By default for Lorj::Data(:object), hParams[aKey] will get or set object attributes
523
- #
524
- # - Controller create/query/update/delete/get to build the hParams
525
- # The object behavior is adapted to the controller usage
526
- # By default for Lorj::Data(:object), hParams[aKey] will get or set controller object
527
- #
528
- class ObjectData
529
- # Intialize the object. By default, usage is for controller context.
530
- #
531
- # * *Args* :
532
- # - +bInternal+ : Context
533
- # - true if process context
534
- # - false if controller context. This is the default value.
535
- #
536
- # * *Returns* :
537
- # - nothing
538
- #
539
- # * *Raises* :
540
- # No exceptions
541
- def initialize(bInternal = false)
542
-
543
- @hParams = {}
544
- @hParams[:hdata] = {} unless bInternal
545
- @bInternal = bInternal
546
- end
547
-
548
- # Get function
549
- #
550
- # key can be an array, a string (converted to a symbol) or a symbol.
551
- #
552
- # * *Args* :
553
- # - +key+ : key tree (list of keys)
554
- # If key[1] == :attrs, get will forcelly use the Lorj::Data object attributes
555
- # If key[1] == :ObjectData, get will forcelly return the controller object
556
- # otherwise, get will depends on the context:
557
- # - controller context: will return the controller object
558
- # - Process context: will return the Lorj::Data object attributes
559
- # * *Returns* :
560
- # value found or nil.
561
- # * *Raises* :
562
- # nothing
563
- def [] (*key)
564
-
565
- key = key.flatten
566
- # Return ObjectData Element if asked. Ignore additional keys.
567
- return @hParams[key[0]] if key[1] == :ObjectData
568
-
569
- return @hParams if key.length == 0
570
-
571
- oObject = Lorj::rhGet(@hParams, key[0])
572
- return nil if oObject.nil?
573
-
574
- # Return attributes if asked
575
- return oObject[:attrs, key[2..-1]] if key[1] == :attrs
576
-
577
- if oObject.is_a?(Lorj::Data)
578
- if @bInternal
579
- # params are retrieved in process context
580
- # By default, if key is detected as a framework object, return its data.
581
- return oObject[:attrs, key[1..-1]]
582
- else
583
- # params are retrieved in controller context
584
- # By default, if key is detected as a controller object, return its data.
585
- return oObject[:object, key[1..-1]]
586
- end
587
- end
588
-
589
- # otherwise, simply return what is found in keys hierarchy.
590
- Lorj::rhGet(@hParams, key)
591
- end
592
-
593
- # Functions used to set simple data/Object for controller/process function call.
594
- # TODO: to revisit this function, as we may consider simple data, as Lorj::Data object
595
- def []= (*key, value)
596
- return nil if [:object, :query].include?(key[0])
597
- Lorj::rhSet(@hParams, value, key)
598
- end
599
-
600
- # Add function. Add a Lorj::Data (data or list) to the ObjectData list.
601
- #
602
- # key can be an array, a string (converted to a symbol) or a symbol.
603
- #
604
- # * *Args* :
605
- # - +oDataObject+ : Lorj::Data object
606
- # * *Returns* :
607
- # Nothing
608
- # * *Raises* :
609
- # nothing
610
- def add(oDataObject)
611
- # Requires to be a valid framework object.
612
- raise Lorj::PrcError.new, "Invalid Framework object type '%s'." % oDataObject.class unless oDataObject.is_a?(Lorj::Data)
613
-
614
- sObjectType = oDataObject.object_type?
615
-
616
- if oDataObject.type? == :list
617
- oOldDataObject = Lorj::rhGet(@hParams, :query, sObjectType)
618
- oOldDataObject.unregister if oOldDataObject
619
- Lorj::rhSet(@hParams, oDataObject, :query, sObjectType)
620
- else
621
- oOldDataObject = Lorj::rhGet(@hParams, sObjectType)
622
- oOldDataObject.unregister if oOldDataObject
623
- @hParams[sObjectType] = oDataObject
624
- end
625
- oDataObject.register
626
- end
627
-
628
- # delete function. delete a Lorj::Data (data or list) from the ObjectData list.
629
- #
630
- # key can be an array, a string (converted to a symbol) or a symbol.
631
- #
632
- # * *Args* :
633
- # - +oDataObject+ : Lorj::Data object
634
- # * *Returns* :
635
- # Nothing
636
- # * *Raises* :
637
- # nothing
638
- def delete(oObj)
639
- if oObj.is_a?(Symbol)
640
- sObjectType = oObj
641
- oObj = @hParams[sObjectType]
642
- @hParams[sObjectType] = nil
643
- else
644
- raise Lorj::PrcError.new(), "ObjectData: delete error. oObj is not a framework data Object. Is a '%s'" % oObj.class unless oObj.is_a?(Lorj::Data)
645
- if oObj.type? == :list
646
- Lorj::rhSet(@hParams, nil, :query, oObj.object_type?)
647
- else
648
- sObjectType = oObj.object_type?
649
- @hParams[sObjectType] = nil
650
- end
651
- end
652
- oObj.unregister unless oObj.nil?
653
- end
654
-
655
- # Merge 2 ObjectData.
656
- #
657
- # * *Args* :
658
- # - +hHash+ : Hash of Lorj::Data. But it is possible to have different object type (not Lorj::Data)
659
- # * *Returns* :
660
- # hash merged
661
- # * *Raises* :
662
- # nothing
663
- def << (hHash)
664
- @hParams.merge!(hHash) unless hHash.nil?
665
- end
666
-
667
- # check Lorj::Data attributes or object exists. Or check key/value pair existence.
668
- #
669
- # * *Args* :
670
- # - +hHash+ : Hash of Lorj::Data. But it is possible to have different object type (not Lorj::Data)
671
- # * *Returns* :
672
- # true/false
673
- # * *Raises* :
674
- # PrcError
675
- def exist?(*key)
676
- raise Lorj::PrcError.new, "ObjectData: key is not list of values (string/symbol or array)" if not [Array, String, Symbol].include?(key.class)
677
-
678
- key = [key] if key.is_a?(Symbol) or key.is_a?(String)
679
-
680
- key = key.flatten
681
-
682
- oObject = Lorj::rhGet(@hParams, key[0])
683
- return false if oObject.nil?
684
-
685
- if oObject.is_a?(Lorj::Data)
686
- # Return true if ObjectData Element is found when asked.
687
- return true if key[1] == :ObjectData and oObject.type?(key[0]) == :object
688
-
689
- # Return true if attritutes or controller object attributes found when asked.
690
- return oObject.exist?(key[2..-1]) if key[1] == :attrs
691
- return oObject.exist?(key[1..-1]) if key.length > 1
692
- true
693
- else
694
- # By default true if found key hierarchy
695
- (Lorj::rhExist?(@hParams, key) == key.length)
696
- end
697
- end
698
-
699
- # Determine the type of object identified by a key. Lorj::Data attributes or object exists. Or check key/value pair existence.
700
- #
701
- # * *Args* :
702
- # - +key+ : Key to check in ObjectData list.
703
- # * *Returns* :
704
- # - nil if not found
705
- # - :data if the key value is simply a data
706
- # - :DataObject if the key value is a Lorj::Data
707
- # * *Raises* :
708
- # PrcError
709
-
710
- def type?(key)
711
- return nil if Lorj::rhExist?(@hParams, key) != 1
712
- :data
713
- :DataObject if @hParams[key].type?() == :object
714
- end
715
-
716
- def cObj(*key)
717
- Lorj::rhGet(@hParams, key, :object) if Lorj::rhExist?(@hParams, key, :object) == 2
718
- end
719
-
720
- end
721
-
380
+ end
381
+ end
722
382
  end