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
@@ -0,0 +1,109 @@
|
|
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
|
+
# We added test requiring :first_name and :last_name
|
34
|
+
required?(hParams, :first_name)
|
35
|
+
required?(hParams, :last_name)
|
36
|
+
|
37
|
+
hParams[:connection].create_student(hParams[:student_name],
|
38
|
+
hParams[:hdata])
|
39
|
+
else
|
40
|
+
controller_error "'%s' is not a valid object for 'create'", sObjectType
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# This function return one element identified by an ID.
|
45
|
+
# But get is not a YamlStudent API functions. But query help to use :id
|
46
|
+
#
|
47
|
+
# so we will do a query
|
48
|
+
def get(sObjectType, id, hParams)
|
49
|
+
case sObjectType
|
50
|
+
when :student
|
51
|
+
result = query(sObjectType, { :id => id }, hParams)
|
52
|
+
return nil if result.length == 0
|
53
|
+
result[0]
|
54
|
+
else
|
55
|
+
controller_error "'%s' is not a valid object for 'create'", sObjectType
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# This function return a collection which have to provide:
|
60
|
+
# functions: [], length, each
|
61
|
+
def query(sObjectType, sQuery, hParams)
|
62
|
+
case sObjectType
|
63
|
+
when :student
|
64
|
+
required?(hParams, :connection)
|
65
|
+
|
66
|
+
hParams[:connection].query_student(sQuery)
|
67
|
+
else
|
68
|
+
controller_error "'%s' is not a valid object for 'create'", sObjectType
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Example 4: Delete added to the controller.
|
73
|
+
def delete(sObjectType, hParams)
|
74
|
+
case sObjectType
|
75
|
+
when :student
|
76
|
+
required?(hParams, :connection)
|
77
|
+
|
78
|
+
hParams[:connection].delete_student(hParams[sObjectType][:id])
|
79
|
+
else
|
80
|
+
Error format("'%s' is not a valid object for 'create'", sObjectType)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# This controller function read the data and
|
85
|
+
# extract the information requested by the framework.
|
86
|
+
# Those data will be mapped to the process data model.
|
87
|
+
# The key is an array, to get data from a level tree.
|
88
|
+
# [data_l1, data_l2, data_l3] => should retrieve data from structure like
|
89
|
+
# data[ data_l2[ data_l3 ] ]
|
90
|
+
def get_attr(oControlerObject, key)
|
91
|
+
attributes = oControlerObject
|
92
|
+
|
93
|
+
controller_error("get_attr: attribute '%s' is unknown in '%s'. "\
|
94
|
+
"Valid one are : '%s'",
|
95
|
+
key[0], oControlerObject.class,
|
96
|
+
valid_attributes) unless valid_attributes.include?(key[0])
|
97
|
+
attributes.rh_get(key)
|
98
|
+
rescue => e
|
99
|
+
controller_error "get_attr: Unable to map '%s'. %s\n See %s",
|
100
|
+
key, e.message, e.backtrace[0]
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# These are the valid controller fields.
|
106
|
+
def valid_attributes
|
107
|
+
[:name, :first_name, :last_name, :id, :status, :training]
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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
|
+
# To simplify controller wrapper, we use hdata built by lorj, and passed to
|
62
|
+
# the API
|
63
|
+
# This hdata is a hash containing mapped data, thanks to def_hdata.
|
64
|
+
def_hdata :first_name
|
65
|
+
def_hdata :last_name
|
66
|
+
# Instead of 'course', the yaml API uses 'training'
|
67
|
+
def_hdata :course, :mapping => :training
|
68
|
+
|
69
|
+
def_attr_mapping :course, :training
|
70
|
+
# instead of 'student_name', the yaml API uses 'name'
|
71
|
+
def_attr_mapping :student_name, :name
|
72
|
+
end
|
@@ -0,0 +1,103 @@
|
|
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
|
+
# In this version 4, The process will ensure a student is created only if
|
18
|
+
# missing and remove duplicates.
|
19
|
+
|
20
|
+
# Students process
|
21
|
+
class StudentsProcess
|
22
|
+
# create_student process handler to get a student.
|
23
|
+
#
|
24
|
+
# * If not found, create it.
|
25
|
+
# * If multiple found, remove duplicates
|
26
|
+
# * otherwise return the one found.
|
27
|
+
def create_student(sObjectType, hParams)
|
28
|
+
PrcLib.state(format("Running creation process for object '%s' = '%s'",
|
29
|
+
sObjectType, hParams[:student_name]))
|
30
|
+
|
31
|
+
list = process_query(sObjectType, :student_name => hParams[:student_name])
|
32
|
+
case list.length
|
33
|
+
when 0
|
34
|
+
create_new_student(hParams)
|
35
|
+
when 1
|
36
|
+
found_one_student(list[0], hParams[:student_name])
|
37
|
+
else
|
38
|
+
found_multiple_students(list, hParams[:student_name])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Create a single new student
|
45
|
+
def create_new_student(hParams)
|
46
|
+
user = hParams[:student_name].split(' ')
|
47
|
+
|
48
|
+
controller_data = {}
|
49
|
+
unless hParams.exist?(:first_name)
|
50
|
+
if user.length == 1
|
51
|
+
controller_data[:first_name] = 'unknown first name'
|
52
|
+
else
|
53
|
+
controller_data[:first_name] = user[0..-2].join(' ')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
controller_data[:last_name] = user[-1] unless hParams.exist?(:last_name)
|
57
|
+
|
58
|
+
student = controller_create(:student, controller_data)
|
59
|
+
|
60
|
+
process_fail format("Student '%s' not created.",
|
61
|
+
hParams[:student_name]) if student.nil?
|
62
|
+
|
63
|
+
PrcLib.info(format("'student': '%s' created with id %s",
|
64
|
+
hParams[:student_name],
|
65
|
+
student[:id]))
|
66
|
+
student
|
67
|
+
end
|
68
|
+
|
69
|
+
# Identified 1 student
|
70
|
+
def found_one_student(student, student_name)
|
71
|
+
PrcLib.info(format("'student': '%s' loaded with id %s",
|
72
|
+
student_name, student[:id]))
|
73
|
+
|
74
|
+
student
|
75
|
+
end
|
76
|
+
|
77
|
+
# Identified multiple identical students
|
78
|
+
# It will remove duplicated.
|
79
|
+
def found_multiple_students(list, student_name)
|
80
|
+
PrcLib.warning(format("More than one student named '%s' is found: %s "\
|
81
|
+
'records. Selecting the first one and removing '\
|
82
|
+
'duplicates.',
|
83
|
+
student_name, list.length))
|
84
|
+
remove_multiple_students(list[1..-1], student_name)
|
85
|
+
PrcLib.info("'student': First loaded with id %s", list[0, :id])
|
86
|
+
list[0]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Remove list of identical students
|
90
|
+
def remove_multiple_students(list, student_name)
|
91
|
+
return false unless list.is_a?(Array)
|
92
|
+
return false if list.length == 0
|
93
|
+
|
94
|
+
count = 0
|
95
|
+
list.each { |elem| count += remove_student_object(elem) }
|
96
|
+
PrcLib.info("'student': %s duplicated '%s' removed. ", count, student_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
def remove_student_object(object)
|
100
|
+
register(object)
|
101
|
+
controller_delete(:student)
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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
|
+
# In this version 4, The process will ensure a student is created only if
|
18
|
+
# missing and remove duplicates.
|
19
|
+
|
20
|
+
# Declaring your data model and handlers.
|
21
|
+
class Lorj::BaseDefinition # rubocop: disable Style/ClassAndModuleChildren
|
22
|
+
# We need to define the student object and the handler to use while we need to
|
23
|
+
# create it.
|
24
|
+
define_obj(:student,
|
25
|
+
# The function to call in the class Students
|
26
|
+
:create_e => :create_student,
|
27
|
+
# We use predefined call to the controller query
|
28
|
+
:query_e => :controller_query,
|
29
|
+
# We use predefined call to the controller get
|
30
|
+
:get_e => :controller_get,
|
31
|
+
# We use predefined call to the controller delete
|
32
|
+
:delete_e => :controller_delete
|
33
|
+
)
|
34
|
+
|
35
|
+
# obj_needs is used to declare parameters to pass to handlers.
|
36
|
+
# :for indicates those parameters to be passed to create_e handler only.
|
37
|
+
# Those data (or objects) will be collected and passed to the process
|
38
|
+
# handler as hParams.
|
39
|
+
|
40
|
+
obj_needs :data, :student_name, :for => [:create_e]
|
41
|
+
|
42
|
+
# By default, all data are required.
|
43
|
+
# You can set it as optional. Your process will need to deal with this
|
44
|
+
# optional data.
|
45
|
+
obj_needs_optional
|
46
|
+
obj_needs :data, :first_name, :for => [:create_e]
|
47
|
+
obj_needs :data, :last_name, :for => [:create_e]
|
48
|
+
obj_needs :data, :course
|
49
|
+
# Note that in this model, the training is renamed as course.
|
50
|
+
|
51
|
+
# the controller will need to map it to 'training'.
|
52
|
+
|
53
|
+
# def_attribute defines the data model.
|
54
|
+
# The process will be able to access those data
|
55
|
+
def_attribute :course
|
56
|
+
def_attribute :student_name
|
57
|
+
def_attribute :first_name
|
58
|
+
def_attribute :last_name
|
59
|
+
def_attribute :status
|
60
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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
|
+
# In this version 4, The process will ensure a student is created only if
|
18
|
+
# missing and remove duplicates.
|
19
|
+
|
20
|
+
process_path = File.dirname(__FILE__)
|
21
|
+
|
22
|
+
# Define model
|
23
|
+
|
24
|
+
lorj_objects = %w(students)
|
25
|
+
|
26
|
+
lorj_objects.each do |name|
|
27
|
+
require File.join(process_path, 'students', 'code', name + '.rb')
|
28
|
+
require File.join(process_path, 'students', 'definition', name + '.rb')
|
29
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# Writing student version 4
|
2
|
+
|
3
|
+
In this example, we will enhance the process to remove duplicates, and ensure
|
4
|
+
a student is created if it does not exist.
|
5
|
+
|
6
|
+
We will also manage a little more data, like first name, last name and course.
|
7
|
+
|
8
|
+
And we will simplify the way to transmit those data to the controller using the
|
9
|
+
notion of hdata
|
10
|
+
|
11
|
+
First of all, let's add 4 additional fields to the process:
|
12
|
+
- student_name : Already configured.
|
13
|
+
- first_name : The controller should be able to use a different first_name than
|
14
|
+
the one splitted from student_name. This is a new data.
|
15
|
+
- last_name : list first_name, last_name can be set directly, instead of built
|
16
|
+
from student_name
|
17
|
+
- course : This is a new field. We will consider that YamlStudent API know it
|
18
|
+
it as 'training' instead.
|
19
|
+
|
20
|
+
---
|
21
|
+
Before any update, compare to example 3, we have splitted `process/students.rb`
|
22
|
+
in several files, to make the distintion of 'definition' and 'code'
|
23
|
+
|
24
|
+
`process/students.rb` now contains:
|
25
|
+
```ruby
|
26
|
+
process_path = File.dirname(__FILE__)
|
27
|
+
|
28
|
+
# Define model
|
29
|
+
|
30
|
+
lorj_objects = %w(students)
|
31
|
+
|
32
|
+
lorj_objects.each do | name |
|
33
|
+
require File.join(process_path, 'students', 'code', name + '.rb')
|
34
|
+
require File.join(process_path, 'students', 'definition', name + '.rb')
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
The definition part is stored in:
|
39
|
+
`process/students/definition/students.rb` : Definition of student meta object.
|
40
|
+
It contains the BaseDefinition code.
|
41
|
+
`process/students/code/students.rb` : Student meta object code.
|
42
|
+
It contains the StudentsProcess code.
|
43
|
+
|
44
|
+
---
|
45
|
+
Ok, To add new field to the process, update the process definition file:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class Lorj::BaseDefinition # rubocop: disable Style/ClassAndModuleChildren
|
49
|
+
# We need to define the student object and the handler to use while we need to
|
50
|
+
# create it.
|
51
|
+
define_obj(:student,
|
52
|
+
# The function to call in the class Students
|
53
|
+
:create_e => :create_student,
|
54
|
+
# We use predefined call to the controller query
|
55
|
+
:query_e => :controller_query,
|
56
|
+
# We use predefined call to the controller get
|
57
|
+
:get_e => :controller_get,
|
58
|
+
# We use predefined call to the controller delete
|
59
|
+
:delete_e => :controller_delete
|
60
|
+
)
|
61
|
+
|
62
|
+
# obj_needs is used to declare parameters to pass to handlers.
|
63
|
+
# :for indicates those parameters to be passed to create_e handler only.
|
64
|
+
# Those data (or objects) will be collected and passed to the process
|
65
|
+
# handler as hParams.
|
66
|
+
|
67
|
+
obj_needs :data, :student_name, :for => [:create_e]
|
68
|
+
|
69
|
+
# By default, all data are required.
|
70
|
+
# You can set it as optional. Your process will need to deal with this
|
71
|
+
# optional data.
|
72
|
+
obj_needs_optional
|
73
|
+
obj_needs :data, :first_name, :for => [:create_e]
|
74
|
+
obj_needs :data, :last_name, :for => [:create_e]
|
75
|
+
obj_needs :data, :course
|
76
|
+
# Note that in this model, the training is renamed as course.
|
77
|
+
|
78
|
+
# the controller will need to map it to 'training'.
|
79
|
+
|
80
|
+
# def_attribute defines the data model.
|
81
|
+
# The process will be able to access those data
|
82
|
+
def_attribute :course
|
83
|
+
def_attribute :student_name
|
84
|
+
def_attribute :first_name
|
85
|
+
def_attribute :last_name
|
86
|
+
def_attribute :status
|
87
|
+
|
88
|
+
undefine_attribute :name
|
89
|
+
end
|
90
|
+
|
91
|
+
```
|
92
|
+
|
93
|
+
The YamlStudent controller needs to be updated as well, because we considered
|
94
|
+
that training is the known field to use for course. We need to map it.
|
95
|
+
|
96
|
+
We will also instroduce the hdata.
|
97
|
+
hdata will ask lorj to create a Hash with the data set and already mapped.
|
98
|
+
So, instead of setting yourself an Hash that the API may requires to work,
|
99
|
+
you declare it and lorj will build it for you.
|
100
|
+
|
101
|
+
Then on the controller code, you will just need to refer to the :hdata.
|
102
|
+
We will see that in the next file.
|
103
|
+
|
104
|
+
Here in the controller definition, we just declared the hdata to map.
|
105
|
+
|
106
|
+
So, we need to update the controller definition file:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class YamlStudents
|
110
|
+
define_obj(:connection,
|
111
|
+
# Nothing complex to do. So, simply call the controller create.
|
112
|
+
:create_e => :controller_create
|
113
|
+
)
|
114
|
+
|
115
|
+
obj_needs :data, :connection_string, :mapping => :file_name
|
116
|
+
undefine_attribute :id # Do not return any predefined ID
|
117
|
+
undefine_attribute :name # Do not return any predefined NAME
|
118
|
+
|
119
|
+
define_obj(:student)
|
120
|
+
obj_needs :CloudObject, :connection
|
121
|
+
|
122
|
+
# To simplify controller wrapper, we use hdata built by lorj, and passed to
|
123
|
+
# the API
|
124
|
+
# This hdata is a hash containing mapped data, thanks to def_hdata.
|
125
|
+
def_hdata :first_name
|
126
|
+
def_hdata :last_name
|
127
|
+
# Instead of 'course', the yaml API uses 'training'
|
128
|
+
def_hdata :course, :mapping => :training
|
129
|
+
|
130
|
+
def_attr_mapping :course, :training
|
131
|
+
# instead of 'student_name', the yaml API uses 'name'
|
132
|
+
def_attr_mapping :student_name, :name
|
133
|
+
```
|
134
|
+
|
135
|
+
ok, cool.
|
136
|
+
|
137
|
+
Now we need to update the controller code because we did not implemented the
|
138
|
+
delete task in the controller. The process needs it to remove duplicates.
|
139
|
+
|
140
|
+
But we need also to accept first and last name data from the process.
|
141
|
+
We will move the split to the process as well.
|
142
|
+
|
143
|
+
Additionnally, we talked about 'hdata'. 'hdata' will simplify the code as well.
|
144
|
+
|
145
|
+
Let's see.
|
146
|
+
We need to change the create, as we are going to use hdata:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
# controller wrapper
|
150
|
+
def create(sObjectType, hParams)
|
151
|
+
case sObjectType
|
152
|
+
when :connection
|
153
|
+
required?(hParams, :hdata, :file_name)
|
154
|
+
YamlSchool.new(hParams[:hdata, :file_name])
|
155
|
+
when :student
|
156
|
+
required?(hParams, :connection)
|
157
|
+
required?(hParams, :student_name)
|
158
|
+
# We added test requiring :first_name and :last_name
|
159
|
+
required?(hParams, :first_name)
|
160
|
+
required?(hParams, :last_name)
|
161
|
+
|
162
|
+
#We replaced the previous code with simply hParams[:hdata].
|
163
|
+
hParams[:connection].create_student(hParams[:student_name],
|
164
|
+
hParams[:hdata])
|
165
|
+
else
|
166
|
+
controller_error "'%s' is not a valid object for 'create'", sObjectType
|
167
|
+
end
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
And then add the delete function used by the process to remove duplicates.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
# Example 4: Delete added to the controller.
|
175
|
+
def delete(sObjectType, hParams)
|
176
|
+
case sObjectType
|
177
|
+
when :student
|
178
|
+
required?(hParams, :connection)
|
179
|
+
|
180
|
+
hParams[:connection].delete_student(hParams[sObjectType][:id])
|
181
|
+
else
|
182
|
+
Error format("'%s' is not a valid object for 'create'", sObjectType)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
```
|
186
|
+
That's it.
|
187
|
+
|
188
|
+
As you saw, the main program has not changed. Just process and controllers.
|
189
|
+
|
190
|
+
In the next version is the full implementation of what `yaml_students/students.rb`
|
191
|
+
main basic tool running the YamlStudent API.
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
app_path = File.dirname(__FILE__)
|
19
|
+
|
20
|
+
if ENV['BYEBUG']
|
21
|
+
require 'byebug'
|
22
|
+
lib_path = File.expand_path(File.join(app_path, '..', '..', 'lib'))
|
23
|
+
$LOAD_PATH << lib_path
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'lorj'
|
27
|
+
|
28
|
+
# If you want to see what is happening in the framework, uncomment debug
|
29
|
+
# settings.
|
30
|
+
PrcLib.level = Logger::DEBUG # Printed out to your console.
|
31
|
+
PrcLib.core_level = 3 # framework debug levels.
|
32
|
+
|
33
|
+
# Initialize the framework
|
34
|
+
processes = [File.join(app_path, 'process', 'students.rb')]
|
35
|
+
controller = File.join(app_path, 'controller', 'yaml_students.rb')
|
36
|
+
|
37
|
+
# now we changed from mock to our own controller, located in
|
38
|
+
# controller/yaml_students.rb
|
39
|
+
# student_core = Lorj::Core.new(nil, processes, :mock)
|
40
|
+
config = Lorj::Config.new
|
41
|
+
config[:connection_string] = '/tmp/students.yaml'
|
42
|
+
student_core = Lorj::Core.new(config, processes, controller)
|
43
|
+
|
44
|
+
# Ask the framework to create the object student 'Robert Redford'
|
45
|
+
student_core.create(:student, :student_name => 'Robert Redford')
|
46
|
+
|
47
|
+
# Want to create a duplicated student 'Robert Redford'?
|
48
|
+
student_core.create(:student, :student_name => 'Robert Redford')
|
49
|
+
# no problem. The key is the key in the Mock controller array.
|
50
|
+
|
51
|
+
student_core.create(:student, :student_name => 'Anthony Hopkins')
|
52
|
+
|
53
|
+
# Let's create a third different student.
|
54
|
+
students = student_core.query(:student, :name => 'Robert Redford')
|
55
|
+
|
56
|
+
puts format('%s students found', students.length)
|
57
|
+
|
58
|
+
students.each do |a_student|
|
59
|
+
puts format('%s: %s', a_student[:id], a_student[:name])
|
60
|
+
end
|
61
|
+
|
62
|
+
# let's check the get function, who is the ID 2?
|
63
|
+
student = student_core.get(:student, 2)
|
64
|
+
|
65
|
+
puts format('The student ID 2 is %s', student[:name])
|