lorj 0.1.0

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.gitreview +4 -0
  4. data/Gemfile +25 -0
  5. data/Gemfile.lock +34 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +652 -0
  8. data/Rakefile +24 -0
  9. data/bin/cloud_test.rb +81 -0
  10. data/example/students_1/process/Students.rb +20 -0
  11. data/example/students_1/students.rb +16 -0
  12. data/example/students_2/process/Students.rb +27 -0
  13. data/example/students_2/students.rb +36 -0
  14. data/example/students_3/controller/yaml_students.rb +94 -0
  15. data/example/students_3/controller/yaml_students_controller.rb +123 -0
  16. data/example/students_3/process/students.rb +118 -0
  17. data/example/students_3/students.rb +93 -0
  18. data/example/students_4/controller/yaml_students.rb +82 -0
  19. data/example/students_4/controller/yaml_students_controller.rb +141 -0
  20. data/example/students_4/process/students.rb +112 -0
  21. data/example/students_4/students.rb +103 -0
  22. data/example/yaml_students/students.rb +78 -0
  23. data/example/yaml_students/yaml_students.rb +115 -0
  24. data/lib/concept.md +111 -0
  25. data/lib/core/core.rb +723 -0
  26. data/lib/core/definition.rb +505 -0
  27. data/lib/core/definition_internal.rb +338 -0
  28. data/lib/core/lorj-basecontroller.rb +90 -0
  29. data/lib/core/lorj-basedefinition.rb +1079 -0
  30. data/lib/core/lorj-baseprocess.rb +231 -0
  31. data/lib/core/lorj-data.rb +567 -0
  32. data/lib/core/lorj-keypath.rb +115 -0
  33. data/lib/core_process/CloudProcess.rb +334 -0
  34. data/lib/core_process/global_process.rb +406 -0
  35. data/lib/core_process/network_process.rb +603 -0
  36. data/lib/img/.directory +4 -0
  37. data/lib/img/account_data_access.png +0 -0
  38. data/lib/img/config_data_access.png +0 -0
  39. data/lib/img/forj-lib-concept.png +0 -0
  40. data/lib/lorj/version.rb +3 -0
  41. data/lib/lorj.rb +51 -0
  42. data/lib/prc-account.rb +339 -0
  43. data/lib/prc-config.rb +1023 -0
  44. data/lib/prc-logging.rb +183 -0
  45. data/lib/prc.rb +108 -0
  46. data/lib/providers/hpcloud/Hpcloud.rb +419 -0
  47. data/lib/providers/hpcloud/compute.rb +108 -0
  48. data/lib/providers/hpcloud/network.rb +117 -0
  49. data/lib/providers/hpcloud/security_groups.rb +67 -0
  50. data/lib/providers/mock/Mock.rb +141 -0
  51. data/lib/providers/openstack/Openstack.rb +47 -0
  52. data/lib/providers/templates/compute.rb +42 -0
  53. data/lib/providers/templates/core.rb +61 -0
  54. data/lib/providers/templates/network.rb +33 -0
  55. data/lorj-spec/defaults.yaml +26 -0
  56. data/lorj.gemspec +39 -0
  57. data/spec/forj-account_spec.rb +75 -0
  58. data/spec/forj-config_spec.rb +196 -0
  59. metadata +164 -0
