aws-sdk 1.3.4 → 1.3.5

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 (47) hide show
  1. data/lib/aws.rb +2 -0
  2. data/lib/aws/api_config/SimpleWorkflow-2012-01-25.yml +1163 -0
  3. data/lib/aws/core.rb +16 -11
  4. data/lib/aws/core/configuration.rb +65 -47
  5. data/lib/aws/dynamo_db/item_collection.rb +2 -3
  6. data/lib/aws/dynamo_db/table.rb +2 -2
  7. data/lib/aws/ec2/collection.rb +1 -1
  8. data/lib/aws/ec2/snapshot_collection.rb +1 -1
  9. data/lib/aws/ec2/tagged_collection.rb +6 -1
  10. data/lib/aws/elb/backend_server_policy_collection.rb +1 -11
  11. data/lib/aws/elb/load_balancer.rb +4 -4
  12. data/lib/aws/elb/load_balancer_collection.rb +1 -1
  13. data/lib/aws/iam/policy.rb +1 -1
  14. data/lib/aws/record.rb +10 -4
  15. data/lib/aws/record/hash_model/finder_methods.rb +2 -3
  16. data/lib/aws/s3/bucket_lifecycle_configuration.rb +2 -2
  17. data/lib/aws/s3/policy.rb +1 -1
  18. data/lib/aws/simple_email_service.rb +8 -2
  19. data/lib/aws/simple_workflow.rb +223 -0
  20. data/lib/aws/simple_workflow/activity_task.rb +173 -0
  21. data/lib/aws/simple_workflow/activity_task_collection.rb +112 -0
  22. data/lib/aws/simple_workflow/activity_type.rb +131 -0
  23. data/lib/aws/simple_workflow/activity_type_collection.rb +93 -0
  24. data/lib/aws/simple_workflow/client.rb +57 -0
  25. data/lib/aws/simple_workflow/config.rb +18 -0
  26. data/lib/aws/simple_workflow/count.rb +49 -0
  27. data/lib/aws/simple_workflow/decision_task.rb +603 -0
  28. data/lib/aws/simple_workflow/decision_task_collection.rb +213 -0
  29. data/lib/aws/simple_workflow/domain.rb +122 -0
  30. data/lib/aws/simple_workflow/domain_collection.rb +169 -0
  31. data/lib/aws/simple_workflow/errors.rb +57 -0
  32. data/lib/aws/simple_workflow/history_event.rb +276 -0
  33. data/lib/aws/simple_workflow/history_event_collection.rb +76 -0
  34. data/lib/aws/simple_workflow/option_formatters.rb +75 -0
  35. data/lib/aws/simple_workflow/request.rb +80 -0
  36. data/lib/aws/simple_workflow/resource.rb +94 -0
  37. data/lib/aws/simple_workflow/type.rb +89 -0
  38. data/lib/aws/simple_workflow/type_collection.rb +139 -0
  39. data/lib/aws/simple_workflow/workflow_execution.rb +386 -0
  40. data/lib/aws/simple_workflow/workflow_execution_collection.rb +617 -0
  41. data/lib/aws/simple_workflow/workflow_type.rb +177 -0
  42. data/lib/aws/simple_workflow/workflow_type_collection.rb +91 -0
  43. data/lib/aws/sns/policy.rb +1 -1
  44. data/lib/aws/sns/subscription.rb +2 -2
  45. data/lib/aws/sqs/errors.rb +2 -2
  46. data/lib/aws/sqs/policy.rb +1 -1
  47. metadata +111 -54
@@ -44,7 +44,7 @@ module AWS
44
44
  #
45
45
  # == Adding Rules
46
46
  #
47
- # You can add a rule to a bucket lifecycle configuration using #{add_rule}.
47
+ # You can add a rule to a bucket lifecycle configuration using {#add_rule}.
48
48
  #
49
49
  # # add a rule that deletes backups after they are 1 year old
50
50
  # bucket.lifecycle_configuration.update do
@@ -62,7 +62,7 @@ module AWS
62
62
  # == Replacing Rules
63
63
  #
64
64
  # If you prefer to completely replace a lifecycle configuration, call
65
- # #add_rule inside a #replace block instead of an #update block:
65
+ # {#add_rule} inside a #replace block instead of an #update block:
66
66
  #
67
67
  # # replace all existing rules with the following
68
68
  # bucket.lifecycle_configuration.replace do
@@ -14,7 +14,7 @@
14
14
  module AWS
15
15
  class S3
16
16
 
17
- # @see Core::Policy
17
+ # (see Core::Policy)
18
18
  class Policy < Core::Policy
