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
@@ -0,0 +1,1079 @@
1
+ # encoding: UTF-8
2
+
3
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Module Lorj which contains several classes.
18
+ #
19
+ # Those classes describes :
20
+ # - processes (BaseProcess) : How to create/delete/edit/query object.
21
+ # - controler (BaseControler) : If a provider is defined, define how will do object creation/etc...
22
+ # - definition(BaseDefinition): Functions to declare objects, query/data mapping and setup
23
+ # this task to make it to work.
24
+
25
+ module Lorj
26
+ # Following class defines class levels function to
27
+ # declare framework objects.
28
+ # As each process needs to define new object to deal with
29
+ # require that process to define it with definition functions
30
+ # See definition.rb for functions to use.
31
+
32
+ class BaseDefinition
33
+ # Capitalized function are called to start a process. It is done by Core class.
34
+
35
+ # Call meta lorj object creation process.
36
+ # The creation process can implement any logic like:
37
+ # - create an object in the DB.
38
+ # - check object existence in the DB. If not exists, create it.
39
+ #
40
+ # * *Args* :
41
+ # - +ObjectType+ : Meta object type to create.
42
+ # - +Config+ : Optional. Hash containing list of data to use for creation.
43
+ #
44
+ # * *Returns* :
45
+ # - +Object+ : Lorj::Data object of type +ObjectType+ created.
46
+ #
47
+ # * *Raises* :
48
+ # - Warning if the create_e process handler did not return any data. (nil)
49
+ # - Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.
50
+ # - Error if ObjectType has never been declared.
51
+ # - Error if the dependencies create_e process handler did not return any data. (nil) - Loop detection.
52
+ # - Error if the create_e process handler raise an error.
53
+ #
54
+ def Create(sObjectType, hConfig = {})
55
+
56
+ if hConfig.length > 0
57
+ # cleanup runtime data to avoid conflicts between multiple calls
58
+ valid_keys = _identify_data(sObjectType, :create_e)
59
+ valid_keys.each { | sKey|
60
+ value = Lorj::rhGet(hConfig, sKey)
61
+ @oForjConfig[sKey] = value if not @oForjConfig.exist?(sKey) or @oForjConfig.exist?(sKey) == 'runtime'
62
+ Lorj::rhSet(hConfig, nil, sKey)
63
+ }
64
+ if hConfig.length > 0
65
+ PrcLib::warning("'%s' has been passed but not declared to '%s' object. Those are ignored until you add it in the model definition of '%s'" % [hConfig.keys, sObjectType, sObjectType])
66
+ end
67
+ end
68
+
69
+ return nil if not sObjectType
70
+ raise Lorj::PrcError.new(), "%s.Create: '%s' is not a known object type." % [self.class, sObjectType] if Lorj::rhExist?(@@meta_obj, sObjectType) != 1
71
+
72
+ pProc = Lorj::rhGet(@@meta_obj, sObjectType, :lambdas, :create_e)
73
+
74
+ # Check required parameters
75
+ oObjMissing = _check_required(sObjectType, :create_e, pProc).reverse
76
+
77
+ while oObjMissing.length >0
78
+ sElem = oObjMissing.pop
79
+
80
+ raise Lorj::PrcError.new(),"Unable to create Object '%s'" % sElem if not Create(sElem)
81
+ oObjMissing = _check_required(sObjectType, :create_e, pProc).reverse
82
+
83
+ raise Lorj::PrcError.new(), "loop detection: '%s' is required but Create(%s) did not loaded it." % [sElem, sElem] if oObjMissing.include?(sElem)
84
+ end
85
+ @RuntimeContext[:oCurrentObj] = sObjectType # Context: Default object used.
86
+
87
+ if pProc.nil?
88
+ # This object is a meta object, without any data.
89
+ # Used to build other kind of objects.
90
+ oObject = Lorj::Data.new
91
+ oObject.set({}, sObjectType) {}
92
+ else
93
+ # build Function params to pass to the event handler.
94
+ aParams = _get_object_params(sObjectType, :create_e, pProc,)
95
+ Lorj.debug(2, "Create Object '%s' - Running '%s'" % [sObjectType, pProc])
96
+
97
+ # Call the process function.
98
+ # At some point, the process will call the controller, via the framework.
99
+ # This controller call via the framework has the role to
100
+ # create an ObjectData well formatted, with _return_map function
101
+ # See Definition.connect/create/update/query/get functions (lowercase)
102
+ oObject = @oForjProcess.method(pProc).call(sObjectType, aParams)
103
+ # return usually is the main object that the process called should provide.
104
+ # Save Object if the object has been created by the process, without controller
105
+ end
106
+
107
+ unless oObject.nil?
108
+ query_cleanup(sObjectType)
109
+ @ObjectData.add(oObject)
110
+ else
111
+ PrcLib::warning("'%s' has returned no data for object Lorj::Data '%s'!" % [pProc, sObjectType])
112
+ end
113
+ end
114
+
115
+ # Call meta lorj object deletion process
116
+ # There is no implementation of cascade deletion. It is up to the process to do it or not.
117
+ #
118
+ # * *Args* :
119
+ # - +ObjectType+ : Meta object type to create.
120
+ # - +Config+ : Optional. Hash containing list of data to use for creation.
121
+ #
122
+ # * *Returns* :
123
+ # - +Deleted+ : true if deleted or false otherwise.
124
+ #
125
+ # * *Raises* :
126
+ # - Warning if the create_e process handler did not return any data. (nil)
127
+ # - Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.
128
+ # - Error if ObjectType has never been declared.
129
+ # - Error if the dependencies query_e process handler did not return any data. (nil) - Loop detection.
130
+ # - Error if the query_e process handler raise an error.
131
+ #
132
+ def Delete(sCloudObj, hConfig = {})
133
+ return nil if not sCloudObj
134
+
135
+ raise Lorj::PrcError.new(), "%s.Delete: '%s' is not a known object type." % [self.class, sCloudObj] if Lorj::rhExist?(@@meta_obj, sCloudObj) != 1
136
+
137
+ if hConfig.length > 0
138
+ # cleanup runtime data to avoid conflicts between multiple calls
139
+ valid_keys = _identify_data(sCloudObj, :delete_e)
140
+ valid_keys.each { | sKey|
141
+ value = Lorj::rhGet(hConfig, sKey)
142
+ @oForjConfig[sKey] = value if not @oForjConfig.exist?(sKey) or @oForjConfig.exist?(sKey) == 'runtime'
143
+ Lorj::rhSet(hConfig, nil, sKey)
144
+ }
145
+ if hConfig.length > 0
146
+ PrcLib::warning("'%s' has been passed but not declared to '%s' object. Those are ignored until you add it in the model definition of '%s'" % [hConfig.keys, sCloudObj, sCloudObj])
147
+ end
148
+ end
149
+
150
+ pProc = Lorj::rhGet(@@meta_obj, sCloudObj, :lambdas, :delete_e)
151
+
152
+ return nil if pProc.nil?
153
+
154
+ # Check required parameters
155
+ oObjMissing = _check_required(sCloudObj, :delete_e, pProc).reverse
156
+
157
+ while oObjMissing.length >0
158
+ sElem = oObjMissing.pop
159
+ if sElem == sCloudObj
160
+ debug(2, "'%s' object is not previously loaded or created." % sCloudObj) if sElem == sCloudObj
161
+ next
162
+ end
163
+ raise Lorj::PrcError.new(),"Unable to create Object '%s'" % sElem if not Create(sElem)
164
+ oObjMissing = _check_required(sCloudObj, :delete_e, pProc).reverse
165
+ raise Lorj::PrcError.new(), "Unable to delete '%s' object. required '%s' data was not loaded after 'Create(%s)'. Check create handler for object type '%s'." % [sCloudObj, sElem, sElem, sElem] if oObjMissing.include?(sElem)
166
+ end
167
+ @RuntimeContext[:oCurrentObj] = sCloudObj # Context: Default object used.
168
+
169
+ # build Function params to pass to the event handler.
170
+ aParams = _get_object_params(sCloudObj, :delete_e, pProc)
171
+
172
+ bState = @oForjProcess.method(pProc).call(sCloudObj, aParams)
173
+ # return usually is the main object that the process called should provide.
174
+ if bState
175
+ @ObjectData.delete(sCloudObj)
176
+ end
177
+
178
+ end
179
+
180
+ # Function to clean the cache for a specific meta lorj object queried.
181
+ #
182
+ # * *Args* :
183
+ # - +ObjectType+ : Meta object type to cleanup.
184
+ #
185
+ # * *Returns* :
186
+ # no data
187
+ #
188
+ # * *Raises* :
189
+ #
190
+ def query_cleanup(sCloudObj)
191
+ oList = @ObjectData[:query, sCloudObj]
192
+ unless oList.nil?
193
+ @ObjectData.delete(oList)
194
+ Lorj.debug(2, "Query cache for object '%s' cleaned." % sCloudObj)
195
+ end
196
+ end
197
+
198
+ # Function to clean the cache for a specific meta lorj object.
199
+ #
200
+ # * *Args* :
201
+ # - +ObjectType+ : Meta object type to cleanup.
202
+ #
203
+ # * *Returns* :
204
+ # no data
205
+ #
206
+ # * *Raises* :
207
+ #
208
+ def object_cleanup(sCloudObj)
209
+ oObject = @ObjectData[sCloudObj, :ObjectData]
210
+ unless oObject.nil?
211
+ @ObjectData.delete(oObject)
212
+ end
213
+ end
214
+
215
+ # Function to execute a query process. This function returns a Lorj::Data of type :list.
216
+ #
217
+ # * *Args* :
218
+ # - +ObjectType+ : Meta object type to query.
219
+ # - +Query+ : Hash. Represent the query to execute.
220
+ # - +Config+ : Optional. Hash containing list of data to use for query.
221
+ #
222
+ # * *Returns* :
223
+ # Lorj::Data of type :list
224
+ #
225
+ # * *Raises* :
226
+ #
227
+ #
228
+ def Query(sCloudObj, hQuery, hConfig = {})
229
+
230
+ return nil if not sCloudObj
231
+
232
+ raise Lorj::PrcError.new(), "$s.Get: '%s' is not a known object type." % [self.class, sCloudObj] if Lorj::rhExist?(@@meta_obj, sCloudObj) != 1
233
+
234
+ if hConfig.length > 0
235
+ # cleanup runtime data to avoid conflicts between multiple calls
236
+ valid_keys = _identify_data(sCloudObj, :query_e)
237
+ valid_keys.each { | sKey|
238
+ value = Lorj::rhGet(hConfig, sKey)
239
+ @oForjConfig[sKey] = value if not @oForjConfig.exist?(sKey) or @oForjConfig.exist?(sKey) == 'runtime'
240
+ Lorj::rhSet(hConfig, nil, sKey)
241
+ }
242
+ if hConfig.length > 0
243
+ PrcLib::warning("'%s' has been passed but not declared to '%s' object. Those are ignored until you add it in the model definition of '%s'" % [hConfig.keys, sCloudObj, sCloudObj])
244
+ end
245
+ end
246
+
247
+ # Check if we can re-use a previous query
248
+ oList = @ObjectData[:query, sCloudObj]
249
+ unless oList.nil?
250
+ if oList[:query] == hQuery
251
+ Lorj.debug(3, "Using Object '%s' query cache : %s" % [sCloudObj, hQuery])
252
+ return oList
253
+ end
254
+ end
255
+
256
+ pProc = Lorj::rhGet(@@meta_obj, sCloudObj, :lambdas, :query_e)
257
+
258
+ return nil if pProc.nil?
259
+
260
+ # Check required parameters
261
+ oObjMissing = _check_required(sCloudObj, :query_e, pProc).reverse
262
+
263
+ while oObjMissing.length >0
264
+ sElem = oObjMissing.pop
265
+ raise Lorj::PrcError.new(),"Unable to create Object '%s'" % sElem if not Create(sElem)
266
+ oObjMissing = _check_required(sCloudObj, :query_e, pProc).reverse
267
+ raise Lorj::PrcError.new(), "loop detection: '%s' is required but Query(%s) did not loaded it." % [sElem, sElem] if oObjMissing.include?(sElem)
268
+ end
269
+ @RuntimeContext[:oCurrentObj] = sCloudObj # Context: Default object used.
270
+
271
+ # build Function params to pass to the Process Event handler.
272
+ aParams = _get_object_params(sCloudObj, :query_e, pProc)
273
+
274
+ # Call the process function.
275
+ # At some point, the process will call the controller, via the framework.
276
+ # This controller call via the framework has the role to
277
+ # create an ObjectData well formatted, with _return_map function
278
+ # See Definition.connect/create/update/query/get functions (lowercase)
279
+ oObject = @oForjProcess.method(pProc).call(sCloudObj, hQuery, aParams)
280
+ # return usually is the main object that the process called should provide.
281
+ unless oObject.nil?
282
+ # Save Object if the object has been created by the process, without controller
283
+ @ObjectData.add(oObject)
284
+ else
285
+ PrcLib::warning("'%s' returned no collection of objects Lorj::Data for '%s'" % [pProc, sCloudObj])
286
+ end
287
+ end
288
+
289
+ # Function to execute a get process. This function returns a Lorj::Data of type :object.
290
+ #
291
+ # * *Args* :
292
+ # - +ObjectType+ : Meta object type to query.
293
+ # - +UniqId+ : Uniq ID.
294
+ # - +Config+ : Optional. Hash containing list of data to use for getting.
295
+ #
296
+ # * *Returns* :
297
+ # Lorj::Data of type :object
298
+ #
299
+ # * *Raises* :
300
+ # - Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.
301
+ # - Error if ObjectType has never been declared.
302
+ # - Error if the dependencies get_e process handler did not return any data. (nil) - Loop detection.
303
+ # - Error if the get_e process handler raise an error.
304
+ #
305
+ def Get(sCloudObj, sUniqId, hConfig = {})
306
+
307
+ return nil if not sCloudObj
308
+
309
+ raise Lorj::PrcError.new(), "$s.Get: '%s' is not a known object type." % [self.class, sCloudObj] if Lorj::rhExist?(@@meta_obj, sCloudObj) != 1
310
+
311
+ if hConfig.length > 0
312
+ # cleanup runtime data to avoid conflicts between multiple calls
313
+ valid_keys = _identify_data(sCloudObj, :get_e)
314
+ valid_keys.each { | sKey|
315
+ value = Lorj::rhGet(hConfig, sKey)
316
+ @oForjConfig[sKey] = value if not @oForjConfig.exist?(sKey) or @oForjConfig.exist?(sKey) == 'runtime'
317
+ Lorj::rhSet(hConfig, nil, sKey)
318
+ }
319
+ if hConfig.length > 0
320
+ Lorj::warning("'%s' has been passed but not declared to '%s' object. Those are ignored until you add it in the model definition of '%s'" % [hConfig.keys, sCloudObj, sCloudObj])
321
+ end
322
+ end
323
+
324
+ pProc = Lorj::rhGet(@@meta_obj, sCloudObj, :lambdas, :get_e)
325
+
326
+ return nil if pProc.nil?
327
+
328
+ # Check required parameters
329
+ oObjMissing = _check_required(sCloudObj, :get_e, pProc).reverse
330
+
331
+ while oObjMissing.length >0
332
+ sElem = oObjMissing.pop
333
+ raise Lorj::PrcError.new(),"Unable to create Object '%s'" % sElem if not Create(sElem)
334
+ oObjMissing = _check_required(sCloudObj, :get_e, pProc).reverse
335
+ raise Lorj::PrcError.new(), "loop detection: '%s' is required but Get(%s) did not loaded it." % [sElem, sElem] if oObjMissing.include?(sElem)
336
+ end
337
+ @RuntimeContext[:oCurrentObj] = sCloudObj # Context: Default object used.
338
+
339
+ # build Function params to pass to the Process Event handler.
340
+ aParams = _get_object_params(sCloudObj, :get_e, pProc)
341
+
342
+ # Call the process function.
343
+ # At some point, the process will call the controller, via the framework.
344
+ # This controller call via the framework has the role to
345
+ # create an ObjectData well formatted, with _return_map function
346
+ # See Definition.connect/create/update/query/get functions (lowercase)
347
+ oObject = @oForjProcess.method(pProc).call(sCloudObj, sUniqId, aParams)
348
+ # return usually is the main object that the process called should provide.
349
+ unless oObject.nil?
350
+ # Save Object if the object has been created by the process, without controller
351
+ @ObjectData.add(oObject)
352
+ end
353
+ end
354
+
355
+ # Function to execute a update process. This function returns a Lorj::Data of type :object.
356
+ #
357
+ # * *Args* :
358
+ # - +ObjectType+ : Meta object type to query.
359
+ # - +Config+ : Optional. Hash containing list of data to use for updating.
360
+ #
361
+ # * *Returns* :
362
+ # Lorj::Data of type :object
363
+ #
364
+ # * *Raises* :
365
+ # - Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.
366
+ # - Error if ObjectType has never been declared.
367
+ # - Error if the dependencies get_e process handler did not return any data. (nil) - Loop detection.
368
+ # - Error if the get_e process handler raise an error.
369
+ #
370
+ def Update(sCloudObj, hConfig = {})
371
+
372
+ return nil if not sCloudObj
373
+
374
+ raise Lorj::PrcError.new(), "$s.Update: '%s' is not a known object type." % [self.class, sCloudObj] if Lorj::rhExist?(@@meta_obj, sCloudObj) != 1
375
+
376
+ if hConfig.length > 0
377
+ # cleanup runtime data to avoid conflicts between multiple calls
378
+ valid_keys = _identify_data(sCloudObj, :update_e)
379
+ valid_keys.each { | sKey|
380
+ value = Lorj::rhGet(hConfig, sKey)
381
+ @oForjConfig[sKey] = value if not @oForjConfig.exist?(sKey) or @oForjConfig.exist?(sKey) == 'runtime'
382
+ Lorj::rhSet(hConfig, nil, sKey)
383
+ }
384
+ if hConfig.length > 0
385
+ PrcLib::warning("'%s' has been passed but not declared to '%s' object. Those are ignored until you add it in the model definition of '%s'" % [hConfig.keys, sCloudObj, sCloudObj])
386
+ end
387
+ end
388
+
389
+ pProc = Lorj::rhGet(@@meta_obj, sCloudObj, :lambdas, :update_e)
390
+
391
+ return nil if pProc.nil?
392
+
393
+ # Check required parameters
394
+ oObjMissing = _check_required(sCloudObj, :update_e, pProc).reverse
395
+
396
+ while oObjMissing.length >0
397
+ sElem = oObjMissing.pop
398
+ raise Lorj::PrcError.new(),"Unable to create Object '%s'" % sElem if not Create(sElem)
399
+ oObjMissing = _check_required(sCloudObj, :update_e, pProc).reverse
400
+ raise Lorj::PrcError.new(), "loop detection: '%s' is required but Update(%s) did not loaded it." % [sElem, sElem] if oObjMissing.include?(sElem)
401
+ end
402
+ @RuntimeContext[:oCurrentObj] = sCloudObj # Context: Default object used.
403
+
404
+ # build Function params to pass to the event handler.
405
+ aParams = _get_object_params(sCloudObj, :update_e, pProc)
406
+
407
+ oObject = @oForjProcess.method(pProc).call(sCloudObj, aParams)
408
+ # return usually is the main object that the process called should provide.
409
+ unless oObject.nil?
410
+ # Save Object if the object has been created by the process, without controller
411
+ @ObjectData.add(oObject)
412
+ end
413
+ end
414
+
415
+ # Function to execute a setup process.
416
+ # The setup process will ask the end user to enter values as defined by the defaults.yaml application defaults.
417
+ # For setup features implemented, see Lorj::BaseDefinition::meta_data class variable definition.
418
+ #
419
+ # Setup by default, will ask any kind of data required by a meta object and all dependencies.
420
+ # If the setup needs to add some extra fields to ask to the user, set it in /:setup/:ask_step/*:add/* section
421
+ #
422
+ # Setup uses a Config model object which requires to have at least following functions:
423
+ # - value = get(key, default)
424
+ # - set(key, value)
425
+ #
426
+ # Setup keep end user data in memory. After setup, you HAVE to save them
427
+ # If you are using Lorj::Account, use function ac_save
428
+ # If you are using Lorj::Config, use function configSave
429
+ #
430
+ # * *Args* :
431
+ # - +ObjectType+ : Meta object type to query.
432
+ # - +Config+ : Optional. Hash containing list of data to use for updating.
433
+ #
434
+ # * *Returns* :
435
+ # Lorj::Data of type :object
436
+ #
437
+ # * *Raises* :
438
+ #
439
+ def Setup(sObjectType, sAccountName)
440
+ # Loop in dependencies to get list of data object to setup
441
+ raise Lorj::PrcError,new(), "Setup: '%s' not a valid object type." if Lorj::rhExist?(@@meta_obj, sObjectType) != 1
442
+
443
+ hAskStep = Lorj::Default.get(:ask_step, :setup)
444
+ aSetup = []
445
+ hAskStep.each{ | value |
446
+ aSetup << {
447
+ :desc => value[:desc],
448
+ :explanation => value[:explanation],
449
+ :pre_step_handler => value[:pre_step_function],
450
+ :order => [[]],
451
+ :post_step_handler => value[:post_step_function]
452
+ }
453
+
454
+ }
455
+ oInspectedObjects = []
456
+ oInspectObj = [sObjectType]
457
+
458
+ @oForjConfig.ac_load(sAccountName) if sAccountName
459
+
460
+ Lorj.debug(2, "Setup is identifying account data to ask for '%s'" % sObjectType)
461
+ while oInspectObj.length() >0
462
+ # Identify data to ask
463
+ # A data to ask is a data needs from an object type
464
+ # which is declared in section of defaults.yaml
465
+ # and is declared :account to true (in defaults.yaml or in process declaration - define_data)
466
+
467
+ sObjectType = oInspectObj.pop
468
+ sAsk_step = 0
469
+ Lorj.debug(1, "Checking '%s'" % sObjectType)
470
+ hTopParams = Lorj::rhGet(@@meta_obj,sObjectType, :params)
471
+ if hTopParams[:keys].nil?
472
+ Lorj.debug(1, "Warning! Object '%s' has no data/object needs. Check the process" % sObjectType)
473
+ next
474
+ end
475
+ hTopParams[:keys].each { |sKeypath, hParams|
476
+ oKeyPath = KeyPath.new(sKeypath)
477
+ sKey = oKeyPath.sKey
478
+ case hParams[:type]
479
+ when :data
480
+ hMeta = _get_meta_data(sKey)
481
+ next if hMeta.nil?
482
+ sAsk_step = hMeta[:ask_step] if Lorj::rhExist?(hMeta, :ask_step) == 1 and hMeta[:ask_step].is_a?(Fixnum)
483
+ Lorj.debug(3, "#{sKey} is part of setup step #{sAsk_step}")
484
+ aOrder = aSetup[sAsk_step][:order]
485
+
486
+ if oInspectedObjects.include?(sKey)
487
+ Lorj.debug(2, "#{sKey} is already asked. Ignored.")
488
+ next
489
+ end
490
+ if hMeta[:account].is_a?(TrueClass)
491
+ if not hMeta[:depends_on].is_a?(Array)
492
+ PrcLib.warning("'%s' depends_on definition have to be an array." % oKeyPath.sFullPath) unless hMeta[:depends_on].nil?
493
+ iLevel = 0
494
+ bFound = true
495
+ else
496
+ # Searching highest level from dependencies.
497
+ bFound = false
498
+ iLevel = 0
499
+ hMeta[:depends_on].each { |depend_key|
500
+ aOrder.each_index { |iCurLevel|
501
+ if aOrder[iCurLevel].include?(depend_key)
502
+ bFound = true
503
+ iLevel = [iLevel, iCurLevel + 1].max
504
+ end
505
+ }
506
+ aOrder[iLevel] = [] if aOrder[iLevel].nil?
507
+ }
508
+ end
509
+ if bFound
510
+ if not aOrder[iLevel].include?(sKey)
511
+ if hMeta[:ask_sort].is_a?(Fixnum)
512
+ iOrder = hMeta[:ask_sort]
513
+ if aOrder[iLevel][iOrder].nil?
514
+ aOrder[iLevel][iOrder] = sKey
515
+ else
516
+ aOrder[iLevel].insert(iOrder, sKey)
517
+ end
518
+ Lorj.debug(3, "S%s/L%s/O%s: '%s' added in setup list. " % [sAsk_step, iLevel, iOrder, sKey])
519
+ else
520
+ aOrder[iLevel] << sKey
521
+ Lorj.debug(3, "S%s/L%s/Last: '%s' added in setup list." % [sAsk_step, iLevel, sKey])
522
+ end
523
+ end
524
+ end
525
+ oInspectedObjects << sKey
526
+ else
527
+ Lorj.debug(2, "#{sKey} used by #{sObjectType} won't be asked during setup. :account = true not set.")
528
+ end
529
+ when :CloudObject
530
+ oInspectObj << sKey if not oInspectObj.include?(sKey) and not oInspectedObjects.include?(sKey)
531
+ end
532
+ }
533
+ oInspectedObjects << sObjectType
534
+ end
535
+ Lorj.debug(2, "Setup check if needs to add unrelated data in the process")
536
+ hAskStep.each_index{ | iStep |
537
+ value = hAskStep[iStep]
538
+ if Lorj::rhExist?(value, :add) == 1
539
+ sKeysToAdd = Lorj::rhGet(value, :add)
540
+ sKeysToAdd.each { | sKeyToAdd |
541
+ bFound = false
542
+ aSetup[iStep][:order].each_index { | iOrder |
543
+ sKeysToAsk = aSetup[iStep][:order][iOrder]
544
+ unless sKeysToAsk.index(sKeyToAdd).nil?
545
+ bFound = true
546
+ break
547
+ end
548
+ }
549
+ next if bFound
550
+ iLevel = 0
551
+ iOrder = aSetup[iStep][:order].length
552
+ iAtStep = iStep
553
+ hMeta = _get_meta_data(sKeyToAdd)
554
+ if Lorj::rhExist?(hMeta, :after) == 1
555
+ sAfterKeys = hMeta[:after]
556
+ sAfterKeys = [ sAfterKeys ] if not sAfterKeys.is_a?(Array)
557
+ sAfterKeys.each{ |sAfterKey |
558
+ bFound = false
559
+ aSetup.each_index { |iStepToCheck|
560
+ aSetup[iStepToCheck][:order].each_index { | iLevelToCheck |
561
+ sKeysToAsk = aSetup[iStepToCheck][:order][iLevelToCheck]
562
+ iOrderToCheck = sKeysToAsk.index(sAfterKey)
563
+ unless iOrderToCheck.nil?
564
+ iAtStep = iStepToCheck if iStepToCheck > iAtStep
565
+ iLevel = iLevelToCheck if iLevelToCheck > iLevel
566
+ iOrder = iOrderToCheck + 1 if iOrderToCheck + 1 > iOrder
567
+ bFound = true
568
+ break
569
+ end
570
+ }
571
+ }
572
+ }
573
+ end
574
+ aSetup[iAtStep][:order][iLevel].insert(iOrder, sKeyToAdd)
575
+ Lorj.debug(3, "S%s/L%s/O%s: '%s' added in setup list at position." % [iAtStep, iLevel, iOrder, sKeyToAdd])
576
+ }
577
+ end
578
+ }
579
+
580
+ Lorj.debug(2, "Setup will ask for :\n %s" % aSetup.to_yaml)
581
+
582
+ PrcLib.info("Configuring account : '#{config[:account_name]}', provider '#{config[:provider_name]}'")
583
+
584
+ # Ask for user input
585
+ aSetup.each_index { | iStep |
586
+ Lorj.debug(2, "Ask step %s:" % iStep)
587
+ puts "%s%s%s" % [ANSI.bold, aSetup[iStep][:desc], ANSI.clear] unless aSetup[iStep][:desc].nil?
588
+ puts "%s\n\n" % ANSI.yellow(aSetup[iStep][:explanation]) unless aSetup[iStep][:explanation].nil?
589
+ aOrder = aSetup[iStep][:order]
590
+ aOrder.each_index { | iIndex |
591
+ Lorj.debug(2, "Ask order %s:" % iIndex)
592
+ aOrder[iIndex].each { | sKey |
593
+ hParam = _get_meta_data(sKey)
594
+ hParam = {} if hParam.nil?
595
+
596
+ bOk = false
597
+
598
+ if hParam[:pre_step_function]
599
+ pProc = hParam[:pre_step_function]
600
+ bOk = not(@oForjProcess.method(pProc).call(sKey))
601
+ end
602
+
603
+
604
+ sDesc = "'%s' value" % sKey
605
+ puts "#{sKey}: %s" % [hParam[:explanation]] unless Lorj::rhGet(hParam, :explanation).nil?
606
+ sDesc = hParam[:desc] unless hParam[:desc].nil?
607
+ sDefault = @oForjConfig.get(sKey, hParam[:default_value])
608
+ rValidate = nil
609
+
610
+ rValidate = hParam[:validate] unless hParam[:validate].nil?
611
+ bRequired = (hParam[:required] == true)
612
+ while not bOk
613
+ bOk = true
614
+ if not hParam[:list_values].nil?
615
+ hValues = hParam[:list_values]
616
+ sObjectToLoad = hValues[:object]
617
+
618
+ bListStrict = (hValues[:validate] == :list_strict)
619
+
620
+ case hValues[:query_type]
621
+ when :controller_call
622
+ oObject = @ObjectData[sObjectToLoad, :ObjectData]
623
+ PrcLib.message("Loading #{sObjectToLoad}.")
624
+ oObject = Create(sObjectToLoad) if oObject.nil?
625
+ return nil if oObject.nil?
626
+ oParams = ObjectData.new
627
+ oParams.add(oObject)
628
+ oParams << hValues[:query_params]
629
+ raise Lorj::PrcError.new(), "#{sKey}: query_type => :controller_call requires missing :query_call declaration (Controller function)" if hValues[:query_call].nil?
630
+ pProc = hValues[:query_call]
631
+ begin
632
+ aList = @oProvider.method(pProc).call(sObjectToLoad, oParams)
633
+ rescue => e
634
+ raise Lorj::PrcError.new(), "Error during call of '%s':\n%s" % [pProc, e.message]
635
+ end
636
+ when :query_call
637
+ sQuery = {}
638
+ sQuery = hValues[:query_params] unless hValues[:query_params].nil?
639
+ PrcLib.message("Querying #{sObjectToLoad}.")
640
+ oObjectList = Query(sObjectToLoad, sQuery)
641
+ aList = []
642
+ oObjectList.each { | oElem |
643
+ aList << oElem[hValues[:value]]
644
+ }
645
+ aList.sort!
646
+ when :process_call
647
+ raise Lorj::PrcError.new(), "#{sKey}: query_type => :process_call requires missing :query_call declaration (Provider function)" if hValues[:query_call].nil?
648
+ pProc = hValues[:query_call]
649
+ sObjectToLoad = hValues[:object]
650
+ oParams = ObjectData.new
651
+ oParams.add(oObject)
652
+ oParams << hValues[:query_params]
653
+ begin
654
+ aList = @oForjProcess.method(pProc).call(sObjectToLoad, oParams)
655
+ rescue => e
656
+ raise Lorj::PrcError.new(), "Error during call of '%s':\n%s" % [pProc, e.message]
657
+ end
658
+ else
659
+ raise Lorj::PrcError.new, "'%s' invalid. %s/list_values/values_type supports %s. " % [hValues[:values_type], sKey, [:provider_function]]
660
+ end
661
+ PrcLib.fatal(1, "%s requires a value from the '%s' query which is empty." % [sKey, sObjectToLoad])if aList.nil? and bListStrict
662
+ aList = [] if aList.nil?
663
+ if not bListStrict
664
+ aList << "other"
665
+ end
666
+ say("Enter %s" % ((sDefault.nil?)? sDesc : sDesc + " |%s|" % sDefault))
667
+ value = choose { | q |
668
+ q.choices(*aList)
669
+ q.default = sDefault if sDefault
670
+ }
671
+ if not bListStrict and value == "other"
672
+ value = _ask(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
673
+ end
674
+ else
675
+ pValidateProc = hParam[:validate_function]
676
+ pAskProc = hParam[:ask_function]
677
+
678
+ if pAskProc.nil?
679
+ unless pValidateProc.nil?
680
+ value = _ask(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
681
+ while not @oForjProcess.method(pValidateProc).call(value)
682
+ value = _ask(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
683
+ end
684
+ else
685
+ value = _ask(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
686
+ end
687
+ else
688
+ unless pValidateProc.nil?
689
+ value = @oForjProcess.method(pAskProc).call(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
690
+ while not @oForjProcess.method(pValidateProc).call(value)
691
+ value = @oForjProcess.method(pAskProc).call(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
692
+ end
693
+ else
694
+ value = @oForjProcess.method(pAskProc).call(sDesc, sDefault, rValidate, hParam[:encrypted], bRequired)
695
+ end
696
+ end
697
+ end
698
+
699
+ @oForjConfig.set(sKey, value)
700
+ if hParam[:post_step_function]
701
+ pProc = hParam[:post_step_function]
702
+ bOk = @oForjProcess.method(pProc).call()
703
+ end
704
+ end
705
+ }
706
+ }
707
+ }
708
+ end
709
+
710
+ # Initialize Lorj BaseDefinition object
711
+
712
+ def initialize(oForjConfig, oForjProcess, oForjProvider = nil)
713
+ # Object Data object. Contains all loaded object data.
714
+ # This object is used to build hParams as well.
715
+ @ObjectData = ObjectData.new(true)
716
+ #
717
+ @RuntimeContext = {
718
+ :oCurrentObj => nil
719
+ }
720
+
721
+ @oForjConfig = oForjConfig
722
+ raise Lorj::PrcError.new(), "'%s' is not a valid ForjAccount or ForjConfig Object." % [oForjConfig.class] if not oForjConfig.is_a?(Lorj::Account) and not oForjConfig.is_a?(Lorj::Config)
723
+
724
+ @oProvider = oForjProvider
725
+ if oForjProvider
726
+ raise Lorj::PrcError.new(), "'%s' is not a valid ForjProvider Object type." % [oForjProvider.class] if not oForjProvider.is_a?(BaseController)
727
+ end
728
+
729
+ @oForjProcess = oForjProcess
730
+ raise Lorj::PrcError.new(), "'%s' is not a valid BaseProcess Object type." % [oForjProcess.class] if not oForjProcess.is_a?(BaseProcess)
731
+
732
+ @oForjProcess.set_BaseObject(self)
733
+ end
734
+
735
+ # ------------------------------------------------------
736
+ # Functions used by processes functions
737
+ # ------------------------------------------------------
738
+ # Ex: object.set_data(...)
739
+ # config
740
+
741
+
742
+ # Function to manipulate the config object.
743
+ # 2 kind of functions:
744
+ # - set (key, value) and []=(key, value)
745
+ # From processes, you can set a runtime data with:
746
+ # config.set(key, value)
747
+ # OR
748
+ # config[key] = value
749
+ #
750
+ # - get (key, default) and [](key, default)
751
+ # default is an optional value.
752
+ # From processes, you can get a data (runtime/account/config.yaml or defaults.yaml) with:
753
+ # config.get(key)
754
+ # OR
755
+ # config[key]
756
+
757
+ def config
758
+ raise Lorj::PrcError.new(), "No config object loaded." if not @oForjConfig
759
+ @oForjConfig
760
+ end
761
+
762
+ def format_query(sObjectType, oControlerObject, hQuery)
763
+ {
764
+ :object => oControlerObject,
765
+ :object_type => :object_list,
766
+ :list_type => sObjectType,
767
+ :list => [],
768
+ :query => hQuery
769
+ }
770
+ end
771
+
772
+ def format_object(sCloudObj, oMiscObject)
773
+ return nil if not sCloudObj or not [String, Symbol].include?(sCloudObj.class)
774
+
775
+ sCloudObj = sCloudObj.to_sym if sCloudObj.class == String
776
+
777
+ oCoreObject = {
778
+ :object_type => sCloudObj,
779
+ :attrs => {},
780
+ :object => oMiscObject,
781
+ }
782
+ end
783
+
784
+ def get_data_metadata(sKey)
785
+ _get_meta_data(sKey)
786
+ end
787
+
788
+ # Before doing a query, mapping fields
789
+ # Transform Object query field to Provider query Fields
790
+ def query_map(sCloudObj, hParams)
791
+ return nil if not sCloudObj or not [String, Symbol].include?(sCloudObj.class)
792
+ return {} if not hParams
793
+
794
+ sCloudObj = sCloudObj.to_sym if sCloudObj.class == String
795
+
796
+ hReturn = {}
797
+ hMap = Lorj::rhGet(@@meta_obj, sCloudObj, :query_mapping)
798
+ hParams.each { |key, value|
799
+ oKeyPath = KeyPath.new(key)
800
+ sKeyPath = oKeyPath.sFullPath
801
+ raise Lorj::PrcError.new(), "Forj query field '%s.%s' not defined by class '%s'.\n" % [sCloudObj, oKeyPath.sKey, self.class ] +
802
+ "#{ANSI.bold}ACTION REQUIRED#{ANSI.clear}:\n" +
803
+ "Missing data model 'def_attribute' or 'def_query_attribute' for '%s'??? Check the object '%s' data model." % [oKeyPath.sKey, sCloudObj] if not hMap.key?(oKeyPath.sFullPath)
804
+ oMapPath = KeyPath.new(hMap[oKeyPath.sFullPath])
805
+ hValueMapping = Lorj::rhGet(@@meta_obj, sCloudObj, :value_mapping, sKeyPath)
806
+ if hValueMapping
807
+ raise Lorj::PrcError.new(), "'%s.%s': No value mapping for '%s'" % [sCloudObj, oKeyPath.sKey, value] if Lorj::rhExist?(hValueMapping, value) != 1
808
+
809
+ Lorj::rhSet(hReturn, hValueMapping[value], oMapPath.aTree)
810
+ else
811
+ Lorj::rhSet(hReturn, value, oMapPath.aTree)
812
+ end
813
+ }
814
+ hReturn
815
+ end
816
+
817
+ # Obsolete. Used by the Process.
818
+ # Ask controller get_attr to get a data
819
+ # The result is the data of a defined data attribute.
820
+ # If the value is normally mapped (value mapped), the value is
821
+ # returned as a recognized data attribute value.
822
+ def get_attr(oObject, key)
823
+
824
+ raise Lorj::PrcError.new(), "'%s' is not a valid Object type. " % [oObject.class] if not oObject.is_a?(Hash) and Lorj::rhExist?(oObject, :object_type) != 1
825
+ sCloudObj = oObject[:object_type]
826
+ oKeyPath = KeyPath.new(key)
827
+ raise Lorj::PrcError.new(), "'%s' key is not declared as data of '%s' CloudObject. You may need to add obj_needs..." % [oKeyPath.sKey, sCloudObj] if Lorj::rhExist?(@@meta_obj, sCloudObj, :returns, oKeyPath.sFullPath) != 3
828
+ begin
829
+ oMapPath = KeyPath.new Lorj::rhGet(@@meta_obj, sCloudObj, :returns, oKeyPath.sFullPath)
830
+ hMap = oMapPath.sFullPath
831
+ value = @oProvider.get_attr(get_cObject(oObject), hMap)
832
+
833
+ hValueMapping = Lorj::rhGet(@@meta_obj, sCloudObj, :value_mapping, oKeyPath.sFullPath)
834
+
835
+ if hValueMapping
836
+ hValueMapping.each { | found_key, found_value |
837
+ if found_value == value
838
+ value = found_key
839
+ break
840
+ end
841
+ }
842
+ end
843
+ rescue => e
844
+ raise Lorj::PrcError.new(), "'%s.get_attr' fails to provide value of '%s'" % [oProvider.class, key]
845
+ end
846
+ end
847
+
848
+ # Register the object to the internal @ObjectData instance
849
+ def register(oObject, sObjectType = nil, sDataType = :object)
850
+ if oObject.is_a?(Lorj::Data)
851
+ oDataObject = oObject
852
+ else
853
+ raise Lorj::PrcError.new(), "Unable to register an object '%s' as Lorj::Data object if ObjectType is not given." % [ oObject.class ] if not sObjectType
854
+ oDataObject = Lorj::Data.new(sDataType)
855
+ oDataObject.set(oObject, sObjectType) { | sObjType, oControlerObject |
856
+ _return_map(sObjType, oControlerObject)
857
+ }
858
+ end
859
+ @ObjectData.add oDataObject
860
+ end
861
+
862
+ def DataObjects(sObjectType, *key)
863
+ @ObjectData[sObjectType, key]
864
+ end
865
+
866
+ # get an attribute/object/... from an object.
867
+ def get_data(oObj, *key)
868
+ if oObj.is_a?(Hash) and oObj.key?(:object_type)
869
+ oObjData = ObjectData.new
870
+ oObjData << oObj
871
+ else
872
+ oObjData = @ObjectData
873
+ end
874
+ oObjData[oObj, *key]
875
+ end
876
+
877
+ #~ def hParams(sCloudObj, hParams)
878
+ #~ aParams = _get_object_params(sCloudObj, ":ObjectData.hParams")
879
+ #~ end
880
+
881
+ def get_cObject(oObject)
882
+ return nil if Lorj::rhExist?(oObject, :object) != 1
883
+ Lorj::rhGet(oObject, :object)
884
+ end
885
+
886
+ # a Process can execute any kind of predefined controler task.
887
+ # Those function build hParams with Provider compliant data (mapped)
888
+ # Results are formatted as usual framework Data object and stored.
889
+ def connect(sObjectType)
890
+
891
+ hParams = _get_object_params(sObjectType, :create_e, :connect, true)
892
+ oControlerObject = @oProvider.connect(sObjectType, hParams)
893
+ oDataObject = Lorj::Data.new
894
+ oDataObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
895
+ begin
896
+ _return_map(sObjType, oObject)
897
+ rescue => e
898
+ raise Lorj::PrcError.new(), "connect %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
899
+ end
900
+ }
901
+ @ObjectData.add oDataObject
902
+ oDataObject
903
+ end
904
+
905
+ def create(sObjectType)
906
+ # The process ask the controller to create the object.
907
+ # hParams have to be fully readable by the controller.
908
+ hParams = _get_object_params(sObjectType, :create_e, :create, true)
909
+ oControlerObject = @oProvider.create(sObjectType, hParams)
910
+ oDataObject = Lorj::Data.new
911
+ oDataObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
912
+ begin
913
+ _return_map(sObjType, oObject)
914
+ rescue => e
915
+ raise Lorj::PrcError.new(), "create %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
916
+ end
917
+ }
918
+ @ObjectData.add oDataObject
919
+
920
+ oDataObject
921
+ end
922
+
923
+ # The controller must return true to inform about the real deletion
924
+ def delete(sObjectType)
925
+ hParams = _get_object_params(sObjectType, :delete_e, :delete, true)
926
+ raise Lorj::PrcError.new(), "delete Controller - %s: Object '%s' is not loaded." % [@oProvider.class, key] if not hParams.exist?(sObjectType)
927
+ bState = @oProvider.delete(sObjectType, hParams)
928
+ @ObjectData.delete(sObjectType) if bState
929
+ bState
930
+ end
931
+
932
+ def get(sObjectType, sUniqId)
933
+
934
+ hParams = _get_object_params(sObjectType, :get_e, :get, true)
935
+
936
+ oControlerObject = @oProvider.get(sObjectType, sUniqId, hParams)
937
+ oDataObject = Lorj::Data.new
938
+ oDataObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
939
+ begin
940
+ _return_map(sObjType, oObject)
941
+ rescue => e
942
+ raise Lorj::PrcError.new(), "get %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
943
+ end
944
+ }
945
+ @ObjectData.add oDataObject
946
+
947
+ oDataObject
948
+ end
949
+
950
+ def query(sObjectType, hQuery)
951
+
952
+ # Check if we can re-use a previous query
953
+ oList = @ObjectData[:query, sObjectType]
954
+ unless oList.nil?
955
+ if oList[:query] == hQuery
956
+ Lorj.debug(3, "Using Object '%s' query cache : %s" % [sObjectType, hQuery])
957
+ return oList
958
+ end
959
+ end
960
+
961
+
962
+ hParams = _get_object_params(sObjectType, :query_e, :query, true)
963
+ sProviderQuery = query_map(sObjectType, hQuery)
964
+
965
+ oControlerObject = @oProvider.query(sObjectType, sProviderQuery, hParams)
966
+
967
+ oDataObjects = Lorj::Data.new :list
968
+ oDataObjects.set(oControlerObject, sObjectType, hQuery) { | sObjType, key |
969
+ begin
970
+ _return_map(sObjType, key)
971
+ rescue => e
972
+ raise Lorj::PrcError.new(), "query %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
973
+ end
974
+ }
975
+
976
+ Lorj.debug(2, "Object %s - queried. Found %s object(s)." % [sObjectType, oDataObjects.length()])
977
+
978
+ @ObjectData.add oDataObjects
979
+ oDataObjects
980
+ end
981
+
982
+ def update(sObjectType)
983
+ # Need to detect data updated and update the Controler object with the controler
984
+
985
+ hParams = _get_object_params(sObjectType, :update_e, :update, true)
986
+
987
+ oObject = @ObjectData[sObjectType, :ObjectData]
988
+ oControlerObject = oObject[:object]
989
+
990
+ bUpdated = false
991
+ oObject[:attrs].each { |key, value |
992
+ oKeyPath = KeyPath.new(key)
993
+ oMapPath = KeyPath.new Lorj::rhGet(@@meta_obj, sObjectType, :returns, oKeyPath.sFullPath)
994
+ old_value = @oProvider.get_attr(oControlerObject, oMapPath.aTree)
995
+ if value != old_value
996
+ bUpdated = true
997
+ @oProvider.set_attr(oControlerObject, oMapPath.aTree, value)
998
+ Lorj.debug(2, "%s.%s - Updating: %s = %s (old : %s)" % [@oForjProcess.class, sObjectType, key, value, old_value])
999
+ end
1000
+ }
1001
+
1002
+ bDone = @oProvider.update(sObjectType, oObject, hParams) if bUpdated
1003
+
1004
+ raise Lorj::PrcError.new, "Controller function 'update' must return True or False. Class returned: '%s'" % bDone.class if not [TrueClass, FalseClass].include?(bDone.class)
1005
+
1006
+ Lorj.debug(1, "%s.%s - updated." % [@oForjProcess.class, sObjectType]) if bDone
1007
+ oObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
1008
+ begin
1009
+ _return_map(sObjType, oObject)
1010
+ rescue => e
1011
+ raise Lorj::PrcError.new(), "update %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
1012
+ end
1013
+ }
1014
+ bDone
1015
+ end
1016
+
1017
+
1018
+ private
1019
+
1020
+ # -------------------------------------------------------------------------
1021
+ # Functions available for Process to communicate with the controler Object
1022
+ # -------------------------------------------------------------------------
1023
+ def cloud_obj_requires(sCloudObj, res = {})
1024
+ aCaller = caller
1025
+ aCaller.pop
1026
+
1027
+ return res if @ObjectData.exist?(sCloudObj)
1028
+ #~ return res if Lorj::rhExist?(@CloudData, sCloudObj) == 1
1029
+
1030
+ Lorj::rhGet(@@meta_obj,sCloudObj, :params).each { |key, hParams|
1031
+ case hParams[:type]
1032
+ when :data
1033
+ if hParams.key?(:array)
1034
+ hParams[:array].each{ | aElem |
1035
+ aElem = aElem.clone
1036
+ aElem.pop # Do not go until last level, as used to loop next.
1037
+ Lorj::rhGet(hParams, aElem).each { | subkey, hSubParam |
1038
+ next if aElem.length == 0 and [:array, :type].include?(subkey)
1039
+ if hSubParams[:required] and @oForjConfig.get(subkey).nil?
1040
+ res[subkey] = hSubParams
1041
+ end
1042
+ }
1043
+ }
1044
+ else
1045
+ if hParams[:required] and @oForjConfig.get(key).nil?
1046
+ res[key] = hParams
1047
+ end
1048
+ end
1049
+ when :CloudObject
1050
+ #~ if hParams[:required] and Lorj::rhExist?(@CloudData, sCloudObj) != 1
1051
+ if hParams[:required] and not @ObjectData.exist?(sCloudObj)
1052
+ res[key] = hParams
1053
+ cloud_obj_requires(key, res)
1054
+ end
1055
+ end
1056
+ }
1057
+ res
1058
+ end
1059
+
1060
+ def get_object(sCloudObj)
1061
+ #~ return nil if Lorj::rhExist?(@CloudData, sCloudObj) != 1
1062
+ return nil if not @ObjectData.exist?(sCloudObj)
1063
+ @ObjectData[sCloudObj, :ObjectData]
1064
+ #~ Lorj::rhGet(@CloudData, sCloudObj)
1065
+ end
1066
+
1067
+ def objectExist?(sCloudObj)
1068
+ @ObjectData.exist?(sCloudObj)
1069
+ #~ (Lorj::rhExist?(@CloudData, sCloudObj) != 1)
1070
+ end
1071
+
1072
+ def get_forjKey(oCloudData, key)
1073
+ return nil if not @ObjectData.exist?(sCloudObj)
1074
+ @ObjectData[sCloudObj, :attrs, key]
1075
+ #~ return nil if Lorj::rhExist?(oCloudData, sCloudObj) != 1
1076
+ #~ Lorj::rhGet(oCloudData, sCloudObj, :attrs, key)
1077
+ end
1078
+ end
1079
+ end