aws-sdk-resources 2.0.0.pre

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.
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