aws-sdk-resources 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-resources.rb +36 -0
  3. data/lib/aws-sdk-resources/batch.rb +100 -0
  4. data/lib/aws-sdk-resources/builder.rb +86 -0
  5. data/lib/aws-sdk-resources/builder_sources.rb +136 -0
  6. data/lib/aws-sdk-resources/collection.rb +137 -0
  7. data/lib/aws-sdk-resources/definition.rb +363 -0
  8. data/lib/aws-sdk-resources/documenter.rb +18 -0
  9. data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +269 -0
  10. data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +47 -0
  11. data/lib/aws-sdk-resources/documenter/enumerate_data_operation_documenter.rb +50 -0
  12. data/lib/aws-sdk-resources/documenter/enumerate_resource_operation_documenter.rb +69 -0
  13. data/lib/aws-sdk-resources/documenter/operation_documenter.rb +43 -0
  14. data/lib/aws-sdk-resources/documenter/reference_operation_documenter.rb +102 -0
  15. data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +65 -0
  16. data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +81 -0
  17. data/lib/aws-sdk-resources/errors.rb +15 -0
  18. data/lib/aws-sdk-resources/operation_methods.rb +53 -0
  19. data/lib/aws-sdk-resources/operations.rb +294 -0
  20. data/lib/aws-sdk-resources/options.rb +23 -0
  21. data/lib/aws-sdk-resources/request.rb +39 -0
  22. data/lib/aws-sdk-resources/request_params.rb +225 -0
  23. data/lib/aws-sdk-resources/resource.rb +137 -0
  24. data/lib/aws-sdk-resources/source.rb +39 -0
  25. data/lib/aws-sdk-resources/validator.rb +152 -0
  26. data/lib/aws-sdk-resources/validator/context.rb +60 -0
  27. data/lib/aws-sdk-resources/validator/identifier_validator.rb +107 -0
  28. data/lib/aws-sdk-resources/validator/operation_validator.rb +352 -0
  29. data/lib/aws-sdk-resources/validator/rule.rb +45 -0
  30. data/lib/aws-sdk-resources/validator/shape_validator.rb +47 -0
  31. metadata +87 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2258aa532dd93701acb1dd469ef9d45c2ffac526