@@ -0,0 +1,82 @@
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
+
18
+ # This class describes how to process some actions, and will do everything prior
19
+ # this task to make it to work.
20
+
21
+ # This Mock controller keep the data in memory in hash/Array data.
22
+
23
+ # declare yaml student API to the controller
24
+ cur_path = File.dirname(__FILE__)
25
+ api_file = File.expand_path(File.join(cur_path, "..", "..", "yaml_students", 'yaml_students.rb'))
26
+ require api_file
27
+
28
+ # The controller is a combination of 2 elements:
29
+ # - Controller class
30
+ # Code which will interfere with the external API.
31
+ #
32
+ # The file name must respect the name of the class. 1st letter already capitalized and letter after _ is capitalized.
33
+ # file: my_code.rb => needs to create MyCodeController class
34
+ #
35
+ # - Definition class
36
+ # This class declare any kind of mapping or additional fields to consider.
37
+ # Additionnal fields are unknow by the process. So, those fields will needs 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,'yaml_students_controller.rb'))
43
+ require controller_file # Load controller mapping
44
+
45
+ # Declare
46
+ # - additional objects and their specific process (:connection using basic predefined :controller_create process)
47
+ # - data_mapping :
48
+ # :connection_string => :file_name
49
+ # :course => :training
50
+ #
51
+ # If some data has been added by the controller, the main and process, won't take care and the framework will fails.
52
+ # To eliminate this errors, there is 2 cases:
53
+ # - detect this change in the process or the main.
54
+ # - set it up, using lorj setup function, if the data is declared askable by the controller.
55
+ # The controller can define how the setup have to ask values, and even can get data
56
+ # from itself.
57
+
58
+ class YamlStudents
59
+
60
+ define_obj(:connection,{
61
+ :create_e => :controller_create # Nothing complex to do. So, simply call the controller create.
62
+ })
63
+
64
+ obj_needs :data, :connection_string, :mapping => :file_name
65
+ undefine_attribute :id # Do not return any predefined ID
66
+ undefine_attribute :name # Do not return any predefined NAME
67
+
68
+ # The student model has been expanded. The object name will be built from first and last name
69
+ define_obj(:student)
70
+ obj_needs :CloudObject, :connection
71
+
72
+ set_hdata :first_name
73
+ set_hdata :last_name
74
+ set_hdata :course, :mapping => :training
75
+
76
+ get_attr_mapping :course, :training
77
+
78
+ # This controller will know how to manage a student file with those data.
79
+ # But note that the file can have a lot of more data than what the process
80
+ # usually manage. It is up to you to increase your process to manage more data.
81
+ # Then each controller may need to define mapping fields.
82
+ end
@@ -0,0 +1,141 @@
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
+
18
+ # This class describes how to process some actions, and will do everything prior
19
+ # this task to make it to work.
20
+
21
+ # This Mock controller keep the data in memory in hash/Array data.
22
+
23
+ # declare yaml student API to the controller
24
+ cur_file = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), "..", "yaml_students", 'yaml_students.rb'))
25
+ require cur_file
26
+
27
+ # The controller is a combination of 2 elements:
28
+ # - Controller class
29
+ # Code which will interfere with the external API.
30
+ #
31
+ # The file name must respect the name of the class. 1st letter already 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 to be setup before.
37
+ #
38
+ # file name convention is identical than controller class.
39
+ # file: my_code.rb => needs to create MyCode class
40
+
41
+ class YamlStudentsController
42
+ def initialize()
43
+ @@valid_attributes = [:name, :first_name, :last_name, :id, :status, :training]
44
+
45
+ end
46
+
47
+ def create(sObjectType, hParams)
48
+ case sObjectType
49
+ when :connection
50
+ required?(hParams, :hdata, :file_name)
51
+ YamlSchool.new(hParams[:hdata, :file_name])
52
+ when :student
53
+ required?(hParams, :connection)
54
+ required?(hParams, :student_name)
55
+
56
+ hParams[:connection].create_student(hParams[:student_name], hParams[:hdata])
57
+ else
58
+ Error "'%s' is not a valid object for 'create'" % sObjectType
59
+ end
60
+ end
61
+
62
+ # This function return a collection which have to provide:
63
+ # functions: [], length, each
64
+ # Used by network process.
65
+ def query(sObjectType, sQuery, hParams)
66
+ case sObjectType
67
+ when :student
68
+ required?(hParams, :connection)
69
+
70
+ hParams[:connection].query_student(sQuery)
71
+ else
72
+ Error "'%s' is not a valid object for 'create'" % sObjectType
73
+ end
74
+
75
+ end
76
+
77
+ def delete(sObjectType, hParams)
78
+ case sObjectType
79
+ when :student
80
+ required?(hParams, :connection)
81
+
82
+ hParams[:connection].delete_student(hParams[sObjectType][:id])
83
+ else
84
+ Error "'%s' is not a valid object for 'create'" % sObjectType
85
+ end
86
+ end
87
+
88
+ def get(sObjectType, sUniqId, hParams)
89
+ case sObjectType
90
+ when :student
91
+ required?(hParams, :connection)
92
+
93
+ list = hParams[:connection].query_student({:id => sUniqId})
94
+ if list.length == 0
95
+ nil
96
+ else
97
+ list[0]
98
+ end
99
+ else
100
+ Error "'%s' is not a valid object for 'create'" % sObjectType
101
+ end
102
+ end
103
+
104
+ def get_attr(oControlerObject, key)
105
+ # This controller function read the data and
106
+ # extract the information requested by the framework.
107
+ # Those data will be mapped to the process data model.
108
+ # The key is an array, to get data from a level tree.
109
+ # [data_l1, data_l2, data_l3] => should retrieve data from structure like data[ data_l2[ data_l3 ] ]
110
+ begin
111
+ attributes = oControlerObject
112
+ raise "get_attr: attribute '%s' is unknown in '%s'. Valid one are : '%s'" % [key[0], oControlerObject.class, @@valid_attributes ] unless @@valid_attributes.include?(key[0])
113
+ Lorj::rhGet(attributes, key)
114
+ rescue => e
115
+ Error "get_attr: Unable to map '%s'. %s" % [key, e.message]
116
+ end
117
+ end
118
+
119
+ def set_attr(oControlerObject, key, value)
120
+ begin
121
+ attributes = oControlerObject
122
+ raise "set_attr: attribute '%s' is unknown in '%s'. Valid one are : '%s'" % [key[0], oControlerObject.class, @@valid_attributes ] unless @@valid_attributes.include?(key[0])
123
+ Lorj::rhSet(attributes, value, key)
124
+ rescue => e
125
+ Error "set_attr: Unable to map '%s' on '%s'" % [key, sObjectType]
126
+ end
127
+ end
128
+
129
+
130
+ def update(sObjectType, oObject, hParams)
131
+ case sObjectType
132
+ when :student
133
+ required?(hParams, :connection)
134
+
135
+ hParams[:connection].update_student(oObject)
136
+ else
137
+ Error "'%s' is not a valid object for 'create'" % sObjectType
138
+ end
139
+ end
140
+
141
+ end
@@ -0,0 +1,112 @@
1
+ # Students process
2
+ class StudentsProcess
3
+ def create_student(sObjectType, hParams)
4
+ PrcLib::state ("Running creation process for object '%s' = '%s'" % [sObjectType, hParams[:student_name] ])
5
+
6
+ aStudentName = hParams[:student_name].split(" ")
7
+ # config object is a reference to runtime/config data.
8
+ config[:first_name] = aStudentName[0]
9
+ config[:last_name] = aStudentName[1]
10
+
11
+ oList = Query(sObjectType, {:name => hParams[:student_name]})
12
+ case oList.length
13
+ when 0
14
+ oObject = controller_create(sObjectType)
15
+ raise "Student '%s' not created." % hParams[:student_name] if oObject.nil?
16
+ PrcLib::info ("'%s': '%s' created with id %s" % [sObjectType, hParams[:student_name], oObject[:id]])
17
+ when 1
18
+ oObject = oList[0]
19
+ PrcLib::info ("'%s': '%s' loaded with id %s" % [sObjectType, hParams[:student_name], oObject[:id]])
20
+ else
21
+ oObject = oList[0]
22
+ PrcLib::warning("More than one student named '%s' is found: %s records. Selecting the first one and removing duplicates." % [hParams[:student_name], oList.length])
23
+ iCount = 0
24
+ oList[1..-1].each { | elem |
25
+ register(elem)
26
+ iCount += controller_delete(sObjectType)
27
+ }
28
+ PrcLib::info ("'%s': %s duplicated '%s' removed. First loaded with id %s" % [sObjectType, iCount, hParams[:student_name], oObject[:id]])
29
+ end
30
+ oObject
31
+ end
32
+
33
+ def query_student(sObjectType, sQuery, hParams)
34
+ PrcLib::state ("Running query process for object '%s' with query '%s'" % [sObjectType, sQuery])
35
+
36
+ oObjects = controller_query(sObjectType, sQuery)
37
+ raise "Query error." if oObjects.nil?
38
+
39
+ PrcLib::info ("'%s': Queried. %s records found." % [sObjectType, oObjects.length])
40
+ oObjects
41
+ end
42
+
43
+ def get_student(sObjectType, sId, hParams)
44
+ PrcLib::state ("Running get process for object '%s' with ID %s" % [sObjectType, sId ])
45
+
46
+ oObject = controller_get(sObjectType, sId)
47
+ PrcLib::debug("No ID %s found." % sId) if oObject.nil?
48
+
49
+ oObject
50
+ end
51
+
52
+ def delete_student(sObjectType, hParams)
53
+ Error "Unable to delete students, if at least one student is not loaded, or query not defined." if not hParams.exist?(:student) and not hParams.exist?(:query)
54
+
55
+ # This student deletion process supports 2 modes:
56
+ # - Delete from a query field (:query hParams)
57
+ # - Delete the latest loaded student.
58
+
59
+ if hParams.exist?(:query)
60
+ result = Query(sObjectType, hParams[:query])
61
+ if result.length > 0
62
+ result.each { | student |
63
+ puts "Student to remove: %s = %s" % [student[:id], student[:name]]
64
+ register(student)
65
+ controller_delete(:student)
66
+ PrcLib::info ("'%s:%s' student removed" % [student[:id], student[:name]])
67
+ }
68
+ end
69
+ else
70
+ controller_delete(:student)
71
+ end
72
+ end
73
+ end
74
+
75
+ # Declaring your data model and handlers.
76
+ class Lorj::BaseDefinition
77
+
78
+ # We need to define the student object and the handler to use while we need to create it.
79
+ define_obj(:student,
80
+ {
81
+ :create_e => :create_student, # The function to call in the class Students
82
+ :query_e => :query_student,
83
+ :delete_e => :delete_student,
84
+ :get_e => :get_student
85
+ })
86
+
87
+ # All obj_needs will be collected and passed to the process handler as hParams.
88
+ # Data required to create a student
89
+ obj_needs :data, :student_name, { :for => [:create_e] }
90
+
91
+ # Data optional for any kind of event
92
+ obj_needs_optional
93
+ obj_needs :data, :query, { :for => [:delete_e] }
94
+ obj_needs :data, :first_name
95
+ obj_needs :data, :last_name
96
+ obj_needs :data, :course
97
+
98
+ # Define Data a student object needs to take care.
99
+ # The controller should map it if needed (if the value exists)
100
+ # But it can also add some extra attributes not predefined by the process.
101
+ # Usually, the process should ignore it.
102
+ # But if it detect it, the process should be careful with this data
103
+ # which are really specific to only one controller and may break the controller agnostic capability.
104
+ def_attribute :course
105
+ def_attribute :first_name
106
+ def_attribute :last_name
107
+ def_attribute :name
108
+ def_attribute :status
109
+ end
110
+
111
+ class Lorj::BaseDefinition
112
+ end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $APP_PATH = File.dirname(__FILE__)
4
+ require 'lorj'
5
+ require 'ansi'
6
+
7
+ # If you want to see what is happening in the framework, uncomment debug settings.
8
+ #PrcLib.level = Logger::DEBUG # Printed out to your console.
9
+ #PrcLib.core_level = 3 # framework debug levels. (0 to 5)
10
+
11
+ # Load global Config
12
+
13
+ # This object is used to provide configuration data to lorj
14
+
15
+ # The config search is:
16
+ # 1- Application defaults (defaults.yaml) - Not defined by default. update the following line and create defaults.yaml
17
+ # PrcLib.app_defaults = $APP_PATH
18
+ # 2- Local defaults (~/.<Application Name>/config.yaml) - <Application Name> is 'Lorj' by default. Can be updated with following line.
19
+ # PrcLib.app_name = 'myapp'
20
+ # 3 - runtime. Those variables are set, with oConfig[key] = value
21
+
22
+ oConfig = Lorj::Config.new() # Use Simple Config Object
23
+
24
+ # You can use an account object, which add an extra account level
25
+ # between runtime and config.yaml/app default
26
+ # oConfig = Lorj::Account.new('MyAccount')
27
+
28
+
29
+ # Initialize the framework
30
+ # Use students process
31
+ hProcesses = [ File.join($APP_PATH, 'process', 'students.rb')]
32
+ # Use yaml_students controller
33
+ sController = File.join($APP_PATH, 'controller', 'yaml_students.rb')
34
+ oStudentCore = Lorj::Core.new( oConfig, hProcesses, sController )
35
+
36
+ # This kind of connection_string should be part of an Account Data.
37
+ # So, we won't need to set this config.
38
+ # But you can imagine to set at runtime this config as well.
39
+ oConfig[:connection_string] = "/tmp/students.yaml"
40
+
41
+ # Note that we have commented the next line.
42
+ # oStudentCore.Create(:connection, :connection_string => "/tmp/students.yaml")
43
+ # This call is not required, as the framework has all the information to create
44
+ # the connection, at the first time this connection is required.
45
+ # ie, while starting to create a student.
46
+
47
+
48
+ # Set the student name to use
49
+ oConfig[:student_name] = "Robert Redford"
50
+
51
+ # Ask the framework to create the object student 'Robert Redford'
52
+ puts ANSI.bold("Create 1st student:")
53
+ oStudentCore.Create(:student)
54
+ # The connection is made because creating a student requires
55
+ # the object :connection. (See example/students_4/controller/yaml_students.rb, around line 70)
56
+
57
+ puts ANSI.bold("Create 2nd student:")
58
+ # Want to create a duplicated student 'Robert Redford'?
59
+ oStudentCore.Create(:student)
60
+ # Because the process ensure that there is no duplicate, this won't create duplicates
61
+
62
+ # We can set runtime configuration instantly from the Create call
63
+ # The following line :
64
+ puts ANSI.bold("Create 3rd student:")
65
+ oStudentCore.Create(:student, {:student_name => "Anthony Hopkins"})
66
+ # replaced the following :
67
+ # oConfig[:student_name] = "Anthony Hopkins"
68
+ # oStudentCore.Create(:student)
69
+
70
+ # Let's query students named "Robert Redford"
71
+ puts ANSI.bold("Querying students as 'Robert Redford':")
72
+ oStudents = oStudentCore.Query(:student, { :name => "Robert Redford" } )
73
+
74
+ puts "%s students found for '%s':" % [oStudents.length, "Robert Redford"]
75
+
76
+ oStudents.each { | oStudent |
77
+ puts "%s: %s" % [oStudent[:id], oStudent[:name]]
78
+ }
79
+
80
+ # let's check the get function, who is the ID 2?
81
+ puts ANSI.bold("Who is student ID 2?")
82
+ oStudent = oStudentCore.Get(:student, 2)
83
+
84
+ puts "\nThe student ID 2 is %s" % oStudent[:name] unless oStudent.nil?
85
+ puts "\nThe student ID 2 doesn't exist." if oStudent.nil?
86
+
87
+ puts ANSI.bold("Create mistake")
88
+ oStudentCore.Create(:student, {
89
+ :student_name => "Anthony Mistake",
90
+ :course => 'what ever you want!!!'
91
+ })
92
+
93
+ # The query logic has been implemented directly in the process,
94
+ # so now, any kind of controller Delete will have the same behavior...
95
+ puts ANSI.bold("Remove mistake")
96
+ hQuery = { :name => "Anthony Mistake"}
97
+ oStudentCore.Delete(:student, :query => hQuery)
98
+
99
+ puts ANSI.bold("List of students for 'Art Drama':")
100
+ puts oStudentCore.Query(:student, { :course => "Art Drama"}).to_a
101
+
102
+ puts ANSI.bold("Deleted students:")
103
+ puts oStudentCore.Query(:student,{ :status => :removed}).to_a
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # encoding: UTF-8
4
+
5
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'rubygems'
20
+ require 'ansi'
21
+
22
+ $APP_PATH = File.dirname(__FILE__)
23
+
24
+ require File.join($APP_PATH, 'yaml_students.rb')
25
+
26
+ school = YamlSchool.new('/tmp/students.yaml')
27
+
28
+ puts ANSI.bold("Create 1st student:")
29
+ if school.query_student({:name => "Robert Redford"}).length == 0
30
+ school.create_student("Robert Redford", {
31
+ first_name: 'Robert',
32
+ last_name: 'Redford',
33
+ training: 'Art Comedy'
34
+ })
35
+ end
36
+
37
+ puts ANSI.bold("Create 2nd student:")
38
+ if school.query_student({:name => "Anthony Hopkins"}).length == 0
39
+ school.create_student("Anthony Hopkins", {
40
+ first_name: 'Anthony',
41
+ last_name: 'Hopkins',
42
+ training: 'Art Drama'
43
+ })
44
+ end
45
+
46
+ puts ANSI.bold("Create 3rd student:")
47
+ if school.query_student({:name => "Marilyn Monroe"}).length == 0
48
+ school.create_student("Marilyn Monroe", {
49
+ first_name: 'Marilyn',
50
+ last_name: 'Mistake',
51
+ training: 'Art Drama'
52
+ })
53
+ end
54
+
55
+ puts ANSI.bold("Create mistake")
56
+ oStudent = school.create_student("Anthony Mistake", {
57
+ first_name: 'Anthony',
58
+ last_name: 'Mistake',
59
+ training: 'what ever you want!!!'
60
+ })
61
+
62
+ puts "Student created: '%s'" % oStudent
63
+
64
+ puts ANSI.bold("Remove mistake")
65
+ result = school.query_student({:name => "Anthony Mistake"})
66
+ if result.length > 0
67
+ result.each { | student |
68
+ puts "Wrong student to remove: %s = %s" % [student[:id], student[:name]]
69
+ school.delete_student(student[:id])
70
+ }
71
+ end
72
+
73
+
74
+ puts ANSI.bold("List of students for 'Art Drama':")
75
+ puts school.query_student({ :training => "Art Drama"})
76
+
77
+ puts ANSI.bold("Deleted students:")
78
+ puts school.query_student({ :status => :removed})
@@ -0,0 +1,115 @@
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
+
18
+ # This class describes how to process some actions, and will do everything prior
19
+ # this task to make it to work.
20
+
21
+ require 'yaml'
22
+
23
+ class YamlSchool
24
+ attr_accessor :sFile
25
+ attr_accessor :hData
26
+
27
+ def initialize(sFile)
28
+ @hData = { :students => []}
29
+ @sFile = sFile
30
+ load_data()
31
+ end
32
+
33
+ def load_data()
34
+ if File.exists?(@sFile)
35
+ @hData = YAML.load_file(@sFile)
36
+ @hData = { :students => []} if not @hData
37
+ @hData[:students] = [] unless @hData.key?(:students)
38
+ end
39
+ end
40
+
41
+ def save_data()
42
+ begin
43
+ File.open(@sFile, 'w') do |out|
44
+ YAML.dump(@hData, out)
45
+ end
46
+ rescue => e
47
+ Lorj.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
48
+ return false
49
+ end
50
+ true
51
+ end
52
+
53
+ def create_student(name, fields)
54
+
55
+ if fields[ :first_name].nil? or fields[ :last_name].nil?
56
+ puts "YAML API: Unable to create a student. :first_name and :last_name required."
57
+ return nil
58
+ end
59
+
60
+ result = fields.clone
61
+ result[:name] = name
62
+ result[:name] = "%s %s" % [result[:first_name], result[:first_name]] if name.nil?
63
+ result[:status] = :active
64
+
65
+ @hData[:students] << result
66
+
67
+ result[:id] = @hData[:students].length()-1
68
+
69
+ save_data()
70
+ result
71
+ end
72
+
73
+ def delete_student(sId)
74
+ return false unless File.exists?(sFile)
75
+
76
+ @hData[:students].each { | value |
77
+ hElem = value
78
+ if value[:id] == sId
79
+ @hData[:students][sId][:status] = :removed
80
+ save_data()
81
+ return 1
82
+ end
83
+ }
84
+ 0
85
+ end
86
+
87
+ def query_student(sQuery)
88
+
89
+ result = []
90
+
91
+ @hData[:students].each { | value |
92
+ hElem = value
93
+ sQuery.each { | query_key, query_value |
94
+ hElem = nil if (
95
+ value.key?(:status) and
96
+ value[:status] != :active and
97
+ not sQuery.key?(:status)) or
98
+ not value.key?(query_key) or
99
+ value[query_key] != query_value
100
+ }
101
+ result << hElem if hElem
102
+ }
103
+ result
104
+
105
+ end
106
+
107
+ def update_student(sId, fields)
108
+ aList = query_student({ :id => Id})
109
+ if aList.length == 1
110
+ aList[0].merge(fields)
111
+ end
112
+ save_data()
113
+ end
114
+
115
+ end