lorj 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
data/Rakefile CHANGED
@@ -17,9 +17,16 @@
17
17
  require 'bundler/gem_tasks'
18
18
  require 'rspec/core/rake_task'
19
19
  require 'rubocop/rake_task'
20
+ require 'rdoc/task'
20
21
 
21
22
  task :default => [:lint, :spec]
22
23
 
24
+ desc 'Generate lorj documentation'
25
+ RDoc::Task.new do |rdoc|
26
+ rdoc.main = 'README.md'
27
+ rdoc.rdoc_files.include('README.md', 'lib', 'example', 'bin')
28
+ end
29
+
23
30
  desc 'Run the specs.'
24
31
  RSpec::Core::RakeTask.new do |t|
25
32
  t.pattern = 'spec/*_spec.rb'
@@ -0,0 +1,115 @@
1
+ # Writing student version 1
2
+
3
+ **NOTE**: following example is available in `examples/students_1/`
4
+
5
+ First of all, write your first main. Create a file `example.rb` with following content:
6
+
7
+ ## File `students.rb`
8
+
9
+ ``` ruby
10
+ #!/usr/bin/env ruby
11
+
12
+ app_path = File.dirname(__FILE__)
13
+ require 'lorj'
14
+
15
+ # If you want to see what is happening in the framework, uncomment debug settings.
16
+ # PrcLib.level = Logger::DEBUG # Printed out to your console.
17
+ # PrcLib.core_level = 3 # framework debug levels.
18
+
19
+ # Initialize the framework
20
+ processes = [ File.join(app_path, 'process', 'students.rb')]
21
+ student_core = Lorj::Core.new( nil, processes)
22
+
23
+ # Ask the framework to create the object student 'Robert Redford'
24
+ student_core.create(:student, :student_name => "Robert Redford")
25
+ ```
26
+
27
+ ## File `process/students.rb`
28
+
29
+ Now, let's write our first process. We are going to create a file Students.rb
30
+ under a sub-directory 'process'.
31
+
32
+ ``` ruby
33
+ # Students process
34
+ class StudentsProcess
35
+ def create_student(object_type, params)
36
+ puts format("Running creation process for object '%s' = '%s'",
37
+ object_type, params[:student_name] )
38
+
39
+ # If you prefer to print out to the log system instead:
40
+ # PrcLib::debug("Running creation process for object '%s' = '%s'",
41
+ # object_type, params[:student_name])
42
+ end
43
+ end
44
+
45
+ # Declaring your data model and handlers.
46
+ class Lorj::BaseDefinition
47
+
48
+ # We need to define the student object and the handler to use while we need to create it.
49
+ define_obj(:student,
50
+ # The function to call in the class Students
51
+ :create_e => :create_student
52
+ )
53
+
54
+ obj_needs :data, :student_name, :for => [:create_e]
55
+
56
+ end
57
+ ```
58
+
59
+ What did we wrote?
60
+
61
+ * We defined a *StudentsProcess* class
62
+
63
+ This is the core of your GENERIC process. It describes how to handle the
64
+ object requested. The data to use is available in `params`.
65
+
66
+ **IMPORTANT !!** There is no reference to any files or Database connection.
67
+
68
+ **NOTE**: Lorj framework requires you to define a class name composed by the
69
+ name of the process and 'Process'.
70
+ Here, it is 'Students' + **'Process'**
71
+
72
+
73
+ * We declared the data model and the process handlers with declaration in
74
+ *Lorj::BaseDefinition* class.
75
+
76
+ In short, we declared `:student` object, which needs `:student_name` at
77
+ creation step.
78
+ Currently the data model used here is very simple. There is one meta object
79
+ with some limited attributes, handlers and parameters.
80
+ The process itself is defined by several functions in StudentsProcess class
81
+ with one handlers function declared by the data model.
82
+
83
+ **NOTE** Implicitely, the framework consider that the object contains at
84
+ least 2 attributes, :id (should be unique) and :name (string)
85
+
86
+ We used the following feature provided by *Lorj::BaseDefinition*:
87
+ * define_obj : Declare a meta object, and attach handlers
88
+ * obj_needs : Assign some data as parameters.
89
+
90
+
91
+ Currently, this model do nothing except printing out.
92
+
93
+ ##typical output
94
+
95
+ $ example/students_1/students.rb
96
+ WARNING: PrcLib.app_defaults is not set. Application defaults won't be loaded.
97
+ Running creation process for object 'student' = 'Robert Redford'
98
+ WARNING: 'create_student' has returned no data for object Lorj::Data 'student'!
99
+
100
+ There is 2 warnings.
101
+
102
+ * **PrcLib.app_defaults** represents the application name. It is used to keep
103
+ your application configuration data in ~/.{PrcLib.app_defaults}/ directory.
104
+ Defining this data in your main, will eliminate this warning.
105
+ * **create_student** function in your process has returned nothing. while lorj
106
+ is called to create an object, it assumes to get the object data created. Lorj
107
+ keep those data in a cache. In this example, **create_student** returned nil,
108
+ and lorj raise a warning about that.
109
+
110
+ # what next? version 2
111
+
112
+ Complete the process to have create/query/get and delete capability, with mock controller.
113
+ The mock controller is basically a controller keeping data in memory.
114
+
115
+ [Details is explained here](../students_2/student_v2_md.html)
@@ -15,14 +15,20 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ if ENV['BYEBUG']
19
+ require 'byebug'
20
+ lib_path = File.expand_path(File.join(app_path, '..', '..', 'lib'))
21
+ $LOAD_PATH << lib_path
22
+ end
23
+
18
24
  app_path = File.dirname(__FILE__)
