aws-sdk 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/lib/aws.rb +2 -0
  2. data/lib/aws/api_config/DynamoDB-2011-12-05.yml +721 -0
  3. data/lib/aws/core.rb +10 -1
  4. data/lib/aws/core/client.rb +17 -12
  5. data/lib/aws/core/configuration.rb +13 -3
  6. data/lib/aws/core/configured_json_client_methods.rb +71 -0
  7. data/lib/aws/core/lazy_error_classes.rb +7 -2
  8. data/lib/aws/core/option_grammar.rb +67 -13
  9. data/lib/aws/core/resource.rb +9 -1
  10. data/lib/aws/core/session_signer.rb +95 -0
  11. data/lib/aws/dynamo_db.rb +169 -0
  12. data/lib/aws/dynamo_db/attribute_collection.rb +460 -0
  13. data/lib/aws/dynamo_db/batch_get.rb +206 -0
  14. data/lib/aws/dynamo_db/client.rb +119 -0
  15. data/lib/aws/dynamo_db/config.rb +20 -0
  16. data/lib/aws/dynamo_db/errors.rb +57 -0
  17. data/lib/aws/dynamo_db/expectations.rb +40 -0
  18. data/lib/aws/dynamo_db/item.rb +130 -0
  19. data/lib/aws/dynamo_db/item_collection.rb +837 -0
  20. data/lib/aws/{record/optimistic_locking.rb → dynamo_db/item_data.rb} +9 -12
  21. data/lib/aws/{record/attributes/boolean.rb → dynamo_db/keys.rb} +15 -23
  22. data/lib/aws/dynamo_db/primary_key_element.rb +47 -0
  23. data/lib/aws/dynamo_db/request.rb +78 -0
  24. data/lib/aws/{record/attributes/float.rb → dynamo_db/resource.rb} +10 -25
  25. data/lib/aws/dynamo_db/table.rb +418 -0
  26. data/lib/aws/dynamo_db/table_collection.rb +165 -0
  27. data/lib/aws/dynamo_db/types.rb +86 -0
  28. data/lib/aws/ec2/resource_tag_collection.rb +3 -1
  29. data/lib/aws/record.rb +36 -8
  30. data/lib/aws/record/abstract_base.rb +642 -0
  31. data/lib/aws/record/attributes.rb +384 -0
  32. data/lib/aws/record/dirty_tracking.rb +0 -1
  33. data/lib/aws/record/errors.rb +0 -8
  34. data/lib/aws/record/hash_model.rb +163 -0
  35. data/lib/aws/record/hash_model/attributes.rb +182 -0
  36. data/lib/aws/record/hash_model/finder_methods.rb +178 -0
  37. data/lib/aws/record/hash_model/scope.rb +108 -0
  38. data/lib/aws/record/model.rb +429 -0
  39. data/lib/aws/record/model/attributes.rb +377 -0
  40. data/lib/aws/record/model/finder_methods.rb +232 -0
  41. data/lib/aws/record/model/scope.rb +213 -0
  42. data/lib/aws/record/scope.rb +43 -169
  43. data/lib/aws/record/validations.rb +11 -11
  44. data/lib/aws/s3/client.rb +9 -6
  45. data/lib/aws/s3/object_collection.rb +1 -1
  46. data/lib/aws/simple_db/expect_condition_option.rb +1 -1
  47. data/lib/aws/simple_db/item_collection.rb +5 -3
  48. data/lib/aws/sts/client.rb +9 -0
  49. metadata +73 -30
  50. data/lib/aws/record/attribute.rb +0 -94
  51. data/lib/aws/record/attribute_macros.rb +0 -312
  52. data/lib/aws/record/attributes/date.rb +0 -89
  53. data/lib/aws/record/attributes/datetime.rb +0 -86
  54. data/lib/aws/record/attributes/integer.rb +0 -68
  55. data/lib/aws/record/attributes/sortable_float.rb +0 -60
  56. data/lib/aws/record/attributes/sortable_integer.rb +0 -95
  57. data/lib/aws/record/attributes/string.rb +0 -69
  58. data/lib/aws/record/base.rb +0 -828
  59. data/lib/aws/record/finder_methods.rb +0 -230
  60. data/lib/aws/record/scopes.rb +0 -55
