restfulie 0.8.0 → 0.8.1

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 (102) hide show
  1. data/Gemfile +10 -5
  2. data/Rakefile +5 -2
  3. data/lib/restfulie.rb +10 -5
  4. data/lib/restfulie/client.rb +13 -9
  5. data/lib/restfulie/client/base.rb +24 -65
  6. data/lib/restfulie/client/configuration.rb +62 -64
  7. data/lib/restfulie/client/entry_point.rb +36 -0
  8. data/lib/restfulie/client/ext/atom_ext.rb +12 -0
  9. data/lib/restfulie/client/ext/http_ext.rb +22 -0
  10. data/lib/restfulie/client/ext/json_ext.rb +12 -0
  11. data/lib/restfulie/client/ext/xml_ext.rb +4 -0
  12. data/lib/restfulie/client/http.rb +25 -13
  13. data/lib/restfulie/client/http/cache.rb +22 -22
  14. data/lib/restfulie/client/http/error.rb +70 -70
  15. data/lib/restfulie/client/http/link_request_builder.rb +15 -0
  16. data/lib/restfulie/client/http/request_adapter.rb +209 -0
  17. data/lib/restfulie/client/http/request_builder.rb +107 -0
  18. data/lib/restfulie/client/http/request_builder_executor.rb +24 -0
  19. data/lib/restfulie/client/http/request_executor.rb +17 -0
  20. data/lib/restfulie/client/http/request_follow.rb +42 -0
  21. data/lib/restfulie/client/http/request_follow_executor.rb +10 -0
  22. data/lib/restfulie/client/http/request_history.rb +69 -0
  23. data/lib/restfulie/client/http/request_history_executor.rb +10 -0
  24. data/lib/restfulie/client/http/request_marshaller.rb +127 -0
  25. data/lib/restfulie/client/http/request_marshaller_executor.rb +10 -0
  26. data/lib/restfulie/client/http/response.rb +23 -0
  27. data/lib/restfulie/client/http/response_handler.rb +67 -0
  28. data/lib/restfulie/client/http/response_holder.rb +9 -0
  29. data/lib/restfulie/client/mikyung.rb +17 -14
  30. data/lib/restfulie/client/mikyung/concatenator.rb +15 -12
  31. data/lib/restfulie/client/mikyung/core.rb +65 -39
  32. data/lib/restfulie/client/mikyung/languages.rb +8 -26
  33. data/lib/restfulie/client/mikyung/languages/german.rb +24 -0
  34. data/lib/restfulie/client/mikyung/languages/portuguese.rb +23 -0
  35. data/lib/restfulie/client/mikyung/rest_process_model.rb +184 -107
  36. data/lib/restfulie/client/mikyung/steady_state_walker.rb +34 -28
  37. data/lib/restfulie/client/mikyung/then_condition.rb +33 -27
  38. data/lib/restfulie/client/mikyung/when_condition.rb +53 -49
  39. data/lib/restfulie/common.rb +7 -12
  40. data/lib/restfulie/common/converter.rb +20 -9
  41. data/lib/restfulie/common/converter/atom.rb +8 -83
  42. data/lib/restfulie/common/converter/atom/base.rb +89 -0
  43. data/lib/restfulie/common/converter/atom/builder.rb +101 -99
  44. data/lib/restfulie/common/converter/atom/helpers.rb +16 -8
  45. data/lib/restfulie/common/converter/json.rb +12 -0
  46. data/lib/restfulie/common/converter/json/base.rb +84 -0
  47. data/lib/restfulie/common/converter/json/builder.rb +102 -0
  48. data/lib/restfulie/common/converter/json/helpers.rb +17 -0
  49. data/lib/restfulie/common/converter/values.rb +30 -26
  50. data/lib/restfulie/common/converter/xml.rb +14 -0
  51. data/lib/restfulie/common/converter/xml/base.rb +61 -0
  52. data/lib/restfulie/common/converter/xml/builder.rb +112 -0
  53. data/lib/restfulie/common/converter/xml/helpers.rb +17 -0
  54. data/lib/restfulie/common/converter/xml/link.rb +25 -0
  55. data/lib/restfulie/common/converter/xml/links.rb +25 -0
  56. data/lib/restfulie/common/core_ext.rb +1 -5
  57. data/lib/restfulie/common/core_ext/hash.rb +12 -0
  58. data/lib/restfulie/common/error.rb +19 -0
  59. data/lib/restfulie/common/logger.rb +17 -9
  60. data/lib/restfulie/common/representation.rb +9 -10
  61. data/lib/restfulie/common/representation/atom.rb +15 -47
  62. data/lib/restfulie/common/representation/atom/base.rb +122 -365
  63. data/lib/restfulie/common/representation/atom/category.rb +41 -0
  64. data/lib/restfulie/common/representation/atom/entry.rb +52 -100
  65. data/lib/restfulie/common/representation/atom/factory.rb +43 -0
  66. data/lib/restfulie/common/representation/atom/feed.rb +103 -99
  67. data/lib/restfulie/common/representation/atom/link.rb +68 -0
  68. data/lib/restfulie/common/representation/atom/person.rb +48 -0
  69. data/lib/restfulie/common/representation/atom/source.rb +59 -0
  70. data/lib/restfulie/common/representation/atom/tag_collection.rb +38 -0
  71. data/lib/restfulie/common/representation/atom/xml.rb +95 -0
  72. data/lib/restfulie/common/representation/generic.rb +30 -29
  73. data/lib/restfulie/common/representation/json.rb +10 -22
  74. data/lib/restfulie/common/representation/json/base.rb +27 -0
  75. data/lib/restfulie/common/representation/json/keys_as_methods.rb +72 -0
  76. data/lib/restfulie/common/representation/json/link.rb +29 -0
  77. data/lib/restfulie/common/representation/json/link_collection.rb +23 -0
  78. data/lib/restfulie/common/representation/xml.rb +18 -227
  79. data/lib/restfulie/server.rb +9 -10
  80. data/lib/restfulie/server/action_controller.rb +10 -12
  81. data/lib/restfulie/server/action_controller/base.rb +18 -15
  82. data/lib/restfulie/server/action_controller/{routing/patch.rb → patch.rb} +0 -0
  83. data/lib/restfulie/server/action_controller/restful_responder.rb +43 -35
  84. data/lib/restfulie/server/action_view.rb +8 -6
  85. data/lib/restfulie/server/action_view/helpers.rb +47 -41
  86. data/lib/restfulie/server/action_view/template_handlers.rb +24 -12
  87. data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +17 -12
  88. data/lib/restfulie/server/configuration.rb +22 -19
  89. data/lib/restfulie/server/{restfulie_controller.rb → controller.rb} +1 -10
  90. data/lib/restfulie/server/core_ext.rb +1 -1
  91. data/lib/restfulie/version.rb +14 -0
  92. metadata +52 -16
  93. data/lib/restfulie/client/http/adapter.rb +0 -502
  94. data/lib/restfulie/client/http/atom_ext.rb +0 -4
  95. data/lib/restfulie/client/http/core_ext.rb +0 -6
  96. data/lib/restfulie/client/http/core_ext/http.rb +0 -19
  97. data/lib/restfulie/client/http/marshal.rb +0 -145
  98. data/lib/restfulie/client/http/xml_ext.rb +0 -7
  99. data/lib/restfulie/common/core_ext/proc.rb +0 -48
  100. data/lib/restfulie/common/errors.rb +0 -15
  101. data/lib/restfulie/server/action_controller/routing.rb +0 -12
  102. data/lib/restfulie/server/action_controller/routing/restful_route.rb +0 -14