19
25
 
20
26
  require 'lorj'
21
27
 
22
28
  # If you want to see what is happening in the framework, uncomment debug
23
29
  # settings.
24
- # PrcLib.level = Logger::DEBUG # Printed out to your console.
25
- # PrcLib.core_level = 3 # framework debug levels.
30
+ # PrcLib.level = Logger::DEBUG # Printed out to your console.
31
+ # PrcLib.core_level = 3 # framework debug levels.
26
32
 
27
33
  # Initialize the framework
28
34
  processes = [File.join(app_path, 'process', 'students.rb')]
@@ -19,12 +19,12 @@ class StudentsProcess
19
19
  def create_student(sObjectType, hParams)
20
20
  PrcLib.state(format("Running creation process for object '%s' = '%s'",
21
21
  sObjectType, hParams[:student_name]))
22
-
22
+ # byebug if ENV['BYEBUG'] # rubocop: disable Debugger
23
23
  object = controller_create(sObjectType)
24
- fail format("Student '%s' not created.",
25
- hParams[:student_name]) if object.nil?
26
- PrcLib.info(format("'%s': '%s' created with id %s",
27
- sObjectType, hParams[:student_name], object[:id]))
24
+ PrcLib.runtime_fail "Student '%s' not created.",
25
+ hParams[:student_name] if object.nil?
26
+ PrcLib.info("'%s': '%s' created with id %s",
27
+ sObjectType, hParams[:student_name], object[:id])
28
28
  object
29
29
  end
30
30
  end
