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/core/core.rb ADDED
@@ -0,0 +1,723 @@
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
+ # Module Lorj which contains several classes.
19
+ #
20
+ # Those classes describes :
21
+ # - 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
+ # this task to make it to work.
25
+
26
+ 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
+ # TODO: Replace Global variables by equivalent to PrcLib.<var>
146
+
147
+ PrcLib.core_level = 0 if PrcLib.core_level.nil?
148
+
149
+ if oForjConfig.nil?
150
+ @config = Lorj::Config.new()
151
+ oForjConfig = @config
152
+ Lorj.debug(2, "Using an internal Lorj::Config object.")
153
+ else
154
+ @config = oForjConfig
155
+ end
156
+
157
+
158
+ if processesClass.nil?
159
+ aProcessesClass = []
160
+ elsif not processesClass.is_a?(Array)
161
+ aProcessesClass = [processesClass]
162
+ else
163
+ aProcessesClass = processesClass
164
+ end
165
+
166
+ cBaseProcess = BaseProcess
167
+ cProcessClass = nil
168
+
169
+ aProcessesClass.each { | sProcessClass |
170
+ Lorj.debug(1, "Loading Process '%s'" % sProcessClass)
171
+
172
+ # And load the content from the <sProcessClass>.rb
173
+ if sProcessClass.is_a?(Symbol)
174
+ # Ensure file and processName is capitalized
175
+ sProcessClass = sProcessClass.to_s.capitalize if (/[A-Z]/ =~ sProcessClass.to_s) != 0
176
+ sFile = File.join($CORE_PROCESS_PATH, sProcessClass + '.rb')
177
+ else
178
+ if sProcessClass.include?('/')
179
+ # Consider a path to the process file. File name is the name of the class.
180
+ # We accept filename not capitalized.
181
+ sPath = File.dirname(File.expand_path(sProcessClass))
182
+ sFile = File.basename(sProcessClass)
183
+ file = File.basename(sProcessClass)
184
+ file['.rb'] = '' if file['.rb']
185
+ sProcessClass = file
186
+ sProcessClass = sProcessClass.capitalize if (/[A-Z]/ =~ sProcessClass) != 0
187
+ mFound = sProcessClass.scan(/_[a-z]/)
188
+ if mFound
189
+ mFound.each { | str |
190
+ sProcessClass[str] = str[1].capitalize
191
+ }
192
+ end
193
+ else
194
+ sPath = $CORE_PROCESS_PATH
195
+ sProcessClass = sProcessClass.capitalize if (/[A-Z]/ =~ sProcessClass) != 0
196
+ sFile = sProcessClass + '.rb'
197
+ end
198
+ # Ensure process name is capitalized
199
+ sFile = File.join(sPath, sFile)
200
+ end
201
+ if File.exists?(sFile)
202
+ cNewClass = Class.new(cBaseProcess)
203
+ sProcessClass = "%sProcess" % sProcessClass if not /Process$/ =~ sProcessClass
204
+ Lorj.debug(1, "Declaring Process '%s'" % sProcessClass)
205
+ cBaseProcess = Object.const_set(sProcessClass, cNewClass)
206
+ cProcessClass = sProcessClass
207
+ BaseDefinition.current_process(cBaseProcess)
208
+ load sFile
209
+ else
210
+ PrcLib.warning("Process file definition '%s' is missing. " % sFile)
211
+ end
212
+ }
213
+
214
+ if sControllerClass
215
+ Lorj.debug(1, "Loading Controller/definition '%s'" % sControllerClass)
216
+ # Add Provider Object -------------
217
+ if sControllerClass.is_a?(Symbol)
218
+ sPath = File.join($PROVIDERS_PATH, sControllerClass.to_s)
219
+ sControllerClass = sControllerClass.to_s.capitalize if (/[A-Z]/ =~ sControllerClass.to_s) != 0
220
+ sFile = sControllerClass.to_s + '.rb'
221
+ else
222
+ if sControllerClass.include?('/')
223
+ # Consider a path to the process file. File name is the name of the class.
224
+ sPath = File.dirname(File.expand_path(sControllerClass))
225
+ sFile = File.basename(sControllerClass)
226
+ file = File.basename(sControllerClass)
227
+ file = file.capitalize if (/[A-Z]/ =~ file) != 0
228
+ file['.rb'] = '' if file['.rb']
229
+ sControllerClass = file
230
+ sControllerClass = sControllerClass.capitalize if (/[A-Z]/ =~ sControllerClass) != 0
231
+ mFound = sControllerClass.scan(/_[a-z]/)
232
+ if mFound
233
+ mFound.each { | str |
234
+ sControllerClass[str] = str[1].capitalize
235
+ }
236
+ end
237
+ else
238
+ sPath = File.join($PROVIDERS_PATH, sControllerClass)
239
+ sControllerClass = sControllerClass.capitalize if (/[A-Z]/ =~ sControllerClass) != 0
240
+ sFile = sControllerClass + '.rb'
241
+ end
242
+ end
243
+ sFile = File.join(sPath, sFile)
244
+
245
+ # Initialize an empty class derived from BaseDefinition.
246
+ # This to ensure provider Class will be derived from this Base Class
247
+ # If this class is derived from a different Class, ruby will raise an error.
248
+
249
+ # Create Definition and Controler derived from respectively BaseDefinition and BaseControler
250
+ cBaseDefinition = Class.new(BaseDefinition)
251
+ # Finally, name that class!
252
+ Lorj.debug(2, "Declaring Definition '%s'" % sControllerClass)
253
+ Object.const_set sControllerClass, cBaseDefinition
254
+
255
+ cBaseControler = Class.new(BaseController)
256
+ Lorj.debug(2, "Declaring Controller '%s'" % [sControllerClass + 'Controller'])
257
+ Object.const_set sControllerClass + 'Controller', cBaseControler
258
+
259
+ # Loading Provider base file. This file should load a class
260
+ # which have the same name as the file.
261
+ if File.exists?(sFile)
262
+ load sFile
263
+ else
264
+ raise Lorj::PrcError.new(), "Provider file definition '%s' is missing. Cannot go on" % sFile
265
+ end
266
+
267
+ # Identify Provider Classes. Search for
268
+ # - Definition Class (sControllerClass) - Contains ForjClass Object
269
+ # - Controller Class (sControllerClass + 'Controller') - Provider Cloud controler object
270
+
271
+ # Search for Definition Class
272
+ begin
273
+ # Get it from Objects
274
+ oDefClass = Object.const_get(sControllerClass)
275
+ rescue
276
+ raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % sControllerClass
277
+ end
278
+
279
+ # Search for Controler Class
280
+ # - Process Class (sControllerClass + 'Process') - Provider Process object if defined
281
+ begin
282
+ # Get the same one suffixed with 'Provider' from Objects
283
+ oCoreObjectControllerClass = Object.const_get(sControllerClass + 'Controller')
284
+ rescue
285
+ raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % sControllerClass + 'Controller'
286
+ end
287
+
288
+ # Then, we create an BaseCloud Object with 2 objects joined:
289
+ # ForjAccount and a BaseControler Object type
290
+
291
+
292
+ else
293
+ oCoreObjectControllerClass = nil
294
+ oDefClass = BaseDefinition
295
+ end
296
+
297
+ # Add Process management object ---------------
298
+ unless cProcessClass.nil?
299
+ begin
300
+ oBaseProcessDefClass = Object.const_get(cProcessClass)
301
+ rescue
302
+ raise Lorj::PrcError.new(), 'Lorj::Core: Unable to find class "%s"' % cProcessClass
303
+ end
304
+ else
305
+ raise Lorj::PrcError.new(), 'Lorj::Core: No valid process loaded. Aborting.'
306
+ end
307
+ # Ex: Hpcloud(ForjAccount, HpcloudProvider)
308
+ if oCoreObjectControllerClass
309
+ @oCoreObject = oDefClass.new(oForjConfig, oBaseProcessDefClass.new(), oCoreObjectControllerClass.new())
310
+ else
311
+ @oCoreObject = oDefClass.new(oForjConfig, oBaseProcessDefClass.new())
312
+ end
313
+
314
+ end
315
+
316
+ # a wrapper to Create call. Use this function for code readibility.
317
+ #
318
+ # * *Args* :
319
+ # - +oCloudObj+ : Name of the object to initialize.
320
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
321
+ # If you use this variable, any other runtime config defined
322
+ # by the Data model will be cleaned before
323
+ #
324
+ # * *Returns* :
325
+ # - +Lorj::Data+ : Represents the Object initialized.
326
+ #
327
+ # * *Raises* :
328
+ # No exceptions
329
+
330
+ def Connect(oCloudObj, hConfig = {})
331
+ return nil if not oCloudObj or not @oCoreObject
332
+ @oCoreObject.Create(oCloudObj, hConfig)
333
+ end
334
+
335
+ # Execute the creation process to create the object `oCloudObj`.
336
+ # The creation process can add any kind of complexity to
337
+ # get the a memory representation of the object manipulated during creation process.
338
+ # This means that a creation process can be (non exhaustive list of possibilities)
339
+ # - a connection initialization
340
+ # - an internal memory data structure, like hash, array, ruby object...
341
+ # - a get or create logic
342
+ # - ...
343
+ #
344
+ # * *Args* :
345
+ # - +oCloudObj+ : Name of the object to initialize.
346
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
347
+ # If you use this variable, any other runtime config defined
348
+ # by the Data model will be cleaned before
349
+ #
350
+ # * *Returns* :
351
+ # - +Lorj::Data+ : Represents the Object initialized.
352
+ #
353
+ # * *Raises* :
354
+ # No exceptions
355
+ def Create(oCloudObj, hConfig = {})
356
+ return nil if not oCloudObj or not @oCoreObject
357
+ @oCoreObject.Create(oCloudObj, hConfig)
358
+ end
359
+
360
+ # a wrapper to Create call. Use this function for code readibility.
361
+ #
362
+ # * *Args* :
363
+ # - +oCloudObj+ : Name of the object to initialize.
364
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
365
+ # If you use this variable, any other runtime config defined
366
+ # by the Data model will be cleaned before
367
+ #
368
+ # * *Returns* :
369
+ # - +Lorj::Data+ : Represents the Object initialized.
370
+ #
371
+ # * *Raises* :
372
+ # No exceptions
373
+
374
+ def GetOrCreate(oCloudObj, hConfig = {})
375
+ return nil if not oCloudObj or not @oCoreObject
376
+ @oCoreObject.Create(oCloudObj, hConfig)
377
+ end
378
+
379
+ # Execution of the delete process for the `oCloudObj` object.
380
+ # It requires the object to be loaded in lorj Lorj::Data objects cache.
381
+ # You can use `Create` or `Get` functions to load this object.
382
+ #
383
+ # * *Args* :
384
+ # - +oCloudObj+ : Name of the object to initialize.
385
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
386
+ # If you use this variable, any other runtime config defined
387
+ # by the Data model will be cleaned before
388
+ #
389
+ # * *Returns* :
390
+ # - +Lorj::Data+ : Represents the Object initialized.
391
+ #
392
+ # * *Raises* :
393
+ # No exceptions
394
+
395
+ def Delete(oCloudObj, hConfig = {})
396
+ return nil if not oCloudObj or not @oCoreObject
397
+
398
+ @oCoreObject.Delete(oCloudObj, hConfig)
399
+ end
400
+
401
+ # Execution of the Query process for the `oCloudObj` object.
402
+ #
403
+ # * *Args* :
404
+ # - +oCloudObj+ : Name of the object to initialize.
405
+ # - +sQuery+ : Hash representing the query filter.
406
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
407
+ # If you use this variable, any other runtime config defined
408
+ # by the Data model will be cleaned before
409
+ #
410
+ # * *Returns* :
411
+ # - +Lorj::Data+ : Represents the Object initialized.
412
+ #
413
+ # * *Raises* :
414
+ # No exceptions
415
+
416
+ def Query(oCloudObj, sQuery, hConfig = {})
417
+ return nil if not oCloudObj or not @oCoreObject
418
+
419
+ @oCoreObject.Query(oCloudObj, sQuery, hConfig)
420
+ end
421
+
422
+ # Execution of the Get process for the `oCloudObj` object.
423
+ #
424
+ # * *Args* :
425
+ # - +oCloudObj+ : Name of the object to initialize.
426
+ # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data object.
427
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
428
+ # If you use this variable, any other runtime config defined
429
+ # by the Data model will be cleaned before
430
+ #
431
+ # * *Returns* :
432
+ # - +Lorj::Data+ : Represents the Object initialized.
433
+ #
434
+ # * *Raises* :
435
+ # No exceptions
436
+
437
+ def Get(oCloudObj, sId, hConfig = {})
438
+ return nil if not oCloudObj or not @oCoreObject or sId.nil?
439
+
440
+ @oCoreObject.Get(oCloudObj, sId, hConfig)
441
+ end
442
+
443
+ # Execution of the Update process for the `oCloudObj` object.
444
+ # Usually, the Controller object data is updated by the process (BaseController::set_attr)
445
+ # then it should call a controller_update to really update the data in the controller.
446
+ #
447
+ # * *Args* :
448
+ # - +oCloudObj+ : Name of the object to initialize.
449
+ # - +sId+ : data representing the ID (attribute :id) of a Lorj::Data object.
450
+ # - +hConfig+ : Hash of hashes containing data required to initialize the object.
451
+ # If you use this variable, any other runtime config defined
452
+ # by the Data model will be cleaned before
453
+ #
454
+ # * *Returns* :
455
+ # - +Lorj::Data+ : Represents the Object initialized.
456
+ #
457
+ # * *Raises* :
458
+ # No exceptions
459
+
460
+ def Update(oCloudObj, hConfig = {})
461
+ return nil if not oCloudObj or not @oCoreObject
462
+
463
+ @oCoreObject.Update(oCloudObj, hConfig)
464
+ end
465
+
466
+ # Function used to ask users about setting up his account.
467
+ #
468
+ # * *Args* :
469
+ # - +oCloudObj+ : Name of the object to initialize.
470
+ # - +sAccountName+ : Account file name. If not set, Config[:account_name] is used.
471
+ # If you use this variable, any other runtime config defined
472
+ # by the Data model will be cleaned before
473
+ #
474
+ # * *Returns* :
475
+ # - +Lorj::Data+ : Represents the Object initialized.
476
+ #
477
+ # * *Raises* :
478
+ # No exceptions
479
+
480
+ def Setup(oCloudObj, sAccountName = nil)
481
+ return nil if not oCloudObj or not @oCoreObject
482
+ @oCoreObject.Setup(oCloudObj, sAccountName)
483
+ end
484
+ end
485
+
486
+ # This class based on generic Core, defines a Cloud Process to use.
487
+ class CloudCore < Core
488
+ def initialize(oConfig, sAccount = nil, aProcesses = [])
489
+
490
+ unless oConfig.is_a?(ForjAccount)
491
+ oForjAccount = Lorj::Account.new(oConfig)
492
+ unless sAccount.nil?
493
+ oForjAccount.ac_load(sAccount)
494
+ end
495
+ else
496
+ oForjAccount = oConfig
497
+ end
498
+ aProcessList = [:CloudProcess]
499
+
500
+ sControllerMod = oForjAccount.get(:provider_name)
501
+ raise Lorj::PrcError.new(), "Provider_name not set. Unable to create instance CloudCore." if sControllerMod.nil?
502
+
503
+ sControllerProcessMod = File.join($PROVIDERS_PATH, sControllerMod, sControllerMod.capitalize + "Process.rb")
504
+ if File.exist?(sControllerProcessMod)
505
+ aProcessList << sControllerProcessMod
506
+ else
507
+ Lorj.debug(1, "No Provider process defined. File '%s' not found." % sControllerProcessMod)
508
+ end
509
+
510
+ super(oForjAccount, aProcessList.concat(aProcesses), sControllerMod)
511
+ end
512
+ end
513
+
514
+ # Represents a list of key/value pairs
515
+ # if the value is a Lorj::Data(data or list), the key will be the Lorj::Data type.
516
+ #
517
+ #
518
+ #
519
+ # Used by
520
+ # - BaseDefinition to get a Lorj::Data cache.
521
+ # - Process create/query/update/delete/get to build the hParams
522
+ # The object behavior is adapted to the process usage
523
+ # By default for Lorj::Data(:object), hParams[aKey] will get or set object attributes
524
+ #
525
+ # - Controller create/query/update/delete/get to build the hParams
526
+ # The object behavior is adapted to the controller usage
527
+ # By default for Lorj::Data(:object), hParams[aKey] will get or set controller object
528
+ #
529
+ class ObjectData
530
+ # Intialize the object. By default, usage is for controller context.
531
+ #
532
+ # * *Args* :
533
+ # - +bInternal+ : Context
534
+ # - true if process context
535
+ # - false if controller context. This is the default value.
536
+ #
537
+ # * *Returns* :
538
+ # - nothing
539
+ #
540
+ # * *Raises* :
541
+ # No exceptions
542
+ def initialize(bInternal = false)
543
+
544
+ @hParams = {}
545
+ @hParams[:hdata] = {} unless bInternal
546
+ @bInternal = bInternal
547
+ end
548
+
549
+ # Get function
550
+ #
551
+ # key can be an array, a string (converted to a symbol) or a symbol.
552
+ #
553
+ # * *Args* :
554
+ # - +key+ : key tree (list of keys)
555
+ # If key[1] == :attrs, get will forcelly use the Lorj::Data object attributes
556
+ # If key[1] == :ObjectData, get will forcelly return the controller object
557
+ # otherwise, get will depends on the context:
558
+ # - controller context: will return the controller object
559
+ # - Process context: will return the Lorj::Data object attributes
560
+ # * *Returns* :
561
+ # value found or nil.
562
+ # * *Raises* :
563
+ # nothing
564
+ def [] (*key)
565
+
566
+ key = key.flatten
567
+ # Return ObjectData Element if asked. Ignore additional keys.
568
+ return @hParams[key[0]] if key[1] == :ObjectData
569
+
570
+ return @hParams if key.length == 0
571
+
572
+ oObject = Lorj::rhGet(@hParams, key[0])
573
+ return nil if oObject.nil?
574
+
575
+ # Return attributes if asked
576
+ return oObject[:attrs, key[2..-1]] if key[1] == :attrs
577
+
578
+ if oObject.is_a?(Lorj::Data)
579
+ if @bInternal
580
+ # params are retrieved in process context
581
+ # By default, if key is detected as a framework object, return its data.
582
+ return oObject[:attrs, key[1..-1]]
583
+ else
584
+ # params are retrieved in controller context
585
+ # By default, if key is detected as a controller object, return its data.
586
+ return oObject[:object, key[1..-1]]
587
+ end
588
+ end
589
+
590
+ # otherwise, simply return what is found in keys hierarchy.
591
+ Lorj::rhGet(@hParams, key)
592
+ end
593
+
594
+ # Functions used to set simple data/Object for controller/process function call.
595
+ # TODO: to revisit this function, as we may consider simple data, as Lorj::Data object
596
+ def []= (*key, value)
597
+ return nil if [:object, :query].include?(key[0])
598
+ Lorj::rhSet(@hParams, value, key)
599
+ end
600
+
601
+ # Add function. Add a Lorj::Data (data or list) to the ObjectData list.
602
+ #
603
+ # key can be an array, a string (converted to a symbol) or a symbol.
604
+ #
605
+ # * *Args* :
606
+ # - +oDataObject+ : Lorj::Data object
607
+ # * *Returns* :
608
+ # Nothing
609
+ # * *Raises* :
610
+ # nothing
611
+ def add(oDataObject)
612
+ # Requires to be a valid framework object.
613
+ raise Lorj::PrcError.new, "Invalid Framework object type '%s'." % oDataObject.class unless oDataObject.is_a?(Lorj::Data)
614
+
615
+ sObjectType = oDataObject.object_type?
616
+
617
+ if oDataObject.type? == :list
618
+ oOldDataObject = Lorj::rhGet(@hParams, :query, sObjectType)
619
+ oOldDataObject.unregister if oOldDataObject
620
+ Lorj::rhSet(@hParams, oDataObject, :query, sObjectType)
621
+ else
622
+ oOldDataObject = Lorj::rhGet(@hParams, sObjectType)
623
+ oOldDataObject.unregister if oOldDataObject
624
+ @hParams[sObjectType] = oDataObject
625
+ end
626
+ oDataObject.register
627
+ end
628
+
629
+ # delete function. delete a Lorj::Data (data or list) from the ObjectData list.
630
+ #
631
+ # key can be an array, a string (converted to a symbol) or a symbol.
632
+ #
633
+ # * *Args* :
634
+ # - +oDataObject+ : Lorj::Data object
635
+ # * *Returns* :
636
+ # Nothing
637
+ # * *Raises* :
638
+ # nothing
639
+ def delete(oObj)
640
+ if oObj.is_a?(Symbol)
641
+ sObjectType = oObj
642
+ oObj = @hParams[sObjectType]
643
+ @hParams[sObjectType] = nil
644
+ else
645
+ 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)
646
+ if oObj.type? == :list
647
+ Lorj::rhSet(@hParams, nil, :query, oObj.object_type?)
648
+ else
649
+ sObjectType = oObj.object_type?
650
+ @hParams[sObjectType] = nil
651
+ end
652
+ end
653
+ oObj.unregister unless oObj.nil?
654
+ end
655
+
656
+ # Merge 2 ObjectData.
657
+ #
658
+ # * *Args* :
659
+ # - +hHash+ : Hash of Lorj::Data. But it is possible to have different object type (not Lorj::Data)
660
+ # * *Returns* :
661
+ # hash merged
662
+ # * *Raises* :
663
+ # nothing
664
+ def << (hHash)
665
+ @hParams.merge!(hHash)
666
+ end
667
+
668
+ # check Lorj::Data attributes or object exists. Or check key/value pair existence.
669
+ #
670
+ # * *Args* :
671
+ # - +hHash+ : Hash of Lorj::Data. But it is possible to have different object type (not Lorj::Data)
672
+ # * *Returns* :
673
+ # true/false
674
+ # * *Raises* :
675
+ # PrcError
676
+ def exist?(*key)
677
+ raise Lorj::PrcError.new, "ObjectData: key is not list of values (string/symbol or array)" if not [Array, String, Symbol].include?(key.class)
678
+
679
+ key = [key] if key.is_a?(Symbol) or key.is_a?(String)
680
+
681
+ key = key.flatten
682
+
683
+ oObject = Lorj::rhGet(@hParams, key[0])
684
+ return false if oObject.nil?
685
+
686
+ if oObject.is_a?(Lorj::Data)
687
+ # Return true if ObjectData Element is found when asked.
688
+ return true if key[1] == :ObjectData and oObject.type?(key[0]) == :object
689
+
690
+ # Return true if attritutes or controller object attributes found when asked.
691
+ return oObject.exist?(key[2..-1]) if key[1] == :attrs
692
+ return oObject.exist?(key[1..-1]) if key.length > 1
693
+ true
694
+ else
695
+ # By default true if found key hierarchy
696
+ (Lorj::rhExist?(@hParams, key) == key.length)
697
+ end
698
+ end
699
+
700
+ # Determine the type of object identified by a key. Lorj::Data attributes or object exists. Or check key/value pair existence.
701
+ #
702
+ # * *Args* :
703
+ # - +key+ : Key to check in ObjectData list.
704
+ # * *Returns* :
705
+ # - nil if not found
706
+ # - :data if the key value is simply a data
707
+ # - :DataObject if the key value is a Lorj::Data
708
+ # * *Raises* :
709
+ # PrcError
710
+
711
+ def type?(key)
712
+ return nil if Lorj::rhExist?(@hParams, key) != 1
713
+ :data
714
+ :DataObject if @hParams[key].type?() == :object
715
+ end
716
+
717
+ def cObj(*key)
718
+ Lorj::rhGet(@hParams, key, :object) if Lorj::rhExist?(@hParams, key, :object) == 2
719
+ end
720
+
721
+ end
722
+
723
+ end