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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +39 -579
- data/Rakefile +7 -0
- data/example/students_1/student_v1.md +115 -0
- data/example/students_1/students.rb +8 -2
- data/example/students_2/process/students.rb +5 -5
- data/example/students_2/student_v2.md +90 -0
- data/example/students_2/students.rb +6 -6
- data/example/students_3/controller/yaml_students.rb +23 -73
- data/example/students_3/controller/yaml_students_code.rb +106 -0
- data/example/students_3/controller/yaml_students_def.rb +69 -0
- data/example/students_3/process/students.rb +23 -157
- data/example/students_3/student_v3.md +283 -0
- data/example/students_3/students.rb +26 -83
- data/example/students_4/controller/yaml_students.rb +51 -0
- data/example/students_4/controller/yaml_students_code.rb +109 -0
- data/example/students_4/controller/yaml_students_def.rb +72 -0
- data/example/students_4/process/students/code/students.rb +103 -0
- data/example/students_4/process/students/definition/students.rb +60 -0
- data/example/students_4/process/students.rb +29 -0
- data/example/students_4/student_v4.md +191 -0
- data/example/students_4/students.rb +65 -0
- data/example/students_5/controller/yaml_students.rb +106 -0
- data/example/{students_3 → students_5}/controller/yaml_students_controller.rb +5 -3
- data/example/students_5/process/students.rb +182 -0
- data/example/students_5/student_v5.md +382 -0
- data/example/students_5/students.rb +119 -0
- data/example/yaml_students/students.rb +1 -1
- data/example/yaml_students/yaml_students.rb +102 -23
- data/lib/concept.md +3 -3
- data/lib/core/core.rb +15 -15
- data/lib/core/core_controller.rb +49 -24
- data/lib/core/core_internal.rb +2 -2
- data/lib/core/core_model.rb +13 -7
- data/lib/core/core_object_data.rb +18 -18
- data/lib/core/core_object_params.rb +75 -34
- data/lib/core/core_process.rb +104 -59
- data/lib/core/core_process_setup.rb +11 -11
- data/lib/core/core_setup_ask.rb +24 -14
- data/lib/core/core_setup_encrypt.rb +17 -15
- data/lib/core/core_setup_init.rb +19 -15
- data/lib/core/core_setup_list.rb +12 -12
- data/lib/core/definition.rb +20 -20
- data/lib/core/definition_internal.rb +20 -10
- data/lib/core/lorj_basecontroller.rb +8 -8
- data/lib/core/lorj_basedefinition.rb +47 -126
- data/lib/core/lorj_baseprocess.rb +81 -57
- data/lib/core/lorj_data.rb +28 -27
- data/lib/core/lorj_keypath.rb +1 -1
- data/lib/core_process/cloud/process/flavor.rb +3 -2
- data/lib/core_process/cloud/process/keypairs.rb +5 -4
- data/lib/core_process/cloud/process/network.rb +4 -3
- data/lib/core_process/cloud/process/public_ip.rb +3 -2
- data/lib/core_process/cloud/process/rules.rb +7 -6
- data/lib/core_process/cloud/process/security_groups.rb +1 -1
- data/lib/core_process/cloud/process/server.rb +1 -1
- data/lib/core_process/cloud/process/server_log.rb +1 -1
- data/lib/core_process/cloud/process/subnetwork.rb +4 -1
- data/lib/core_process/cloud_process.rb +1 -1
- data/lib/logging.rb +41 -48
- data/lib/lorj/version.rb +1 -1
- data/lib/lorj.rb +7 -0
- data/lib/lorj_account.rb +3 -3
- data/lib/lorj_config.rb +1 -1
- data/lib/lorj_defaults.rb +222 -26
- data/lib/overview.md +120 -0
- data/lib/prc.rb +97 -24
- data/lib/prc_core_config.rb +134 -52
- data/lib/providers/hpcloud/compute.rb +3 -3
- data/lib/providers/hpcloud/hpcloud.rb +14 -14
- data/lib/providers/hpcloud/network.rb +4 -4
- data/lib/providers/hpcloud/security_groups.rb +1 -1
- data/lib/providers/mock/mock.rb +3 -3
- data/lib/providers/openstack/openstack.rb +12 -12
- data/lib/providers/templates/compute.rb +6 -6
- data/lib/rh.rb +7 -5
- data/spec/04_prc_core_config_spec.rb +52 -0
- data/spec/11_lorj_config_spec.rb +1 -1
- 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
|
-
#
|
25
|
-
#
|
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
|
-
|
25
|
-
|
26
|
-
PrcLib.info(
|
27
|
-
|
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['
|
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 |
|
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.
|
23
|
-
|
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
|
-
|
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
|
-
#
|
47
|
-
#
|
48
|
-
|
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
|