@@ -20,6 +20,7 @@ require 'aws/core/autoloader'
20
20
  #
21
21
  # The currently supported services are:
22
22
  #
23
+ # * {DynamoDB}
23
24
  # * {EC2}
24
25
  # * {ELB}
25
26
  # * {IAM}
@@ -57,7 +58,7 @@ require 'aws/core/autoloader'
57
58
  module AWS
58
59
 
59
60
  # Current version of the AWS SDK for Ruby
60
- VERSION = "1.2.6"
61
+ VERSION = "1.3.0"
61
62
 
62
63
  register_autoloads(self) do
63
64
  autoload :Errors, 'errors'
@@ -78,6 +79,7 @@ module AWS
78
79
  autoload :Configuration, 'configuration'
79
80
  autoload :ConfiguredClientMethods, 'configured_client_methods'
80
81
  autoload :ConfiguredGrammars, 'configured_grammars'
82
+ autoload :ConfiguredJsonClientMethods, 'configured_json_client_methods'
81
83
  autoload :ConfiguredOptionGrammars, 'configured_option_grammars'
82
84
  autoload :ConfiguredXmlGrammars, 'configured_xml_grammars'
83
85
  autoload :DefaultSigner, 'default_signer'
@@ -96,6 +98,7 @@ module AWS
96
98
  autoload :Response, 'response'
97
99
  autoload :ResponseCache, 'response_cache'
98
100
  autoload :ServiceInterface, 'service_interface'
101
+ autoload :SessionSigner, 'session_signer'
99
102
  autoload :UriEscape, 'uri_escape'
100
103
  autoload :XmlGrammar, 'xml_grammar'
101
104
  end
@@ -153,6 +156,12 @@ module AWS
153
156
  # @param [Hash] options
154
157
  # @option options [String] :access_key_id (nil) AWS access key id
155
158
  # credential.
159
+ # @option options [String] :dynamo_db_endpoint ('dynamodb.amazonaws.com') The
160
+ # service endpoint for Amazon DynamoDB.
161
+ # @option options [String] :dynamo_db_retry_throughput_errors (false) When
162
+ # true, AWS::DynamoDB::Errors::ProvisionedThroughputExceededException
163
+ # errors will be retried. You may need to increase the maximum number
164
+ # of retries if you have a low provisioned throughput.
156
165
  # @option options [String] :ec2_endpoint ('ec2.amazonaws.com') The
157
166
  # service endpoint for Amazon EC2.
158
167
  # @option options [Object] :http_handler (AWS::HTTPartyHandler) The
@@ -181,7 +181,7 @@ module AWS
181
181
  populate_error(response)
182
182
  retry_delays ||= sleep_durations(response)
183
183
  if should_retry?(response) and !retry_delays.empty?
184
- response.rebuild_request
184
+ rebuild_http_request(response)
185
185
  @http_handler.sleep_with_callback(retry_delays.shift) do
186
186
  async_request_with_retries(response, response.http_request, retry_delays)
187
187
  end
@@ -222,15 +222,19 @@ module AWS
222
222
  while should_retry?(response)
223
223
  break if sleeps.empty?
224
224
  Kernel.sleep(sleeps.shift)
225
-
226
225
  # rebuild the request to get a fresh signature
227
- response.rebuild_request
226
+ rebuild_http_request(response)
228
227
  response = yield
229
228
  end
230
229
 
231
230
  response
232
231
 
233
232
  end
233
+
234
+ private
235
+ def rebuild_http_request response
236
+ response.rebuild_request
237
+ end
234
238
 
235
239
  private
236
240
  def sleep_durations response
@@ -266,10 +270,8 @@ module AWS
266
270
  response.error = nil
267
271
  status = response.http_response.status
268
272
  code = nil
269
- code = xml_error_grammar.parse(response.http_response.body).code if
270
- xml_error_response?(response)
271
-
272
-
273
+ code = extract_error_code(response)
274
+
273
275
  case