@@ -0,0 +1,90 @@
1
+ # Writing student version 2
2
+
3
+ **NOTE**: following example is available in `examples/students_2/`
4
+
5
+ lorj comes with a `:mock` controller. This one is really basic. It keeps data in an Hash in MockController class.<br>
6
+ In this example, we add create/get/query/delete capability in the process and use the `:mock` controller to store the data.
7
+
8
+ ## File `process/Students.rb`
9
+
10
+ Add 3 handlers query_e, get_e and delete_e like this. Add the :mapping case as well.
11
+
12
+ ``` ruby
13
+ class Lorj::BaseDefinition
14
+ define_obj(:student,
15
+ {
16
+ :create_e => :create_student, # The function to call in the class Students
17
+ :query_e => :controller_query, # We use predefined call to the controller query
18
+ :get_e => :controller_get, # We use predefined call to the controller get
19
+ :delete_e => :controller_delete # We use predefined call to the controller delete
20
+ })
21
+
22
+ # Note about mapping. This is usually done by the controller. We will see this later.
23
+ obj_needs :data, :student_name, :for => [:create_e], :mapping => :name
24
+
25
+ end
26
+ ```
27
+
28
+ Update the handler `create_student`:
29
+
30
+ ``` ruby
31
+ def create_student(sObjectType, hParams)
32
+ PrcLib.state("Running creation process for object '%s' = '%s'",
33
+ sObjectType, hParams[:student_name])
34
+
35
+ object = controler.create(sObjectType)
36
+ fail "Student '%s' not created.",
37
+ hParams[:student_name] if object.nil?
38
+ PrcLib.info("'%s': '%s' created with id %s",
39
+ sObjectType, hParams[:student_name], object[:id])
40
+ object
41
+ end
42
+ ```
43
+
44
+
45
+
46
+ ## File `students.rb`
47
+ The update your main and add those lines. In the following, we create 3 students, while 2 are duplicated.
48
+
49
+ ``` ruby
50
+
51
+ # Want to create a duplicated student 'Robert Redford'?
52
+ student_core.create(:student, :student_name => "Robert Redford")
53
+ # no problem. The key is the key in the Mock controller array.
54
+
55
+ student_core.create(:student, :student_name => "Anthony Hopkins")
56
+
57
+ # Let's create a third different student.
58
+ students = student_core.query(:student, { :name => "Robert Redford" } )
59
+
60
+ puts "%s students found" % students.length
61
+
62
+ students.each { | a_student |
63
+ puts "%s: %s" % [a_student[:id], a_student[:name]]
64
+ }
65
+
66
+ # let's check the get function, who is the ID 2?
67
+ student = student_core.get(:student, 2)
68
+
69
+ puts "The student ID 2 is %s" % student[:name]
70
+
71
+ ```
72
+
73
+ ##typical output:
74
+
75
+ $ example/students_2/students.rb
76
+ WARNING: PrcLib.app_defaults is not set. Application defaults won't be loaded.
77
+ 2 students found
78
+ 0: Robert Redford
79
+ 1: Robert Redford
80
+ The student ID 2 is Anthony Hopkins
81
+
82
+
83
+ Cool! But everything is in memory! We would like to write this in a file.
84
+ Writing our controller, means that the process should not be updated anymore!
85
+
86
+ Let's move to the most interesting version. Integrate an API example in lorj!
87
+
88
+ # Next?
89
+
90
+ [Details is explained here](../students_3/student_v3_md.html)
@@ -17,7 +17,7 @@
17
17
 
18
18
  app_path = File.dirname(__FILE__)
19
19
 
20
- if ENV['LORJ_DEV']
20
+ if ENV['BYEBUG']
21
21
  require 'byebug'
22
22
  lib_path = File.expand_path(File.join(app_path, '..', '..', 'lib'))
23
23
  $LOAD_PATH << lib_path
@@ -27,19 +27,19 @@ require 'lorj'
27
27
 
28
28
  # If you want to see what is happening in the framework, uncomment debug
29
29
  # settings.
30
- PrcLib.level = Logger::DEBUG # Printed out to your console.
31
- PrcLib.core_level = 3 # framework debug levels.
30
+ # PrcLib.level = Logger::DEBUG # Printed out to your console.
31
+ # PrcLib.core_level = 3 # framework debug levels.
32
32
 
33
33
  # Initialize the framework
34
34
  processes = [File.join(app_path, 'process', 'students.rb')]
35
35
 
