elasticity 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.mediawiki → README.md} +34 -32
- data/elasticity.gemspec +0 -2
- data/lib/elasticity/aws_request.rb +11 -4
- data/lib/elasticity/emr.rb +12 -5
- data/lib/elasticity/job_flow.rb +31 -21
- data/lib/elasticity/job_flow_step.rb +22 -19
- data/lib/elasticity/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/add_instance_groups/one_group_successful.yml +2 -2
- data/spec/fixtures/vcr_cassettes/add_instance_groups/one_group_unsuccessful.yml +1 -1
- data/spec/fixtures/vcr_cassettes/add_jobflow_steps/add_multiple_steps.yml +3 -3
- data/spec/fixtures/vcr_cassettes/describe_jobflows/all_jobflows.yml +2 -2
- data/spec/fixtures/vcr_cassettes/direct/terminate_jobflow.yml +1 -1
- data/spec/fixtures/vcr_cassettes/hive_job/hive_ads.yml +1 -1
- data/spec/fixtures/vcr_cassettes/modify_instance_groups/set_instances_to_3.yml +2 -2
- data/spec/fixtures/vcr_cassettes/pig_job/apache_log_reports.yml +2 -2
- data/spec/fixtures/vcr_cassettes/pig_job/apache_log_reports_with_bootstrap.yml +1 -1
- data/spec/fixtures/vcr_cassettes/run_jobflow/word_count.yml +1 -1
- data/spec/fixtures/vcr_cassettes/set_termination_protection/nonexistent_job_flows.yml +2 -2
- data/spec/fixtures/vcr_cassettes/set_termination_protection/protect_multiple_job_flows.yml +2 -2
- data/spec/fixtures/vcr_cassettes/terminate_jobflows/one_jobflow.yml +1 -1
- data/spec/lib/elasticity/aws_request_spec.rb +48 -2
- data/spec/lib/elasticity/emr_spec.rb +9 -1
- data/spec/lib/elasticity/job_flow_spec.rb +69 -1
- data/spec/lib/elasticity/job_flow_step_spec.rb +15 -1
- metadata +6 -6
@@ -1,10 +1,14 @@
|
|
1
1
|
Elasticity provides programmatic access to Amazon's Elastic Map Reduce service. The aim is to conveniently wrap the API operations in a manner that makes working with EMR job flows from Ruby more productive and more enjoyable, without having to understand the nuts and bolts of the EMR REST API. At the very least, using Elasticity allows you to easily experiment with the EMR API :)
|
2
2
|
|
3
|
-
|
3
|
+
**BACKLOG**: Have a look at the [backlog](https://www.pivotaltracker.com/projects/272429) to see where this is headed.
|
4
4
|
|
5
|
-
|
5
|
+
**CREDITS**: AWS signing was used from [RightScale's](http://www.rightscale.com/) amazing [right_aws gem](https://github.com/rightscale/right_aws) which works extraordinarily well! If you need access to any AWS service (EC2, S3, etc.), have a look. Used camelize from ActiveSupport as well, thank you \Rails :)
|
6
6
|
|
7
|
-
|
7
|
+
**CONTRIBUTIONS**:
|
8
|
+
|
9
|
+
+ [Wouter Broekhof](https://github.com/wouter/) - HTTPS and AWS region support, additional params to describe_jobflows.
|
10
|
+
|
11
|
+
# Installation and Usage
|
8
12
|
|
9
13
|
<pre>
|
10
14
|
gem install elasticity
|
@@ -12,7 +16,7 @@ Elasticity provides programmatic access to Amazon's Elastic Map Reduce service.
|
|
12
16
|
|
13
17
|
All you have to do is <code>require 'elasticity'</code> and you're all set!
|
14
18
|
|
15
|
-
|
19
|
+
# Simplified API Reference
|
16
20
|
|
17
21
|
Elasticity currently provides simplified access to launching Hive and Pig job flows, specifying several default values that you may optionally override:
|
18
22
|
|
@@ -28,7 +32,7 @@ Elasticity currently provides simplified access to launching Hive and Pig job fl
|
|
28
32
|
|
29
33
|
These are all accessible from HiveJob and PigJob. See the PigJob description for an example.
|
30
34
|
|
31
|
-
|
35
|
+
### Bootstrap Actions
|
32
36
|
|
33
37
|
You can also configure Hadoop options with add_hadoop_bootstrap_action().
|
34
38
|
|
@@ -38,7 +42,7 @@ You can also configure Hadoop options with add_hadoop_bootstrap_action().
|
|
38
42
|
...
|
39
43
|
</pre>
|
40
44
|
|
41
|
-
|
45
|
+
## Hive
|
42
46
|
|
43
47
|
HiveJob allows you to quickly launch Hive jobs without having to understand the ins and outs of the EMR API. Specify only the Hive script location and (optionally) variables to make available to the Hive script.
|
44
48
|
|
@@ -52,7 +56,7 @@ HiveJob allows you to quickly launch Hive jobs without having to understand the
|
|
52
56
|
> "j-129V5AQFMKO1C"
|
53
57
|
</pre>
|
54
58
|
|
55
|
-
|
59
|
+
## Pig
|
56
60
|
|
57
61
|
Like HiveJob, PigJob allows you to quickly launch Pig jobs :)
|
58
62
|
|
@@ -68,9 +72,9 @@ Like HiveJob, PigJob allows you to quickly launch Pig jobs :)
|
|
68
72
|
> "j-16PZ24OED71C6"
|
69
73
|
</pre>
|
70
74
|
|
71
|
-
|
75
|
+
### PARALLEL
|
72
76
|
|
73
|
-
Given the importance of specifying a reasonable value for [http://pig.apache.org/docs/r0.8.1/cookbook.html#Use+the+Parallel+Features PARALLEL
|
77
|
+
Given the importance of specifying a reasonable value for [the number of parallel reducers](http://pig.apache.org/docs/r0.8.1/cookbook.html#Use+the+Parallel+Features PARALLEL), Elasticity calculates and passes through a reasonable default up with every invocation in the form of a script variable called E_PARALLELS. This default value is based off of the formula in the Pig Cookbook and the number of reducers AWS configures per instance.
|
74
78
|
|
75
79
|
For example, if you had 8 instances in total and your slaves were m1.xlarge, the value is 26 (as shown below).
|
76
80
|
|
@@ -92,21 +96,21 @@ Use this as you would any other Pig variable.
|
|
92
96
|
...
|
93
97
|
</pre>
|
94
98
|
|
95
|
-
|
99
|
+
# Amazon API Reference
|
96
100
|
|
97
101
|
Elasticity wraps all of the EMR API calls. Please see the Amazon guide for details on these operations because the default values aren't obvious (e.g. the meaning of <code>DescribeJobFlows</code> without parameters).
|
98
102
|
|
99
103
|
You may opt for "direct" access to the API where you specify the params and Elasticity takes care of the signing for you, responding with the XML from Amazon. Direct access is described below the API catalog.
|
100
104
|
|
101
|
-
In addition to the [http://aws.amazon.com/elasticmapreduce/
|
105
|
+
In addition to the [AWS EMR subsite](http://aws.amazon.com/elasticmapreduce/), there are three primary resources of reference information for EMR:
|
102
106
|
|
103
|
-
* [http://docs.amazonwebservices.com/ElasticMapReduce/latest/GettingStartedGuide/
|
104
|
-
* [http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/
|
105
|
-
* [http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/
|
107
|
+
* [Amazon EMR Getting Started Guide](http://docs.amazonwebservices.com/ElasticMapReduce/latest/GettingStartedGuide/)
|
108
|
+
* [Amazon EMR Developer Guide](http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/)
|
109
|
+
* [Amazon EMR API Reference](http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/)
|
106
110
|
|
107
|
-
Unfortunately, the documentation is sometimes incorrect and sometimes missing. E.g. the allowable values for AddInstanceGroups are present in the [http://awsdocs.s3.amazonaws.com/ElasticMapReduce/20090331/emr-api-20090331.pdf
|
111
|
+
Unfortunately, the documentation is sometimes incorrect and sometimes missing. E.g. the allowable values for AddInstanceGroups are present in the [PDF](http://awsdocs.s3.amazonaws.com/ElasticMapReduce/20090331/emr-api-20090331.pdf) version of the API reference but not in the [HTML](http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/) version. Elasticity implements the API as specified in the PDF reference as that is the most complete description I could find.
|
108
112
|
|
109
|
-
|
113
|
+
## AddInstanceGroups
|
110
114
|
|
111
115
|
AddInstanceGroups adds a group of instances to an existing job flow. The available instance configuration options are listed in the EMR API reference. They've been converted to be more Ruby-like in the wrappers, as shown in the example below.
|
112
116
|
|
@@ -132,7 +136,7 @@ Some combinations of the options will be rejected by Amazon and some once-valid
|
|
132
136
|
> Task instance group already exists in the job flow, cannot add more task groups
|
133
137
|
</pre>
|
134
138
|
|
135
|
-
|
139
|
+
## AddJobFlowSteps
|
136
140
|
|
137
141
|
AddJobFlowSteps adds the specified steps to the specified job flow.
|
138
142
|
|
@@ -158,7 +162,7 @@ AddJobFlowSteps adds the specified steps to the specified job flow.
|
|
158
162
|
})
|
159
163
|
</pre>
|
160
164
|
|
161
|
-
|
165
|
+
## DescribeJobFlows
|
162
166
|
|
163
167
|
DescribeJobFlows returns detailed information as to the state of all jobs. Currently this is wrapped in an <code>Elasticity::JobFlow</code> that contains the <code>name</code>, <code>jobflow_id</code> and <code>state</code>.
|
164
168
|
|
@@ -170,7 +174,7 @@ DescribeJobFlows returns detailed information as to the state of all jobs. Curr
|
|
170
174
|
> ["Hive Test", "Pig Test", "Interactive Hadoop", "Interactive Hive"]
|
171
175
|
</pre>
|
172
176
|
|
173
|
-
|
177
|
+
## ModifyInstanceGroups
|
174
178
|
|
175
179
|
A job flow contains several "instance groups" of various types. These instances are where the work for your EMR task occurs. After a job flow has been created, you can find these instance groups in the AWS web UI by clicking on a job flow and then clicking on the "Instance Groups" tab.
|
176
180
|
|
@@ -197,7 +201,7 @@ Or if you attempt to increase the instance count of the MASTER instance group:
|
|
197
201
|
> ArgumentError: A master instance group may not be modified
|
198
202
|
</pre>
|
199
203
|
|
200
|
-
|
204
|
+
## RunJobFlow
|
201
205
|
|
202
206
|
RunJobFlow creates and starts a new job flow. Specifying the arguments to RunJobFlow is a bit of a hot mess at the moment, requiring you to understand the EMR syntax as well as the data structure for specifying jobs. Here's a beefy example:
|
203
207
|
|
@@ -252,9 +256,9 @@ RunJobFlow creates and starts a new job flow. Specifying the arguments to RunJo
|
|
252
256
|
> "j-129V5AQFMKO1C"
|
253
257
|
</pre>
|
254
258
|
|
255
|
-
Currently Elasticity doesn't do much to ease this pain although this is what I would like to focus on in coming releases. Feel free to ship ideas my way. In the meantime, have a look at the EMR API [http://awsdocs.s3.amazonaws.com/ElasticMapReduce/20090331/emr-api-20090331.pdf
|
259
|
+
Currently Elasticity doesn't do much to ease this pain although this is what I would like to focus on in coming releases. Feel free to ship ideas my way. In the meantime, have a look at the EMR API [PDF](http://awsdocs.s3.amazonaws.com/ElasticMapReduce/20090331/emr-api-20090331.pdf) under the RunJobFlow action and riff off of the example here.
|
256
260
|
|
257
|
-
|
261
|
+
## SetTerminationProtection
|
258
262
|
|
259
263
|
Enable or disable "termination protection" on the specified job flows. Termination protection prevents a job flow from from being terminated by any user-initiated action.
|
260
264
|
|
@@ -269,7 +273,7 @@ To disable termination protection, specify false as the second parameter.
|
|
269
273
|
emr.set_termination_protection(["j-1B4D1XP0C0A35", "j-1YG2MYL0HVYS5"], false)
|
270
274
|
</pre>
|
271
275
|
|
272
|
-
|
276
|
+
## TerminateJobFlows
|
273
277
|
|
274
278
|
Terminate the specified job flow. When the job flow '''exists''', you will receive no output. This is because Amazon does not return anything other than a 200 when you terminate a job flow :) You'll want to continuously poll with DescribeJobFlows to see when the job was actually terminated.
|
275
279
|
|
@@ -287,7 +291,7 @@ When the job flow '''doesn't exist''':
|
|
287
291
|
> ArgumentError: Job flow 'no-flow' does not exist.
|
288
292
|
</pre>
|
289
293
|
|
290
|
-
|
294
|
+
# Direct Response Access
|
291
295
|
|
292
296
|
If you're fine with Elasticity's invocation wrapping and would prefer to get at the resulting XML rather than the wrapped response, throw a block our way and we'll yield the result. This still saves you the trouble of having to create the params and sign the request yet gives you direct access to the response XML for your parsing pleasure.
|
293
297
|
|
@@ -295,12 +299,12 @@ If you're fine with Elasticity's invocation wrapping and would prefer to get at
|
|
295
299
|
emr = Elasticity::EMR.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_KEY"])
|
296
300
|
emr.describe_jobflows{|xml| puts xml[0..77]}
|
297
301
|
|
298
|
-
>
|
302
|
+
> <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/200...
|
299
303
|
</pre>
|
300
304
|
|
301
|
-
|
305
|
+
# Direct Request/Response Access
|
302
306
|
|
303
|
-
If you're chomping at the bit to initiate some EMR functionality that isn't wrapped (or isn't wrapped in a way you prefer :) feel free to access the AWS EMR API directly by using <code>EMR.direct()</code>. You can find the allowed values in Amazon's EMR API [http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/index.html
|
307
|
+
If you're chomping at the bit to initiate some EMR functionality that isn't wrapped (or isn't wrapped in a way you prefer :) feel free to access the AWS EMR API directly by using <code>EMR.direct()</code>. You can find the allowed values in Amazon's EMR API [developer documentation](http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/index.html).
|
304
308
|
|
305
309
|
<pre>
|
306
310
|
emr = Elasticity::EMR.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_KEY"])
|
@@ -308,10 +312,10 @@ If you're chomping at the bit to initiate some EMR functionality that isn't wrap
|
|
308
312
|
result_xml = emr.direct(params)
|
309
313
|
result_xml[0..78]
|
310
314
|
|
311
|
-
>
|
315
|
+
> <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009...
|
312
316
|
</pre>
|
313
317
|
|
314
|
-
|
318
|
+
# License
|
315
319
|
|
316
320
|
<pre>
|
317
321
|
Copyright 2011 Robert Slifka
|
@@ -327,6 +331,4 @@ If you're chomping at the bit to initiate some EMR functionality that isn't wrap
|
|
327
331
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
328
332
|
See the License for the specific language governing permissions and
|
329
333
|
limitations under the License.
|
330
|
-
</pre>
|
331
|
-
|
332
|
-
<!-- __NOTOC__ -->
|
334
|
+
</pre>
|
data/elasticity.gemspec
CHANGED
@@ -11,8 +11,6 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = %q{Programmatic access to Amazon's Elastic Map Reduce service.}
|
12
12
|
s.description = %q{Programmatic access to Amazon's Elastic Map Reduce service.}
|
13
13
|
|
14
|
-
s.rubyforge_project = "elasticity"
|
15
|
-
|
16
14
|
s.add_dependency("rest-client")
|
17
15
|
s.add_dependency("nokogiri")
|
18
16
|
|
@@ -2,14 +2,21 @@ module Elasticity
|
|
2
2
|
|
3
3
|
class AwsRequest
|
4
4
|
|
5
|
-
|
5
|
+
# Supported values for options:
|
6
|
+
# :region - AWS region (e.g. us-west-1)
|
7
|
+
# :secure - true or false, default true.
|
8
|
+
def initialize(aws_access_key_id, aws_secret_access_key, options = {})
|
6
9
|
@access_key = aws_access_key_id
|
7
10
|
@secret_key = aws_secret_access_key
|
11
|
+
@options = {:secure => true}.merge(options)
|
8
12
|
end
|
9
13
|
|
10
14
|
def aws_emr_request(params)
|
11
|
-
|
12
|
-
|
15
|
+
host = @options[:region] ? "elasticmapreduce.#{@options[:region]}.amazonaws.com" : "elasticmapreduce.amazonaws.com"
|
16
|
+
protocol = @options[:secure] ? "https" : "http"
|
17
|
+
|
18
|
+
signed_params = sign_params(params, "GET", host, "/")
|
19
|
+
signed_request = "#{protocol}://#{host}?#{signed_params}"
|
13
20
|
RestClient.get signed_request
|
14
21
|
end
|
15
22
|
|
@@ -45,4 +52,4 @@ module Elasticity
|
|
45
52
|
|
46
53
|
end
|
47
54
|
|
48
|
-
end
|
55
|
+
end
|
data/lib/elasticity/emr.rb
CHANGED
@@ -2,13 +2,20 @@ module Elasticity
|
|
2
2
|
|
3
3
|
class EMR
|
4
4
|
|
5
|
-
def initialize(aws_access_key_id, aws_secret_access_key)
|
6
|
-
@aws_request = Elasticity::AwsRequest.new(aws_access_key_id, aws_secret_access_key)
|
5
|
+
def initialize(aws_access_key_id, aws_secret_access_key, options = {})
|
6
|
+
@aws_request = Elasticity::AwsRequest.new(aws_access_key_id, aws_secret_access_key, options)
|
7
7
|
end
|
8
8
|
|
9
9
|
# Lists all jobflows in all states.
|
10
|
-
|
11
|
-
|
10
|
+
#
|
11
|
+
# To override this behaviour, pass additional filters as specified in the AWS
|
12
|
+
# documentation - http://docs.amazonwebservices.com/ElasticMapReduce/latest/API/index.html?API_DescribeJobFlows.html.
|
13
|
+
#
|
14
|
+
# describe_jobflows(:CreatedBefore => "2011-10-04")
|
15
|
+
def describe_jobflows(params = {})
|
16
|
+
aws_result = @aws_request.aws_emr_request(EMR.convert_ruby_to_aws(
|
17
|
+
params.merge({:operation => "DescribeJobFlows"}))
|
18
|
+
)
|
12
19
|
xml_doc = Nokogiri::XML(aws_result)
|
13
20
|
xml_doc.remove_namespaces!
|
14
21
|
yield aws_result if block_given?
|
@@ -31,7 +38,7 @@ module Elasticity
|
|
31
38
|
#
|
32
39
|
# add_instance_groups takes an array of {}. Returns an array of the instance IDs
|
33
40
|
# that were created by the specified configs.
|
34
|
-
#
|
41
|
+
#
|
35
42
|
# ["ig-2GOVEN6HVJZID", "ig-1DU9M2UQMM051", "ig-3DZRW4Y2X4S", ...]
|
36
43
|
def add_instance_groups(jobflow_id, instance_group_configs)
|
37
44
|
params = {
|
data/lib/elasticity/job_flow.rb
CHANGED
@@ -6,34 +6,44 @@ module Elasticity
|
|
6
6
|
attr_accessor :jobflow_id
|
7
7
|
attr_accessor :state
|
8
8
|
attr_accessor :steps
|
9
|
+
attr_accessor :created_at
|
10
|
+
attr_accessor :started_at
|
11
|
+
attr_accessor :ready_at
|
12
|
+
attr_accessor :instance_count
|
13
|
+
attr_accessor :master_instance_type
|
14
|
+
attr_accessor :slave_instance_type
|
9
15
|
|
10
16
|
def initialize
|
11
17
|
@steps = []
|
12
18
|
end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
# Create a jobflow from an AWS <member> (Nokogiri::XML::Element):
|
21
|
+
# /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member
|
22
|
+
def self.from_member_element(xml_element)
|
23
|
+
jobflow = JobFlow.new
|
24
|
+
jobflow.name = xml_element.xpath("./Name").text.strip
|
25
|
+
jobflow.jobflow_id = xml_element.xpath("./JobFlowId").text.strip
|
26
|
+
jobflow.state = xml_element.xpath("./ExecutionStatusDetail/State").text.strip
|
27
|
+
jobflow.steps = JobFlowStep.from_members_nodeset(xml_element.xpath("./Steps/member"))
|
28
|
+
jobflow.created_at = Time.parse(xml_element.xpath("./ExecutionStatusDetail/CreationDateTime").text.strip)
|
29
|
+
started_at = xml_element.xpath("./ExecutionStatusDetail/StartDateTime").text.strip
|
30
|
+
jobflow.started_at = (started_at == "") ? (nil) : (Time.parse(started_at))
|
31
|
+
ready_at = xml_element.xpath("./ExecutionStatusDetail/ReadyDateTime").text.strip
|
32
|
+
jobflow.ready_at = (ready_at == "") ? (nil) : (Time.parse(ready_at))
|
33
|
+
jobflow.instance_count = xml_element.xpath("./Instances/InstanceCount").text.strip
|
34
|
+
jobflow.master_instance_type = xml_element.xpath("./Instances/MasterInstanceType").text.strip
|
35
|
+
jobflow.slave_instance_type = xml_element.xpath("./Instances/SlaveInstanceType").text.strip
|
36
|
+
jobflow
|
37
|
+
end
|
26
38
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
jobflows
|
39
|
+
# Create JobFlows from a collection of AWS <member> nodes (Nokogiri::XML::NodeSet):
|
40
|
+
# /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows
|
41
|
+
def self.from_members_nodeset(members_nodeset)
|
42
|
+
jobflows = []
|
43
|
+
members_nodeset.each do |member|
|
44
|
+
jobflows << from_member_element(member)
|
35
45
|
end
|
36
|
-
|
46
|
+
jobflows
|
37
47
|
end
|
38
48
|
|
39
49
|
end
|
@@ -4,29 +4,32 @@ module Elasticity
|
|
4
4
|
|
5
5
|
attr_accessor :name
|
6
6
|
attr_accessor :state
|
7
|
+
attr_accessor :started_at
|
8
|
+
attr_accessor :ended_at
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
# Create a job flow from an AWS <member> (Nokogiri::XML::Element):
|
11
|
+
# /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member/Steps/member
|
12
|
+
def self.from_member_element(xml_element)
|
13
|
+
job_flow_step = JobFlowStep.new
|
14
|
+
job_flow_step.name = xml_element.xpath("./StepConfig/Name").text.strip
|
15
|
+
job_flow_step.state = xml_element.xpath("./ExecutionStatusDetail/State").text.strip
|
16
|
+
started_at = xml_element.xpath("./ExecutionStatusDetail/StartDateTime").text.strip
|
17
|
+
job_flow_step.started_at = (started_at == "") ? (nil) : (Time.parse(started_at))
|
18
|
+
ended_at = xml_element.xpath("./ExecutionStatusDetail/EndDateTime").text.strip
|
19
|
+
job_flow_step.ended_at = (ended_at == "") ? (nil) : (Time.parse(ended_at))
|
20
|
+
job_flow_step
|
21
|
+
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
jobflow_steps
|
23
|
+
# Create JobFlowSteps from a collection of AWS <member> nodes (Nokogiri::XML::NodeSet):
|
24
|
+
# /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member/Steps/member
|
25
|
+
def self.from_members_nodeset(members_nodeset)
|
26
|
+
jobflow_steps = []
|
27
|
+
members_nodeset.each do |member|
|
28
|
+
jobflow_steps << from_member_element(member)
|
27
29
|
end
|
30
|
+
jobflow_steps
|
28
31
|
end
|
29
32
|
|
30
33
|
end
|
31
34
|
|
32
|
-
end
|
35
|
+
end
|
data/lib/elasticity/version.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&InstanceGroups.member.1.InstanceCount=1&InstanceGroups.member.1.InstanceRole=TASK&InstanceGroups.member.1.InstanceType=m1.small&InstanceGroups.member.1.Market=ON_DEMAND&InstanceGroups.member.1.Name=Go%20Canucks%20Go!&JobFlowId=j-OALI7TZTQMHX&Operation=AddInstanceGroups/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&InstanceGroups.member.1.BidPrice=0&InstanceGroups.member.1.InstanceCount=1&InstanceGroups.member.1.InstanceRole=TASK&InstanceGroups.member.1.InstanceType=m1.small&InstanceGroups.member.1.Market=ON_DEMAND&InstanceGroups.member.1.Name=Go%20Canucks%20Go!&JobFlowId=j-19WDDS68ZUENP&Operation=AddInstanceGroups/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?.*Operation=RunJobFlow/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -36,7 +36,7 @@
|
|
36
36
|
- !ruby/struct:VCR::HTTPInteraction
|
37
37
|
request: !ruby/struct:VCR::Request
|
38
38
|
method: :get
|
39
|
-
uri: !ruby/regexp /^
|
39
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?.*Operation=AddJobFlowSteps/
|
40
40
|
body:
|
41
41
|
headers:
|
42
42
|
accept:
|
@@ -67,7 +67,7 @@
|
|
67
67
|
- !ruby/struct:VCR::HTTPInteraction
|
68
68
|
request: !ruby/struct:VCR::Request
|
69
69
|
method: :get
|
70
|
-
uri: !ruby/regexp /^
|
70
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?.*Operation=DescribeJobFlows/
|
71
71
|
body:
|
72
72
|
headers:
|
73
73
|
accept:
|
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&Operation=DescribeJobFlows/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&JobFlowIds.member.1=j-1MZ5TVWFJRSKN&Operation=TerminateJobFlows/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&Instances\.Ec2KeyName=sharethrough_dev&Instances\.HadoopVersion=0\.20&Instances\.InstanceCount=2&Instances\.MasterInstanceType=m1\.small&Instances\.SlaveInstanceType=m1\.small&Name=Elasticity%20Hive%20Job&Operation=RunJobFlow&.*&Steps\.member\.1\.ActionOnFailure=TERMINATE_JOB_FLOW&Steps\.member\.1\.HadoopJarStep\.Args\.member\.1=s3:\/\/elasticmapreduce\/libs\/hive\/hive-script&Steps\.member\.1\.HadoopJarStep\.Args\.member\.2=--base-path&Steps\.member\.1\.HadoopJarStep\.Args\.member\.3=s3:\/\/elasticmapreduce\/libs\/hive\/&Steps\.member\.1\.HadoopJarStep\.Args\.member\.4=--install-hive&Steps\.member\.1\.HadoopJarStep\.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner\.jar&Steps\.member\.1\.Name=Setup%20Hive&Steps\.member\.2\.ActionOnFailure=TERMINATE_JOB_FLOW&Steps\.member\.2\.HadoopJarStep\.Args\.member\.1=s3:\/\/elasticmapreduce\/libs\/hive\/hive-script&Steps\.member\.2\.HadoopJarStep\.Args\.member\.10=-d&Steps\.member\.2\.HadoopJarStep\.Args\.member\.11=LIBS=s3n:\/\/elasticmapreduce\/samples\/hive-ads\/libs&Steps\.member\.2\.HadoopJarStep\.Args\.member\.2=--run-hive-script&Steps\.member\.2\.HadoopJarStep\.Args\.member\.3=--args&Steps\.member\.2\.HadoopJarStep\.Args\.member\.4=-f&Steps\.member\.2\.HadoopJarStep\.Args\.member\.5=s3n:\/\/elasticmapreduce\/samples\/hive-ads\/libs\/model-build\.q&Steps\.member\.2\.HadoopJarStep\.Args\.member\.6=-d&Steps\.member\.2\.HadoopJarStep\.Args\.member\.7=INPUT=s3n:\/\/elasticmapreduce\/samples\/hive-ads\/tables&Steps\.member\.2\.HadoopJarStep\.Args\.member\.8=-d&Steps\.member\.2\.HadoopJarStep\.Args\.member\.9=OUTPUT=s3n:\/\/slif-elasticity\/hive-ads\/output\/2011-04-19&Steps\.member\.2\.HadoopJarStep\.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner\.jar&Steps\.member\.2\.Name=Run%20Hive%20Script/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&InstanceGroups.member.1.InstanceCount=2&InstanceGroups.member.1.InstanceGroupId=ig-2T1HNUO61BG3O&Operation=ModifyInstanceGroups/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&Instances.Ec2KeyName=sharethrough_dev&Instances.HadoopVersion=0.20&Instances.InstanceCount=2&Instances.MasterInstanceType=m1.small&Instances.SlaveInstanceType=m1.small&LogUri=s3n:\/\/slif-elasticity\/pig-apache\/logs&Name=Elasticity%20Pig%20Job&Operation=RunJobFlow&.*&Steps.member.1.ActionOnFailure=TERMINATE_JOB_FLOW&Steps.member.1.HadoopJarStep.Args.member.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps.member.1.HadoopJarStep.Args.member.2=--base-path&Steps.member.1.HadoopJarStep.Args.member.3=s3:\/\/elasticmapreduce\/libs\/pig\/&Steps.member.1.HadoopJarStep.Args.member.4=--install-pig&Steps.member.1.HadoopJarStep.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner.jar&Steps.member.1.Name=Setup%20Pig&Steps.member.2.ActionOnFailure=TERMINATE_JOB_FLOW&Steps.member.2.HadoopJarStep.Args.member.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps.member.2.HadoopJarStep.Args.member.10=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/do-reports.pig&Steps.member.2.HadoopJarStep.Args.member.2=--run-pig-script&Steps.member.2.HadoopJarStep.Args.member.3=--args&Steps.member.2.HadoopJarStep.Args.member.4=-p&Steps.member.2.HadoopJarStep.Args.member.5=INPUT=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/input&Steps.member.2.HadoopJarStep.Args.member.6=-p&Steps.member.2.HadoopJarStep.Args.member.7=OUTPUT=s3n:\/\/slif-elasticity\/pig-apache\/output\/2011-05-04&Steps.member.2.HadoopJarStep.Args.member.8=-p&Steps.member.2.HadoopJarStep.Args.member.9=E_PARALLELS=1&Steps.member.2.HadoopJarStep.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner.jar&Steps.member.2.Name=Run%20Pig%20Script/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&BootstrapActions.member.1.Name=Elasticity%20Bootstrap%20Action%20\(Configure%20Hadoop\)&BootstrapActions.member.1.ScriptBootstrapAction.Args.member.1=-m&BootstrapActions.member.1.ScriptBootstrapAction.Args.member.2=mapred.job.reuse.jvm.num.tasks=120&BootstrapActions.member.1.ScriptBootstrapAction.Path=s3n:\/\/elasticmapreduce\/bootstrap-actions\/configure-hadoop&Instances.Ec2KeyName=sharethrough_dev&Instances.HadoopVersion=0.20&Instances.InstanceCount=2&Instances.MasterInstanceType=m1.small&Instances.SlaveInstanceType=m1.small&Name=Elasticity%20Pig%20Job&Operation=RunJobFlow&.*&Steps.member.1.ActionOnFailure=TERMINATE_JOB_FLOW&Steps.member.1.HadoopJarStep.Args.member.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps.member.1.HadoopJarStep.Args.member.2=--base-path&Steps.member.1.HadoopJarStep.Args.member.3=s3:\/\/elasticmapreduce\/libs\/pig\/&Steps.member.1.HadoopJarStep.Args.member.4=--install-pig&Steps.member.1.HadoopJarStep.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner.jar&Steps.member.1.Name=Setup%20Pig&Steps.member.2.ActionOnFailure=TERMINATE_JOB_FLOW&Steps.member.2.HadoopJarStep.Args.member.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps.member.2.HadoopJarStep.Args.member.10=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/do-reports.pig&Steps.member.2.HadoopJarStep.Args.member.2=--run-pig-script&Steps.member.2.HadoopJarStep.Args.member.3=--args&Steps.member.2.HadoopJarStep.Args.member.4=-p&Steps.member.2.HadoopJarStep.Args.member.5=INPUT=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/input&Steps.member.2.HadoopJarStep.Args.member.6=-p&Steps.member.2.HadoopJarStep.Args.member.7=OUTPUT=s3n:\/\/slif-elasticity\/pig-apache\/output\/2011-05-10&Steps.member.2.HadoopJarStep.Args.member.8=-p&Steps.member.2.HadoopJarStep.Args.member.9=E_PARALLELS=1&Steps.member.2.HadoopJarStep.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner.jar&Steps.member.2.Name=Run%20Pig%20Script/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&Instances\.Ec2KeyName=sharethrough-dev&Instances\.HadoopVersion=0\.20&Instances\.InstanceCount=2&Instances\.MasterInstanceType=m1\.small&Instances\.Placement\.AvailabilityZone=us-east-1a&Instances\.SlaveInstanceType=m1\.small&Name=Elasticity%20Test%20Flow%20\(EMR%20Pig%20Script\)&Operation=RunJobFlow&.*&Steps\.member\.1\.ActionOnFailure=TERMINATE_JOB_FLOW&Steps\.member\.1\.HadoopJarStep\.Args\.member\.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps\.member\.1\.HadoopJarStep\.Args\.member\.2=--base-path&Steps\.member\.1\.HadoopJarStep\.Args\.member\.3=s3:\/\/elasticmapreduce\/libs\/pig\/&Steps\.member\.1\.HadoopJarStep\.Args\.member\.4=--install-pig&Steps\.member\.1\.HadoopJarStep\.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner\.jar&Steps\.member\.1\.Name=Setup%20Pig&Steps\.member\.2\.ActionOnFailure=TERMINATE_JOB_FLOW&Steps\.member\.2\.HadoopJarStep\.Args\.member\.1=s3:\/\/elasticmapreduce\/libs\/pig\/pig-script&Steps\.member\.2\.HadoopJarStep\.Args\.member\.2=--run-pig-script&Steps\.member\.2\.HadoopJarStep\.Args\.member\.3=--args&Steps\.member\.2\.HadoopJarStep\.Args\.member\.4=-p&Steps\.member\.2\.HadoopJarStep\.Args\.member\.5=INPUT=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/input&Steps\.member\.2\.HadoopJarStep\.Args\.member\.6=-p&Steps\.member\.2\.HadoopJarStep\.Args\.member\.7=OUTPUT=s3n:\/\/slif-elasticity\/pig-apache\/output\/2011-04-19&Steps\.member\.2\.HadoopJarStep\.Args\.member\.8=s3n:\/\/elasticmapreduce\/samples\/pig-apache\/do-reports\.pig&Steps\.member\.2\.HadoopJarStep\.Jar=s3:\/\/elasticmapreduce\/libs\/script-runner\/script-runner\.jar&Steps\.member\.2\.Name=Run%20Pig%20Script/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&JobFlowIds.member.1=j-1B4D1XP0C0A35&JobFlowIds.member.2=j-2&Operation=SetTerminationProtection.*&TerminationProtected=true/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,8 +2,8 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
6
|
-
body:
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&JobFlowIds.member.1=j-1B4D1XP0C0A35&JobFlowIds.member.2=j-1YG2MYL0HVYS5&Operation=SetTerminationProtection&.*TerminationProtected=true/
|
6
|
+
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
9
9
|
- "*/*; q=0.5, application/xml"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: !ruby/regexp /^
|
5
|
+
uri: !ruby/regexp /^https:\/\/elasticmapreduce.amazonaws.com\/\?AWSAccessKeyId=\S+&JobFlowIds.member.1=j-1MZ5TVWFJRSKN&Operation=TerminateJobFlows/
|
6
6
|
body:
|
7
7
|
headers:
|
8
8
|
accept:
|
@@ -15,7 +15,7 @@ describe Elasticity::AwsRequest do
|
|
15
15
|
|
16
16
|
describe "#sign_params" do
|
17
17
|
before do
|
18
|
-
Time.
|
18
|
+
Time.stub(:now).and_return(Time.at(1302461096))
|
19
19
|
end
|
20
20
|
it "should sign according to Amazon's rules" do
|
21
21
|
request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_access_key")
|
@@ -24,4 +24,50 @@ describe Elasticity::AwsRequest do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
describe "#aws_emr_request" do
|
28
|
+
before do
|
29
|
+
Time.stub(:now).and_return(Time.at(1302461096))
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "options" do
|
33
|
+
|
34
|
+
describe "region" do
|
35
|
+
context "when :region is specified" do
|
36
|
+
it "should request against that region" do
|
37
|
+
request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_access_key",
|
38
|
+
:region => "eu-west-1")
|
39
|
+
RestClient.should_receive(:get).with(/elasticmapreduce\.eu\-west\-1\.amazonaws\.com/)
|
40
|
+
request.aws_emr_request({})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
context "when :region is not specified" do
|
44
|
+
it "should use the default request url" do
|
45
|
+
request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_access_key")
|
46
|
+
RestClient.should_receive(:get).with(/elasticmapreduce\.amazonaws\.com/)
|
47
|
+
request.aws_emr_request({})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ":secure" do
|
53
|
+
context "when :secure is specified" do
|
54
|
+
it "should use the value to determine the request type" do
|
55
|
+
request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_access_key",
|
56
|
+
:secure => false)
|
57
|
+
RestClient.should_receive(:get).with(/^http:/)
|
58
|
+
request.aws_emr_request({})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
context "when :secure is not specified" do
|
62
|
+
it "should default to secure connection" do
|
63
|
+
request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_access_key")
|
64
|
+
RestClient.should_receive(:get).with(/^https:/)
|
65
|
+
request.aws_emr_request({})
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -293,6 +293,14 @@ describe Elasticity::EMR do
|
|
293
293
|
jobflows.map(&:name).should == ["Pig Job", "Hive Job"]
|
294
294
|
end
|
295
295
|
|
296
|
+
it "should accept additional parameters" do
|
297
|
+
aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
|
298
|
+
aws_request.should_receive(:aws_emr_request).with({"Operation" => "DescribeJobFlows","CreatedBefore" => "2011-10-04"}).and_return(@describe_jobflows_xml)
|
299
|
+
Elasticity::AwsRequest.should_receive(:new).and_return(aws_request)
|
300
|
+
emr = Elasticity::EMR.new("aws_access_key_id", "aws_secret_key")
|
301
|
+
emr.describe_jobflows(:CreatedBefore => "2011-10-04")
|
302
|
+
end
|
303
|
+
|
296
304
|
context "when a block is provided" do
|
297
305
|
it "should yield the XML result" do
|
298
306
|
aws_request = Elasticity::AwsRequest.new("aws_access_key_id", "aws_secret_key")
|
@@ -783,4 +791,4 @@ describe Elasticity::EMR do
|
|
783
791
|
end
|
784
792
|
end
|
785
793
|
|
786
|
-
end
|
794
|
+
end
|
@@ -11,6 +11,15 @@ describe Elasticity::JobFlow do
|
|
11
11
|
<JobFlowId>j-p</JobFlowId>
|
12
12
|
<Name>Pig Job</Name>
|
13
13
|
<ExecutionStatusDetail>
|
14
|
+
<CreationDateTime>
|
15
|
+
2011-10-04T21:49:16Z
|
16
|
+
</CreationDateTime>
|
17
|
+
<StartDateTime>
|
18
|
+
2011-10-04T21:49:17Z
|
19
|
+
</StartDateTime>
|
20
|
+
<ReadyDateTime>
|
21
|
+
2011-10-04T21:49:18Z
|
22
|
+
</ReadyDateTime>
|
14
23
|
<State>TERMINATED</State>
|
15
24
|
</ExecutionStatusDetail>
|
16
25
|
<Steps>
|
@@ -31,13 +40,60 @@ describe Elasticity::JobFlow do
|
|
31
40
|
</ExecutionStatusDetail>
|
32
41
|
</member>
|
33
42
|
</Steps>
|
43
|
+
<Instances>
|
44
|
+
<Placement>
|
45
|
+
<AvailabilityZone>
|
46
|
+
eu-west-1a
|
47
|
+
</AvailabilityZone>
|
48
|
+
</Placement>
|
49
|
+
<SlaveInstanceType>
|
50
|
+
m1.small
|
51
|
+
</SlaveInstanceType>
|
52
|
+
<MasterInstanceType>
|
53
|
+
m1.small
|
54
|
+
</MasterInstanceType>
|
55
|
+
<Ec2KeyName>
|
56
|
+
myec2keyname
|
57
|
+
</Ec2KeyName>
|
58
|
+
<InstanceCount>
|
59
|
+
4
|
60
|
+
</InstanceCount>
|
61
|
+
</Instances>
|
34
62
|
</member>
|
35
63
|
<member>
|
36
64
|
<JobFlowId>j-h</JobFlowId>
|
37
65
|
<Name>Hive Job</Name>
|
38
66
|
<ExecutionStatusDetail>
|
67
|
+
<CreationDateTime>
|
68
|
+
2011-10-04T22:49:16Z
|
69
|
+
</CreationDateTime>
|
70
|
+
<StartDateTime>
|
71
|
+
|
72
|
+
</StartDateTime>
|
73
|
+
<ReadyDateTime>
|
74
|
+
|
75
|
+
</ReadyDateTime>
|
39
76
|
<State>TERMINATED</State>
|
40
77
|
</ExecutionStatusDetail>
|
78
|
+
<Instances>
|
79
|
+
<Placement>
|
80
|
+
<AvailabilityZone>
|
81
|
+
eu-west-1b
|
82
|
+
</AvailabilityZone>
|
83
|
+
</Placement>
|
84
|
+
<SlaveInstanceType>
|
85
|
+
c1.medium
|
86
|
+
</SlaveInstanceType>
|
87
|
+
<MasterInstanceType>
|
88
|
+
c1.medium
|
89
|
+
</MasterInstanceType>
|
90
|
+
<Ec2KeyName>
|
91
|
+
myec2keyname
|
92
|
+
</Ec2KeyName>
|
93
|
+
<InstanceCount>
|
94
|
+
2
|
95
|
+
</InstanceCount>
|
96
|
+
</Instances>
|
41
97
|
</member>
|
42
98
|
</JobFlows>
|
43
99
|
</DescribeJobFlowsResult>
|
@@ -56,6 +112,12 @@ describe Elasticity::JobFlow do
|
|
56
112
|
jobflow.state.should == "TERMINATED"
|
57
113
|
jobflow.steps.map(&:name).should == ["Setup Hive", "Run Hive Script"]
|
58
114
|
jobflow.steps.map(&:state).should == ["FAILED", "PENDING"]
|
115
|
+
jobflow.created_at.should == Time.parse("2011-10-04T21:49:16Z")
|
116
|
+
jobflow.started_at.should == Time.parse("2011-10-04T21:49:17Z")
|
117
|
+
jobflow.ready_at.should == Time.parse("2011-10-04T21:49:18Z")
|
118
|
+
jobflow.master_instance_type.should == "m1.small"
|
119
|
+
jobflow.slave_instance_type.should == "m1.small"
|
120
|
+
jobflow.instance_count.should == "4"
|
59
121
|
end
|
60
122
|
end
|
61
123
|
|
@@ -65,7 +127,13 @@ describe Elasticity::JobFlow do
|
|
65
127
|
jobflow.map(&:name).should == ["Pig Job", "Hive Job"]
|
66
128
|
jobflow.map(&:jobflow_id).should == ["j-p", "j-h"]
|
67
129
|
jobflow.map(&:state).should == ["TERMINATED", "TERMINATED"]
|
130
|
+
jobflow.map(&:created_at).should == [Time.parse("2011-10-04T21:49:16Z"), Time.parse("2011-10-04T22:49:16Z")]
|
131
|
+
jobflow.map(&:started_at).should == [Time.parse("2011-10-04T21:49:17Z"), nil]
|
132
|
+
jobflow.map(&:ready_at).should == [Time.parse("2011-10-04T21:49:18Z"), nil]
|
133
|
+
jobflow.map(&:master_instance_type).should == ["m1.small","c1.medium"]
|
134
|
+
jobflow.map(&:slave_instance_type).should == ["m1.small", "c1.medium"]
|
135
|
+
jobflow.map(&:instance_count).should == ["4","2"]
|
68
136
|
end
|
69
137
|
end
|
70
138
|
|
71
|
-
end
|
139
|
+
end
|
@@ -20,6 +20,12 @@ describe Elasticity::JobFlowStep do
|
|
20
20
|
</StepConfig>
|
21
21
|
<ExecutionStatusDetail>
|
22
22
|
<State>FAILED</State>
|
23
|
+
<StartDateTime>
|
24
|
+
2011-10-04T21:49:16Z
|
25
|
+
</StartDateTime>
|
26
|
+
<EndDateTime>
|
27
|
+
2011-10-04T21:51:16Z
|
28
|
+
</EndDateTime>
|
23
29
|
</ExecutionStatusDetail>
|
24
30
|
</member>
|
25
31
|
<member>
|
@@ -28,6 +34,10 @@ describe Elasticity::JobFlowStep do
|
|
28
34
|
</StepConfig>
|
29
35
|
<ExecutionStatusDetail>
|
30
36
|
<State>PENDING</State>
|
37
|
+
<StartDateTime>
|
38
|
+
</StartDateTime>
|
39
|
+
<EndDateTime>
|
40
|
+
</EndDateTime>
|
31
41
|
</ExecutionStatusDetail>
|
32
42
|
</member>
|
33
43
|
</Steps>
|
@@ -46,6 +56,8 @@ describe Elasticity::JobFlowStep do
|
|
46
56
|
jobflow_step = Elasticity::JobFlowStep.from_member_element(@members_nodeset[0])
|
47
57
|
jobflow_step.name.should == "Setup Hive"
|
48
58
|
jobflow_step.state.should == "FAILED"
|
59
|
+
jobflow_step.started_at.should == Time.parse("2011-10-04T21:49:16Z")
|
60
|
+
jobflow_step.ended_at.should == Time.parse("2011-10-04T21:51:16Z")
|
49
61
|
end
|
50
62
|
end
|
51
63
|
|
@@ -54,8 +66,10 @@ describe Elasticity::JobFlowStep do
|
|
54
66
|
jobflow_steps = Elasticity::JobFlowStep.from_members_nodeset(@members_nodeset)
|
55
67
|
jobflow_steps.map(&:name).should == ["Setup Hive", "Run Hive Script"]
|
56
68
|
jobflow_steps.map(&:state).should == ["FAILED", "PENDING"]
|
69
|
+
jobflow_steps.map(&:started_at).should == [Time.parse("2011-10-04T21:49:16Z"), nil]
|
70
|
+
jobflow_steps.map(&:ended_at).should == [Time.parse("2011-10-04T21:51:16Z"), nil]
|
57
71
|
end
|
58
72
|
end
|
59
73
|
|
60
74
|
|
61
|
-
end
|
75
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 3
|
10
|
+
version: 1.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Robert Slifka
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-09 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -166,7 +166,7 @@ files:
|
|
166
166
|
- Gemfile
|
167
167
|
- HISTORY.mediawiki
|
168
168
|
- LICENSE
|
169
|
-
- README.
|
169
|
+
- README.md
|
170
170
|
- Rakefile
|
171
171
|
- elasticity.gemspec
|
172
172
|
- lib/elasticity.rb
|
@@ -227,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
227
|
version: "0"
|
228
228
|
requirements: []
|
229
229
|
|
230
|
-
rubyforge_project:
|
230
|
+
rubyforge_project:
|
231
231
|
rubygems_version: 1.4.1
|
232
232
|
signing_key:
|
233
233
|
specification_version: 3
|