274
276
  when response.timeout?
275
277
  response.error = Timeout::Error.new
@@ -290,12 +292,15 @@ module AWS
290
292
  end
291
293
 
292
294
  protected
293
- def xml_error_response? response
294
- response.http_response.status >= 300 and
295
- response.http_response.body and
296
- xml_error_grammar.parse(response.http_response.body).respond_to?(:code)
295
+ def extract_error_code response
296
+ if response.http_response.status >= 300 and
297
+ body = response.http_response.body and
298
+ parse = xml_error_grammar.parse(body) and
299
+ parse.respond_to?(:code)
300
+ parse.code
301
+ end
297
302
  end
298
-
303
+
299
304
  protected
300
305
  def xml_error_grammar
301
306
  if service_module::const_defined?(:Errors) and
@@ -273,9 +273,19 @@ module AWS
273
273
 
274
274
  accepted_options << name
275
275
 
276
- define_method(name) do
277
- value = supplied.has_key?(name) ? supplied[name] : default_value
276
+ define_method(name) do |&default_override|
277
+
278
+ value =
279
+ if supplied.has_key?(name)
280
+ supplied[name]
281
+ elsif default_override
282
+ default_override.call
283
+ else
284
+ default_value
285
+ end
286
+
278
287
  transform ? transform.call(value) : value
288
+
279
289
  end
280
290
 
281
291
  alias_method("#{name}?", name) if options[:boolean]
@@ -339,7 +349,7 @@ module AWS
339
349
 
340
350
  add_option :access_key_id,
341
351
  ENV['AWS_ACCESS_KEY_ID'] || ENV['AMAZON_ACCESS_KEY_ID']
342
-
352
+
343
353
  add_option :http_handler, Core::Http::NetHttpHandler.new
344
354
 
345
355
  add_option :logger
@@ -0,0 +1,71 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'json'
15
+
16
+ module AWS
17
+ module Core
18
+
19
+ # @private
20
+ module ConfiguredJsonClientMethods
21
+
22
+ # @private
23
+ module ClassMethods
24
+
25
+ include ApiConfig
26
+
27
+ def configure_client
28
+
29
+ super
30
+
31
+ unless self::Options.include?(ConfiguredOptionGrammars)
32
+ self::Options.module_eval do
33
+ include(ConfiguredOptionGrammars)
34
+ define_configured_grammars
35
+ end
36
+ end
37
+
38
+ api_config[:operations].each do |name, customizations|
39
+ option_grammar = self::Options.operation_grammar(name)
40
+ target_prefix = self::TARGET_PREFIX
41
+ add_client_request_method(Inflection.ruby_name(name).to_sym) do
42
+ configure_request do |request, options|
43
+ request.headers["x-amz-target"] = target_prefix + name
44
+ request.body = option_grammar.to_json(options)
45
+ end
46
+
47
+ process_response do |response|
48
+ data = JSON.load(response.http_response.body)
49
+ MetaUtils.extend_method(response, :data) { data }
50
+ end
51
+
52
+ simulate_response do |response|
53
+ data = {}
54
+ MetaUtils.extend_method(response, :data) { data }
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ def self.included(mod)
64
+ mod.extend(ClassMethods)
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+
@@ -22,14 +22,16 @@ module AWS
22
22
 
23
23
  def const_missing(name)
24
24
  base_error_grammar = self::BASE_ERROR_GRAMMAR
25
+ mod = self::ERROR_MODULE
25
26
  const_missing_mutex.synchronize do
26
27
  return if const_defined?(name)
27
28
  const_set(name,
28
29
  Class.new(self::Base) do
29
- include Errors::ModeledError
30
-
30
+ include mod::ModeledError
31
+
31
32
  # so that MyService::Errors::Foo::Bar will work
32
33
  const_set(:BASE_ERROR_GRAMMAR, base_error_grammar)
34
+ const_set(:ERROR_MODULE, mod)
33
35
  include LazyErrorClasses
34
36
  end)
35
37
  end
@@ -51,6 +53,9 @@ module AWS
51
53
  unless mod.const_defined?(:BASE_ERROR_GRAMMAR)