4
+ data.tar.gz: 6d2aacfaae954de3f151c22a5da7455922519f5d
5
+ SHA512:
6
+ metadata.gz: a319ba138c25889d126981b916917f7a11eb02d2445074f74b81d722d2ecaff841fadfa6722153a4aa8c28855da2f50d46de4e2b9dae7d2ddd544da4ccaf78a6
7
+ data.tar.gz: 9508bad7873f5f233c91eff4dac292c99aead6dc3c4748f1f0312e39139464125256457d61090cad9aa0d5d139044a110f4679a76f9f8992315dd8eaa2de16ef
@@ -0,0 +1,36 @@
1
+ require 'aws-sdk-core'
2
+
3
+ module Aws
4
+ module Resources
5
+
6
+ autoload :Batch, 'aws-sdk-resources/batch'
7
+ autoload :Builder, 'aws-sdk-resources/builder'
8
+ autoload :BuilderSources, 'aws-sdk-resources/builder_sources'
9
+ autoload :Collection, 'aws-sdk-resources/collection'
10
+ autoload :Definition, 'aws-sdk-resources/definition'
11
+ autoload :Documenter, 'aws-sdk-resources/documenter'
12
+ autoload :Errors, 'aws-sdk-resources/errors'
13
+ autoload :Operations, 'aws-sdk-resources/operations'
14
+ autoload :OperationMethods, 'aws-sdk-resources/operation_methods'
15
+ autoload :Options, 'aws-sdk-resources/options'
16
+ autoload :Request, 'aws-sdk-resources/request'
17
+ autoload :RequestParams, 'aws-sdk-resources/request_params'
18
+ autoload :Resource, 'aws-sdk-resources/resource'
19
+ autoload :Source, 'aws-sdk-resources/source'
20
+ autoload :Validator, 'aws-sdk-resources/validator'
21
+
22
+ end
23
+
24
+ service_added do |_, svc_module, options|
25
+ definition = options[:resources]
26
+ definition = case definition
27
+ when nil then Resources::Definition.new({})
28
+ when Resources::Definition then definition
29
+ when Hash then Resources::Definition.new(definition)
30
+ when String then Resources::Definition.new(Aws.load_json(definition), source_path: definition)
31
+ else raise ArgumentError, "invalid resource definition #{definition}"
32
+ end
33
+ definition.apply(svc_module)
34
+ end
35
+
36
+ end
@@ -0,0 +1,100 @@
1
+ module Aws
2
+ module Resources
3
+
4
+ # A batch provides array like access to a list of resources. Batches
5
+ # also provide the ability to invoke certain operations against
6
+ # the entire batch.
7
+ #
8
+ # ## Getting a Batch
9
+ #
10
+ # You should normally not need to construct a batch. Anywhere a list
11
+ # of resources is returned, they are returned as a batch:
12
+ #
13
+ # # security_groups is a batch
14
+ # security_groups = ec2.instance('i-12345678').security_groups
15
+ #
16
+ # When the possible number of resources is unknown or large, the
17
+ # resources will be returned in a collection. Collections can enumerate
18
+ # individual resources or batches. They manage paging over the
19
+ # AWS request/responses to produce batches.
20
+ #
21
+ # # objects is a collection
22
+ # objects = s3.bucket('aws-sdk').objects
23
+ #
24
+ # You can invoke batch operations against collections and they will
25
+ # invoke them on each batch.
26
+ #
27
+ # # delets all all objects in this bucket in batches of 1k
28
+ # objects = s3.bucket('aws-sdk').objects
29
+ # objects.delete
30
+ #
31
+ # ## Batch Operations
32
+ #
33
+ # Batches provide operations that operate on the entire batch. These
34
+ # operations are only defined for resources where the AWS API accepts
35
+ # multiple inputs. This means a batch operation for n elements will
36
+ # only make one request.
37
+ #
38
+ # Resource classes document each of their own batch operations.
39
+ # See {S3::Object} for an example.
40
+ #
41
+ class Batch
42
+
43
+ include Enumerable
44
+ extend OperationMethods
45
+
46
+ # @param [Array<Resource>] resources
47
+ # @option options [Seahorse::Client::Response] :response
48
+ def initialize(resources, options = {})
49
+ @resources = resources
50
+ @options = options
51
+ end
52
+
53
+ # @return [Seahorse::Client::Response, nil]
54
+ def response
55
+ @options[:response]
56
+ end
57
+
58
+ # @return [Integer]
59
+ def size
60
+ @resources.size
61
+ end
62
+
63
+ alias count size
64
+
65
+ # @param [Integer] index
66
+ # @return [Resource]
67
+ def [](index)
68
+ @resources[index]
69
+ end
70
+
71
+ # Yields each resource of the batch, one at a time.
72
+ def each(&block)
73
+ enum = @resources.to_enum
74
+ enum.each(&block) if block_given?
75
+ enum
76
+ end
77
+
78
+ # @param [Integer] count
79
+ # @return [Resource, Batch]
80
+ def first(count = nil)
81
+ if count
82
+ self.class.new(@resources.first(count), @options)
83
+ else
84
+ @resources.first
85
+ end
86
+ end
87
+
88
+ # @return [Boolean]
89
+ def empty?
90
+ @resources.empty?
91
+ end
92
+
93
+ # @api private
94
+ def inspect
95
+ "#<#{self.class.name} resources=#{@resources}>"
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,86 @@
1
+ require 'jamespath'
2
+
3
+ module Aws
4
+ module Resources
5
+
6
+ # A {Builder} construct resource objects. It extracts resource identifiers
7
+ # for the objects it builds from another resource object and/or an
8
+ # AWS response.
9
+ class Builder
10
+
11
+ include Options
12
+
13
+ # @option options [required, Class<Resource>] resource_class
14
+ # @option options [Array<BuilderSources::Source>] :sources ([])
15
+ def initialize(options = {})
16
+ @resource_class = options[:resource_class]
17
+ @sources = options[:sources] || []
18
+ end
19
+
20
+ # @return [Class<Resource>]
21
+ attr_reader :resource_class
22
+
23
+ # @return [Array<BuilderSources::Source>] A list of resource
24
+ # identifier sources.
25
+ attr_reader :sources
26
+
27
+ # @return [Boolean] Returns `true` if this builder returns an array
28
+ # of resource objects from {#build}.
29
+ def plural?
30
+ @sources.any?(&:plural?)
31
+ end
32
+
33
+ # @option [Resource] :resource
34
+ # @option [Seahorse::Client::Response] :response
35
+ # @return [Resource, Array<Resource>] Returns a resource object or an
36
+ # array of resource objects if {#plural?}.
37
+ def build(options = {})
38
+ identifier_map = @sources.each.with_object({}) do |source, hash|
39
+ hash[source.target] = source.extract(options)
40
+ end
41
+ if plural?
42
+ build_batch(identifier_map, options)
43
+ else
44
+ build_one(identifier_map, options)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def build_batch(identifier_map, options, &block)
51
+ resources = (0...resource_count(identifier_map)).collect do |n|
52
+ identifiers = @sources.each.with_object({}) do |source, identifiers|
53
+ identifiers[source.target] = source.plural? ?
54
+ identifier_map[source.target][n] :
55
+ identifier_map[source.target]
56
+ end
57
+ resource = build_one(identifiers, options)
58
+ yield(resource) if block_given?
59
+ resource
60
+ end
61
+ resource_class::Batch.new(resources, options)
62
+ end
63
+
64
+ def build_one(identifiers, options)
65
+ if identifiers.values.any?(&:nil?)
66
+ nil
67
+ else
68
+ @resource_class.new(identifiers.merge(
69
+ client: client(options)
70
+ ))
71
+ end
72
+ end
73
+
74
+ def resource_count(identifier_map)
75
+ identifier_map.values.inject(0) do |max, values|
76
+ [max, values.is_a?(Array) ? values.size : 0].max
77
+ end
78
+ end
79
+
80
+ def client(options)
81
+ Array(options[:resource]).first.client
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,136 @@
1
+ require 'jamespath'
2
+
3
+ module Aws
4
+ module Resources
5
+ module BuilderSources
6
+
7
+ # Used by a {Builder} to extract resource identifiers from an AWS
8
+ # response or from another resource object.
9
+ #
10
+ # This is the base class of each of the builder sources. Each
11
+ # source is responsible for extracting a single identifier.
12
+ #
13
+ # @see {Argument}
14
+ # @see {Identifier}
15
+ # @see {DataMember}
16
+ # @see {RequestParameter}
17
+ # @see {ResponsePath}
18
+ #
19
+ class Base
20
+
21
+ include Options
22
+
23
+ # @param [String] source
24
+ # @param [Symbol] target
25
+ def initialize(source, target)
26
+ @source = source
27
+ @target = target.to_sym
28
+ end
29
+
30
+ # @return [String]
31
+ attr_reader :source
32
+
33
+ # @return [Symbol]
34
+ attr_reader :target
35
+
36
+ # @return [Boolean]
37
+ def plural?
38
+ source.include?('[')
39
+ end
40
+
41
+ # @param [Hash] options
42
+ # @return [String, Array<String>]
43
+ def extract(options)
44
+ raise NotImplementedError, 'must be defined in subclasses'
45
+ end
46
+
47
+ end
48
+
49
+ class Argument < Base
50
+
51
+ def initialize(target)
52
+ super(target.to_s, target)
53
+ end
54
+
55
+ # @option [required, String] :argument
56
+ def extract(options)
57
+ (options[:args] || []).first
58
+ end
59
+
60
+ end
61
+
62
+ # Extracts an identifier from a parent resource identifier. Used
63
+ # when building a {Resource} from the context of another resource.
64
+ class Identifier < Base
65
+
66
+ # @option [required, Resource] :resource
67
+ def extract(options)
68
+ resource(options).identifiers[source.to_sym]
69
+ end
70
+
71
+ private
72
+
73
+ def resource(options)
74
+ option(:resource, options)
75
+ end
76
+
77
+ end
78
+
79
+ # Extracts an identifier from the data of a parent resource. Used
80
+ # when building a {Resource} from the context of another resource.
81
+ class DataMember < Base
82
+
83
+ # @option [required, Resource] :resource
84
+ def extract(options)
85
+ Jamespath.search(source, resource(options).data)
86
+ end
87
+
88
+ private
89
+
90
+ def resource(options)
91
+ option(:resource, options)
92
+ end
93
+
94
+ end
95
+
96
+ # Extracts an identifier from the request parameters used to generate
97
+ # a response. Used when building a {Resource} object from the response
98
+ # of an operation.
99
+ class RequestParameter < Base
100
+
101
+ # @option [required, Seahorse::Client::Response] :response
102
+ def extract(options)
103
+ response(options).context.params[source.to_sym]
104
+ end
105
+
106
+ private
107
+
108
+ def response(options)
109
+ option(:response, options)
110
+ end
111
+
112
+ end
113
+
114
+ # Extracts an identifier from the data of a response. Used when
115
+ # building a {Resource} object from the response of an operation.
116
+ class ResponsePath < Base
117
+
118
+ # @option [required, Seahorse::Client::Response] :response
119
+ def extract(options)
120
+ if source == '$'
121
+ response(options).data
122
+ else
123
+ Jamespath.search(source, response(options).data)
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ def response(options)
130
+ option(:response, options)
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,137 @@
1
+ module Aws
2
+ module Resources
3
+ class Collection
4
+
5
+ include Enumerable
6
+
7
+ # @param [EnumerateResourceOperation] operation
8
+ # @option (see EnumerateResourceOperation#call)
9
+ # @api private
10
+ def initialize(operation, options)
11
+ @operation = operation
12
+ @options = options
13
+ reject_limit_param(options)
14
+ end
15
+
16
+ # @return [Enumerator<Resource>]
17
+ def each(&block)
18
+ if block_given?
19
+ batches.each { |batch| batch.each(&block) }
20
+ else
21
+ self
22
+ end
23
+ end
24
+
25
+ # @return [Enumerator<Batch>]
26
+ def batches(&block)
27
+ @operation.batches(@options)
28
+ end
29
+
30
+ # Specifies the maximum number of items to enumerate.
31
+ #
32
+ # collection.limit(10).each do |resource|
33
+ # # yields at most 10 times
34
+ # end
35
+ #
36
+ # @param [Integer] limit The maximum number of items to yield
37
+ # via {#each} or {#batches}.
38
+ # @return [Collection]
39
+ def limit(limit)
40
+ self.class.new(@operation, @options.merge(limit: limit))
41
+ end
42
+
43
+ # Specifies max size of each batch. Some services may return fewer
44
+ # than `size` number of items per request.
45
+ #
46
+ # @example Enumerate the collection in batches with a max size
47
+ #
48
+ # collection.batch_size(10).batches.each do |batch|
49
+ # # batch has at most 10 items
50
+ # end
51
+ #
52
+ # @param [Integer] size
53
+ # @return [Collection]
54
+ def batch_size(size)
55
+ if limit_key
56
+ self.class.new(@operation, @options.merge(batch_size: size))
57
+ else
58
+ resource = resource_class.name
59
+ method_name = @operation.request.method_name
60
+ msg = "batch size not supported by #{resource}##{method_name}"
61
+ raise NotImplementedError, msg
62
+ end
63
+ end
64
+
65
+ # Returns the first resource from the collection.
66
+ #
67
+ # resource = collection.first
68
+ #
69
+ # If you pass a count, then the first `count` resources are returned in
70
+ # a single batch. See the resource specific batch documentation for
71
+ # a list of supported batch methods.
72
+ #
73
+ # resources = collection.first(10)
74
+ # resources.delete
75
+ #
76
+ # @return [Resource, Batch]
77
+ def first(count = 1)
78
+ if count == 1
79
+ limit(1).to_a.first
80
+ else
81
+ resource_class::Batch.new(limit(count).to_a)
82
+ end
83
+ end
84
+
85
+ # @api private
86
+ def respond_to?(method_name, *args)
87
+ if resource_class::Batch.instance_methods.include?(method_name.to_sym)
88
+ true
89
+ else
90
+ super
91
+ end
92
+ end
93
+
94
+ # @api private
95
+ def method_missing(method_name, *args, &block)
96
+ if respond_to?(method_name)
97
+ batches.each do |batch|
98
+ batch.send(method_name, *args, &block)
99
+ end
100
+ else
101
+ super
102
+ end
103
+ end
104
+
105
+ # @api private
106
+ def inspect
107
+ parts = {}
108
+ parts[:type] = resource_class.name
109
+ parts[:limit] = @options[:limit]
110
+ parts[:batch_size] = @options[:batch_size] if limit_key
111
+ parts[:params] = @options[:params] || {}
112
+ parts = parts.inject("") {|s,(k,v)| s << " #{k}=#{v.inspect}" }
113
+ ['#<', self.class.name, parts, '>'].join
114
+ end
115
+
116
+ private
117
+
118
+ # @api private
119
+ def limit_key
120
+ @operation.limit_key
121
+ end
122
+
123
+ def reject_limit_param(options)
124
+ if options[:params] && options[:params][limit_key]
125
+ msg = "invalid option :#{limit_key}, call #limit or #batch_size "
126
+ msg << "on the returned Aws::Resources::Collection instead"
127
+ raise ArgumentError, msg
128
+ end
129
+ end
130
+
131
+ def resource_class
132
+ @operation.builder.resource_class
133
+ end
134
+
135
+ end
136
+ end
137
+ end