19
19
 
20
20
  class Statement < Core::Policy::Statement
@@ -290,8 +290,14 @@ module AWS
290
290
  send_opts = {}
291
291
  send_opts[:raw_message] = {}
292
292
  send_opts[:raw_message][:data] = raw_message.to_s
293
- send_opts[:source] = options[:from] if options[:from]
294
- send_opts[:destinations] = [options[:to]].flatten if options[:to]
293
+
294
+ if raw_message.class.name == 'Mail::Message'
295
+ send_opts[:source] = raw_message.from.first
296
+ send_opts[:destinations] = raw_message.destinations
297
+ else
298
+ send_opts[:source] = options[:from] if options[:from]
299
+ send_opts[:destinations] = [options[:to]].flatten if options[:to]
300
+ end
295
301
 
296
302
  client.send_raw_email(send_opts)
297
303
  nil
@@ -0,0 +1,223 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/core'
15
+ require 'aws/simple_workflow/config'
16
+
17
+ module AWS
18
+
19
+ # This is the starting point for working with Amazon Simple Workflow Service.
20
+ #
21
+ # = Domains
22
+ #
23
+ # To get started, you need to first create a domain. Domains are used to
24
+ # organize related tasks and activities.
25
+ #
26
+ # swf = AWS::SimpleWorkflow.new
27
+ #
28
+ # # name the domain and specify the retention period (in days)
29
+ # domain = swf.domains.create('my-domain', 10)
30
+ #
31
+ # You can reference existin domains as well.
32
+ #
33
+ # domain = swf.domains['my-domain']
34
+ #
35
+ # = Workflow and Activity Types
36
+ #
37
+ # Once you have a domain you can create a workflow and
38
+ # activity types. Both types (workflow and activity) are templates that
39
+ # can be used to start workflow executions or schedule activity tasks.
40
+ #
41
+ # Workflow and Acitivity types both have a number of default values
42
+ # (e.g. default task list, timeouts, etc). If you do not specify these
43
+ # optional default values when creating the type, you *MUST* specify
44
+ # the actual values when starting a workflow execution or scheduling
45
+ # an activity task.
46
+ #
47
+ # == Sample Workflow type and activity type
48
+ #
49
+ # # register an workflow type with the version id '1'
50
+ # workflow_type = domain.workflow_types.create('my-long-processes', '1',
51
+ # :default_task_list => 'my-task-list',
52
+ # :default_child_policy => :request_cancel,
53
+ # :default_task_start_to_close_timeout => 3600,
54
+ # :default_execution_start_to_close_timeout => 24 * 3600)
55
+ #
56
+ # # register an activity type, with the version id '1'
57
+ # activity_type = domain.activity_types.create('do-something', '1',
58
+ # :default_task_list => 'my-task-list',
59
+ # :default_task_heartbeat_timeout => 900,
60
+ # :default_task_schedule_to_start_timeout => 60,
61
+ # :default_task_schedule_to_close_timeout => 3660,
62
+ # :default_task_start_to_close_timeout => 3600)
63
+ #
64
+ # = Starting a Workflow Execution
65
+ #
66
+ # Once you have a domain and at least one workflow type you can
67
+ # start a workflow execution. You may provide a workflow id, or a
68
+ # random one will be generated. You may also provide optional
69
+ # input and override any of the defaults registered with the
70
+ # workflow type.
71
+ #
72
+ # workflow_execution = workflow_type.start_execution :input => '...'
73
+ #
74
+ # workflow_execution.workflow_id #=> "5abbdd75-70c7-4af3-a324-742cd29267c2"
75
+ # workflow_execution.run_id #=> "325a8c34-d133-479e-9ecf-5a61286d165f"
76
+ #
77
+ # = Decision Tasks
78
+ #
79
+ # Once a workflow execution has been started, it will start to generte
80
+ # decision tasks. You poll for decision tasks from a task list.
81
+ # Yielded decsion tasks provide access to the history of events
82
+ # for the workflow execution. You can also enumerate only new
83
+ # events since the last decision.
84
+ #
85
+ # To make decisions you call methods from the list below. You can call
86
+ # any number of decision methods any number of times.
87
+ #
88
+ # * schedule_activity_task
89
+ # * request_cancel_activity_task
90
+ # * complete_workflow_execution
91
+ # * fail_workflow_execution
92
+ # * cancel_workflow_execution
93
+ # * continue_as_new_workflow_execution
94
+ # * record_marker
95
+ # * start_timer
96
+ # * cancel_timer
97
+ # * signal_external_workflow_execution
98
+ # * request_cancel_external_workflow_execution workflow_execution, options = {}
99
+ # * start_child_workflow_execution workflow_type, options = {}
100
+ #
101
+ # # poll for decision tasks from 'my-task-list'
102
+ # domain.decision_tasks.poll('my-task-list') do |decision_task|
103
+ #
104
+ # # invesitate new events and make decisions
105
+ # decision_task.new_events.each do |event|
106
+ # case event.event_type
107
+ # when 'WorkflowExecutionStarted'
108
+ # task.schedule_activity_task 'do-something', :input => 'abc xyz'
109
+ # when 'ActivityTaskCompleted'
110
+ # task.comlete_workflow_execution :results => event.attributes.result
111
+ # end
112
+ # end
113
+ #
114
+ # end # decision task is completed here
115
+ #
116
+ # When you are done calling decision methods, you need to complete the
117
+ # decision task. This is done by default if you pass a block to
118
+ # +poll+ or +poll_for_single_task+.
119
+ #
120
+ # = Activity Tasks
121
+ #
122
+ # The only way to spawn activity tasks is to call +schedule_activity_task+
123
+ # on a decision task. Scheduled activity tasks are returned when you
124
+ # poll for activity tasks.
125
+ #
126
+ # # poll 'my-task-list' for activities
127
+ # domain.activity_tasks.poll('my-task-list') do |activity_task|
128
+ #
129
+ # case activity_task.activity_type.name
130
+ # when 'do-something'
131
+ # # ...
132
+ # else
133
+ # activity_task.fail! :reason => 'unknown activity task type'
134
+ # end
135
+ #
136
+ # end
137
+ #
138
+ # == Activity Task Heartbeats
139
+ #
140
+ # When you receive an activity task, you need to update the service
141
+ # with status messages. This is called recording a heartbeat.#
142
+ # To record a heartbeat, just call {ActivityTask#record_heartbeat!}.
143
+ # When you call +record_heartbeat+ you should rescue
144
+ # {ActivityTask::CancelRequestedError}. These are thrown when a task
145
+ # should be canceled. You can cleanup the task and then call
146
+ # +cancel!+ when you are finished.
147
+ #
148
+ # # poll 'my-task-list' for activities
149
+ # domain.activity_tasks.poll('my-task-list') do |activity_task|
150
+ # begin
151
+ #
152
+ # # do stuff ...
153
+ #
154
+ # activity_task.record_heartbeat! :details => '25%'
155
+ #
156
+ # # do more stuff ...
157
+ #
158
+ # activity_task.record_heartbeat! :details => '50%'
159
+ #
160
+ # # do more stuff ...
161
+ #
162
+ # activity_task.record_heartbeat! :details => '75%'
163
+ #
164
+ # # do more stuff ...
165
+ #
166
+ # rescue ActivityTask::CancelRequestedError
167
+ # # cleanup after ourselves
168
+ # activity_task.cancel!
169
+ # end
170
+ # end
171
+ #
172
+ # Like decision tasks, activity tasks are auto-completed at the
173
+ # end of a poll block.
174
+ #
175
+ # = History Events
176
+ #
177
+ # You might want to view the event history for a running workflow
178
+ # execution. You can get a workflow execution by its workflow
179
+ # id (you may optionally provide the run id as well).
180
+ #
181
+ # execution = domain.workflow_executions['workflow-id']
182
+ # execution.events.each do |event|
183
+ # puts event.attributes.to_h.inspect
184
+ # end
185
+ #
186
+ # See {HistoryEvent} and {HistoryEvent::Attributes} for more information.
187
+ #
188
+ class SimpleWorkflow
189
+
190
+ AWS.register_autoloads(self, 'aws/simple_workflow') do
191
+ autoload :ActivityType, 'activity_type'
192
+ autoload :ActivityTypeCollection, 'activity_type_collection'
193
+ autoload :ActivityTask, 'activity_task'
194
+ autoload :ActivityTaskCollection, 'activity_task_collection'
195
+ autoload :Client, 'client'
196
+ autoload :Count, 'count'
197
+ autoload :DecisionTask, 'decision_task'
198
+ autoload :DecisionTaskCollection, 'decision_task_collection'
199
+ autoload :Domain, 'domain'
200
+ autoload :DomainCollection, 'domain_collection'
201
+ autoload :Errors, 'errors'
202
+ autoload :HistoryEvent, 'history_event'
203
+ autoload :HistoryEventCollection, 'history_event_collection'
204
+ autoload :OptionFormatters, 'option_formatters'
205
+ autoload :Request, 'request'
206
+ autoload :Resource, 'resource'
207
+ autoload :Type, 'type'
208
+ autoload :TypeCollection, 'type_collection'
209
+ autoload :WorkflowExecution, 'workflow_execution'
210
+ autoload :WorkflowExecutionCollection, 'workflow_execution_collection'
211
+ autoload :WorkflowType, 'workflow_type'
212
+ autoload :WorkflowTypeCollection, 'workflow_type_collection'
213
+ end
214
+
215
+ include Core::ServiceInterface
216
+
217
+ # @return [DomainCollection]
218
+ def domains
219
+ DomainCollection.new(:config => config)
220
+ end
221
+
222
+ end
223
+ end
@@ -0,0 +1,173 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ module AWS
15
+ class SimpleWorkflow
16
+ class ActivityTask
17
+
18
+ # Raised by {ActivityTask#record_heartbeat!} when this activity
19
+ # task has received a cancelation request.
20
+ class CancelRequestedError < StandardError; end
21
+
22
+ include Core::Model
23
+
24
+ # @private
25
+ def initialize domain, data, options = {}
26
+
27
+ @domain = domain
28
+
29
+ @task_token = data['taskToken']
30
+ @activity_id = data['activityId']
31
+ @started_event_id = data['startedEventId']
32
+ @input = data['input']
33
+
34
+ name = data['activityType']['name']
35
+ version = data['activityType']['version']
36
+ @activity_type = domain.activity_types[name,version]
37
+
38
+ workflow_id = data['workflowExecution']['workflowId']
39
+ run_id = data['workflowExecution']['runId']
40
+ @workflow_execution = domain.workflow_executions[workflow_id,run_id]
41
+
42
+ super
43
+
44
+ end
45
+
46
+ # @return [String] The opaque string used as a handle on the task.
47
+ attr_reader :task_token
48
+
49
+ # @return [String] The unique identifier of this task.
50
+ attr_reader :activity_id
51
+
52
+ # @return [Domain] The domain this task was scheduled in.
53
+ attr_reader :domain
54
+
55
+ # @return [Integer] The id of the ActivityTaskStarted event recorded
56
+ # in the history.
57
+ attr_reader :started_event_id
58
+
59
+ # @return [String,nil] The input provided when the activity task was
60
+ # scheduled.
61
+ attr_reader :input
62
+
63
+ # @return [ActivityType]
64
+ attr_reader :activity_type
65
+
66
+ # @return [WorkflowExecution]
67
+ attr_reader :workflow_execution
68
+
69
+ # Reports to the service that the activity task is progressing.
70
+ #
71
+ # You can optionally specifiy +:details+ that decibe the progress.
72
+ # This might be a percetnage completetion, step number, etc.
73
+ #
74
+ # activity_task.record_heartbeat! :details => '.75' # 75% complete
75
+ #
76
+ # If the activity task has been canceled since it was received or
77
+ # since the last recorded heartbeat, this method will raise
78
+ # a CancelRequestedError.
79
+ #
80
+ # If you are processing the activity task inside a block passed
81
+ # to one of the polling methods in {ActivityTaskCollection}
82
+ # then untrapped CancelRequestedErrors are caught
83
+ # and responded to automatically.
84
+ #
85
+ # domain.activity_tasks.poll('task-list') do |task|
86
+ #
87
+ # task.record_heartbeat! # raises CancelRequestedError
88
+ #
89
+ # end # traps the error and responds activity task cancled.
90
+ #
91
+ # If you need to cleanup or provide addtional details in the
92
+ # cancelation response, you can trap the error and
93
+ # respond manually.
94
+ #
95
+ # domain.activity_tasks.poll('task-list') do |task|
96
+ #
97
+ # task.record_heartbeat! # raises CancelRequestedError
98
+ #
99
+ # rescue CancelRequestedError => e
100
+ #
101
+ # # cleanup
102
+ #
103
+ # task.respond_canceled! :details => '...'
104
+ #
105
+ # end
106
+ #
107
+ # @param [Hash] options
108
+ #
109
+ # @option options [String] :details (nil)
110
+ # If specified, contains details about the progress of the task.
111
+ #
112
+ def record_heartbeat! options = {}
113
+
114
+ client_opts = {}
115
+ client_opts[:task_token] = task_token
116
+ client_opts[:details] = options[:details] if options[:details]
117
+
118
+ response = client.record_activity_task_heartbeat(client_opts)
119
+
120
+ raise CancelRequestedError if response.data['cancelRequested']
121
+
122
+ nil
123
+
124
+ end
125
+
126
+ # @param [Hash] options
127
+ #
128
+ # @option options [String] :result (nil)
129
+ #
130
+ # @return [nil]
131
+ #
132
+ def complete! options = {}
133
+ respond :completed, options
134
+ end
135
+
136
+ # @param [Hash] options
137
+ #
138
+ # @option options [String] :details (nil)
139
+ #
140
+ # @return [nil]
141
+ #
142
+ def cancel! options = {}
143
+ respond :canceled, options
144
+ end
145
+
146
+ # @param [Hash] options
147
+ #
148
+ # @option options [String] :details (nil)
149
+ #
150
+ # @option options [String] :reason (nil)
151
+ #
152
+ # @return [nil]
153
+ #
154
+ def fail! options = {}
155
+ respond :failed, options
156
+ end
157
+
158
+ def responded?
159
+ !!@responded
160
+ end
161
+
162
+ protected
163
+ def respond status, options
164
+ raise "already responded" if responded?
165
+ @responded = status
166
+ options[:task_token] = task_token
167
+ client.send("respond_activity_task_#{status}", options)
168
+ nil
169
+ end
170
+
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,112 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ module AWS
15
+ class SimpleWorkflow
16
+
17
+ class ActivityTaskCollection
18
+
19
+ include Core::Model
20
+ include OptionFormatters
21
+
22
+ # @private
23
+ def initialize domain, options = {}
24
+ @domain = domain
25
+ super
26
+ end
27
+
28
+ # @return [Domain]
29
+ attr_reader :domain
30
+
31
+ # Returns the number of tasks in the specified +task_list+.
32
+ #
33
+ # @note This operation is eventually consistent. The results are best
34
+ # effort and may not exactly reflect recent updates and changes.
35
+ #
36
+ # @param [String] task_list The name of the task list.
37
+ #
38
+ # @return [Count] Returns a possibly truncated count of
39
+ # pending activity tasks for the given +task_list+.
40
+ #
41
+ def count task_list
42
+ options = {}
43
+ options[:domain] = domain.name
44
+ options[:task_list] = { :name => task_list }
45
+ response = client.count_pending_activity_tasks(options)
46
+ Count.new(response.data['count'], response.data['truncated'])
47
+ end
48
+
49
+ # @param [String] task_list The task list to check for pending
50
+ # activity tasks in.
51
+ #
52
+ # @param [Hash] options
53
+ #
54
+ # @option options [String] :identity (nil) Identity of the worker
55
+ # making the request, which is recorded in the ActivityTaskStarted
56
+ # event in the workflow history. This enables diagnostic tracing
57
+ # when problems arise. The form of this identity is user defined.
58
+ #
59
+ # @yieldparam [ActivityTask] activity_task Yields if a task is
60
+ # available within 60 seconds.
61
+ #
62
+ # @return [ActivityTask,nil] Returns an activity task when one is
63
+ # available, +nil+ otherwise. If you call this function with
64
+ # a block, +nil+ is always returned.
65
+ #
66
+ def poll_for_single_task task_list, options = {}, &block
67
+
68
+ client_opts = {}
69
+ client_opts[:domain] = domain.name
70
+ client_opts[:task_list] = { :name => task_list }
71
+ client_opts[:identity] = options[:identity] if options[:identity]
72
+
73
+ response = client.poll_for_activity_task(client_opts)
74
+
75
+ if response.data['taskToken']
76
+ activity_task = ActivityTask.new(domain, response.data)
77
+ if block_given?
78
+ begin
79
+ yield(activity_task)
80
+ activity_task.complete! unless activity_task.responded?
81
+ rescue ActivityTask::CancelRequestedError
82
+ activity_task.cancel! unless activity_task.responded?
83
+ rescue StandardError => e
84
+ unless activity_task.responded?
85
+ reason = "UNTRAPPED ERROR: #{e.message}"
86
+ details = e.backtrace.join("\n")
87
+ activity_task.fail!(:reason => reason, :details => details)
88
+ end
89
+ raise e
90
+ end
91
+ nil
92
+ else
93
+ activity_task
94
+ end
95
+ else
96
+ nil
97
+ end
98
+
99
+ end
100
+
101
+ def poll task_list, options = {}, &block
102
+ loop do
103
+ poll_for_single_task(task_list, options) do |activity_task|
104
+ yield(activity_task)
105
+ end
106
+ end
107
+ nil
108
+ end
109
+
110
+ end
111
+ end
112
+ end