@@ -1,15 +1,18 @@
1
- # Concatenates pure text in order to build messages
2
- # that are used as patterns.
3
- # Usage:
4
- # When there is a machine
5
- #
6
- # Will invoke concatenate 'machine' with 'a' with 'is' with 'there'
7
- class Restfulie::Client::Mikyung::Concatenator
8
- attr_reader :content
9
- def initialize(content, *args)
10
- @content = content
11
- args.each do |arg|
12
- @content << " " << arg.content
1
+ module Restfulie
2
+ module Client
3
+ module Mikyung
4
+ # Concatenates pure text in order to build messages
5
+ # that are used as patterns.
6
+ # Usage:
7
+ # When there is a machine
8
+ #
9
+ # Will invoke concatenate 'machine' with 'a' with 'is' with 'there'
10
+ class Concatenator
11
+ attr_reader :content
12
+ def initialize(content, *args)
13
+ @content = args.inject(content) { |buf, arg| buf << " " << arg.content }
14
+ end
15
+ end
13
16
  end
14
17
  end
15
18
  end
@@ -1,44 +1,70 @@
1
- # iterates following a series of steps provided a goal and a starting uri.
2
- #
3
- # Restfulie::Client::Mikyung.achieve(objective).at(uri).run
4
- #
5
- # In order to implement your own walker, supply an object that respond to the move method.
6
- # Check the run method code.
7
- class Restfulie::Client::Mikyung::Core
8
-
9
- attr_reader :start, :goal, :walker
10
-
11
- def initialize
12
- @walker = Restfulie::Client::Mikyung::SteadyStateWalker.new
13
- end
14
-
15
- def walks_with(walker)
16
- @walker = walker
17
- self
18
- end
1
+ module Restfulie
2
+ module Client
3
+ module Mikyung
4
+ # iterates following a series of steps provided a goal and a starting uri.
5
+ #
6
+ # Restfulie::Client::Mikyung.achieve(objective).at(uri).run
7
+ #
8
+ # In order to implement your own walker, supply an object that respond to the move method.
9
+ # Check the run method code.
10
+ class Core
11
+ attr_reader :start, :goal, :walker, :accepts, :follow
12
+
13
+ def initialize
14
+ @walker = Restfulie::Client::Mikyung::SteadyStateWalker.new
15
+ end
16
+
17
+ def walks_with(walker)
18
+ @walker = walker
19
+ self
20
+ end
21
+
22
+ # initializes with a goal in mind
23
+ def achieve(goal)
24
+ @goal = goal
25
+ self
26
+ end
27
+
28
+ def at(start)
29
+ @start = start
30
+ self
31
+ end
19
32
 