36
+ # byebug if ENV['BYEBUG'] # rubocop: disable Debugger
36
37
  student_core = Lorj::Core.new(nil, processes, :mock)
37
-
38
38
  # Ask the framework to create the object student 'Robert Redford'
39
39
  student_core.create(:student, :student_name => 'Robert Redford')
40
40
 
41
41
  # Want to create a duplicated student 'Robert Redford'?
42
- student_core.create(:student)
42
+ student_core.create(:student, :student_name => 'Robert Redford')
43
43
  # no problem. The key is the key in the Mock controller array.
44
44
 
45
45
  student_core.create(:student, :student_name => 'Anthony Hopkins')
@@ -49,7 +49,7 @@ students = student_core.query(:student, :name => 'Robert Redford')
49
49
 
50
50
  puts format('%s students found', students.length)
51
51
 
52
- students.each do | a_student |
52
+ students.each do |a_student|
53
53
  puts format('%s: %s', a_student[:id], a_student[:name])
54
54
  end
55
55
 
@@ -14,88 +14,38 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ # when you declare this controller with a file name, lorj expect this file
18
+ # to contains the controller code and the controller definition.
19
+ # The code have to be declared in a class which is named as follow from the file
20
+ # name:
21
+ # 1st letter is capitalized
22
+ # A '_' followed by a letterif replaced by the capicatl letter.
23
+ # Ex: my_code.rb => assume to declare MyCode class
24
+ #
25
+ # The controller code class is built from the source file name as explained
26
+ # below + 'Controller'
27
+ # Ex: my_code.rb => assume to use MyCodeController for controller handlers and
28
+ # functions.
29
+ #
30
+ # The controller definition class is build from the file name only.
31
+ # Ex: my_code.rb => assume to use MyCode for controller definition.
32
+
17
33
  # This class describes how to process some actions, and will do everything prior
18
34
  # this task to make it to work.
19
35
 
20
36
  # declare yaml student API to the controller
21
- cur_path = File.dirname(__FILE__)
22
- api_file = File.expand_path(File.join(cur_path, '..', '..',
23
- 'yaml_students', 'yaml_students.rb'))
37
+ cur_path = File.expand_path(File.dirname(__FILE__))
38
+ api_file = File.join(cur_path, '..', '..', 'yaml_students', 'yaml_students.rb')
39
+
24
40
  require api_file
25
41
 
26
42
  # The controller is a combination of 2 elements:
27
43
  # - Controller class
28
44
  # Code which will interfere with the external API.
29
45
  #
30
- # The file name must respect the name of the class. 1st letter already
31
- # capitalized and letter after _ is capitalized.
32
- # file: my_code.rb => needs to create MyCodeController class
33
- #
34
- # - Definition class
35
- # This class declare any kind of mapping or additional fields to consider.
36
- # Additionnal fields are unknow by the process. So, those fields will needs
37
- # to be setup before.
38
- #
39
- # file name convention is identical than controller class.
40
- # file: my_code.rb => needs to create MyCode class
41
-
42
- controller_file = File.expand_path(File.join(cur_path,
43
- 'yaml_students_controller.rb'))
46
+ controller_file = File.join(cur_path, 'yaml_students_code.rb')
44
47
  require controller_file # Load controller mapping
45
48
 