52
54
  mod.const_set(:BASE_ERROR_GRAMMAR, XmlGrammar)
53
55
  end
56
+ unless mod.const_defined?(:ERROR_MODULE)
57
+ mod.const_set(:ERROR_MODULE, mod)
58
+ end
54
59
  mutex = Mutex.new
55
60
  MetaUtils.extend_method(mod, :const_missing_mutex) { mutex }
56
61
  mod.send(:include, Errors)
@@ -12,6 +12,7 @@
12
12
  # language governing permissions and limitations under the License.
13
13
 
14
14
  require 'base64'
15
+ require 'bigdecimal'
15
16
 
16
17
  module AWS
17
18
  module Core
@@ -219,7 +220,13 @@ module AWS
219
220
  return [Http::Request::Param.new(prefixed_name(prefix), "")] if params.empty?
220
221
  params
221
222
  end
222
-
223
+
224
+ def hash_format(value)
225
+ value.map do |v|
226
+ member_option.hash_format(v)
227
+ end
228
+ end
229
+
223
230
  def join
224
231
  '.'
225
232
  end
@@ -284,6 +291,7 @@ module AWS
284
291
  MetaUtils.extend_method(option, :member_options) { options.values }
285
292
  by_ruby_name = options.values.inject({}) do |memo, member_option|
286
293
  memo[member_option.ruby_name] = member_option
294
+ memo[member_option.name] = member_option
287
295
  memo
288
296
  end
289
297
  MetaUtils.extend_method(option, :member_option) { |n| by_ruby_name[n] }
@@ -306,7 +314,8 @@ module AWS
306
314
  raise ArgumentError.new("missing required key #{option.ruby_name} for #{context}") if
307
315
  option.required? and
308
316
  !value.has_key?(option.ruby_name) and
309
- !value.has_key?(option.ruby_name.to_sym)
317
+ !value.has_key?(option.ruby_name.to_sym) and
318
+ !value.has_key?(option.name)
310
319
  end
311
320
  end
312
321
 
@@ -316,7 +325,15 @@ module AWS
316
325
  member_option(name).request_params(value, prefixed_name(prefix))
317
326
  end.flatten
318
327
  end
319
-
328
+
329
+ def hash_format(hash)
330
+ hash.inject({}) do |hash, (name, value)|
331
+ option = member_option(name.to_s)
332
+ hash[option.name] = option.hash_format(value)
333
+ hash
334
+ end
335
+ end
336
+
320
337
  end
321
338
 
322
339
  module Map
@@ -388,13 +405,20 @@ module AWS
388
405
  @_value_option ||= MapOption.new("value")
389
406
  end
390
407
 
391
- class MapOption < DefaultOption
392
- def param_name
393
- @param_name || name
394
- end
395
- def param_name= name
396
- @param_name = name
397
- end
408
+ end
409
+
410
+ module Bigdecimal
411
+
412
+ extend NoArgs
413
+
414
+ def validate(value, context = nil)
415
+ raise format_error("decimal value", context) unless
416
+ value.kind_of?(Numeric) or
417
+ value.respond_to?(:to_int)
418
+ end
419
+
420
+ def hash_format(value)
421
+ BigDecimal(value.to_s)
398
422
  end
399
423
 
400
424
  end
@@ -421,7 +445,11 @@ module AWS
421
445
  def request_params(value, prefix = nil)
422
446
  [Http::Request::Param.new(prefixed_name(prefix), encode_value(value))]
423
447
  end
424
-
448
+
449
+ def hash_format(value)
450
+ value
451
+ end
452
+
425
453
  def prefixed_name(prefix)
426
454
  return "#{prefix}.#{name}" if prefix
427
455
  name
@@ -527,7 +555,8 @@ module AWS
527
555
  options.has_key?(option.ruby_name) || options.has_key?(option.ruby_name.to_sym)
528
556
  end
529
557
  end
530
-
558
+
559
+ # Returns the options in AWS/Query format
531
560
  def request_params(options)
532
561
  validate(options)
533
562
  options.map do |(name, value)|
