lorj 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +39 -579
  4. data/Rakefile +7 -0
  5. data/example/students_1/student_v1.md +115 -0
  6. data/example/students_1/students.rb +8 -2
  7. data/example/students_2/process/students.rb +5 -5
  8. data/example/students_2/student_v2.md +90 -0
  9. data/example/students_2/students.rb +6 -6
  10. data/example/students_3/controller/yaml_students.rb +23 -73
  11. data/example/students_3/controller/yaml_students_code.rb +106 -0
  12. data/example/students_3/controller/yaml_students_def.rb +69 -0
  13. data/example/students_3/process/students.rb +23 -157
  14. data/example/students_3/student_v3.md +283 -0
  15. data/example/students_3/students.rb +26 -83
  16. data/example/students_4/controller/yaml_students.rb +51 -0
  17. data/example/students_4/controller/yaml_students_code.rb +109 -0
  18. data/example/students_4/controller/yaml_students_def.rb +72 -0
  19. data/example/students_4/process/students/code/students.rb +103 -0
  20. data/example/students_4/process/students/definition/students.rb +60 -0
  21. data/example/students_4/process/students.rb +29 -0
  22. data/example/students_4/student_v4.md +191 -0
  23. data/example/students_4/students.rb +65 -0
  24. data/example/students_5/controller/yaml_students.rb +106 -0
  25. data/example/{students_3 → students_5}/controller/yaml_students_controller.rb +5 -3
  26. data/example/students_5/process/students.rb +182 -0
  27. data/example/students_5/student_v5.md +382 -0
  28. data/example/students_5/students.rb +119 -0
  29. data/example/yaml_students/students.rb +1 -1
  30. data/example/yaml_students/yaml_students.rb +102 -23
  31. data/lib/concept.md +3 -3
  32. data/lib/core/core.rb +15 -15
  33. data/lib/core/core_controller.rb +49 -24
  34. data/lib/core/core_internal.rb +2 -2
  35. data/lib/core/core_model.rb +13 -7
  36. data/lib/core/core_object_data.rb +18 -18
  37. data/lib/core/core_object_params.rb +75 -34
  38. data/lib/core/core_process.rb +104 -59
  39. data/lib/core/core_process_setup.rb +11 -11
  40. data/lib/core/core_setup_ask.rb +24 -14
  41. data/lib/core/core_setup_encrypt.rb +17 -15
  42. data/lib/core/core_setup_init.rb +19 -15
  43. data/lib/core/core_setup_list.rb +12 -12
  44. data/lib/core/definition.rb +20 -20
  45. data/lib/core/definition_internal.rb +20 -10
  46. data/lib/core/lorj_basecontroller.rb +8 -8
  47. data/lib/core/lorj_basedefinition.rb +47 -126
  48. data/lib/core/lorj_baseprocess.rb +81 -57
  49. data/lib/core/lorj_data.rb +28 -27
  50. data/lib/core/lorj_keypath.rb +1 -1
  51. data/lib/core_process/cloud/process/flavor.rb +3 -2
  52. data/lib/core_process/cloud/process/keypairs.rb +5 -4
  53. data/lib/core_process/cloud/process/network.rb +4 -3
  54. data/lib/core_process/cloud/process/public_ip.rb +3 -2
  55. data/lib/core_process/cloud/process/rules.rb +7 -6
  56. data/lib/core_process/cloud/process/security_groups.rb +1 -1
  57. data/lib/core_process/cloud/process/server.rb +1 -1
  58. data/lib/core_process/cloud/process/server_log.rb +1 -1
  59. data/lib/core_process/cloud/process/subnetwork.rb +4 -1
  60. data/lib/core_process/cloud_process.rb +1 -1
  61. data/lib/logging.rb +41 -48
  62. data/lib/lorj/version.rb +1 -1
  63. data/lib/lorj.rb +7 -0
  64. data/lib/lorj_account.rb +3 -3
  65. data/lib/lorj_config.rb +1 -1
  66. data/lib/lorj_defaults.rb +222 -26
  67. data/lib/overview.md +120 -0
  68. data/lib/prc.rb +97 -24
  69. data/lib/prc_core_config.rb +134 -52
  70. data/lib/providers/hpcloud/compute.rb +3 -3
  71. data/lib/providers/hpcloud/hpcloud.rb +14 -14
  72. data/lib/providers/hpcloud/network.rb +4 -4
  73. data/lib/providers/hpcloud/security_groups.rb +1 -1
  74. data/lib/providers/mock/mock.rb +3 -3
  75. data/lib/providers/openstack/openstack.rb +12 -12
  76. data/lib/providers/templates/compute.rb +6 -6
  77. data/lib/rh.rb +7 -5
  78. data/spec/04_prc_core_config_spec.rb +52 -0
  79. data/spec/11_lorj_config_spec.rb +1 -1
  80. metadata +21 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68cdd89f8867872019b885eaeca7358bf1108c61