46
- # Declare
47
- # - additional objects and their specific process (:connection using basic
48
- # predefined :controller_create process)
49
- # - data_mapping :
50
- # :connection_string => :file_name
51
- # :course => :training
52
- #
53
- # If some data has been added by the controller, the main and process,
54
- # won't take care and the framework will fails.
55
- # To eliminate this errors, there is 2 cases:
56
- # - detect this change in the process or the main.
57
- # - set it up, using lorj setup function, if the data is declared askable by
58
- # the controller.
59
- # The controller can define how the setup have to ask values, and even can get
60
- # data from itself.
61
- class YamlStudents
62
- # This is a new object which is known by the controller only.
63
- # Used to open the yaml file. Generically, I named it :connection.
64
- # But this can be any name you want. Only the controller will deal with it.
65
- define_obj(:connection,
66
- # Nothing complex to do. So, simply call the controller create.
67
- :create_e => :controller_create
68
- )
69
-
70
- obj_needs :data, :connection_string, :mapping => :file_name
71
- undefine_attribute :id # Do not return any predefined ID
72
- undefine_attribute :name # Do not return any predefined NAME
73
-
74
- # The student model have to be expanded.
75
- define_obj(:student)
76
- # It requires to create a connection to the data, ie opening the yaml file.
77
- # So, before working with the :student object, the controller requires a
78
- # connection
79
- # This connection will be loaded in the memory and provided to the controller
80
- # when needed.
81
- # obj_needs :CloudObject update the :student object to requires a connection
82
- # before.
83
- obj_needs :CloudObject, :connection
84
-
85
- # To simplify controller wrapper, we use hdata built by lorj, and passed to
86
- # the API
87
- # This hdata is a hash containing mapped data, thanks to def_hdata.
88
- def_hdata :first_name
89
- def_hdata :last_name
90
- # Instead of 'course', the yaml API uses 'training'
91
- def_hdata :course, :mapping => :training
92
-
93
- def_attr_mapping :course, :training
94
- # instead of 'student_name', the yaml API uses 'name'
95
- def_attr_mapping :student_name, :name
96
-
97
- # This controller will know how to manage a student file with those data.
98
- # But note that the file can have a lot of more data than what the process
99
- # usually manage. It is up to you to increase your process to manage more data
100
- # Then each controller may need to define mapping fields.
101
- end
49
+ # - Definition class
50
+ # This class declare any kind of mapping or additional attributes to consider.
51
+ require File.join(cur_path, 'yaml_students_def.rb')
@@ -0,0 +1,106 @@
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
+ # This class describes how to process some actions, and will do everything prior
18
+ # this task to make it to work.
19
+
20
+ # This file describe the controller code.
21
+ # The class name is determined by lorj.
22
+ # See controller/yaml_students.rb for details
23
+ class YamlStudentsController
24
+ # controller wrapper
25
+ def create(sObjectType, hParams)
26
+ case sObjectType
27
+ when :connection
28
+ required?(hParams, :hdata, :file_name)
29
+ YamlSchool.new(hParams[:hdata, :file_name])
30
+ when :student
31
+ required?(hParams, :connection)
32
+ required?(hParams, :student_name)
33
+
34
+ # Yaml Student API requires to provide :
35
+ # student_name, first and last name.
36
+ # We are splitting student_name to get first and last name.
37
+ # But we need to ensure to find at least one space.
38
+ # if not, we will forcelly set to 'first_name unknown'
39
+ # Currently the Generic Student Process do not take care of
40
+ # this kind of data structure. In Version 4, we will move this feature
41
+ # to the process.
42
+ fields = hParams[:student_name].split(' ')
43
+ fields.insert(0, 'first_name unknown') if fields.length == 1
44
+
45
+ options = { :first_name => fields[0..-2].join(' '),
46
+ :last_name => fields[-1] }
47
+ hParams[:connection].create_student(hParams[:student_name], options)
48
+ else
49
+ controller_error "'%s' is not a valid object for 'create'", sObjectType
50
+ end
51
+ end
52
+
53
+ # This function return one element identified by an ID.
54
+ # But get is not a YamlStudent API functions. But query help to use :id
55
+ #
56
+ # so we will do a query
57
+ def get(sObjectType, id, hParams)
58
+ case sObjectType
59
+ when :student
60
+ result = query(sObjectType, { :id => id }, hParams)
61
+ return nil if result.length == 0
62
+ result[0]
63
+ else
64
+ controller_error "'%s' is not a valid object for 'create'", sObjectType
65
+ end
66
+ end
67
+
68
+ # This function return a collection which have to provide:
69
+ # functions: [], length, each
70
+ def query(sObjectType, sQuery, hParams)
71
+ case sObjectType
72
+ when :student
73
+ required?(hParams, :connection)
74
+
75
+ hParams[:connection].query_student(sQuery)
76
+ else
77
+ controller_error "'%s' is not a valid object for 'create'", sObjectType
78
+ end
79
+ end
80
+
81
+ # This controller function read the data and
82
+ # extract the information requested by the framework.
83
+ # Those data will be mapped to the process data model.
84
+ # The key is an array, to get data from a level tree.
85
+ # [data_l1, data_l2, data_l3] => should retrieve data from structure like
86
+ # data[ data_l2[ data_l3 ] ]
87
+ def get_attr(oControlerObject, key)
88
+ attributes = oControlerObject
89
+
90
+ controller_error("get_attr: attribute '%s' is unknown in '%s'. "\
91
+ "Valid one are : '%s'",
92
+ key[0], oControlerObject.class,
93
+ valid_attributes) unless valid_attributes.include?(key[0])
94
+ attributes.rh_get(key)
95
+ rescue => e
96
+ controller_error "get_attr: Unable to map '%s'. %s\n See %s",
97
+ key, e.message, e.backtrace[0]
98
+ end
99
+
100
+ private
101
+
102
+ # These are the valid controller fields.
103
+ def valid_attributes
104
+ [:name, :first_name, :last_name, :id, :status, :training]
105
+ end
106
+ end
@@ -0,0 +1,69 @@
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
+ # Declare
18
+ # - additional objects and their specific process (:connection using basic
19
+ # predefined :controller_create process)
20
+ # - data_mapping :
21
+ # :connection_string => :file_name
22
+ # :course => :training
23
+ #
24
+ # If some meta objects attributes has been added by the controller,
25
+ # the main program and the GENERIC process will ignore them.
26
+ #
27
+ # If your controller will requires to have some data in this specific controller
28
+ # attributes, you will have 2 options:
29
+ # - Write a controller process which can take care of those new attributes
30
+ # This controller process will need to execute the original GENERIC process
31
+ # and then complete the task, with specific controller process to set
32
+ # these specific controller attributes.
33
+ # - Set it up, using lorj setup function, if the data is declared setup-able by
34
+ # the controller.
35
+ # The controller can define how the setup have to ask values, and even can get
36
+ # data from the GENERIC process.
37
+ class YamlStudents
38
+ # This is a new object which is known by the controller only.
39
+ # Used to open the yaml file. Generically, I named it :connection.
40
+ # But this can be any name you want. Only the controller will deal with it.
41
+ define_obj(:connection,
42
+ # Nothing complex to do. So, simply call the controller create.
43
+ :create_e => :controller_create
44
+ )
45
+
46
+ obj_needs :data, :connection_string, :mapping => :file_name
47
+ undefine_attribute :id # Do not return any predefined ID
48
+ undefine_attribute :name # Do not return any predefined NAME
49
+
50
+ # The student model have to be expanded.
51
+ define_obj(:student)
52
+ # It requires to create a connection to the data, ie opening the yaml file.
53
+ # So, before working with the :student object, the controller requires a
54
+ # connection
55
+ # This connection will be loaded in the memory and provided to the controller
56
+ # when needed.
57
+ # obj_needs :CloudObject update the :student object to requires a connection
58
+ # before.
59
+ obj_needs :CloudObject, :connection
60
+
61
+ # instead of 'student_name', the yaml API uses 'name'
62
+ def_attr_mapping :student_name, :name
63
+
64
+ # This controller will know how to manage a student file with those data.
65
+ # But note that the file can have a lot of more data than what the process
66
+ # usually manage. It is up to you to increase your process to manage more data
67
+ # Then each controller may need to define mapping fields.
68
+ # The example 4 shows those mapping definition.
69
+ end