amazon-mws 0.1.0
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.
- data/.gitignore +1 -0
- data/README.markdown +31 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/amazon-mws.gemspec +164 -0
- data/examples/xml/cancel_feed_submissions.xml +16 -0
- data/examples/xml/cancel_report_requests.xml +18 -0
- data/examples/xml/error.xml +10 -0
- data/examples/xml/get_feed_submission_count.xml +10 -0
- data/examples/xml/get_feed_submission_list.xml +16 -0
- data/examples/xml/get_feed_submission_list_by_next_token.xml +16 -0
- data/examples/xml/get_feed_submission_result.xml +30 -0
- data/examples/xml/get_report_count.xml +9 -0
- data/examples/xml/get_report_list.xml +17 -0
- data/examples/xml/get_report_request_count.xml +8 -0
- data/examples/xml/get_report_request_list.xml +120 -0
- data/examples/xml/get_report_request_list_by_next_token.xml +20 -0
- data/examples/xml/get_report_schedule_count.xml +10 -0
- data/examples/xml/get_report_schedule_list.xml +15 -0
- data/examples/xml/get_report_schedule_list_by_next_token.xml +15 -0
- data/examples/xml/manage_report_schedule.xml +14 -0
- data/examples/xml/request_report.xml +17 -0
- data/examples/xml/submit_feed.xml +14 -0
- data/examples/xml/update_report_acknowledgements.xml +18 -0
- data/examples/xsd/Inventory.xsd +49 -0
- data/examples/xsd/Item.xsd +285 -0
- data/examples/xsd/Listings.xsd +32 -0
- data/examples/xsd/OrderAcknowledgement.xsd +55 -0
- data/examples/xsd/OrderAdjustment.xsd +94 -0
- data/examples/xsd/OrderFulfillment.xsd +57 -0
- data/examples/xsd/Override.xsd +48 -0
- data/examples/xsd/Price.xsd +59 -0
- data/examples/xsd/ProcessingReport.xsd +87 -0
- data/examples/xsd/Product.xsd +220 -0
- data/examples/xsd/Product/AutoAccessory.xsd +807 -0
- data/examples/xsd/Product/Beauty.xsd +114 -0
- data/examples/xsd/Product/CE.xsd +544 -0
- data/examples/xsd/Product/CameraPhoto.xsd +2410 -0
- data/examples/xsd/Product/FoodAndBeverages.xsd +270 -0
- data/examples/xsd/Product/Gourmet.xsd +85 -0
- data/examples/xsd/Product/Health.xsd +189 -0
- data/examples/xsd/Product/Home.xsd +654 -0
- data/examples/xsd/Product/Jewelry.xsd +603 -0
- data/examples/xsd/Product/Miscellaneous.xsd +157 -0
- data/examples/xsd/Product/MusicalInstruments.xsd +853 -0
- data/examples/xsd/Product/Office.xsd +550 -0
- data/examples/xsd/Product/PetSupplies.xsd +40 -0
- data/examples/xsd/Product/ProductClothing.xsd +197 -0
- data/examples/xsd/Product/SWVG.xsd +238 -0
- data/examples/xsd/Product/Sports.xsd +308 -0
- data/examples/xsd/Product/TiresAndWheels.xsd +159 -0
- data/examples/xsd/Product/Tools.xsd +66 -0
- data/examples/xsd/Product/ToysBaby.xsd +241 -0
- data/examples/xsd/Product/Wireless.xsd +77 -0
- data/examples/xsd/ProductImage.xsd +39 -0
- data/examples/xsd/Relationship.xsd +47 -0
- data/examples/xsd/SettlementReport.xsd +158 -0
- data/examples/xsd/amzn-base.xsd +1601 -0
- data/examples/xsd/amzn-envelope.xsd +98 -0
- data/examples/xsd/amzn-header.xsd +45 -0
- data/lib/amazon/mws.rb +86 -0
- data/lib/amazon/mws/authentication.rb +9 -0
- data/lib/amazon/mws/authentication/query_string.rb +28 -0
- data/lib/amazon/mws/authentication/signature.rb +43 -0
- data/lib/amazon/mws/base.rb +61 -0
- data/lib/amazon/mws/connection.rb +99 -0
- data/lib/amazon/mws/connection/management.rb +94 -0
- data/lib/amazon/mws/connection/request_builder.rb +67 -0
- data/lib/amazon/mws/exceptions.rb +80 -0
- data/lib/amazon/mws/feed.rb +223 -0
- data/lib/amazon/mws/feed_builder.rb +67 -0
- data/lib/amazon/mws/feed_enumerations.rb +46 -0
- data/lib/amazon/mws/feed_submission.rb +14 -0
- data/lib/amazon/mws/lib/extensions.rb +162 -0
- data/lib/amazon/mws/lib/memoizable.rb +10 -0
- data/lib/amazon/mws/orders.rb +9 -0
- data/lib/amazon/mws/report.rb +310 -0
- data/lib/amazon/mws/report_enumerations.rb +44 -0
- data/lib/amazon/mws/report_info.rb +16 -0
- data/lib/amazon/mws/report_request.rb +19 -0
- data/lib/amazon/mws/report_schedule.rb +13 -0
- data/lib/amazon/mws/response.rb +32 -0
- data/lib/amazon/mws/response/cancel_feed_submissions_response.rb +14 -0
- data/lib/amazon/mws/response/cancel_report_requests_response.rb +14 -0
- data/lib/amazon/mws/response/get_feed_submission_count_response.rb +13 -0
- data/lib/amazon/mws/response/get_feed_submission_list_by_next_token_response.rb +15 -0
- data/lib/amazon/mws/response/get_feed_submission_list_response.rb +15 -0
- data/lib/amazon/mws/response/get_feed_submission_result_response.rb +54 -0
- data/lib/amazon/mws/response/get_report_count_response.rb +13 -0
- data/lib/amazon/mws/response/get_report_list_response.rb +15 -0
- data/lib/amazon/mws/response/get_report_request_count_response.rb +13 -0
- data/lib/amazon/mws/response/get_report_request_list_by_next_token_response.rb +15 -0
- data/lib/amazon/mws/response/get_report_request_list_response.rb +15 -0
- data/lib/amazon/mws/response/get_report_schedule_count_response.rb +13 -0
- data/lib/amazon/mws/response/get_report_schedule_list_by_next_token_response.rb +15 -0
- data/lib/amazon/mws/response/get_report_schedule_list_response.rb +15 -0
- data/lib/amazon/mws/response/manage_report_schedule_response.rb +14 -0
- data/lib/amazon/mws/response/request_report_response.rb +14 -0
- data/lib/amazon/mws/response/response_error.rb +15 -0
- data/lib/amazon/mws/response/submit_feed_response.rb +13 -0
- data/lib/amazon/mws/response/update_reports_acknowledgements_response.rb +14 -0
- data/lib/amazon/mws/version.rb +12 -0
- data/pkg/amazon-mws-0.1.0.gem +0 -0
- data/test/authentication_test.rb +15 -0
- data/test/connection_test.rb +5 -0
- data/test/feed_builder_test.rb +15 -0
- data/test/feed_submission_test.rb +32 -0
- data/test/feed_test.rb +64 -0
- data/test/query_string_test.rb +21 -0
- data/test/report_test.rb +29 -0
- data/test/request_test.rb +18 -0
- data/test/response_test.rb +197 -0
- data/test/signature_test.rb +30 -0
- data/test/test_config.yml +5 -0
- data/test/test_helper.rb +22 -0
- metadata +179 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<!-- Revision="$Revision: #6 $" -->
|
3
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
4
|
+
<!--
|
5
|
+
$Date: 2007/01/18 $
|
6
|
+
|
7
|
+
AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
|
8
|
+
confidential and proprietary information of Amazon.com and may not be reproduced,
|
9
|
+
distributed or used, in whole or in part, for any purpose other than as necessary
|
10
|
+
to list products for sale on the www.amazon.com web site pursuant to an agreement
|
11
|
+
with Amazon.com.
|
12
|
+
-->
|
13
|
+
<xsd:include schemaLocation="amzn-base.xsd"/>
|
14
|
+
<xsd:include schemaLocation="amzn-header.xsd"/>
|
15
|
+
<xsd:include schemaLocation="FulfillmentCenter.xsd"/>
|
16
|
+
<xsd:include schemaLocation="Inventory.xsd"/>
|
17
|
+
<xsd:include schemaLocation="Listings.xsd"/>
|
18
|
+
<xsd:include schemaLocation="OrderAcknowledgement.xsd"/>
|
19
|
+
<xsd:include schemaLocation="OrderAdjustment.xsd"/>
|
20
|
+
<xsd:include schemaLocation="OrderFulfillment.xsd"/>
|
21
|
+
|
22
|
+
<xsd:include schemaLocation="Override.xsd"/>
|
23
|
+
<xsd:include schemaLocation="Price.xsd"/>
|
24
|
+
<xsd:include schemaLocation="ProcessingReport.xsd"/>
|
25
|
+
<xsd:include schemaLocation="ProductImage.xsd"/>
|
26
|
+
<xsd:include schemaLocation="Product.xsd"/>
|
27
|
+
<xsd:include schemaLocation="Relationship.xsd"/>
|
28
|
+
<xsd:include schemaLocation="SettlementReport.xsd"/>
|
29
|
+
<xsd:element name="AmazonEnvelope">
|
30
|
+
<xsd:complexType>
|
31
|
+
<xsd:sequence>
|
32
|
+
<xsd:element ref="Header"/>
|
33
|
+
<xsd:element name="MessageType">
|
34
|
+
<xsd:simpleType>
|
35
|
+
<xsd:restriction base="xsd:string">
|
36
|
+
<xsd:enumeration value="FulfillmentCenter"/>
|
37
|
+
<xsd:enumeration value="Inventory"/>
|
38
|
+
<xsd:enumeration value="Listings"/>
|
39
|
+
<xsd:enumeration value="OrderAcknowledgement"/>
|
40
|
+
<xsd:enumeration value="OrderAdjustment"/>
|
41
|
+
<xsd:enumeration value="OrderFulfillment"/>
|
42
|
+
<xsd:enumeration value="Override"/>
|
43
|
+
<xsd:enumeration value="Price"/>
|
44
|
+
<xsd:enumeration value="ProcessingReport"/>
|
45
|
+
<xsd:enumeration value="Product"/>
|
46
|
+
<xsd:enumeration value="ProductImage"/>
|
47
|
+
<xsd:enumeration value="Relationship"/>
|
48
|
+
<xsd:enumeration value="SettlementReport"/>
|
49
|
+
</xsd:restriction>
|
50
|
+
</xsd:simpleType>
|
51
|
+
</xsd:element>
|
52
|
+
<xsd:element ref="MarketplaceName" minOccurs="0">
|
53
|
+
<xsd:annotation>
|
54
|
+
<xsd:documentation>
|
55
|
+
The MarketplaceName is only supported for
|
56
|
+
Override feeds.
|
57
|
+
If included here, the MarketplaceName will
|
58
|
+
apply to all messages in the feed.
|
59
|
+
</xsd:documentation>
|
60
|
+
</xsd:annotation>
|
61
|
+
</xsd:element>
|
62
|
+
<xsd:element name="PurgeAndReplace" type="xsd:boolean" minOccurs="0"/>
|
63
|
+
<xsd:element name="EffectiveDate" type="xsd:dateTime" minOccurs="0"/>
|
64
|
+
<xsd:element name="Message" maxOccurs="unbounded">
|
65
|
+
<xsd:complexType>
|
66
|
+
<xsd:sequence>
|
67
|
+
<xsd:element name="MessageID" type="IDNumber"/>
|
68
|
+
<xsd:element name="OperationType" minOccurs="0">
|
69
|
+
<xsd:simpleType>
|
70
|
+
<xsd:restriction base="xsd:string">
|
71
|
+
<xsd:enumeration value="Update"/>
|
72
|
+
<xsd:enumeration value="Delete"/>
|
73
|
+
<xsd:enumeration value="PartialUpdate"/>
|
74
|
+
</xsd:restriction>
|
75
|
+
</xsd:simpleType>
|
76
|
+
</xsd:element>
|
77
|
+
<xsd:choice>
|
78
|
+
<xsd:element ref="FulfillmentCenter"/>
|
79
|
+
<xsd:element ref="Inventory"/>
|
80
|
+
<xsd:element ref="Listings"/>
|
81
|
+
<xsd:element ref="OrderAcknowledgement"/>
|
82
|
+
<xsd:element ref="OrderAdjustment"/>
|
83
|
+
<xsd:element ref="OrderFulfillment"/>
|
84
|
+
<xsd:element ref="Override"/>
|
85
|
+
<xsd:element ref="Price"/>
|
86
|
+
<xsd:element ref="ProcessingReport"/>
|
87
|
+
<xsd:element ref="Product"/>
|
88
|
+
<xsd:element ref="ProductImage"/>
|
89
|
+
<xsd:element ref="Relationship"/>
|
90
|
+
<xsd:element ref="SettlementReport"/>
|
91
|
+
</xsd:choice>
|
92
|
+
</xsd:sequence>
|
93
|
+
</xsd:complexType>
|
94
|
+
</xsd:element>
|
95
|
+
</xsd:sequence>
|
96
|
+
</xsd:complexType>
|
97
|
+
</xsd:element>
|
98
|
+
</xsd:schema>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<!-- "$Revision: #3 $" -->
|
3
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
4
|
+
|
5
|
+
<!--
|
6
|
+
$Date: 2005/04/01 $
|
7
|
+
|
8
|
+
AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
|
9
|
+
confidential and proprietary information of Amazon.com and may not be reproduced,
|
10
|
+
distributed or used, in whole or in part, for any purpose other than as necessary
|
11
|
+
to list products for sale on the www.amazon.com web site pursuant to an agreement
|
12
|
+
with Amazon.com.
|
13
|
+
-->
|
14
|
+
|
15
|
+
<xsd:include schemaLocation="amzn-base.xsd"/>
|
16
|
+
|
17
|
+
<xsd:element name="Header">
|
18
|
+
<xsd:complexType>
|
19
|
+
<xsd:sequence>
|
20
|
+
|
21
|
+
<xsd:element name="DocumentVersion">
|
22
|
+
<xsd:simpleType>
|
23
|
+
<xsd:restriction base="xsd:string">
|
24
|
+
<xsd:pattern value="\d{1,2}\.\d{1,2}"/>
|
25
|
+
</xsd:restriction>
|
26
|
+
</xsd:simpleType>
|
27
|
+
</xsd:element>
|
28
|
+
|
29
|
+
<xsd:element name="MerchantIdentifier" type="String"/>
|
30
|
+
|
31
|
+
<xsd:element name="OverrideReleaseId" minOccurs="0">
|
32
|
+
<xsd:simpleType>
|
33
|
+
<xsd:restriction base="xsd:string">
|
34
|
+
<xsd:pattern value="\d{1,4}\.\d{1,4}"/>
|
35
|
+
</xsd:restriction>
|
36
|
+
</xsd:simpleType>
|
37
|
+
</xsd:element>
|
38
|
+
|
39
|
+
</xsd:sequence>
|
40
|
+
</xsd:complexType>
|
41
|
+
</xsd:element>
|
42
|
+
|
43
|
+
</xsd:schema>
|
44
|
+
|
45
|
+
|
data/lib/amazon/mws.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'cgi'
|
3
|
+
require 'uri'
|
4
|
+
require 'openssl'
|
5
|
+
require 'net/https'
|
6
|
+
require 'time'
|
7
|
+
require 'date'
|
8
|
+
require 'hmac'
|
9
|
+
require 'hmac-sha2'
|
10
|
+
require 'base64'
|
11
|
+
require 'builder'
|
12
|
+
require "rexml/document"
|
13
|
+
|
14
|
+
# ROXML - nokogiri and roxml are the only dependencies
|
15
|
+
I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 = true
|
16
|
+
# module ROXML
|
17
|
+
# XML_PARSER = 'nokogiri' # or 'libxml'
|
18
|
+
# end
|
19
|
+
require 'roxml'
|
20
|
+
# /ROXML
|
21
|
+
|
22
|
+
|
23
|
+
$:.unshift(File.dirname(__FILE__))
|
24
|
+
require 'mws/lib/extensions'
|
25
|
+
require 'builder'
|
26
|
+
#require_library_or_gem 'mime/types', 'mime-types' unless defined? MIME::Types
|
27
|
+
|
28
|
+
module Amazon
|
29
|
+
module MWS
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
require 'mws/lib/memoizable'
|
36
|
+
|
37
|
+
require 'mws/feed_builder'
|
38
|
+
require 'mws/feed_enumerations'
|
39
|
+
require 'mws/feed'
|
40
|
+
require 'mws/report_enumerations'
|
41
|
+
require 'mws/report'
|
42
|
+
|
43
|
+
|
44
|
+
require 'mws/response'
|
45
|
+
require 'mws/feed_submission'
|
46
|
+
require 'mws/report_request'
|
47
|
+
require 'mws/report_info'
|
48
|
+
require 'mws/report_schedule'
|
49
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'mws/response/*.rb')).each {|f| require f }
|
50
|
+
|
51
|
+
require 'mws/base'
|
52
|
+
require 'mws/version'
|
53
|
+
require 'mws/exceptions'
|
54
|
+
require 'mws/connection'
|
55
|
+
require 'mws/connection/management'
|
56
|
+
require 'mws/connection/request_builder'
|
57
|
+
require 'mws/authentication'
|
58
|
+
require 'mws/authentication/query_string'
|
59
|
+
require 'mws/authentication/signature'
|
60
|
+
|
61
|
+
|
62
|
+
Amazon::MWS::Base.class_eval do
|
63
|
+
include Amazon::MWS::Feed
|
64
|
+
include Amazon::MWS::Report
|
65
|
+
end
|
66
|
+
|
67
|
+
AWS = Amazon
|
68
|
+
|
69
|
+
require_library_or_gem 'xmlsimple', 'xml-simple' unless defined? XmlSimple
|
70
|
+
=begin
|
71
|
+
# If libxml is installed, we use the FasterXmlSimple library, that provides most of the functionality of XmlSimple
|
72
|
+
# except it uses the xml/libxml library for xml parsing (rather than REXML). If libxml isn't installed, we just fall back on
|
73
|
+
# XmlSimple.
|
74
|
+
AWS::S3::Parsing.parser =
|
75
|
+
begin
|
76
|
+
require_library_or_gem 'xml/libxml'
|
77
|
+
# Older version of libxml aren't stable (bus error when requesting attributes that don't exist) so we
|
78
|
+
# have to use a version greater than '0.3.8.2'.
|
79
|
+
raise LoadError unless XML::Parser::VERSION > '0.3.8.2'
|
80
|
+
$:.push(File.join(File.dirname(__FILE__), '..', '..', 'support', 'faster-xml-simple', 'lib'))
|
81
|
+
require_library_or_gem 'faster_xml_simple'
|
82
|
+
FasterXmlSimple
|
83
|
+
rescue LoadError
|
84
|
+
XmlSimple
|
85
|
+
end
|
86
|
+
=end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Amazon::MWS::Authentication
|
2
|
+
|
3
|
+
class QueryString < String
|
4
|
+
def initialize(params = {})
|
5
|
+
query_params = {
|
6
|
+
'AWSAccessKeyId' => params[:access_key],
|
7
|
+
'Marketplace' => params[:marketplace_id],
|
8
|
+
'Merchant' => params[:merchant_id],
|
9
|
+
'SignatureMethod' => Signature::METHOD,
|
10
|
+
'SignatureVersion' => Signature::VERSION,
|
11
|
+
'Timestamp' => Time.now.iso8601,
|
12
|
+
'Version' => Amazon::MWS::Authentication::VERSION
|
13
|
+
}
|
14
|
+
|
15
|
+
# Add any params that are passed in via uri before calculating the signature
|
16
|
+
query_params = query_params.merge(params[:query_params] || {})
|
17
|
+
# Calculate the signature
|
18
|
+
query_params['Signature'] = Signature.new(query_params, params)
|
19
|
+
|
20
|
+
self << formatted_querystring(query_params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def formatted_querystring(query_params)
|
24
|
+
query_params.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&') # order doesn't matter for the actual request
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Amazon::MWS::Authentication
|
2
|
+
|
3
|
+
class Signature < String#:nodoc:
|
4
|
+
extend Memoizable
|
5
|
+
|
6
|
+
VERSION = '2'
|
7
|
+
METHOD = 'HmacSHA256'
|
8
|
+
|
9
|
+
def initialize(queryparams = {}, params = {})
|
10
|
+
verb = params[:verb]
|
11
|
+
secret = params[:secret_access_key]
|
12
|
+
# Create the string to sign
|
13
|
+
string = string_to_sign(verb, canonical_querystring(queryparams))
|
14
|
+
self << sign(string, secret)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a signed string
|
18
|
+
def sign(string, secret_access_key)
|
19
|
+
hmac = HMAC::SHA256.new(secret_access_key)
|
20
|
+
hmac.update(string)
|
21
|
+
# chomp is important! the base64 encoded version will have a newline at the end
|
22
|
+
Base64.encode64(hmac.digest).chomp
|
23
|
+
end
|
24
|
+
|
25
|
+
memoize :sign
|
26
|
+
|
27
|
+
def string_to_sign(verb, querystring)
|
28
|
+
verb = verb.to_s.upcase
|
29
|
+
string = "#{verb}\n#{Amazon::MWS::DEFAULT_HOST}\n/\n#{querystring}"
|
30
|
+
end
|
31
|
+
|
32
|
+
memoize :string_to_sign
|
33
|
+
|
34
|
+
def canonical_querystring(params)
|
35
|
+
# Make sure we have string keys, otherwise the sort does not work
|
36
|
+
params = Hash.keys_to_s(params)
|
37
|
+
params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
|
38
|
+
end
|
39
|
+
|
40
|
+
memoize :canonical_querystring
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Amazon
|
2
|
+
module MWS
|
3
|
+
DEFAULT_HOST = "mws.amazonaws.com"
|
4
|
+
|
5
|
+
class Base
|
6
|
+
attr_accessor :connection
|
7
|
+
|
8
|
+
def self.debug; @@debug ||= false end
|
9
|
+
def self.debug=(bool); @@debug = bool end
|
10
|
+
|
11
|
+
def initialize(options ={})
|
12
|
+
@connection = Amazon::MWS::Connection.connect(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def connection
|
16
|
+
raise Amazon::MWS::NoConnectionEstablished.new if !connected?
|
17
|
+
@connection
|
18
|
+
end
|
19
|
+
|
20
|
+
def connected?
|
21
|
+
!@connection.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def disconnect
|
25
|
+
@connection.http.finish if @connection.persistent?
|
26
|
+
@connection = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Wraps the current connection's request method and picks the appropriate response class to wrap the response in.
|
30
|
+
# If the response is an error, it will raise that error as an exception. All such exceptions can be caught by rescuing
|
31
|
+
# their superclass, the ResponseError exception class.
|
32
|
+
#
|
33
|
+
# It is unlikely that you would call this method directly. Subclasses of Base have convenience methods for each http request verb
|
34
|
+
# that wrap calls to request.
|
35
|
+
def request(verb, path, query_params = {}, body = nil, attempts = 0, &block)
|
36
|
+
# Find the connection method in connection/management.rb which is evaled into Amazon::MWS::Base
|
37
|
+
response = @connection.request(verb, path, query_params, body, attempts, &block)
|
38
|
+
|
39
|
+
# Each calling class is responsible for formatting the result
|
40
|
+
return response
|
41
|
+
rescue InternalError, RequestTimeout
|
42
|
+
if attempts == 3
|
43
|
+
raise
|
44
|
+
else
|
45
|
+
attempts += 1
|
46
|
+
retry
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Make some convenience methods
|
51
|
+
[:get, :post, :put, :delete, :head].each do |verb|
|
52
|
+
class_eval(<<-EVAL, __FILE__, __LINE__)
|
53
|
+
def #{verb}(path, query_params = {}, body = nil, &block)
|
54
|
+
request(:#{verb}, path, query_params, body, &block)
|
55
|
+
end
|
56
|
+
EVAL
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Amazon
|
2
|
+
module MWS
|
3
|
+
|
4
|
+
class Connection
|
5
|
+
# Static/Class methods
|
6
|
+
class << self
|
7
|
+
def connect(options = {})
|
8
|
+
new(options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(params = {})
|
13
|
+
# These values are essential to establishing a connection
|
14
|
+
@server = params['server'] || Amazon::MWS::DEFAULT_HOST
|
15
|
+
@persistent = params['persistent'] || false
|
16
|
+
# These values are essential to signing requests
|
17
|
+
@access_key = params['access_key']
|
18
|
+
@secret_access_key = params['secret_access_key']
|
19
|
+
@merchant_id = params['merchant_id']
|
20
|
+
@marketplace_id = params['marketplace_id']
|
21
|
+
|
22
|
+
raise MissingConnectionOptions if [@access_key, @secret_access_key, @merchant_id, @marketplace_id].any? {|option| option.nil?}
|
23
|
+
|
24
|
+
@http = connect
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create the Net::HTTP object to use for this connection
|
28
|
+
def connect
|
29
|
+
http = Net::HTTP.new(@server, 443)
|
30
|
+
http.use_ssl = true
|
31
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
32
|
+
return http
|
33
|
+
end
|
34
|
+
|
35
|
+
# Make the request, based on the apropriate request object
|
36
|
+
# Called from Amazon::MWS::Base
|
37
|
+
def request(verb, path, query_params, body = nil, attempts = 0, &block)
|
38
|
+
# presumably this is for files
|
39
|
+
body.rewind if body.respond_to?(:rewind) unless attempts.zero?
|
40
|
+
# Prepare the Proc to be called by Net::HTTP
|
41
|
+
proc = requester(verb, path, query_params, body)
|
42
|
+
|
43
|
+
if @persistent
|
44
|
+
@http.start unless @http.started?
|
45
|
+
proc.call
|
46
|
+
else
|
47
|
+
@http.start(&proc)
|
48
|
+
end
|
49
|
+
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
|
50
|
+
@http = connect
|
51
|
+
attempts == 3 ? raise : (attempts += 1; retry)
|
52
|
+
end
|
53
|
+
|
54
|
+
# A Proc used by the request method
|
55
|
+
def requester(verb, path, query_params, body)
|
56
|
+
Proc.new do |http|
|
57
|
+
path = prepare_path(verb, path, query_params)
|
58
|
+
puts "#{path}\n\n" if AWS::MWS::Base.debug
|
59
|
+
request = build_request(verb, path, body)
|
60
|
+
|
61
|
+
@http.request(request)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Create the signed authentication query string.
|
66
|
+
# Add this query string to the path WITHOUT prepending the server address.
|
67
|
+
def prepare_path(verb, path, query_params)
|
68
|
+
query_string = authenticate_query_string(verb, query_params)
|
69
|
+
return "#{path}?#{query_string}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Generates the authentication query string used by Amazon.
|
73
|
+
# Takes the http method and the query string of the request and returns the authenticated query string
|
74
|
+
def authenticate_query_string(verb, query_params = {})
|
75
|
+
Authentication::QueryString.new(
|
76
|
+
:verb => verb,
|
77
|
+
:query_params => query_params,
|
78
|
+
:access_key => @access_key,
|
79
|
+
:secret_access_key => @secret_access_key,
|
80
|
+
:merchant_id => @merchant_id,
|
81
|
+
:marketplace_id => @marketplace_id
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Builds up a Net::HTTP request object
|
86
|
+
def build_request(verb, path, body = nil)
|
87
|
+
builder = RequestBuilder.new(verb, path, body)
|
88
|
+
builder.add_user_agent
|
89
|
+
builder.add_content_type
|
90
|
+
builder.add_content_md5(body) unless body.nil?
|
91
|
+
|
92
|
+
return builder.request
|
93
|
+
end
|
94
|
+
end
|
95
|
+
# Connection
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|