aws-flow 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/lib/aws/decider/options.rb +23 -18
- data/lib/aws/decider/task_poller.rb +2 -2
- data/lib/aws/decider/utilities.rb +8 -3
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/replayer.rb +113 -32
- data/spec/aws/decider/unit/decider_spec.rb +43 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDI2ZDNmZmEwMDNiODkwZWY0ODBkZDI0ZDM1OTFjZjBjZGU4YzJjZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzExMWQ1YjhkZjZmZWVlMTQ4MDU4NTFmNjkxYjUwNTVjMTU5YTIxMA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NWRkNTIyNjk3ZmNkM2E4NWNjYTU3NTIyNTE0NjhjOGEzZjY5YjAwMDcwMTRj
|
10
|
+
YWNhOTNlM2E3M2E4ZDdhNGYzNGY4OTU4MjljMjBhOTIwMjIwNGNlYWVkM2Y0
|
11
|
+
MzVjODgyYjcyYjQ3NWU3NTJhNzM1M2RkNDNmNDI0MTJkMzUzNDQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MjA3NDUyYWVmOTJiMzUwODMwZTVjOGY3ODhlYWY1YzBmYTM4NzdjOWUyYjZh
|
14
|
+
ZGU2YjMxNTBjYTgyMGYzY2RiNTEyMWM1NzZiOGNhZTI1MDc5ZjI1NjhiY2Yy
|
15
|
+
ZWI4ZTU5NWMzZTI1NTZkYzNiNjA4YTA5NTdjNTI1YzMyYmYxMmU=
|
data/lib/aws/decider/options.rb
CHANGED
@@ -537,43 +537,50 @@ module AWS
|
|
537
537
|
def data_converter; FlowConstants.default_data_converter; end
|
538
538
|
end
|
539
539
|
|
540
|
+
# Default values for a registered activity type. These values are set by
|
541
|
+
# default for all activities that use the activity type.
|
540
542
|
class ActivityRegistrationDefaults < ActivityDefaults
|
541
543
|
|
542
|
-
# The default schedule-to-start timeout for activity tasks.
|
543
|
-
# represents the time, in seconds, between when the activity
|
544
|
-
# scheduled to when it is started.
|
544
|
+
# *Optional*. The default schedule-to-start timeout for activity tasks.
|
545
|
+
# This timeout represents the time, in seconds, between when the activity
|
546
|
+
# task is first scheduled to when it is started.
|
545
547
|
#
|
546
548
|
# This default can be overridden when scheduling an activity task. You can
|
547
549
|
# set this value to "NONE" to imply no timeout value.
|
548
550
|
def default_task_schedule_to_start_timeout; Float::INFINITY; end
|
549
551
|
|
550
|
-
# The default schedule-to-close timeout for activity tasks.
|
551
|
-
# represents the time, in seconds, between when the activity
|
552
|
-
# scheduled to when it is closed (whether due to success,
|
553
|
-
# timeout).
|
552
|
+
# *Optional*. The default schedule-to-close timeout for activity tasks.
|
553
|
+
# This timeout represents the time, in seconds, between when the activity
|
554
|
+
# task is first scheduled to when it is closed (whether due to success,
|
555
|
+
# failure, or a timeout).
|
554
556
|
#
|
555
557
|
# This default can be overridden when scheduling an activity task. You can
|
556
558
|
# set this value to "NONE" to imply no timeout value.
|
557
|
-
def default_task_schedule_to_close_timeout;
|
559
|
+
def default_task_schedule_to_close_timeout; Float::INFINITY; end
|
558
560
|
|
559
|
-
# The default start-to-close timeout for activity tasks. This
|
560
|
-
# represents the time, in seconds, between when the activity task
|
561
|
-
# started to when it is closed (whether due to success, failure,
|
562
|
-
# timeout).
|
561
|
+
# *Optional*. The default start-to-close timeout for activity tasks. This
|
562
|
+
# timeout represents the time, in seconds, between when the activity task
|
563
|
+
# is first started to when it is closed (whether due to success, failure,
|
564
|
+
# or a timeout).
|
563
565
|
#
|
564
566
|
# This default can be overridden when scheduling an activity task. You can
|
565
567
|
# set this value to "NONE" to imply no timeout value.
|
566
568
|
def default_task_start_to_close_timeout; Float::INFINITY; end
|
567
569
|
|
568
|
-
# The default maximum time, in seconds, before which a worker
|
569
|
-
# task of this type must report progress.
|
570
|
-
# activity task is automatically timed out. If the worker
|
571
|
-
# attempts to record a heartbeat or returns a result, it will
|
570
|
+
# *Optional*. The default maximum time, in seconds, before which a worker
|
571
|
+
# processing a task of this type must report progress. If the timeout is
|
572
|
+
# exceeded, the activity task is automatically timed out. If the worker
|
573
|
+
# subsequently attempts to record a heartbeat or returns a result, it will
|
574
|
+
# be ignored.
|
572
575
|
#
|
573
576
|
# This default can be overridden when scheduling an activity task. You can
|
574
577
|
# set this value to "NONE" to imply no timeout value.
|
575
578
|
def default_task_heartbeat_timeout; Float::INFINITY; end
|
576
579
|
|
580
|
+
# *Optional*. The default task list to use for all activities that use
|
581
|
+
# this activity type. If not specified, the value
|
582
|
+
# `FlowConstants.use_worker_task_list` will be used, which causes the
|
583
|
+
# activities to use the task list specified for the activity worker.
|
577
584
|
def default_task_list; FlowConstants.use_worker_task_list; end
|
578
585
|
end
|
579
586
|
|
@@ -746,7 +753,6 @@ module AWS
|
|
746
753
|
end
|
747
754
|
result
|
748
755
|
end
|
749
|
-
|
750
756
|
end
|
751
757
|
|
752
758
|
# This class is used to capture the options passed during activity declaration.
|
@@ -786,7 +792,6 @@ module AWS
|
|
786
792
|
def get_registration_options
|
787
793
|
get_options(self.class.registration_options)
|
788
794
|
end
|
789
|
-
|
790
795
|
end
|
791
796
|
|
792
797
|
# Runtime options for an activity.
|
@@ -61,7 +61,7 @@ module AWS
|
|
61
61
|
@logger.debug "Didn't get a task on task_list: #{@task_list}"
|
62
62
|
return false
|
63
63
|
end
|
64
|
-
@logger.info Utilities.workflow_task_to_debug_string("Got decision task", task)
|
64
|
+
@logger.info Utilities.workflow_task_to_debug_string("Got decision task", task, @task_list)
|
65
65
|
|
66
66
|
task_completed_request = @handler.handle_decision_task(task)
|
67
67
|
@logger.debug "Response to the task will be #{task_completed_request.inspect}"
|
@@ -93,7 +93,7 @@ module AWS
|
|
93
93
|
end
|
94
94
|
@logger.error "#{task.workflow_type.inspect} failed with exception: #{e.inspect}"
|
95
95
|
end
|
96
|
-
@logger.info Utilities.workflow_task_to_debug_string("Finished executing task", task)
|
96
|
+
@logger.info Utilities.workflow_task_to_debug_string("Finished executing task", task, @task_list)
|
97
97
|
rescue AWS::SimpleWorkflow::Errors::UnknownResourceFault => e
|
98
98
|
@logger.error "Error in the poller, #{e.inspect}"
|
99
99
|
rescue Exception => e
|
@@ -33,11 +33,16 @@ module AWS
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.workflow_task_to_debug_string(message, task)
|
37
|
-
|
36
|
+
def self.workflow_task_to_debug_string(message, task, task_list)
|
37
|
+
"#{message} #{task.workflow_type.name}.#{task.workflow_type.version} "\
|
38
|
+
"for execution with workflow_id: #{task.workflow_execution.workflow_id}, "\
|
39
|
+
"run_id: #{task.workflow_execution.run_id}, task_list: #{task_list} with "\
|
40
|
+
"task_token: #{task.task_token}"
|
38
41
|
end
|
42
|
+
|
39
43
|
def self.activity_task_to_debug_string(message, task)
|
40
|
-
|
44
|
+
"#{message} #{task.activity_type.name}.#{task.activity_type.version} "\
|
45
|
+
"with input: #{task.input} and task_token: #{task.task_token}"
|
41
46
|
end
|
42
47
|
|
43
48
|
# The following two methods are used to generate an error string when
|
data/lib/aws/decider/version.rb
CHANGED
data/lib/aws/replayer.rb
CHANGED
@@ -1,32 +1,59 @@
|
|
1
1
|
module AWS
|
2
2
|
module Flow
|
3
|
+
# Provides a number of classes useful for debugging workflow executions. For
|
4
|
+
# an example of general use, see {WorkflowReplayer}.
|
5
|
+
#
|
3
6
|
module Replayer
|
4
7
|
require 'aws/decider'
|
5
8
|
include AWS::Flow
|
6
9
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
10
|
+
# Used by {Replayer} to fetch a [DecisionTask][] which will be used by
|
11
|
+
# {DecisionTaskHandler}.
|
12
|
+
#
|
13
|
+
# [DecisionTask]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/DecisionTask.html
|
14
|
+
#
|
15
|
+
# @abstract Implement the `get_history_page` and `get_execution_info` methods to
|
16
|
+
# use it.
|
11
17
|
class DecisionTaskProvider
|
12
18
|
|
13
|
-
#
|
14
|
-
# workflow type
|
15
|
-
# decider to work on
|
19
|
+
# Fetches the workflow history and wraps all the history events,
|
20
|
+
# workflow type and workflow execution inside a decision task for the
|
21
|
+
# decider to work on.
|
22
|
+
#
|
23
|
+
# @param replay_upto [Fixnum] *Optional*. The event_id of the last event
|
24
|
+
# to return. If set, returns the history only until the specified
|
25
|
+
# event is reached. If not set, then all available history will be
|
26
|
+
# returned. See [HistoryEvent][] for more information.
|
27
|
+
#
|
28
|
+
# [HistoryEvent]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/HistoryEvent.html
|
29
|
+
#
|
30
|
+
# @return [DecisionTask] the workflow history encapsulated in a
|
31
|
+
# [DecisionTask][], optionally truncated to the event ID passed to
|
32
|
+
# `replay_upto`.
|
33
|
+
#
|
34
|
+
# [DecisionTask]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/DecisionTask.html
|
35
|
+
#
|
16
36
|
def get_decision_task(replay_upto = nil)
|
37
|
+
|
17
38
|
# Get workflow execution info so that we can populate the workflowType
|
18
|
-
# and execution fields of the DecisionTask.
|
39
|
+
# and execution fields of the [DecisionTask][].
|
40
|
+
#
|
41
|
+
# [DecisionTask]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/DecisionTask.html
|
42
|
+
#
|
19
43
|
execution_info = get_execution_info
|
20
44
|
events = get_history
|
21
45
|
|
22
46
|
# Truncate history if replay_upto variable is set so that we only
|
23
47
|
# replay the history till the specified event
|
48
|
+
#
|
24
49
|
events = truncate_history(events, replay_upto)
|
25
50
|
return nil if events.nil?
|
26
51
|
|
27
|
-
# Generate the hash to instantiate a DecisionTask. We can set
|
28
|
-
# taskToken and nextPageToken to nil since we don't need the
|
29
|
-
# in the replayer
|
52
|
+
# Generate the hash to instantiate a [DecisionTask][]. We can set
|
53
|
+
# *taskToken* and *nextPageToken* to nil since we don't need the
|
54
|
+
# values in the replayer.
|
55
|
+
#
|
56
|
+
# [DecisionTask]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/DecisionTask.html
|
30
57
|
data = {
|
31
58
|
'taskToken' => nil,
|
32
59
|
'workflowExecution' => execution_info["execution"],
|
@@ -37,8 +64,17 @@ module AWS
|
|
37
64
|
AWS::SimpleWorkflow::DecisionTask.new(nil, nil, data)
|
38
65
|
end
|
39
66
|
|
40
|
-
#
|
41
|
-
#
|
67
|
+
# Truncates workflow history to a specified event id.
|
68
|
+
#
|
69
|
+
# @param events the workflow history (events) to truncate.
|
70
|
+
#
|
71
|
+
# @param replay_upto [Fixnum] *Optional*. The event ID of the final
|
72
|
+
# [HistoryEvent][] to return.
|
73
|
+
#
|
74
|
+
# [HistoryEvent]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/HistoryEvent.html
|
75
|
+
#
|
76
|
+
# @return the truncated list of events.
|
77
|
+
#
|
42
78
|
def truncate_history(events, replay_upto = nil)
|
43
79
|
return nil if events.nil? || events.empty?
|
44
80
|
|
@@ -52,21 +88,44 @@ module AWS
|
|
52
88
|
truncated
|
53
89
|
end
|
54
90
|
|
55
|
-
#
|
56
|
-
#
|
91
|
+
# Fetches the workflow history. Implementing classes *must* override
|
92
|
+
# this method.
|
93
|
+
#
|
94
|
+
# @param page_token *Optional*. A token used to get further pages of
|
95
|
+
# workflow history if all events could not be retrieved by the first
|
96
|
+
# call to the method.
|
97
|
+
#
|
98
|
+
# @return a list of [HistoryEvent][]s that comprise the workflow's
|
99
|
+
# available history.
|
100
|
+
#
|
101
|
+
# [HistoryEvent]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/HistoryEvent.html
|
102
|
+
#
|
57
103
|
def get_history(page_token = nil); end
|
58
104
|
|
59
|
-
#
|
60
|
-
# DecisionTask details. Implementing classes must override this
|
105
|
+
# Fetches the workflow execution information used to fill in the
|
106
|
+
# [DecisionTask][] details. Implementing classes *must* override this
|
107
|
+
# method.
|
108
|
+
#
|
109
|
+
# @return the workflow execution information as returned by
|
110
|
+
# [AWS::SimpleWorkflow::Client#describe_workflow_execution][].
|
111
|
+
#
|
112
|
+
# [AWS::SimpleWorkflow::Client#describe_workflow_execution]: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/Client.html#describe_workflow_execution-instance_method
|
61
113
|
def get_execution_info; end
|
62
114
|
|
63
115
|
end
|
64
116
|
|
65
|
-
#
|
66
|
-
# SimpleWorkflowService
|
117
|
+
# Loads a decision task directly from the AWS Simple Workflow Service.
|
67
118
|
class ServiceDecisionTaskProvider < DecisionTaskProvider
|
68
119
|
attr_reader :domain, :execution, :swf
|
69
120
|
|
121
|
+
# Initialize a new **ServiceDecisionTaskProvider**.
|
122
|
+
#
|
123
|
+
# @param options a hash of options to provide. Entries for `:domain` and
|
124
|
+
# `:execution` must be present in the hash.
|
125
|
+
#
|
126
|
+
# @raise |ArgumentError| if either `:domain` or `:execution` is missing
|
127
|
+
# from the *options* parameter.
|
128
|
+
#
|
70
129
|
def initialize(options = {})
|
71
130
|
raise ArgumentError.new("options hash must contain :domain") if options[:domain].nil?
|
72
131
|
raise ArgumentError.new("options hash must contain :execution") if options[:execution].nil?
|
@@ -75,6 +134,7 @@ module AWS
|
|
75
134
|
@swf = AWS::SimpleWorkflow.new.client
|
76
135
|
end
|
77
136
|
|
137
|
+
# Get the complete workflow history.
|
78
138
|
def get_history
|
79
139
|
events = []
|
80
140
|
# Get the first page of the workflow history
|
@@ -89,9 +149,12 @@ module AWS
|
|
89
149
|
events
|
90
150
|
end
|
91
151
|
|
92
|
-
#
|
152
|
+
# Fetches a page of workflow history.
|
153
|
+
#
|
154
|
+
# @param page_token *Optional*. A page token used to retrieve a
|
155
|
+
# particular page of results.
|
93
156
|
def get_history_page(page_token = nil)
|
94
|
-
#
|
157
|
+
# Generate the request options for the service call. Optionally merge
|
95
158
|
# next_page_token to the hash if the page_token value is not nil.
|
96
159
|
request_opts = {
|
97
160
|
domain: @domain,
|
@@ -101,8 +164,11 @@ module AWS
|
|
101
164
|
@swf.get_workflow_execution_history(request_opts)
|
102
165
|
end
|
103
166
|
|
104
|
-
#
|
105
|
-
# information
|
167
|
+
# Call AWS Simple Workflow Service to get workflow execution
|
168
|
+
# information.
|
169
|
+
#
|
170
|
+
# @return the execution information based on the `:execution` and
|
171
|
+
# `:domain` provided as input to the class constructor.
|
106
172
|
def get_execution_info
|
107
173
|
execution = @swf.describe_workflow_execution(
|
108
174
|
domain: @domain,
|
@@ -113,14 +179,15 @@ module AWS
|
|
113
179
|
|
114
180
|
end
|
115
181
|
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
182
|
+
# An AWS Flow Framework utility used to replay a workflow history in the
|
183
|
+
# decider against the workflow implementation. Primarily used for
|
184
|
+
# debugging workflows.
|
119
185
|
#
|
120
|
-
# Usage
|
186
|
+
# ## Usage
|
121
187
|
#
|
122
|
-
#
|
188
|
+
# **Create an instance of the replayer with the required options:**
|
123
189
|
#
|
190
|
+
# ~~~~
|
124
191
|
# replayer = AWS::Flow::Replayer::WorkflowReplayer.new(
|
125
192
|
# domain: '<domain_name>',
|
126
193
|
# execution: {
|
@@ -129,14 +196,25 @@ module AWS
|
|
129
196
|
# },
|
130
197
|
# workflow_class: WorkflowClass
|
131
198
|
# )
|
199
|
+
# ~~~~
|
132
200
|
#
|
133
|
-
#
|
201
|
+
# **Call the replay method (optionally) with the replay_upto event_id number**
|
134
202
|
#
|
203
|
+
# ~~~~
|
135
204
|
# decision = replayer.replay(20)
|
205
|
+
# ~~~~
|
136
206
|
#
|
137
207
|
class WorkflowReplayer
|
138
208
|
attr_reader :task_handler, :task_provider
|
139
209
|
|
210
|
+
# Initialize a new **WorkflowReplayer**.
|
211
|
+
#
|
212
|
+
# @param options A hash of options. The hash must contain at least
|
213
|
+
# `:workflow_class`.
|
214
|
+
#
|
215
|
+
# @raise |ArgumentError| if no options hash was passed in, or if the
|
216
|
+
# options are missing the `:workflow_class` key.
|
217
|
+
#
|
140
218
|
def initialize(options)
|
141
219
|
raise ArgumentError.new("You must pass in an options hash") if options.nil?
|
142
220
|
raise ArgumentError.new("options hash must contain :workflow_class") if options[:workflow_class].nil?
|
@@ -147,14 +225,17 @@ module AWS
|
|
147
225
|
@task_handler = DecisionTaskHandler.from_workflow_class(options[:workflow_class])
|
148
226
|
end
|
149
227
|
|
150
|
-
#
|
228
|
+
# Performs a replay of workflow history.
|
229
|
+
#
|
230
|
+
# @param replay_upto [Fixnum] *Optional*. If set, replays the history
|
231
|
+
# only until the specified event is reached. If not set, then all
|
232
|
+
# history will be returned.
|
233
|
+
#
|
151
234
|
def replay(replay_upto = nil)
|
152
235
|
task = @task_provider.get_decision_task(replay_upto)
|
153
236
|
@task_handler.handle_decision_task(task) unless task.nil?
|
154
237
|
end
|
155
|
-
|
156
238
|
end
|
157
|
-
|
158
239
|
end
|
159
240
|
end
|
160
241
|
end
|
@@ -1537,5 +1537,48 @@ describe "Workflow/Activity return values/exceptions" do
|
|
1537
1537
|
exception.details.should == "SIMULATED"
|
1538
1538
|
end
|
1539
1539
|
|
1540
|
+
|
1541
|
+
# A bug was introduced in the previous commit which resulted in unnecessary
|
1542
|
+
# calls to #describe_workflow_execution during logging of a DecisionTask. This
|
1543
|
+
# test ensures that we don't call describe_workflow_execution anymore.
|
1544
|
+
it "ensures describe_workflow_execution is not called during polling" do
|
1545
|
+
|
1546
|
+
swf = double("swf")
|
1547
|
+
domain = double("domain")
|
1548
|
+
allow(domain).to receive(:name).and_return("foo")
|
1549
|
+
allow(swf).to receive(:domain).and_return(domain)
|
1550
|
+
|
1551
|
+
# Set the expectations for the test
|
1552
|
+
expect_any_instance_of(AWS::SimpleWorkflow::Client::V20120125).to_not receive(:describe_workflow_execution)
|
1553
|
+
|
1554
|
+
class SomeWorkflow
|
1555
|
+
extend Workflows
|
1556
|
+
workflow(:start) do
|
1557
|
+
{
|
1558
|
+
version: "1.0",
|
1559
|
+
default_execution_start_to_close_timeout: 600,
|
1560
|
+
}
|
1561
|
+
end
|
1562
|
+
def start; end
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1566
|
+
def get_decision_task
|
1567
|
+
fake_workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.start", "1.0")
|
1568
|
+
domain = double("domain")
|
1569
|
+
TestHistoryWrapper.new(fake_workflow_type, AWS::SimpleWorkflow::WorkflowExecution.new(domain, "workflow_id", "run_id"),
|
1570
|
+
FakeEvents.new(["WorkflowExecutionStarted",
|
1571
|
+
"DecisionTaskScheduled",
|
1572
|
+
"DecisionTaskStarted",
|
1573
|
+
]))
|
1574
|
+
end
|
1575
|
+
end
|
1576
|
+
workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.entry_point", "1")
|
1577
|
+
client = workflow_client(swf, domain) { { from_class: "SomeWorkflow" } }
|
1578
|
+
|
1579
|
+
worker = SynchronousWorkflowWorker.new(swf, domain, "SomeWorkflow", SomeWorkflow)
|
1580
|
+
worker.start
|
1581
|
+
end
|
1582
|
+
|
1540
1583
|
end
|
1541
1584
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Steger, Paritosh Mohan, Jacques Thomas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-v1
|