lorj 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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