4
- data.tar.gz: 44eac4c611e38053086be179682cef327f8d8341
3
+ metadata.gz: 186c6ba434808e7cc8e6d5ac0e7e703118698cbd
4
+ data.tar.gz: f53774dadcf6ed48fdcee6f3519d13461109bbf6
5
5
  SHA512:
6
- metadata.gz: c3fd2b28bfbf55a97b05bbb6626821f2668afead59e991fa05fb5d128111071f15c3814f39dec2b163862550629c9f6188f57784d679e3c213d2d5ecb9985bd8
7
- data.tar.gz: e6c9f1f3b9d3869f820c502774944a878a6d8da999239362cd1c502d395a28835b5ac5cdf4a8a9c00840fd980b4a8ed2933d441044efece20668aab81136f1ea
6
+ metadata.gz: 60b75966452c090d07aec57ff3bdf67e5100ce575be45fe038ffe256c863c8415edfad2ce23343af60ac52b93fa67818b1cac2e653be2de2844e3b34b0ad2e1d
7
+ data.tar.gz: 8e1b1c7ade0845986befba7a2bb0a34a34b519b0a5d7922fe9b3195692b205438770c2f7d261a2a4ae28ce3fb578905cfe96b0af9a7ebc67e7d8edd252287f4f
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  /_yardoc/
4
4
  /coverage/
5
5
  /doc/
6
+ /html/
6
7
  /pkg/
7
8
  /spec/reports/
8
9
  /tmp/
data/README.md CHANGED
@@ -13,16 +13,25 @@ This framework helps to design any kind of solution which needs to maintain a ge
13
13
  This case was implemented by forj cli to implement services on any kind of cloud solution.
14
14
 
15
15
  forj cli needs to build a forge (collection of servers) on a cloud.
16
- It requires to ensure that everything is in place (network properly configured if not create it, router exists, flavors available, etc.) to create the first server.
16
+ It requires to ensure that everything is in place (network properly configured
17
+ if not create it, router exists, flavors available, etc.) to create the first server.
17
18
 
18
- For **Lorj**, how to create the forge and ensure that everything is in place is the **process**.<br>
19
- And then how to manipulate the cloud (get the network, create the network, create the server, etc...) is the **controller**. <br>
19
+ For **Lorj**, how to create the forge and ensure that everything is in place is
20
+ the **GENERIC process**.<br>
21
+ And then how to manipulate the cloud (get the network, create the network,
22
+ create the server, etc...) is the **controller**. <br>
20
23
  Usually, the controller is a wrapper to an API, which do actions, like 'create server'.
24
+ But depending on what you defined in your GENERIC process, a controller can define
25
+ a controller process, which will deal with the complexity of the controller to execute the
26
+ GENERIC process task requested.
21
27
 
22
- Then, at runtime, while changing the controller to aws, hpcloud, openstack, or even docker or decker, forj cli process will be still the same.
23
- It simplifies forj cli extension, by just adding new controller to support more clouds providers.
28
+ Then, at runtime, while changing the controller to aws, hpcloud, openstack, or
29
+ even docker or decker, forj cli GENERIC process will be still the same.
30
+ It simplifies forj cli extension, by just adding new controller to support more
31
+ clouds providers.
24
32
 
25
- Currently, forj cli has implemented *hpcloud* and *openstack* providers, using *fog*. Docker controller is under development.
33
+ Currently, forj cli has implemented *hpcloud* and *openstack* providers, using
34
+ *fog*. Docker controller is under development.
26
35
 
27
36
  ## Getting started
28
37
 