@@ -535,7 +564,23 @@ module AWS
535
564
  option(name).request_params(value)
536
565
  end.flatten
537
566
  end
538
-
567
+
568
+ # Returns the options as a hash (which is used to generate JSON
569
+ # in to_json).
570
+ def to_h(options)
571
+ validate(options)
572
+ options.inject({}) do |hash, (name, value)|
573
+ option = self.option(name.to_s)
574
+ hash[option.name] = option.hash_format(value)
575
+ hash
576
+ end
577
+ end
578
+
579
+ # Returns the options in JSON format
580
+ def to_json(options)
581
+ to_h(options).to_json
582
+ end
583
+
539
584
  def included(m)
540
585
  m.extend(self::ModuleMethods)
541
586
  end
@@ -636,6 +681,15 @@ module AWS
636
681
  end
637
682
 
638
683
  end
684
+
685
+ class MapOption < DefaultOption
686
+ def param_name
687
+ @param_name || name
688
+ end
689
+ def param_name= name
690
+ @param_name = name
691
+ end
692
+ end
639
693
 
640
694
  extend ModuleMethods
641
695
 
@@ -300,6 +300,7 @@ module AWS
300
300
 
301
301
  case
302
302
  when @options[:to_sym] then value.tr('-','_').downcase.to_sym
303
+ when @options[:timestamp] then Time.at(value.to_i)
303
304
  when @output_translator then @output_translator.call(value)
304
305
  else value
305
306
  end
@@ -364,7 +365,14 @@ module AWS
364
365
  attr = @klass.attributes[attr_name]
365
366
  method = options[:get_as] || attr.get_as
366
367
 
367
- v = resp_obj.respond_to?(method) ? resp_obj.send(method) : nil
368
+ v = case
369
+ when resp_obj.respond_to?(method)
370
+ resp_obj.send(method)
371
+ when resp_obj.respond_to?(:key?) && resp_obj.key?(method)
372
+ resp_obj[method]
373
+ else
374
+ nil
375
+ end
368
376
  v = v.value if v and options[:value_wrapped]
369
377
  v = attr.translate_output_value(v)
370
378
 
@@ -0,0 +1,95 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/sts'
15
+ require 'thread'
16
+
17
+ module AWS
18
+ module Core
19
+
20
+ # @private
21
+ class SessionSigner
22
+
23
+ @create_mutex = Mutex.new
24
+
25
+ def self.for config
26
+ @create_mutex.synchronize do
27
+ @session_signers ||= {}
28
+ @session_signers[config.signer.access_key_id] ||= self.new(config)
29
+ end
30
+ end
31
+
32
+ def initialize config
33
+ @config = config
34
+ @session_mutex = Mutex.new
35
+ end
36
+
37
+ def sign *args
38
+ short_term_signer.sign(*args)
39
+ end
40
+
41
+ def access_key_id
42
+ session.credentials[:access_key_id]
43
+ end
44
+
45
+ def secret_access_key
46
+ session.credentials[:secret_access_key]
47
+ end
48
+
49
+ def session_token
50
+ session.credentials[:session_token]
51
+ end
52
+
53
+ def refresh_session
54
+ sts = AWS::STS.new(:config => @config, :use_ssl => true)
55
+ @session_mutex.synchronize do
56
+ @session = sts.new_session
57
+ end
58
+ end
59
+
60
+ protected
61
+ def get_session
62
+ local_session = nil
63
+ @session_mutex.synchronize do
64
+ local_session = @session
65
+ end
66
+ local_session
67
+ end
68
+
69
+ protected
70
+ def session
71
+
72
+ session = get_session
73
+
74
+ if session.nil?
75
+ refresh_session
76
+ session = get_session
77
+ end
78
+
79
+ if session.expires_at < (Time.now + 15 * 60)
80
+ refresh_session
81
+ session = get_session
82
+ end
83
+
84
+ session
85
+
86
+ end
87
+
88
+ protected
89
+ def short_term_signer
90
+ DefaultSigner.new(access_key_id, secret_access_key, session_token)
91
+ end
92
+
93
+ end
94
+ end
95
+ end