aws-ie 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +0 -0
- data/Gemfile +2 -0
- data/README.org +60 -0
- data/Rakefile +6 -0
- data/VERSION +1 -0
- data/aws-ie.gemspec +35 -0
- data/lib/aws/ie/client.rb +72 -0
- data/lib/aws/ie.rb +5 -0
- data/lib/aws/import/job.rb +110 -0
- data/spec/aws/ie/client_spec.rb +128 -0
- data/spec/aws/import/job_spec.rb +261 -0
- metadata +129 -0
data/COPYING
ADDED
File without changes
|
data/Gemfile
ADDED
data/README.org
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- mode: org; -*-
|
2
|
+
#+TITLE: AWS import/Export API support
|
3
|
+
|
4
|
+
* AWS::Import
|
5
|
+
AWS::Import provides Ruby interface to AWS Import/Export API
|
6
|
+
|
7
|
+
* Getting started
|
8
|
+
|
9
|
+
require 'aws/import/job'
|
10
|
+
|
11
|
+
*** Configure the Import using your access/secret keys
|
12
|
+
AWS::Import::Config.aws_access_key_id = "YOUR-ACCESS-KEY"
|
13
|
+
|
14
|
+
AWS::Import::Config.aws_secret_key_id = "YOUR-SECRET-KEY"
|
15
|
+
|
16
|
+
*** Build Manifest according to AWS API docs
|
17
|
+
manifest = <<EOF
|
18
|
+
|
19
|
+
manifestVersion: 2.0
|
20
|
+
|
21
|
+
bucket: myBucket-Sonian
|
22
|
+
|
23
|
+
accessKeyId: YOUR-ACCESS-KEY
|
24
|
+
|
25
|
+
returnAddress:
|
26
|
+
|
27
|
+
name: Amazon.com ATTN Joe Random
|
28
|
+
|
29
|
+
street1: 120 Nosuch Ave S.
|
30
|
+
|
31
|
+
city: Seattle
|
32
|
+
|
33
|
+
stateOrProvince: WA
|
34
|
+
|
35
|
+
postalCode: 91111
|
36
|
+
|
37
|
+
phoneNumber: 206-266-0000
|
38
|
+
|
39
|
+
country: USA
|
40
|
+
|
41
|
+
eraseDevice: no
|
42
|
+
|
43
|
+
deviceId: 49382
|
44
|
+
|
45
|
+
EOF
|
46
|
+
|
47
|
+
*** Create new Import Job
|
48
|
+
job = AWS::Import::Job.new(:manifest => manifest)
|
49
|
+
|
50
|
+
job.save
|
51
|
+
|
52
|
+
job.id # => JobId node value from response (Example: ABC-123)
|
53
|
+
|
54
|
+
or
|
55
|
+
|
56
|
+
job = AWS::Import::Job.create(:manifest => manifest)
|
57
|
+
|
58
|
+
job.id # => JobId node value from response (Example: ABC-123)
|
59
|
+
|
60
|
+
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/aws-ie.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
version = File.read(File.expand_path("../VERSION",__FILE__)).strip
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.name = 'aws-ie'
|
7
|
+
s.version = version
|
8
|
+
s.summary = 'AWS Import/Export API supoprt.'
|
9
|
+
s.homepage = "http://rubygems.org/gems/aws-ie"
|
10
|
+
|
11
|
+
s.required_ruby_version = '>= 1.8.7'
|
12
|
+
s.required_rubygems_version = ">= 1.3.6"
|
13
|
+
|
14
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
15
|
+
s.add_development_dependency "rspec", "1.3.0"
|
16
|
+
s.add_dependency "nokogiri", "1.4.3.1"
|
17
|
+
|
18
|
+
s.author = 'Maksim Horbul'
|
19
|
+
s.email = 'max@gorbul.net'
|
20
|
+
|
21
|
+
s.files = [
|
22
|
+
"README.org",
|
23
|
+
"COPYING",
|
24
|
+
"Gemfile",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"aws-ie.gemspec",
|
28
|
+
"lib/aws/ie.rb",
|
29
|
+
"lib/aws/import/job.rb",
|
30
|
+
"lib/aws/ie/client.rb",
|
31
|
+
"spec/aws/import/job_spec.rb",
|
32
|
+
"spec/aws/ie/client_spec.rb"
|
33
|
+
]
|
34
|
+
s.require_path = 'lib'
|
35
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module AWS
|
6
|
+
class IE
|
7
|
+
class Client
|
8
|
+
|
9
|
+
API_URL = "https://importexport.amazonaws.com"
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :aws_access_key_id
|
13
|
+
attr_accessor :aws_secret_key_id
|
14
|
+
attr_accessor :test_mode
|
15
|
+
attr_accessor :debug_output
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@url = URI.parse(API_URL)
|
20
|
+
@url.path = "/" if @url.path.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def post(params)
|
24
|
+
request = prepare_request_with_params(params)
|
25
|
+
http = Net::HTTP.new(@url.host, @url.port)
|
26
|
+
unless self.class.debug_output.nil?
|
27
|
+
http.set_debug_output(self.class.debug_output)
|
28
|
+
end
|
29
|
+
http.use_ssl = true
|
30
|
+
http.start { |http| http.request(request) }.body
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def prepare_request_with_params(params)
|
35
|
+
request = Net::HTTP::Post.new(@url.path)
|
36
|
+
request.body = signed_query_string(params)
|
37
|
+
request.content_type = "application/x-www-form-urlencoded"
|
38
|
+
request
|
39
|
+
end
|
40
|
+
|
41
|
+
def signed_query_string(params)
|
42
|
+
canonical_query = canonical_query_string(params)
|
43
|
+
canonical_string = ["POST", @url.host, "/", canonical_query].join("\n")
|
44
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
45
|
+
hmac = OpenSSL::HMAC.
|
46
|
+
digest(digest, self.class.aws_secret_key_id, canonical_string)
|
47
|
+
signature = [hmac].pack("m").strip
|
48
|
+
canonical_query + "&Signature=" + urlencode(signature)
|
49
|
+
end
|
50
|
+
|
51
|
+
def canonical_query_string(params)
|
52
|
+
default_params = {
|
53
|
+
"Timestamp" => Time.now.iso8601,
|
54
|
+
"AWSAccessKeyId" => self.class.aws_access_key_id,
|
55
|
+
"SignatureVersion" => 2,
|
56
|
+
"SignatureMethod" => "HmacSHA1"
|
57
|
+
}
|
58
|
+
default_params["ValidateOnly"] = true if self.class.test_mode == true
|
59
|
+
params.merge!(default_params)
|
60
|
+
sep = "&"
|
61
|
+
params.sort { |a,b| a[0] <=> b[0] }.
|
62
|
+
reduce([]) { |r, p| r << "#{urlencode(p[0].to_s)}=#{urlencode(p[1].to_s)}" }.
|
63
|
+
join(sep)
|
64
|
+
end
|
65
|
+
|
66
|
+
def urlencode(str)
|
67
|
+
r = /[^-_.!~*'()a-zA-Z\d;?@&$,\[\]]/n
|
68
|
+
URI.escape(str, r)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/aws/ie.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module AWS
|
5
|
+
module Import
|
6
|
+
|
7
|
+
class ResponseError < Exception
|
8
|
+
attr_accessor :code
|
9
|
+
def initialize(options)
|
10
|
+
@code = options[:code]
|
11
|
+
super(options[:message])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Job
|
16
|
+
attr_reader :id, :signature, :status
|
17
|
+
attr_accessor :manifest
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
attr_accessor :client
|
22
|
+
|
23
|
+
def create(attributes = { })
|
24
|
+
self.new(attributes) do |job|
|
25
|
+
job.save
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def cancel(job_id)
|
30
|
+
params = {
|
31
|
+
"Operation" => "CancelJob",
|
32
|
+
"JobId" => job_id
|
33
|
+
}
|
34
|
+
xml = self.new.send(:request, params)
|
35
|
+
success = xml.root.xpath("//Success").text
|
36
|
+
return success == "true"
|
37
|
+
end
|
38
|
+
|
39
|
+
def find(job_id)
|
40
|
+
self.new.find(job_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(attributes = { }, &block)
|
46
|
+
@manifest = attributes[:manifest]
|
47
|
+
block.call(self) if block_given?
|
48
|
+
end
|
49
|
+
|
50
|
+
def save
|
51
|
+
self.new_job? ? create : update
|
52
|
+
end
|
53
|
+
|
54
|
+
def find(job_id)
|
55
|
+
params = {
|
56
|
+
"Operation" => "GetStatus",
|
57
|
+
"JobId" => job_id
|
58
|
+
}
|
59
|
+
xml = request(params)
|
60
|
+
@id = xml.root.xpath("//JobId").text
|
61
|
+
@manifest = xml.root.xpath("//CurrentManifest").text
|
62
|
+
@status = {
|
63
|
+
:code => xml.root.xpath("//ProgressCode").text,
|
64
|
+
:message => xml.root.xpath("//ProgressMessage").text
|
65
|
+
}
|
66
|
+
@signature = xml.root.xpath("//Signature").text
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def new_job?
|
71
|
+
self.id.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def create
|
76
|
+
params = {
|
77
|
+
"Operation" => "CreateJob",
|
78
|
+
"Manifest" => self.manifest
|
79
|
+
}
|
80
|
+
xml = request(params)
|
81
|
+
@id = xml.root.xpath("//JobId").text
|
82
|
+
@signature = xml.root.xpath("//Signature").text
|
83
|
+
end
|
84
|
+
|
85
|
+
def update
|
86
|
+
params = {
|
87
|
+
"Operation" => "UpdateJob",
|
88
|
+
"Manifest" => self.manifest,
|
89
|
+
"JobId" => self.id
|
90
|
+
}
|
91
|
+
xml = request(params)
|
92
|
+
success = xml.root.xpath("//Success").text
|
93
|
+
return success == "true"
|
94
|
+
end
|
95
|
+
|
96
|
+
def request(params)
|
97
|
+
self.class.client ||= AWS::IE::Client.new
|
98
|
+
params.merge!("JobType" => "Import")
|
99
|
+
xml = Nokogiri::XML(self.class.client.post(params))
|
100
|
+
xml.remove_namespaces!
|
101
|
+
if xml.root.name == "ErrorResponse"
|
102
|
+
code = xml.root.xpath("//Error/Code").text
|
103
|
+
message = xml.root.xpath("//Error/Message").text
|
104
|
+
raise ResponseError.new(:code => code, :message => message)
|
105
|
+
end
|
106
|
+
xml
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'aws/ie/client'
|
3
|
+
|
4
|
+
describe AWS::IE::Client do
|
5
|
+
|
6
|
+
let(:manifest) do
|
7
|
+
{ }
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:params) do
|
11
|
+
{
|
12
|
+
"Operation" => "CreateJob",
|
13
|
+
"JobType" => "Import",
|
14
|
+
"Manifest" => manifest.to_yaml
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:signed_query_string) do
|
19
|
+
"AWSAccessKeyId=ABC-123" +
|
20
|
+
"&JobType=Import" +
|
21
|
+
"&Manifest=---%20%7B%7D%0A%0A" +
|
22
|
+
"&Operation=CreateJob" +
|
23
|
+
"&SignatureMethod=HmacSHA1" +
|
24
|
+
"&SignatureVersion=2" +
|
25
|
+
"&Timestamp=2010-09-20T05%3A10%3A35%2B00%3A00" +
|
26
|
+
"&Signature=hmgL0julWxoVXeYHHqFQAbvmaL4%3D"
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:timestamp) { Time.parse("2010-09-20 05:10:35") }
|
30
|
+
|
31
|
+
let(:post_request) { Net::HTTP::Post.new("/") }
|
32
|
+
|
33
|
+
let(:http) do
|
34
|
+
stubs = {
|
35
|
+
:start => response,
|
36
|
+
:use_ssl= => nil,
|
37
|
+
:request => response,
|
38
|
+
:set_debug_output => nil
|
39
|
+
}
|
40
|
+
mock("Net::HTTP", stubs)
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:response) do
|
44
|
+
mock("Response", :body => "<xml />")
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:host) { "importexport.amazonaws.com" }
|
48
|
+
let(:port) { 443 }
|
49
|
+
|
50
|
+
let(:access_key) { "ABC-123" }
|
51
|
+
let(:secret_key) { "123-ABC" }
|
52
|
+
|
53
|
+
before do
|
54
|
+
post_request
|
55
|
+
timestamp
|
56
|
+
Time.should_receive(:now).and_return(timestamp)
|
57
|
+
described_class.aws_access_key_id = access_key
|
58
|
+
described_class.aws_secret_key_id = secret_key
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should prepare HTTP Post signed request" do
|
62
|
+
Net::HTTP.stub!(:new).and_return(http)
|
63
|
+
Net::HTTP::Post.should_receive(:new).with("/").and_return(post_request)
|
64
|
+
post_request.should_receive(:body=).with(signed_query_string)
|
65
|
+
post_request.should_receive(:content_type=).
|
66
|
+
with("application/x-www-form-urlencoded")
|
67
|
+
client = described_class.new
|
68
|
+
client.post(params)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should send the signed request" do
|
72
|
+
Net::HTTP::Post.stub!(:new).and_return(post_request)
|
73
|
+
Net::HTTP.should_receive(:new).with(host, port).and_return(http)
|
74
|
+
http.should_receive(:start).and_yield(http)
|
75
|
+
http.should_receive(:use_ssl=).with(true)
|
76
|
+
http.should_receive(:request).with(post_request).and_return(response)
|
77
|
+
client = described_class.new
|
78
|
+
client.post(params).should == "<xml />"
|
79
|
+
end
|
80
|
+
|
81
|
+
context "in debug mode" do
|
82
|
+
|
83
|
+
before do
|
84
|
+
AWS::IE::Client.debug_output = STDOUT
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should set debug output" do
|
88
|
+
Net::HTTP.stub!(:new).and_return(http)
|
89
|
+
Net::HTTP::Post.should_receive(:new).with("/").and_return(post_request)
|
90
|
+
http.should_receive(:set_debug_output).with(STDOUT)
|
91
|
+
client = described_class.new
|
92
|
+
client.post(params)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
context "in test mode" do
|
98
|
+
|
99
|
+
let(:signed_query_string) do
|
100
|
+
"AWSAccessKeyId=ABC-123" +
|
101
|
+
"&JobType=Import" +
|
102
|
+
"&Manifest=---%20%7B%7D%0A%0A" +
|
103
|
+
"&Operation=CreateJob" +
|
104
|
+
"&SignatureMethod=HmacSHA1" +
|
105
|
+
"&SignatureVersion=2" +
|
106
|
+
"&Timestamp=2010-09-20T05%3A10%3A35%2B00%3A00" +
|
107
|
+
"&ValidateOnly=true" +
|
108
|
+
"&Signature=%2BOIG%2F6ouAbS%2FI2vTQZYFsgUKk3Y%3D"
|
109
|
+
end
|
110
|
+
|
111
|
+
before do
|
112
|
+
AWS::IE::Client.test_mode = true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should send validate only request" do
|
116
|
+
Net::HTTP.stub!(:new).and_return(http)
|
117
|
+
Net::HTTP::Post.should_receive(:new).with("/").and_return(post_request)
|
118
|
+
post_request.should_receive(:body=).with(signed_query_string)
|
119
|
+
post_request.should_receive(:content_type=).
|
120
|
+
with("application/x-www-form-urlencoded")
|
121
|
+
client = described_class.new
|
122
|
+
client.post(params)
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'aws/ie'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
describe AWS::Import::Job do
|
6
|
+
|
7
|
+
let(:manifest) do
|
8
|
+
File.read(File.join(File.dirname(__FILE__), "../../fixtures/manifest.yml"))
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:client) do
|
12
|
+
AWS::IE::Client.new
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:response) do
|
16
|
+
File.read(File.join(
|
17
|
+
File.dirname(__FILE__),
|
18
|
+
"../../fixtures/#{response_file_name}"))
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
client.stub!(:post).and_return("<xml />")
|
23
|
+
described_class.client = client
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "in general" do
|
27
|
+
|
28
|
+
it "should have manifest" do
|
29
|
+
job = described_class.new
|
30
|
+
job.manifest.should be_nil
|
31
|
+
job.manifest = "manifest content"
|
32
|
+
job.manifest.should == "manifest content"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should get the parameters from constructor" do
|
36
|
+
job = described_class.new(:manifest => "manifest content")
|
37
|
+
job.manifest.should == "manifest content"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be a new job when it's not saved yet" do
|
41
|
+
job = described_class.new
|
42
|
+
job.should be_new_job
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should create only one instance of the IE::Client" do
|
46
|
+
described_class.client = nil
|
47
|
+
AWS::IE::Client.should_receive(:new).once.and_return(client)
|
48
|
+
job = described_class.new
|
49
|
+
job.save
|
50
|
+
described_class.find("ABC-123")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not be a new job when it's saved already" do
|
54
|
+
response_file = File.
|
55
|
+
join(File.dirname(__FILE__),
|
56
|
+
"../../fixtures/get_status_response_successfull.xml")
|
57
|
+
response = File.read(response_file)
|
58
|
+
client.should_receive(:post).and_return(response)
|
59
|
+
job = AWS::Import::Job.find("ABC-123")
|
60
|
+
job.should_not be_new_job
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "when find a job by id" do
|
66
|
+
|
67
|
+
let(:response_file_name) do
|
68
|
+
"get_status_response_successfull.xml"
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:params) do
|
72
|
+
{
|
73
|
+
"JobType" => "Import",
|
74
|
+
"Operation" => "GetStatus",
|
75
|
+
"JobId" => "ABC-123"
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:job) { AWS::Import::Job.new }
|
80
|
+
|
81
|
+
before do
|
82
|
+
client.stub!(:post).with(params).and_return(response)
|
83
|
+
end
|
84
|
+
|
85
|
+
context "but job does not exist" do
|
86
|
+
|
87
|
+
let(:response_file_name) do
|
88
|
+
"get_status_response_failed.xml"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should raise exception when job is not found" do
|
92
|
+
job
|
93
|
+
lambda { AWS::Import::Job.find("ABC-123") }.
|
94
|
+
should raise_error(AWS::Import::ResponseError)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should send JobStatus API request" do
|
100
|
+
client.should_receive(:post).with(params).and_return(response)
|
101
|
+
AWS::Import::Job.find("ABC-123")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should create Job instance and have all attributes set" do
|
105
|
+
job
|
106
|
+
AWS::Import::Job.should_receive(:new).and_return(job)
|
107
|
+
AWS::Import::Job.find("ABC-123")
|
108
|
+
job.manifest.should == manifest
|
109
|
+
job.id.should == "ABC-123"
|
110
|
+
job.status[:code].should == "Pending"
|
111
|
+
job.status[:message].should == "The specified job has not started."
|
112
|
+
job.signature.should == "D6j+YqwmWiVXQzuy5Bu0lxehI3E="
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "when is being canceled" do
|
118
|
+
|
119
|
+
let(:params) do
|
120
|
+
{
|
121
|
+
"JobType" => "Import",
|
122
|
+
"Operation" => "CancelJob",
|
123
|
+
"JobId" => "ABC-123"
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
context "successfully" do
|
128
|
+
|
129
|
+
let(:response_file_name) { "cancel_job_response_successfull.xml" }
|
130
|
+
|
131
|
+
it "should send cancel request and get successfull response" do
|
132
|
+
client.should_receive(:post).with(params).and_return(response)
|
133
|
+
described_class.cancel("ABC-123").should be_true
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
context "failed" do
|
139
|
+
|
140
|
+
let(:response_file_name) { "cancel_job_response_failed.xml" }
|
141
|
+
|
142
|
+
it "should send cancel request and get failed response" do
|
143
|
+
client.should_receive(:post).with(params).and_return(response)
|
144
|
+
begin
|
145
|
+
described_class.cancel("ABC-123")
|
146
|
+
rescue AWS::Import::ResponseError => e
|
147
|
+
e.code.should == "InvalidJobIdException"
|
148
|
+
e.message.should == "No such job 4Y8ND-VALIDATE-ONLY for your account"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "when is being updated" do
|
157
|
+
|
158
|
+
let(:response_file_name) { "update_job_response_successful.xml" }
|
159
|
+
|
160
|
+
let(:manifest) { { } }
|
161
|
+
|
162
|
+
let(:params) do
|
163
|
+
{
|
164
|
+
"JobType" => "Import",
|
165
|
+
"Operation" => "UpdateJob",
|
166
|
+
"Manifest" => manifest.to_yaml,
|
167
|
+
"JobId" => "ABC-123"
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
let(:job) do
|
172
|
+
job = described_class.new do |j|
|
173
|
+
j.manifest = manifest.to_yaml
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
before do
|
178
|
+
job.stub!(:id).and_return("ABC-123")
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should update the existing job" do
|
182
|
+
client.should_receive(:post).with(params).and_return(response)
|
183
|
+
job.save.should be_true
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "when update API call is failed" do
|
187
|
+
|
188
|
+
let(:response_file_name) { "update_job_response_failed.xml" }
|
189
|
+
|
190
|
+
it "should raise exception" do
|
191
|
+
begin
|
192
|
+
job.save
|
193
|
+
rescue AWS::Import::ResponseError => e
|
194
|
+
e.code.should == "InvalidJobIdException"
|
195
|
+
e.message.should == "No such job 123456 for your account"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "when is being created" do
|
204
|
+
|
205
|
+
let(:response_file_name) { "create_job_response.xml" }
|
206
|
+
|
207
|
+
let(:manifest) do
|
208
|
+
{ }
|
209
|
+
end
|
210
|
+
|
211
|
+
let(:params) do
|
212
|
+
{
|
213
|
+
"JobType" => "Import",
|
214
|
+
"Operation" => "CreateJob",
|
215
|
+
"Manifest" => manifest.to_yaml
|
216
|
+
}
|
217
|
+
end
|
218
|
+
|
219
|
+
before do
|
220
|
+
client.stub!(:post).with(params).and_return(response)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should create AWS::IE::Client instance" do
|
224
|
+
described_class.create(:manifest => manifest.to_yaml).
|
225
|
+
should be_instance_of(described_class)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should send API request" do
|
229
|
+
client.should_receive(:post).with(params).and_return(response)
|
230
|
+
described_class.create(:manifest => manifest.to_yaml).
|
231
|
+
should be_instance_of(described_class)
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should get the Job ID from response" do
|
235
|
+
job = described_class.create(:manifest => manifest.to_yaml)
|
236
|
+
job.id.should == "45HFS-VALIDATE-ONLY"
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should have the signature" do
|
240
|
+
job = described_class.create(:manifest => manifest.to_yaml)
|
241
|
+
job.signature.should == "/dxgK27c8++SFiZLLaIvHt4Oy4k="
|
242
|
+
end
|
243
|
+
|
244
|
+
describe "and error occures" do
|
245
|
+
|
246
|
+
let(:response_file_name) { "create_job_response_failed.xml" }
|
247
|
+
|
248
|
+
it "should return not saved job with errors inside" do
|
249
|
+
begin
|
250
|
+
job = described_class.create
|
251
|
+
rescue AWS::Import::ResponseError => e
|
252
|
+
e.code.should == "MissingParameterException"
|
253
|
+
e.message.should == "Manifest must be specified"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws-ie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Maksim Horbul
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-28 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 23
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 1.0.0
|
33
|
+
requirement: *id001
|
34
|
+
name: bundler
|
35
|
+
prerelease: false
|
36
|
+
type: :development
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - "="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 27
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
version: 1.3.0
|
49
|
+
requirement: *id002
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
type: :development
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - "="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 113
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 4
|
63
|
+
- 3
|
64
|
+
- 1
|
65
|
+
version: 1.4.3.1
|
66
|
+
requirement: *id003
|
67
|
+
name: nokogiri
|
68
|
+
prerelease: false
|
69
|
+
type: :runtime
|
70
|
+
description:
|
71
|
+
email: max@gorbul.net
|
72
|
+
executables: []
|
73
|
+
|
74
|
+
extensions: []
|
75
|
+
|
76
|
+
extra_rdoc_files: []
|
77
|
+
|
78
|
+
files:
|
79
|
+
- README.org
|
80
|
+
- COPYING
|
81
|
+
- Gemfile
|
82
|
+
- Rakefile
|
83
|
+
- VERSION
|
84
|
+
- aws-ie.gemspec
|
85
|
+
- lib/aws/ie.rb
|
86
|
+
- lib/aws/import/job.rb
|
87
|
+
- lib/aws/ie/client.rb
|
88
|
+
- spec/aws/import/job_spec.rb
|
89
|
+
- spec/aws/ie/client_spec.rb
|
90
|
+
has_rdoc: true
|
91
|
+
homepage: http://rubygems.org/gems/aws-ie
|
92
|
+
licenses: []
|
93
|
+
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 57
|
105
|
+
segments:
|
106
|
+
- 1
|
107
|
+
- 8
|
108
|
+
- 7
|
109
|
+
version: 1.8.7
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 23
|
116
|
+
segments:
|
117
|
+
- 1
|
118
|
+
- 3
|
119
|
+
- 6
|
120
|
+
version: 1.3.6
|
121
|
+
requirements: []
|
122
|
+
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 1.3.7
|
125
|
+
signing_key:
|
126
|
+
specification_version: 3
|
127
|
+
summary: AWS Import/Export API supoprt.
|
128
|
+
test_files: []
|
129
|
+
|