@@ -54,595 +63,46 @@ We have written a small class to illustrate this API. (See examples/yaml_student
54
63
 
55
64
  This api has everything to create, query, edit and delete a student in a yaml file.
56
65
 
57
- Using Lorj, you want to propose multiple storage system (not only using the yaml format) to your application, by supporting several storage systems, like mysql DB.
66
+ Using Lorj, you want to propose multiple storage system (not only using the yaml
67
+ format) to your application, by supporting several storage systems, like mysql DB.
58
68
 
59
69
  next, we will write 3 versions, which will introduce how to deal with process and controllers:
60
70
 
61
71
  * version 1:
62
- Writing your first 'do nothing' process, with no controller.
72
+ Writing your first 'do nothing' process, with no controller.
63
73
 
64
- * version 2:
65
- Complete the process to have create/query/get and delete capability, with mock controller.
66
- The mock controller is basically a controller keeping data in memory.
67
-
68
- * version 3:
69
- Update the version 2 to fully implement the example of an yaml_student API.
70
-
71
- The main is `examples/yaml_students/students.rb`<BR>
72
- The API is `examples/yaml_students/yaml_students.rb`
73
-
74
- We have created a full example version 4 which implements some interesting way to improve your code available in `examples/students_4/`
75
-
76
- ---
77
- #### Writing student version 1
78
-
79
- **NOTE**: following example is available in `examples/students_1/`
80
-
81
- First of all, write your first main. Create a file `example.rb` with following content:
82
-
83
- ##### File `students.rb`
84
-
85
- ``` ruby
86
- #!/usr/bin/env ruby
87
-
88
- $APP_PATH = File.dirname(__FILE__)
89
- require 'lorj'
90
-
91
- # If you want to see what is happening in the framework, uncomment debug settings.
92
- # PrcLib.level = Logger::DEBUG # Printed out to your console.
93
- # PrcLib.core_level = 3 # framework debug levels.
94
-
95
- # Initialize the framework
96
- hProcesses = [ File.join($APP_PATH, 'process', 'students.rb')]
97
- oStudentCore = Lorj::Core.new( nil, hProcesses)
98
-
99
- # Ask the framework to create the object student 'Robert Redford'
100
- oStudentCore.Create(:student, {:student_name => "Robert Redford"})
101
- ```
102
-
103
- ##### File `process/Students.rb`
104
-
105
- Now, let's write our first process. We are going to create a file Students.rb under a sub-directory 'process'.
106
-
107
- ``` ruby
108
- # Students process
109
- class StudentsProcess
110
- def create_student(sObjectType, hParams)
111
- puts "Running creation process for object '%s' = '%s'" % [sObjectType, hParams[:student_name] ]
112
-
113
- # If you prefer to print out to the log system instead:
114
- # PrcLib::debug("Running creation process for object '%s' = '%s'" % [sObjectType, hParams[:student_name] ])
115
- end
116
- end
117
-
118
- # Declaring your data model and handlers.
119
- class Lorj::BaseDefinition
120
-
121
- # We need to define the student object and the handler to use while we need to create it.
122
- define_obj(:student,
123
- {
124
- :create_e => :create_student # The function to call in the class Students
125
- })
126
-
127
- obj_needs :data, :student_name, { :for => [:create_e] }
128
-
129
- end
130
- ```
131
-
132
- What did we wrote?
133
-
134
- * We defined a *StudentsProcess* class
135
-
136
- This is the core of your process. It describes how to handle the object requested. The data to use is available in `hParams`.
137
-
138
- **IMPORTANT !!** There is no reference to any files or Database connection.
139
-
140
- **NOTE**: The framework requires you to define a class name composed by the name of the process and 'Process'.
141
- Here, it is 'Students' + **'Process'**
142
-
143
-
144
- * We declared the data model and the process handlers with declaration in *Lorj::BaseDefinition* class.
145
-
146
- In short, we declared `:student` object, which needs `:student_name` at creation step.
147
-
148
- **NOTE** Implicitly, the framework consider that the object contains at least 2 data fields, :id (should be unique) and :name (string)
149
-
150
-
151
- Currently, this model do nothing except printing out.
152
-
153
- #####typical output
154
-
155
- $ example/students_1/students.rb
156
- WARNING: PrcLib.app_defaults is not set. Application defaults won't be loaded.
157
- Running creation process for object 'student' = 'Robert Redford'
158
- WARNING: 'create_student' has returned no data for object Lorj::Data 'student'!
159
-
160
- There is 2 warnings.
161
-
162
- * **PrcLib.app_defaults** represents the application name. It is used to keep your application configuration data in ~/.{PrcLib.app_defaults}/ directory. Defining this data in your main, will eliminate this warning.
163
- * **create_student** function in your process has returned nothing. while lorj is called to create an object, it assumes to get the object data created. Lorj keep those data in a cache. In this example, **create_student** returned nil, and lorj raise a warning about that.
164
-
165
- ---
166
- #### Writing student version 2
167
-
168
- **NOTE**: following example is available in `examples/students_2/`
169
-
170
- lorj comes with a `:mock` controller. This one is really basic. It keep data in an Hash in MockController class.<br>
171
- In this example, we add create/get/query/delete capability in the process and use the `:mock` controller to store the data.
172
-
173
- ##### File `process/Students.rb`
174
-
175
- Add 3 handlers query_e, get_e and delete_e like this. Add the :mapping case as well.
176
-
177
- ``` ruby
178
- class Lorj::BaseDefinition
179
- define_obj(:student,
180
- {
181
- :create_e => :create_student, # The function to call in the class Students
182
- :query_e => :controller_query, # We use predefined call to the controller query
183
- :get_e => :controller_get, # We use predefined call to the controller get
184
- :delete_e => :controller_delete # We use predefined call to the controller delete
185
- })
186
-
187
- # Note about mapping. This is usually done by the controller. We will see this later.
188
- obj_needs :data, :student_name, { :for => [:create_e], :mapping => :name }
189
-
190
- end
191
- ```
192
-
193
- Update the handler `create_student`:
194
-
195
- ``` ruby
196
- def create_student(sObjectType, hParams)
197
- PrcLib::state ("Running creation process for object '%s' = '%s'" % [sObjectType, hParams[:student_name] ])
74
+ [Details is explained here](example/students_1/student_v1_md.html)
198
75
 
199
- oObject = controler.create(sObjectType)
200
- raise "Student '%s' not created." % hParams[:student_name] if oObject.nil?
201
- PrcLib::info ("'%s': '%s' created with id %s" % [sObjectType, hParams[:student_name], oObject[:id]])
202
- oObject
203
- end
204
- ```
205
-
206
-
207
-
208
- ##### File `students.rb`
209
- The update your main and add those lines. In the following, we create 3 students, while 2 are duplicated.
210
-
211
- ``` ruby
212
-
213
- # Want to create a duplicated student 'Robert Redford'?
214
- oStudentCore.Create(:student)
215
- # no problem. The key is the key in the Mock controller array.
216
-
217
- oStudentCore.Create(:student, :student_name => "Anthony Hopkins")
218
-
219
- # Let's create a third different student.
220
- oStudents = oStudentCore.Query(:student, { :name => "Robert Redford" } )
221
-
222
- puts "%s students found" % oStudents.length
223
-
224
- oStudents.each { | oStudent |
225
- puts "%s: %s" % [oStudent[:id], oStudent[:name]]
226
- }
227
-
228
- # let's check the get function, who is the ID 2?
229
- oStudent = oStudentCore.Get(:student, 2)
230
-
231
- puts "The student ID 2 is %s" % oStudent[:name]
232
-
233
- ```
234
-
235
- #####typical output:
236
-
237
- $ example/students_2/students.rb
238
- WARNING: PrcLib.app_defaults is not set. Application defaults won't be loaded.
239
- 2 students found
240
- 0: Robert Redford
241
- 1: Robert Redford
242
- The student ID 2 is Anthony Hopkins
243
-
244
-
245
- Cool! But everything is in memory! We would like to write this in a file.
246
- Writing our controller, means that the process should not be updated anymore!
247
-
248
- Let's move to the most interesting version. Translate an API example to use lorj!
249
-
250
- #### Writing student version 3
251
-
252
- **NOTE**: following example is available in `examples/students_3/`
253
-
254
- A controller is like a wrapper to an API which offer what we would like to use to save our yaml file.<br>
255
- We already have a running API that we can use to manage students in yaml format.
256
-
257
- This API is written in `examples/yaml_students/yaml_students.rb`. <br>
258
- `examples/yaml_students/students.rb` is the main program calling the api and create a basic yaml file example in `/tmp/students.yaml`
259
-
260
- You can review the main 'students.rb' to see the simple code.
261
-
262
- In short, this code do:
263
-
264
- * create 3 students, only if they do not exists
265
- * remove a wrong one
266
- * Identify list of students on a specific training
267
- * Identify students removed.
268
-
269
- We will do the same thing with lorj.
270
-
271
- Using lorj means you are going to split your code in different pieces. You will need to integrate a layer between your main and the API. This layer is composed by :
272
-
273
- * 1 generic data model
274
- * 1 generic process handlers
275
- * 1 controller definition - expanding the data model for our Student yaml API
276
- * 1 controller code - wrapper to the student yaml API.
277
-
278
- So, we are going to update following files:
279
-
280
- * students.rb - Adapt the main to do the same as original students script using the student yaml API.
281
- * process/students.rb - Student data model - Update the process data model.
282
- * process/students.rb - Student process handler - Update student process handlers.
283
- * controller/yaml_students.rb - controller definition - Extend the student data model with controller definition.
284
- * controller/yaml_students_controller.rb - controller code - Write the student yaml API wrapper.
285
-
286
- First of all, let me re-visit the :student data model, then the student process handlers.
287
-
288
- We need to define more parameters for handlers, and define the data model.
289
-
290
- ##### File `process/students.rb`
291
- Update the class Lorj::BaseDefinition, and the data model and handlers parameters.
292
-
293
- *The generic data model:*
294
-
295
- ``` ruby
296
- class Lorj::BaseDefinition
297
- define_obj(:student,
298
- {
299
- :create_e => :create_student, # The function to call in the class Students
300
- :query_e => :controller_query, # We use predefined call to the controller query
301
- :delete_e => :controller_delete # We use predefined call to the controller delete
302
- })
303
-
304
- # obj_needs is used to declare parameters to pass to handlers.
305
- # :for indicates those parameters to be passed to create_e handler only.
306
- # Those data (or objects) will be collected and passed to the process handler as hParams.
307
-
308
- obj_needs :data, :student_name, { :for => [:create_e] }
309
-
310
- # By default, all data are required.
311
- # You can set it as optional. Your process will need to deal with this optional data.
312
- obj_needs_optional
313
- obj_needs :data, :first_name, { :for => [:create_e] }
314
- obj_needs :data, :last_name, { :for => [:create_e] }
315
- obj_needs :data, :course # Note that in this model, the training is renamed as course.
316
- # the controller will need to map it to 'training'.
317
-
318
- # def_attribute defines the data model.
319
- # The process will be able to access those data
320
- # if the controller has mapped them.
321
- # For the exercice, I have changed the name of the training field to become :course instead.
322
- def_attribute :course
323
- # Same thing for the student name. instead of 'name', we defined :student_name
324
- def_attribute :student_name
325
- def_attribute :first_name
326
- def_attribute :last_name
327
- def_attribute :status
328
-
329
- undefine_attribute :name
330
- end
331
- ```
332
-
333
- Then, update the process to manage student duplicates. Update function `create_student`
334
-
335
- *The generic process handlers:*
336
-
337
- ``` ruby
338
- class StudentsProcess
339
- def create_student(sObjectType, hParams)
340
- PrcLib::state ("Running creation process for object '%s' = '%s'" % [sObjectType, hParams[:student_name] ])
341
-
342
- # config object is a reference to runtime/config data.
343
- oList = Query(sObjectType, {:name => hParams[:student_name]})
344
- case oList.length
345
- when 0
346
- oObject = controller_create(sObjectType)
347
- raise "Student '%s' not created." % hParams[:student_name] if oObject.nil?
348
- PrcLib::info ("'%s': '%s' created with id %s" % [sObjectType, hParams[:student_name], oObject[:id]])
349
- when 1
350
- oObject = oList[0]
351
- PrcLib::info ("'%s': '%s' loaded with id %s" % [sObjectType, hParams[:student_name], oObject[:id]])
352
- else
353
- oObject = oList[0]
354
- PrcLib::warning("More than one student named '%s' is found: %s records. Selecting the first one and removing duplicates." % [hParams[:student_name], oList.length])
355
- iCount = 0
356
- oList[1..-1].each { | elem |
357
- register(elem)
358
- iCount += controller_delete(sObjectType)
359
- }
360
- PrcLib::info ("'%s': %s duplicated '%s' removed. First loaded with id %s" % [sObjectType, iCount, hParams[:student_name], oObject[:id]])
361
- end
362
- oObject
363
- end
364
- end
365
- ```
366
-
367
- Here you see that we query, check list, create if missing, or delete if duplicates found.
368
- You can run it now, as we still uses mock controller. It should work.
369
-
370
- ##### File `students.rb`
371
-
372
- Now, let's update the main to be close to what we have on `examples/yaml_students/students.rb`
373
-
374
- This is a simple basic translation of `examples/yaml_students/students.rb`
375
-
376
- ``` ruby
377
- #!/usr/bin/env ruby
378
-
379
- $APP_PATH = File.dirname(__FILE__)
380
- require 'lorj'
381
- require 'ansi'
382
-
383
- # If you want to see what is happening in the framework, uncomment debug settings.
384
- # PrcLib.level = Logger::DEBUG # Printed out to your console.
385
- # PrcLib.core_level = 3 # framework debug levels. Values between 0 to 5.
386
-
387
- # Initialize the framework
388
- hProcesses = [ File.join($APP_PATH, 'process', 'students.rb')]
389
-
390
- # You can try with mock instead. uncomment the next line and comment 2 next lines.
391
- #~ oStudentCore = Lorj::Core.new( nil, hProcesses, :mock)
392
- oStudentCore = Lorj::Core.new( nil, hProcesses, File.join($APP_PATH, 'controller', 'yaml_students.rb'))
393
- oStudentCore.Create(:connection, :connection_string => "/tmp/students.yaml")
394
-
395
- puts ANSI.bold("Create 1st student:")
396
-
397
- oStudentCore.Create(:student, {
398
- student_name: 'Robert Redford',
399
- first_name: 'Robert',
400
- last_name: 'Redford',
401
- course: 'Art Comedy'
402
- })
403
-
404
- puts ANSI.bold("Create 2nd student:")
405
- oStudentCore.Create(:student, {
406
- student_name: 'Anthony Hopkins',
407
- first_name: 'Anthony',
408
- last_name: 'Hopkins',
409
- course: 'Art Drama'
410
- })
411
-
412
- puts ANSI.bold("Create 3rd student:")
413
- oStudentCore.Create(:student, {
414
- student_name: "Marilyn Monroe",
415
- first_name: 'Marilyn',
416
- last_name: 'Monroe',
417
- course: 'Art Drama'
418
- })
419
-
420
- puts ANSI.bold("Create mistake")
421
- oStudentCore.Create(:student, {
422
- :student_name => "Anthony Mistake",
423
- :first_name => 'Anthony',
424
- :last_name => 'Mistake',
425
- :course => 'what ever you want!!!'
426
- })
427
-
428
- # Because the last student was the mistake one, we can directly delete it.
429
- # Usually, we use get instead.
430
- puts ANSI.bold("Remove mistake")
431
- oStudentCore.Delete(:student)
432
-
433
- puts ANSI.bold("List of students for 'Art Drama':")
434
- puts oStudentCore.Query(:student, { :course => "Art Drama"}).to_a
435
-
436
- puts ANSI.bold("Deleted students:")
437
- puts oStudentCore.Query(:student,{ :status => :removed}).to_a
438
- ```
76
+ * version 2:
77
+ Complete the process to have create/query/get and delete capability, with mock controller.
78
+ The mock controller is basically a controller keeping data in memory.
439
79
 
440
- We have reproduced the code. Note that there is no if while creating. It is embedded in the create_student process.
441
-
442
- ##### File `controller/yaml_students_controller.rb`
443
-
444
- We need to write the controller part, now. As I said, it is like a wrapper. Let's have a look:
445
-
446
- *The controller code:*
447
-
448
- ``` ruby
449
- # declare yaml student API to the controller
450
- cur_file = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), "..", "yaml_students", 'yaml_students.rb'))
451
- require cur_file
452
-
453
- # The controller is a combination of 2 elements:
454
- # - Controller class
455
- # Code which will interfere with the external API.
456
- #
457
- # The file name must respect the name of the class. 1st letter already capitalized and letter after _ is capitalized.
458
- # file: my_code.rb => needs to create MyCodeController class
459
- #
460
- # - Definition class
461
- # This class declare any kind of mapping or additional fields to consider.
462
- # Additionnal fields are unknow by the process. So, those fields will needs to be setup before.
463
- #
464
- # file name convention is identical than controller class.
465
- # file: my_code.rb => needs to create MyCode class
466
-
467
- class YamlStudentsController
468
- def initialize()
469
- @@valid_attributes = [:name, :first_name, :last_name, :id, :status, :training]
470
- end
471
-
472
- def create(sObjectType, hParams)
473
- case sObjectType
474
- when :connection
475
- required?(hParams, :hdata, :file_name)
476
- YamlSchool.new(hParams[:hdata, :file_name])
477
- when :student
478
- required?(hParams, :connection)
479
- required?(hParams, :student_name)
480
-
481
- # We use the hdata built by the lorj. See set_hdata in the next file.
482
- hParams[:connection].create_student(hParams[:student_name], hParams[:hdata])
483
- else
484
- Error "'%s' is not a valid object for 'create'" % sObjectType
485
- end
486
- end
487
-
488
- # This function return a collection which have to provide:
489
- # functions: [], length, each
490
- def query(sObjectType, sQuery, hParams)
491
- case sObjectType
492
- when :student
493
- required?(hParams, :connection)
494
-
495
- hParams[:connection].query_student(sQuery)
496
- else
497
- Error "'%s' is not a valid object for 'create'" % sObjectType
498
- end
499
-
500
- end
501
-
502
- def delete(sObjectType, hParams)
503
- case sObjectType
504
- when :student
505
- required?(hParams, :connection)
506
-
507
- hParams[:connection].delete_student(hParams[sObjectType][:id])
508
- else
509
- Error "'%s' is not a valid object for 'create'" % sObjectType
510
- end
511
- end
512
-
513
- def get_attr(oControlerObject, key)
514
- # This controller function read the data and
515
- # extract the information requested by the framework.
516
- # Those data will be mapped to the process data model.
517
- # The key is an array, to get data from a level tree.
518
- # [data_l1, data_l2, data_l3] => should retrieve data from structure
519
- # like data[ data_l2 [ data_l3 ] ]
520
- begin
521
- attributes = oControlerObject
522
- raise "get_attr: attribute '%s' is unknown in '%s'. Valid one are : '%s'",
523
- key[0], oControlerObject.class,
524
- @@valid_attributes unless @@valid_attributes.include?(key[0])
525
- Lorj::rh_get(attributes, key)
526
- rescue => e
527
- Error "get_attr: Unable to map '%s'. %s" % [key, e.message]
528
- end
529
- end
530
-
531
- def set_attr(oControlerObject, key, value)
532
- begin
533
- attributes = oControlerObject
534
- raise "set_attr: attribute '%s' is unknown in '%s'. Valid one are : '%s'",
535
- key[0], oControlerObject.class,
536
- @@valid_attributes unless @@valid_attributes.include?(key[0])
537
- Lorj::rh_set(attributes, value, key)
538
- rescue => e
539
- Error "set_attr: Unable to map '%s' on '%s'" % [key, sObjectType]
540
- end
541
- end
542
-
543
- def update(sObjectType, oObject, hParams)
544
- case sObjectType
545
- when :student
546
- required?(hParams, :connection)
547
-
548
- hParams[:connection].update_student(oObject)
549
- else
550
- Error "'%s' is not a valid object for 'create'" % sObjectType
551
- end
552
- end
553
-
554
- end
80
+ [Details is explained here](example/students_2/student_v2_md.html)
555
81
 
556
- ```
557
- In short, we wrap:
558
-
559
- - create with YamlSchool.create_student
560
- - delete with YamlSchool.delete_student
561
- - query with YamlSchool.query_student
562
- - update with YamlSchool.update_student
563
-
564
- And we have defined 2 additional functions
565
-
566
- - get_attr: to extract data from a YamlSchool Object
567
- - set_attr: to set data to a YamlSchool Object
568
-
569
- ##### File `controller/yaml_students.rb`
570
-
571
- And we need to write some mapping stuff to the controller. We have to add this
572
-
573
- *The controller definition:*
574
-
575
- ``` ruby
576
- class YamlStudents
577
- # This is a new object which is known by the controller only.
578
- # Used to open the yaml file. Generically, I named it :connection.
579
- # But this can be any name you want. Only the controller will deal with it.
580
- define_obj(:connection,{
581
- :create_e => :controller_create # Nothing complex to do. So, simply call the controller create.
582
- })
583
-
584
- obj_needs :data, :connection_string, :mapping => :file_name
585
- undefine_attribute :id # Do not return any predefined ID
586
- undefine_attribute :name # Do not return any predefined NAME
587
-
588
- # The student model have to be expanded.
589
- define_obj(:student)
590
- # It requires to create a connection to the data, ie opening the yaml file.
591
- # So, before working with the :student object, the controller requires a connection
592
- # This connection will be loaded in the memory and provided to the controller
593
- # when needed.
594
- obj_needs :CloudObject, :connection
595
-
596
- # To simplify controller wrapper, we use hdata built by lorj, and passed to the API
597
- # This hdata is a hash containing mapped data, thanks to set_hdata.
598
- set_hdata :first_name
599
- set_hdata :last_name
600
- # Instead of 'course', the yaml API uses 'training'
601
- set_hdata :course, :mapping => :training
602
-
603
- get_attr_mapping :course, :training
604
- # instead of 'student_name', the yaml API uses 'name'
605
- get_attr_mapping :student_name, :name
606
-
607
- # This controller will know how to manage a student file with those data.
608
- # But note that the file can have a lot of more data than what the process
609
- # usually manage. It is up to you to increase your process to manage more data.
610
- # Then each controller may need to define mapping fields.
611
- end
612
- ```
82
+ * version 3:
83
+ In this version, we will just create a controller, to replace mock.
613
84
 
614
- That's it!
85
+ [Details is explained here](example/students_3/student_v3_md.html)
615
86
 
616
- #####typical output:
617
- $ example/students_3/students.rb
618
- WARNING: PrcLib.app_defaults is not set. Application defaults won't be loaded.
619
- Create 1st student:
620
- Create 2nd student:
621
- Create 3rd student:
622
- Create mistake
623
- Student created '{:id=>3, :course=>"what ever you want!!!", :student_name=>"Anthony Mistake", :first_name=>"Anthony", :last_name=>"Mistake", :status=>:active}'
624
- Remove mistake
625
- Wrong student to remove: 3 = Anthony Mistake
626
- List of students for 'Art Drama':
627
- {:id=>1, :course=>"Art Drama", :student_name=>"Anthony Hopkins", :first_name=>"Anthony", :last_name=>"Hopkins", :status=>:active}
628
- {:id=>2, :course=>"Art Drama", :student_name=>"Marilyn Monroe", :first_name=>"Marilyn", :last_name=>"Monroe", :status=>:active}
629
- Deleted students:
630
- {:id=>3, :course=>"what ever you want!!!", :student_name=>"Anthony Mistake", :first_name=>"Anthony", :last_name=>"Mistake", :status=>:removed}
87
+ * version 4:
88
+ In this version, we are going to improve the process, to find way to simplify
89
+ the previous code.
631
90
 
632
- ## What next?
91
+ [Details is explained here](example/students_4/student_v4_md.html)
633
92
 
634
- Check the code in the `examples/students_3/`. It provides a little more than is written here.
93
+ * version 5:
94
+ Update the version 4 to fully implement the example of an yaml_student API.
95
+ ie :
96
+ Reproducind what the main `examples/yaml_students/students.rb` is doing.<BR>
97
+ The API is `examples/yaml_students/yaml_students.rb`
635
98
 
636
- In short, it introduces the usage of Lorj::Config, before initializing Lorj::Core.
99
+ [Details is explained here](example/students_5/student_v5_md.html)
637
100
 
638
- ## next features
101
+ # What next?
639
102
 
640
- lorj provides 2 differents configuration class.
103
+ If you want to understand the concept, check [here](lib/concept_md.html)
641
104
 
642
- * Lorj::Config - Basic config systems. Data are retrieved in **application defaults**, then **local config**, then **runtime**.
643
- * Lorj::Account - Based on Lorj::Config, it introduces an **account** file, between **local config** and **runtime**.
644
- * Logging system - Based on logger. A log file contains all data until debug. It prints to the console only data specified by PrcLib::.level
645
- * lorj.setup - This function works with Lorj::Account. Thanks an application data definition (defaults.yaml), lorj ask the user information to build an account. Those data will be loaded and used by your process/controller flow.
105
+ If you want to get an overview of functionnalities per context, see [here](lib/overview_md.html)
646
106
 
647
107
  For details, see API documentation.
648
108