20
- # initializes with a goal in mind
21
- def achieve(goal)
22
- @goal = goal
23
- self
24
- end
25
-
26
- def at(start)
27
- @start = start
28
- self
29
- end
33
+ def follow
34
+ @follow = true
35
+ self
36
+ end
30
37
 
31
- # keeps changing from a steady state to another until its goal has been achieved
32
- def run
33
- @start = current = (@start.kind_of? String) ? Restfulie.at(@start).get : @start
34
-
35
- while(!@goal.completed?(current))
36
- current = @walker.move(@goal, current, self)
38
+ def accepts(accepts)
39
+ @accepts = accepts
40
+ self
41
+ end
42
+
43
+ # keeps changing from a steady state to another until its goal has been achieved
44
+ def run
45
+ if @start.kind_of? String
46
+ client = Restfulie.at(@start)
47
+ client = client.follow if @follow
48
+ client = client.accepts(@accepts) if @accepts
49
+ @start = current = client.get
50
+ else
51
+ # probably configured thru the Rest Process Model class
52
+ @start = current = @goal.class.get_restfulie.get
53
+ end
54
+
55
+ # load the steps and scenario
56
+ @goal.steps
57
+ @goal.scenario
58
+
59
+ while(!@goal.completed?(current))
60
+ current = @walker.move(@goal, current, self)
61
+ end
62
+ current
63
+ end
64
+ end
37
65
  end
38
- current
39
- end
40
-
41
- end
42
66
 
43
- class Restfulie::Client::UnableToAchieveGoalError < Restfulie::Common::Error::RestfulieError
67
+ class UnableToAchieveGoalError < Restfulie::Common::Error::RestfulieError
68
+ end
69
+ end
44
70
  end
@@ -1,29 +1,11 @@
1
- module Restfulie::Client::Mikyung::German
2
- def Wenn(concat, &block)
3
- When(concat, &block)
4
- end
5
- def Und(concat, &block)
6
- And(concat, &block)
7
- end
8
- def Aber(concat, &block)
9
- But(concat, &block)
10
- end
11
- def Dann(concat, &block)
12
- Then(concat, &block)
1
+ module Restfulie
2
+ module Client
3
+ module Mikyung
4
+ module Languages
5
+ autoload :German, 'restfulie/client/mikyung/german'
6
+ autoload :Portuguese, 'restfulie/client/mikyung/portuguese'
7
+ end
8
+ end
13
9
  end
14
10
  end
15
11
 
16
- module Restfulie::Client::Mikyung::Portuguese
17
- def Quando(concat, &block)
18
- When(concat, &block)
19
- end
20
- def E(concat, &block)
21
- And(concat, &block)
22
- end
23
- def Mas(concat, &block)
24
- But(concat, &block)
25
- end
26
- def Entao(concat, &block)
27
- Then(concat, &block)
28
- end
29
- end
@@ -0,0 +1,24 @@
1
+ module Restfulie
2
+ module Client
3
+ module Mikyung
4
+ module Languages
5
+ module German
6
+ def Wenn(concat, &block)
7
+ When(concat, &block)
8
+ end
9
+ def Und(concat, &block)
10
+ And(concat, &block)
11
+ end
12
+ def Aber(concat, &block)
13
+ But(concat, &block)
14
+ end
15
+ def Dann(concat, &block)
16
+ Then(concat, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+
@@ -0,0 +1,23 @@
1
+ module Restfulie
2
+ module Client
3
+ module Mikyung
4
+ module Languages
5
+ module Portuguese
6
+ def Quando(concat, &block)
7
+ When(concat, &block)
8
+ end
9
+ def E(concat, &block)
10
+ And(concat, &block)
11
+ end
12
+ def Mas(concat, &block)
13
+ But(concat, &block)
14
+ end
15
+ def Entao(concat, &block)
16
+ Then(concat, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
@@ -1,114 +1,191 @@
1
1
  # a configuration error
2
- class Restfulie::Client::Mikyung::ConfigurationError < Restfulie::Common::Error::RestfulieError
3
- end
2
+ module Restfulie
3
+ module Client
4
+ module Mikyung
5
+ class ConfigurationError < Restfulie::Common::Error::RestfulieError
6
+ end
4
7
 
5
- # Provides a DSL to build your process in a human readable way.
6
- #
7
- # Example:
8
- # When there is a machine
9
- # And already installed
10
- # Then reboot
11
- #
12
- # Before creating your DSL you should provide your method content:
13
- #
14
- # When /there (are|is an|is a|is) (.*)/ do |resource, regex|
15
- # resource.keys.first==regex[2]
16
- # end
17
- #
18
- # When "already installed" do |resource|
19
- # @installed
20
- # end
21
- #
22
- # Then "reboot" do |resource|
23
- # resource.machine.boot.post! :boot => {:reason => "Installed #{@software[:name]}"}
24
- # end
25
- class Restfulie::Client::Mikyung::RestProcessModel
26
-
27
- # concatenates anything to a current expression
28
- def method_missing(sym, *args)
29
- Restfulie::Client::Mikyung::Concatenator.new(sym.to_s, *args)
30
- end
31
-
32
- # the list of results
33
- def then_rules
34
- @then_rules ||= []
35
- end
36
-
37
- # the list of conditions
38
- def conditions
39
- @conditions ||= []
40
- end
41
-
42
- # the list of conditional rules
43
- def when_rules
44
- @when_rules ||= []
45
- end
46
-
47
- # creates a When rule or block
48
- #
49
- # When blocks should return true or false whether the current resource matches what you expect:
50
- # When /there (are|is an|is a|is) (.*)/ do |resource, regex|
51
- # resource.keys.first==regex[2]
52
- # end
53
- #
54
- # When rules will group conditions and rules together:
55
- # When there is a machine
56
- # And already installed
57
- # Then reboot
58
- def When(concat, &block)
59
- if concat.respond_to? :content
60
- @condition = when_factory(concat)
61
- conditions << @condition
62
- else
63
- when_rules << [concat, block]
64
- end
65
- end
66
-
67
- # Adds a constraint to the current scenario
68
- def And(concat)
69
- @condition.and when_factory(concat)
70
- end
71
-
72
- # Adds a negative constraint to the current scenario
73
- def But(concat)
74
- @condition.but when_factory(concat)
75
- end
76
-
77
- # Creates a result rule
78
- #
79
- # example:
80
- # Then "reboot" do |resource|
81
- # resource.machine.boot.post! :boot => {:reason => "Installed #{@software[:name]}"}
82
- # end
83
- def Then(concat, &block)
84
- if concat.respond_to? :content
85
- @condition.results_on Restfulie::Client::Mikyung::ThenCondition.new(concat.content)
86
- else
87
- then_rules << [concat, block]
88
- end
89
- end
8
+ class CompletionCriteriaMissingError < Restfulie::Common::Error::RestfulieError
9
+ end
90
10
 
91
- # Goes through every scenario and finds which one fits the current server steady state.
92
- # Picks this step and executes the business rule attached to it.
93
- def next_step(resource, mikyung)
94
- conditions.each do |c|
95
- if c.should_run_for(resource, self)
96
- return c.execute(resource, self, mikyung)
11
+ class StepsFileNotFoundError < Restfulie::Common::Error::RestfulieError
12
+ end
13
+
14
+ class ScenarioFileNotFoundError < StepsFileNotFoundError
15
+ end
16
+
17
+ # Provides a DSL to build your process in a human readable way.
18
+ #
19
+ # Example:
20
+ # When there is a machine
21
+ # And already installed
22
+ # Then reboot
23
+ #
24
+ # Before creating your DSL you should provide your method content:
25
+ #
26
+ # When /there (are|is an|is a|is) (.*)/ do |resource, regex|
27
+ # resource.keys.first==regex[2]
28
+ # end
29
+ #
30
+ # When "already installed" do |resource|
31
+ # @installed
32
+ # end
33
+ #
34
+ # Then "reboot" do |resource|
35
+ # resource.machine.boot.post! :boot => {:reason => "Installed #{@software[:name]}"}
36
+ # end
37
+ class RestProcessModel
38
+ @@at = ""
39
+ @@follow = false
40
+ @@accept = "application/atom+xml"
41
+ @@current_dir = ""
42
+
43
+ def self.at(uri)
44
+ @@at = uri
45
+ end
46
+
47
+ def self.follow(bool)
48
+ @@follow = bool
49
+ end
50
+
51
+ def self.accept(type)
52
+ @@accept = type
53
+ end
54
+
55
+ def self.current_dir(dir)
56
+ @@current_dir = dir
57
+ end
58
+
59
+ def self.get_restfulie
60
+ Restfulie.at(@@at).tap do |client|
61
+ client.follow if @@follow
62
+ client.accepts(@@accept) if @@accept
63
+ end
64
+ end
65
+
66
+ # concatenates anything to a current expression
67
+ def method_missing(sym, *args)
68
+ Restfulie::Client::Mikyung::Concatenator.new(sym.to_s, *args)
69
+ end
70
+
71
+ # the list of results
72
+ def then_rules
73
+ @then_rules ||= []
74
+ end
75
+
76
+ # the list of conditions
77
+ def conditions
78
+ @conditions ||= []
79
+ end
80
+
81
+ # the list of conditional rules
82
+ def when_rules
83
+ @when_rules ||= []
84
+ end
85
+
86
+ # creates a When rule or block
87
+ #
88
+ # When blocks should return true or false whether the current resource matches what you expect:
89
+ # When /there (are|is an|is a|is) (.*)/ do |resource, regex|
90
+ # resource.keys.first==regex[2]
91
+ # end
92
+ #
93
+ # When rules will group conditions and rules together:
94
+ # When there is a machine
95
+ # And already installed
96
+ # Then reboot
97
+ def When(concat, &block)
98
+ if concat.respond_to? :content
99
+ @condition = when_factory(concat)
100
+ conditions << @condition
101
+ else
102
+ when_rules << [concat, block]
103
+ end
104
+ end
105
+
106
+ # Adds a constraint to the current scenario
107
+ def And(concat)
108
+ @condition.and when_factory(concat)
109
+ end
110
+
111
+ # Adds a negative constraint to the current scenario
112
+ def But(concat)
113
+ @condition.but when_factory(concat)
114
+ end
115
+
116
+ # Creates a result rule
117
+ #
118
+ # example:
119
+ # Then "reboot" do |resource|
120
+ # resource.machine.boot.post! :boot => {:reason => "Installed #{@software[:name]}"}
121
+ # end
122
+ def Then(concat, &block)
123
+ if concat.respond_to? :content
124
+ @condition.results_on Restfulie::Client::Mikyung::ThenCondition.new(concat.content)
125
+ else
126
+ then_rules << [concat, block]
127
+ end
128
+ end
129
+
130
+ # Goes through every scenario and finds which one fits the current server steady state.
131
+ # Picks this step and executes the business rule attached to it.
132
+ def next_step(resource, mikyung)
133
+ conditions.each do |c|
134
+ if c.should_run_for(resource, self)
135
+ return c.execute(resource, self, mikyung)
136
+ end
137
+ end
138
+ nil
139
+ end
140
+
141
+ # load step definitions from the 'steps/[class_name].rb'
142
+ # otherwise you can simply override this method with a module
143
+ def steps
144
+ unless @steps_loaded
145
+ step_file = File.expand_path("./steps/#{self.class.name.underscore}.rb", @@current_dir)
146
+ if File.exists?(step_file)
147
+ self.instance_eval File.read(step_file), __FILE__, __LINE__ + 1
148
+ else
149
+ raise StepsFileNotFoundError.new("File #{step_file} not found")
150
+ end
151
+ @steps_loaded = true
152
+ end
153
+ end
154
+
155
+ # load scenario definition from 'scenarios/[class_name].scenario'
156
+ # otherwise you can simply override this method with a module
157
+ def scenario
158
+ unless @scenarios_loaded
159
+ scenario_file = File.expand_path("./scenarios/#{self.class.name.underscore}.scenario", @@current_dir)
160
+ if File.exists?(scenario_file)
161
+ self.instance_eval File.read(scenario_file), __FILE__, __LINE__ + 1
162
+ else
163
+ raise ScenarioFileNotFoundError.new("File #{scenario_file} not found")
164
+ end
165
+ @scenarios_loaded = true
166
+ end
167
+ end
168
+
169
+ # you need to override this method to provide a completion
170
+ # criteria. Will raise an error otherwise
171
+ def completed?(resource)
172
+ raise CompletionCriteriaMissingError.new
173
+ end
174
+
175
+ private
176
+
177
+ def when_factory(concat)
178
+ rule = when_rules.find do |rule|
179
+ concat.content.match(rule[0])
180
+ end
181
+ if rule.nil?
182
+ raise Restfulie::Client::Mikyung::ConfigurationError, "You forgot to create '#{concat.content}' prior to its usage."
183
+ end
184
+ Restfulie::Client::Mikyung::WhenCondition.new(concat.content, rule, concat.content.match(rule[0]))
185
+ end
97
186
  end
98
187
  end
99
- nil
100
- end
101
-
102
- private
103
-
104
- def when_factory(concat)
105
- rule = when_rules.find do |rule|
106
- concat.content.match(rule[0])
107
- end
108
- if rule.nil?
109
- raise Restfulie::Client::Mikyung::ConfigurationError, "You forgot to create '#{concat.content}' prior to its usage."
110
- end
111
- Restfulie::Client::Mikyung::WhenCondition.new(concat.content, rule, concat.content.match(rule[0]))
112
188
  end
113
-
114
189
  end
190
+
191
+