aws-sdk-resources 2.0.21.pre → 2.0.22

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77b5cba9a98eda4c967f72c954941fb51ebdf34c
4
- data.tar.gz: 0e49a9375f4477e25bdc54c86ce2d87cc8fe30f1
3
+ metadata.gz: 406e521dc5e2fa2e3036612ca85bf81dafb64838
4
+ data.tar.gz: 220362ebb755c163929c895b3067a75c878284d4
5
5
  SHA512:
6
- metadata.gz: 96b21cdabadd5130aefc08e948edf112ddf5d2aea691fb2f5c893d97555af57e0c76a171b11bb66f3f456654516fd6fdc8f7385a63a1bb68c7bb10e3354ffa94
7
- data.tar.gz: 125195ea660225826f381c70bb68c623f0451fb59ee8099de3f782b4998f86182a350425416cd3e1480f249f1fd12bb79e7e5d7ef87d2aee217063f7aa37629a
6
+ metadata.gz: 3b0215e8a68171958a3433faceb54c06ce5a455663931b710b5a2cdc39166ac93357ef41ad9675c7cf33fac39d7e4a4bb1c4597dce9df3dd90de94371e6d0fc7
7
+ data.tar.gz: b22a0721824c84b24340aa4dce0b24125edd0fdbb38d2342b45a4e85d6cb44c7c10355f58a77cc133c7318e87eacda1d1eb55aea6f2cbbd60ee77fceb49648c4
@@ -1,8 +1,8 @@
1
1
  require 'aws-sdk-core'
2
2
 
3
3
  module Aws
4
- module Resources
5
4
 
5
+ module Resources
6
6
  autoload :Batch, 'aws-sdk-resources/batch'
7
7
  autoload :Builder, 'aws-sdk-resources/builder'
8
8
  autoload :BuilderSources, 'aws-sdk-resources/builder_sources'
@@ -10,46 +10,35 @@ module Aws
10
10
  autoload :Definition, 'aws-sdk-resources/definition'
11
11
  autoload :Documenter, 'aws-sdk-resources/documenter'
12
12
  autoload :Errors, 'aws-sdk-resources/errors'
13
- autoload :Operations, 'aws-sdk-resources/operations'
14
13
  autoload :OperationMethods, 'aws-sdk-resources/operation_methods'
14
+ autoload :Operations, 'aws-sdk-resources/operations'
15
15
  autoload :Options, 'aws-sdk-resources/options'
16
16
  autoload :Request, 'aws-sdk-resources/request'
17
17
  autoload :RequestParams, 'aws-sdk-resources/request_params'
18
18
  autoload :Resource, 'aws-sdk-resources/resource'
19
19
  autoload :Source, 'aws-sdk-resources/source'
20
- autoload :Validator, 'aws-sdk-resources/validator'
21
-
22
20
  end
23
21
 
24
- class << self
25
-
26
- private
27
-
28
- def define_resource_classes(svc_module, definition)
29
- build_definition(definition).apply(svc_module)
30
- end
31
-
32
- def build_definition(definition)
33
- case definition
22
+ service_added do |name, svc_module, options|
23
+ definition = options[:resources]
24
+ definition = case definition
34
25
  when nil then Resources::Definition.new({})
35
26
  when Resources::Definition then definition
36
27
  when Hash then Resources::Definition.new(definition)
37
- when String, Pathname then Resources::Definition.new(Aws.load_json(definition), source_path: definition.to_s)
28
+ when String
29
+ Resources::Definition.new(Aws.load_json(definition), source_path: definition)
38
30
  else raise ArgumentError, "invalid resource definition #{definition}"
39
- end
40
31
  end
32
+ definition.apply(svc_module)
41
33
 
42
- def load_resource_customizations(svc_name)
43
- require "aws-sdk-resources/services/#{svc_name.downcase}"
44
- rescue LoadError
45
- # no customizations
46
- end
47
-
48
- end
34
+ # load customizations
35
+ svc = File.join(
36
+ File.dirname(__FILE__),
37
+ 'aws-sdk-resources',
38
+ 'services',
39
+ "#{name.downcase}.rb")
49
40
 
50
- service_added do |svc_name, svc_module, options|
51
- define_resource_classes(svc_module, options[:resources])
52
- load_resource_customizations(svc_name)
41
+ require(svc) if File.exists?(svc)
53
42
  end
54
43
 
55
44
  end
@@ -2,7 +2,7 @@ module Aws
2
2
  module Resources
3
3
  class Request
4
4
 
5
- # @option opitons [requried, String] :method_name
5
+ # @option options [required, String] :method_name
6
6
  # @option options [Array<RequestParams::Param>] :params ([]) A list of
7
7
  # request params to apply to the request when called.
8
8
  def initialize(options = {})
@@ -17,7 +17,7 @@ module Aws
17
17
  # @return [Array<RequestParams::Param>]
18
18
  attr_reader :params
19
19
 
20
- # @option options [required,Resource] :resource
20
+ # @option options [required, Resource] :resource
21
21
  # @option options [Array<Mixed>] :args
22
22
  # @return [Seahorse::Client::Response]
23
23
  def call(options)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-sdk-resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.21.pre
4
+ version: 2.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-27 00:00:00.000000000 Z
11
+ date: 2015-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.21
19
+ version: 2.0.22
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.21
26
+ version: 2.0.22
27
27
  description: Provides resource-oriented abstractions for AWS.
28
28
  email:
29
29
  executables: []
@@ -76,15 +76,7 @@ files:
76
76
  - lib/aws-sdk-resources/services/s3/object.rb
77
77
  - lib/aws-sdk-resources/services/s3/object_summary.rb
78
78
  - lib/aws-sdk-resources/services/s3/public_url.rb
79
- - lib/aws-sdk-resources/services/sqs.rb
80
- - lib/aws-sdk-resources/services/sqs/queue.rb
81
79
  - lib/aws-sdk-resources/source.rb
82
- - lib/aws-sdk-resources/validator.rb
83
- - lib/aws-sdk-resources/validator/context.rb
84
- - lib/aws-sdk-resources/validator/dsl.rb
85
- - lib/aws-sdk-resources/validator/operation_validator.rb
86
- - lib/aws-sdk-resources/validator/path_resolver.rb
87
- - lib/aws-sdk-resources/validator/rule.rb
88
80
  homepage: http://github.com/aws/aws-sdk-core-ruby
89
81
  licenses:
90
82
  - Apache 2.0
@@ -100,9 +92,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
92
  version: '0'
101
93
  required_rubygems_version: !ruby/object:Gem::Requirement
102
94
  requirements:
103
- - - ">"
95
+ - - ">="
104
96
  - !ruby/object:Gem::Version
105
- version: 1.3.1
97
+ version: '0'
106
98
  requirements: []
107
99
  rubyforge_project:
108
100
  rubygems_version: 2.2.2
@@ -1,5 +0,0 @@
1
- module Aws
2
- module SQS
3
- require 'aws-sdk-resources/services/sqs/queue.rb'
4
- end
5
- end
@@ -1,102 +0,0 @@
1
- module Aws
2
- module SQS
3
- class Queue
4
- class << self
5
-
6
- private
7
-
8
- def queue_str_attr(method_name, options = {})
9
- name = options[:name] || attr_name(method_name)
10
- define_method(method_name) do
11
- attributes[name]
12
- end
13
- end
14
-
15
- def queue_int_attr(method_name, options = {})
16
- name = options[:name] || attr_name(method_name)
17
- define_method(method_name) do
18
- if value = attributes[name]
19
- value.to_i
20
- end
21
- end
22
- end
23
-
24
- def queue_time_attr(method_name, options = {})
25
- name = options[:name] || attr_name(method_name)
26
- define_method(method_name) do
27
- if value = attributes[name]
28
- Time.at(value.to_i)
29
- end
30
- end
31
- end
32
-
33
- def attr_name(method_name)
34
- method_name.to_s.split('_').map { |s| s[0].upcase + s[1..-1] }.join
35
- end
36
-
37
- end
38
-
39
- # @group Queue Attributes
40
- # @return [String] the queue's policy.
41
- queue_str_attr :policy
42
-
43
- # @group Queue Attributes
44
- # @return [Integer] the visibility timeout for the queue. For more information about visibility timeout, see [Visibility Timeout](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html) in the Amazon SQS Developer Guide.
45
- queue_int_attr :visibility_timeout
46
-
47
- # @group Queue Attributes
48
- # @return [Integer] the limit of how many bytes a message can contain before
49
- # Amazon SQS rejects it.
50
- queue_int_attr :maximum_message_size
51
-
52
- # @group Queue Attributes
53
- # @return [Integer] the number of seconds Amazon SQS retains a message.
54
- queue_int_attr :message_retention_period
55
-
56
- # @group Queue Attributes
57
- # @return [Integer] the approximate number of visible messages in a queue.
58
- # For more information, see [Resources Required to Process Messages](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/ApproximateNumber.html) in the Amazon SQS Developer Guide.
59
- queue_int_attr :approximate_number_of_messages
60
-
61
- # @group Queue Attributes
62
- # @return [Integer] returns the approximate number of messages that are not timed-out and not deleted. For more information, see [Resources Required to Process Messages](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/ApproximateNumber.html) in the Amazon SQS Developer Guide.
63
- queue_int_attr :approximate_number_of_messages_not_visible
64
-
65
- # @group Queue Attributes
66
- # @return [Time] the time when the queue was created.
67
- queue_time_attr :created_timestamp
68
-
69
- # @group Queue Attributes
70
- # @return [Time] the time when the queue was last changed.
71
- queue_time_attr :last_modified_timestamp
72
-
73
- # @group Queue Attributes
74
- # @return [String] the queue's Amazon resource name (ARN).
75
- queue_str_attr :arn, name: 'QueueArn'
76
-
77
- alias queue_arn arn
78
-
79
- # @group Queue Attributes
80
- # @return [Integer] returns the approximate number of messages that
81
- # are pending to be added to the queue.
82
- queue_int_attr :approximate_number_of_messages_delayed
83
-
84
- # @group Queue Attributes
85
- # @return [Integer] the default delay on the queue in seconds.
86
- queue_int_attr :delay_seconds
87
-
88
- # @group Queue Attributes
89
- # @return [Integer] the time for which a {Client#receive_message} call
90
- # will wait for a message to arrive.
91
- queue_int_attr :receive_message_wait_time_seconds
92
-
93
- # @group Queue Attributes
94
- # @return [String] the parameters for dead letter queue functionality of
95
- # the source queue. For more information about RedrivePolicy and dead
96
- # letter queues, see [Using Amazon SQS Dead Letter Queues](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html)
97
- # in the Amazon SQS Developer Guide.
98
- queue_str_attr :redrive_policy
99
-
100
- end
101
- end
102
- end
@@ -1,239 +0,0 @@
1
- require 'json-schema'
2
- require 'aws-sdk-resources/validator/context'
3
- require 'aws-sdk-resources/validator/dsl'
4
- require 'aws-sdk-resources/validator/path_resolver'
5
- require 'aws-sdk-resources/validator/rule'
6
- require 'aws-sdk-resources/validator/operation_validator'
7
-
8
- module Aws
9
- module Resources
10
- module Validator
11
-
12
- extend Validator::DSL
13
-
14
- # identifiers_may_not_be_prefixed_by_their_resource_name
15
- match('#/resources/(\w+)/identifiers/\d+/name') do |c, matches|
16
- resource_name = matches[1]
17
- if c.value.match(/^#{resource_name}/)
18
- c.error("#{c.path} must not be prefixed with '#{resource_name}'")
19
- end
20
- end
21
-
22
- # identifiers_must_have_unique_names
23
- match('#/resources/\w+/identifiers') do |c|
24
- identifiers = c.value.map { |v| v['name'] }
25
- identifiers.each.with_index do |identifier, n|
26
- unless identifiers.count(identifier) == 1
27
- c.error("#{c.path}/#{n}/name must be uniq within #{c.path}/*/name")
28
- end
29
- end
30
- end
31
-
32
- # identifiers_with_memberName_require_the_resource_to_have_a_shape
33
- match('#/resources/(\w+)/identifiers/(\d+)/memberName') do |c, matches|
34
- resource_name = matches[1]
35
- shape_path = "#/resources/#{resource_name}/shape"
36
- unless c.definition['resources'][resource_name]['shape']
37
- c.error("#{c.path} requires #{shape_path} to be set")
38
- end
39
- end
40
-
41
- # identifiers_with_memberName_require_the_resource_shape_to_have_that_member
42
- match('#/resources/(\w+)/identifiers/(\d+)/memberName') do |c, matches|
43
- resource_name = matches[1]
44
- shape_path = "#/resources/#{resource_name}/shape"
45
- shape_name = c.definition['resources'][resource_name]['shape']
46
- if
47
- shape_name &&
48
- c.api['shapes'][shape_name] &&
49
- c.api['shapes'][shape_name]['type'] == 'structure' &&
50
- !c.api['shapes'][shape_name]['members'].key?(c.value)
51
- then
52
- c.error("#{c.path} is not defined at api#/shapes/#{shape_name}/members/#{c.value}")
53
- end
54
- end
55
-
56
- # shape_must_be_defined_in_the_api
57
- match('#/resources/\w+/shape') do |c|
58
- unless c.api['shapes'][c.value]
59
- c.error("#{c.path} not found at api#/shapes/#{c.value}")
60
- end
61
- end
62
-
63
- # shape_must_be_a_structure
64
- # load_requires_shape_to_be_a_structure
65
- match('#/resources/\w+/shape') do |c|
66
- shape = c.api['shapes'][c.value]
67
- if shape && shape['type'] != 'structure'
68
- c.error("#{c.path} must resolve to a structure")
69
- end
70
- end
71
-
72
- # load_requires_shape_to_be_set
73
- match('#/resources/(\w+)/load') do |c, matches|
74
- resource = matches[1]
75
- unless c.definition['resources'][resource]['shape']
76
- c.error("#{c.path} requires #/resources/#{resource}/shape to be set")
77
- end
78
- end
79
-
80
-
81
- # load_operation_must_exist
82
- # TODO : add assertions for service/actions, service/hasMany, actions, etc
83
- match(*%w(
84
- #/service/actions/\w+/request/operation
85
- #/service/hasMany/\w+/request/operation
86
- #/resources/\w+/load/request/operation
87
- #/resources/\w+/actions/\w+/request/operation
88
- #/resources/\w+/batchActions/\w+/request/operation
89
- #/resources/\w+/hasMany/\w+/request/operation
90
- )) do |c|
91
- unless c.api['operations'][c.value]
92
- c.error("#{c.path} is set but is not defined at api#/operations/#{c.value}")
93
- end
94
- end
95
-
96
- # load_operation_must_accept_input_if_params_given
97
- match(*%w(
98
- #/service/actions/\w+/request
99
- #/service/hasMany/\w+/request
100
- #/resources/\w+/load/request
101
- #/resources/\w+/actions/\w+/request
102
- #/resources/\w+/batchActions/\w+/request
103
- #/resources/\w+/hasMany/\w+/request
104
- )) do |c|
105
- # ...
106
- end
107
-
108
- # load_path_must_resolve_to_shape
109
- match('#/resources/(\w+)/load/path') do |c, matches|
110
- operation_name =
111
- c.definition['resources'][matches[1]]['load']['request']['operation']
112
- if operation = c.api['operations'][operation_name]
113
- if from = operation['output']
114
- if shape_name = c.definition['resources'][matches[1]]['shape']
115
- resolved = PathResolver.new(c.api).resolve(c.value, from)
116
- unless resolved == shape_name
117
- c.error("#{c.path} must resolve to a '#{shape_name}' shape")
118
- end
119
- else
120
- # resource defines load but does not define shape
121
- end
122
- else
123
- # resource load operation does not have output shape reference
124
- end
125
- else
126
- # resource load operation not in API model
127
- end
128
- end
129
-
130
- match(*%w(
131
- #/service/actions/\w+/request
132
- #/resources/\w+/load/request
133
- #/resources/\w+/actions/\w+/request
134
- #/resources/\w+/batchActions/\w+/request
135
- #/resources/\w+/hasMany/\w+/request
136
- )) do |c|
137
- end
138
-
139
- match(*%w(
140
- #/service/hasMany/\w+/resource/type
141
- #/resources/\w+/actions/\w+/resource/type
142
- #/resources/\w+/batchActions/\w+/resource/type
143
- #/resources/\w+/hasMany/\w+/resource/type
144
- )) do |c|
145
- end
146
-
147
- match(*%w(
148
- #/service/hasMany/\w+/resource/identifiers
149
- #/resources/\w+/actions/\w+/resource/identifiers
150
- #/resources/\w+/batchActions/\w+/resource/identifiers
151
- #/resources/\w+/hasMany/\w+/resource/identifiers
152
- )) do |c|
153
- # must provide ALL of the identifiers for the target resource
154
- # each identifier must resolve from its
155
- end
156
-
157
- match(*%w(
158
- #/service/hasMany/\w+/resource/path
159
- #/resources/\w+/actions/\w+/resource/path
160
- #/resources/\w+/batchActions/\w+/resource/path
161
- #/resources/\w+/hasMany/\w+/resource/path
162
- )) do |c|
163
- type = c.parent['type']
164
- from = c.parent.parent['request']['operation']
165
- from = c.api['operations'][from]['output']
166
- expected = c.definition['resources'][type]['shape']
167
- resolved = PathResolver.new(c.api).resolve(c.value, from)
168
- unless expected == resolved
169
- c.error("#{c.path} must resolve to a \"#{expected}\" shape")
170
- end
171
- end
172
-
173
- # load_params_can_be_nested
174
- # load_params_must_match_their_static_types
175
- # load_params_must_not_be_dataMembers
176
- # load_params_must_resolve
177
- # load_path_accepts_dollar_signs
178
- # load_path_accepts_nested_paths
179
-
180
- match('#/resources/(\w+)/load') do |context|
181
- v = OperationValidator.new(context)
182
- v.validate_request do
183
- v.validate_param_source_type_not_used('data')
184
- #v.validate_path(origin: :response, target: :self)
185
- end
186
- v.validate_path_set
187
- v.validate_resource_not_set
188
- end
189
-
190
- match('#/resources/(\w+)/actions/\w+') do |context|
191
- v = OperationValidator.new(context)
192
- v.validate_request
193
- if v.resource_set?
194
- v.validate_resource
195
- v.validate_path(origin: :response, target: :resource)
196
- else
197
- v.validate_path(origin: :response)
198
- end
199
- end
200
-
201
- match('#/resources/(\w+)/batchActions/\w+') do |context|
202
- # TODO : much like a normal action???
203
- end
204
-
205
- match('#/resources/(\w+)/hasMany/\w+') do |context|
206
- v = OperationValidator.new(context)
207
- v.validate_request
208
- v.validate_resource do
209
- # at least one of the identifier sources must be plural
210
- end
211
- if v.path_set?
212
- v.validate_path(origin: :response, target: :resource)
213
- v.validate_path_is_plural
214
- end
215
- end
216
-
217
- match('#/resources/(\w+)/has/\w+') do |context, matches|
218
- v = OperationValidator.new(context)
219
- v.validate_request_not_set
220
- v.validate_resource do
221
- # disallow requestParameter
222
- # disallow responsepath
223
- end
224
- # path must resolve FROM the resource data shape
225
- # to the target resource data
226
- v.validate_path(origin: :self, target: :resource)
227
-
228
- if matches[2] == 'hasSome'
229
- # at least one identifier source must be plural
230
- # path must be plural if given
231
- else
232
- # identifier sources must be singular
233
- # path must be singular if given
234
- end
235
- end
236
-
237
- end
238
- end
239
- end
@@ -1,56 +0,0 @@
1
- module Aws
2
- module Resources
3
- module Validator
4
- class Context
5
-
6
- def initialize(options = {})
7
- @parent = options[:parent]
8
- @path = options[:path]
9
- @value = options[:value]
10
- @definition = options[:definition]
11
- @api = options[:api]
12
- @errors = options[:errors] || []
13
- end
14
-
15
- def child(at)
16
- Context.new(
17
- parent: self,
18
- path: "#{path}/#{at}",
19
- value: value[at],
20
- definition: definition,
21
- api: api,
22
- errors: errors
23
- )
24
- end
25
-
26
- # @return [Context,nil]
27
- attr_reader :parent
28
-
29
- # @return [String]
30
- attr_reader :path
31
-
32
- # @return [Object]
33
- attr_reader :value
34
-
35
- # @return [Hash]
36
- attr_reader :definition
37
-
38
- # @return [Hash]
39
- attr_reader :api
40
-
41
- # @return [Array<String>]
42
- attr_reader :errors
43
-
44
- def [] key
45
- @value[key]
46
- end
47
-
48
- def error(msg)
49
- @errors << msg
50
- false
51
- end
52
-
53
- end
54
- end
55
- end
56
- end
@@ -1,88 +0,0 @@
1
- module Aws
2
- module Resources
3
- module Validator
4
- module DSL
5
-
6
- def self.extended(base)
7
-
8
- # @api private
9
- base.const_set(:RULES, [])
10
-
11
- # @api private
12
- base.const_set(:SCHEMA_PATH, File.expand_path(File.join([
13
- File.dirname(__FILE__), '..', '..', '..', 'resources.schema.json'
14
- ])))
15
-
16
- end
17
-
18
- def match(*patterns, &block)
19
- patterns.each do |pattern|
20
- RULES << Rule.new(pattern, &block)
21
- end
22
- end
23
-
24
- # @param [Hash] definition
25
- # @param [Hash] api
26
- # @return [Array<String>]
27
- def validate(definition, api)
28
- errors = validate_against_schema(definition)
29
- if errors.empty?
30
- lint(new_context(definition, api))
31
- else
32
- errors
33
- end
34
- end
35
-
36
- private
37
-
38
- def new_context(definition, api)
39
- Validator::Context.new(
40
- path: '#',
41
- value: definition,
42
- definition: definition,
43
- api: api,
44
- )
45
- end
46
-
47
- # Validates the resource definition document against the JSON
48
- # schema for resources.
49
- # @param [Hash] definition
50
- # @return [Array<String>] Returns an array of schema validation errors.
51
- # Returns an empty array if there are no errors.
52
- def validate_against_schema(definition)
53
- schema = MultiJson.load(File.read(SCHEMA_PATH))
54
- JSON::Validator.fully_validate(schema, definition)
55
- end
56
-
57
- # Recursively lints the resource definition hash against the given
58
- # api.
59
- # @param [Context] context
60
- # @return [Array<String>] Returns an array of schema validation errors.
61
- # Returns an empty array if there are no errors.
62
- def lint(context)
63
- lint_node(context)
64
- case context.value
65
- when Hash
66
- context.value.keys.each do |key, value|
67
- lint(context.child(key))
68
- end
69
- when Array
70
- (0...context.value.size).each do |index|
71
- lint(context.child(index))
72
- end
73
- end
74
- context.errors
75
- end
76
-
77
- def lint_node(context)
78
- RULES.each do |rule|
79
- if matches = rule.matches(context.path)
80
- rule.apply(context, matches)
81
- end
82
- end
83
- end
84
-
85
- end
86
- end
87
- end
88
- end
@@ -1,352 +0,0 @@
1
- module Aws
2
- module Resources
3
- module Validator
4
- class OperationValidator
5
-
6
- PARAM_SOURCES = %w(identifier dataMember string integer boolean)
7
-
8
- # @param [Validator::Context] context
9
- def initialize(context)
10
- @context = context
11
- @operation = context.value
12
- @definition = context.definition
13
- @api = context.api
14
- @path = context.path
15
- end
16
-
17
- # @return [Hash] The service resource definition model.
18
- attr_reader :definition
19
-
20
- # @return [Hash] The api model.
21
- attr_reader :api
22
-
23
- # @return [String] The JSON path inside the definition document.
24
- attr_reader :path
25
-
26
- # @return [Boolean] Returns `true` if the operation defines a request.
27
- def request_set?
28
- @operation.key?('request')
29
- end
30
-
31
- # @return [Boolean] Returns `true` if the operation defines how to
32
- # build a resource.
33
- def resource_set?
34
- @operation.key?('resource')
35
- end
36
-
37
- # @return [Boolean] Returns `true` if the operation defines a path.
38
- def path_set?
39
- @operation.key?('path')
40
- end
41
-
42
- # Performs generic request validation including:
43
- # * request is defined
44
- # * request operation is defined in the api
45
- # * request params resolve as input parameters
46
- # * etc.
47
- # Yields to the given block if the request is defined and exists in
48
- # the api.
49
- # @return [Boolean]
50
- def validate_request(&block)
51
- if
52
- validate_request_set &&
53
- validate_operation_exists
54
- then
55
- yield if block_given?
56
- validate_params
57
- end
58
- end
59
-
60
- # @return [Boolean] Returns `true` if the operation does not define
61
- # a request. Only hasSome/hasOne references should not have a
62
- # request defined.
63
- def validate_request_not_set
64
- if @operation['request']
65
- error("'#{path}/request' is not valid in this context.")
66
- else
67
- true
68
- end
69
- end
70
-
71
- # @return [Boolean] Returns `true` if the operation does not define
72
- # how to build a resource. Only load operations may not define
73
- # a resource.
74
- def validate_resource_not_set
75
- if @operation.key?('resource')
76
- error("'#{path}/resource' is not valid in this context.")
77
- else
78
- true
79
- end
80
- end
81
-
82
- # Performs basic validation on the resource definition.
83
- # @return [Boolean]
84
- def validate_resource(&block)
85
- if resource_set?
86
- validate_resource_exists
87
- else
88
- error("'#{path}/resource' must be set.")
89
- end
90
- end
91
-
92
- # @return [Boolean] Returns `true` if the operation defines a path.
93
- # Load operations require a path.
94
- def validate_path_set
95
- if path_set?
96
- true
97
- else
98
- error("'#{path}/path' must be set.")
99
- end
100
- end
101
-
102
- # Validates a path by resolving it against the resource definition
103
- # and the API model. You must specify the `:origin` and optionally
104
- # the `:target`.
105
- #
106
- # == Origins
107
- #
108
- # * :response - Resolves the path starting from the operation output.
109
- #
110
- # * :request - Resolves the path starting from the operation input.
111
- #
112
- # * :self - Resolves the path starting from the resource data/shape.
113
- #
114
- # == Target
115
- #
116
- # * :resource - Requires the path to resolve to the shape of the operation
117
- # resource entry.
118
- #
119
- # * :self - Requries the path to resolve to the shape of the
120
- # current resource.
121
- #
122
- # @option options [:response, :request, :self] :origin
123
- # @option options [:self, :resource] :target
124
- def validate_path(options = {})
125
- if path_set?
126
- validate_path_resolves(options)
127
- else
128
- true
129
- end
130
- end
131
-
132
- # @return [Boolean] Returns `true` if the path resolves to an array.
133
- # Has many operations require plural paths and at least one plural
134
- # input.
135
- def validate_path_is_plural
136
- if @operation['path'].match(/\[/)
137
- true
138
- else
139
- error("'#{path}/path' must be plural.")
140
- end
141
- end
142
-
143
- # @return [Boolean] Returns `true` if none of the request params
144
- # are for the given `source_type`. Load operations may not use
145
- # "dataMember" source types.
146
- def validate_param_source_type_not_used(source_type)
147
- (@operation['request']['params'] || []).each.with_index do |param, n|
148
- if param['source'] == source_type
149
- error("'#{path}/request/params/#{n}/sourceType' is set to '#{source_type}' which is not valid in this context.")
150
- end
151
- end
152
- end
153
-
154
- private
155
-
156
- def error(msg)
157
- @context.error(msg)
158
- end
159
-
160
- # @option options [:response, :request, :self] :origin
161
- # @option options [:self, :response] :target
162
- def validate_path_resolves(options)
163
- if origin_exists?(options)
164
- resolve_path(options)
165
- else
166
- error("'#{path}/path' requires that '#{origin_path(options)}' be set.")
167
- end
168
- end
169
-
170
- def validate_resource_exists
171
- if definition['resources'].key?(operation_resource_name)
172
- true
173
- else
174
- error("'#{path}/resource/type' references '#{operation_resource_name}' which is not defined.")
175
- end
176
- end
177
-
178
- def resolve_path(options)
179
- if resolved_shape = resolve(@operation['path'], origin(options))
180
- validate_resolved_shape(resolved_shape, options)
181
- else
182
- error("'#{path}/path' does not resolve.")
183
- end
184
- end
185
-
186
- def validate_resolved_shape(resolved_shape, options)
187
- if options[:target]
188
- validate_target_exists(options) &&
189
- validate_resolved_shape_matches(resolved_shape, options)
190
- else
191
- true
192
- end
193
- end
194
-
195
- def validate_target_exists(options)
196
- if target(options)
197
- true
198
- else
199
- error("'#{path}/path' requires that '#/resources/#{target_resource_name(options)}/shape' is set.")
200
- end
201
- end
202
-
203
- def validate_resolved_shape_matches(resolved_shape, options)
204
- if resolved_shape == target(options)
205
- true
206
- else
207
- error("'#{path}/path' did not resolve to a '#{target(options)}' shape.")
208
- end
209
- end
210
-
211
- def origin(options)
212
- case options[:origin]
213
- when :request then api_operation['input']
214
- when :response then api_operation['output']
215
- when :self then { 'shape' => resource_shape_name }
216
- else
217
- msg = "expected :origin to be one of :output, :input, or :self"
218
- raise ArgumentError, msg
219
- end
220
- end
221
-
222
- def target_resource_name(options)
223
- case options[:target]
224
- when :resource then operation_resource_name
225
- when :self then resource_name
226
- else
227
- raise ArgumentError, "expected `:target` as :resource, or :self"
228
- end
229
- end
230
-
231
- def target(options)
232
- @definition['resources'][target_resource_name(options)]['shape']
233
- end
234
-
235
- def origin_path(options)
236
- case options[:origin]
237
- when :request then "api#/operations/#{operation_name}/input"
238
- when :response then "api#/operations/#{operation_name}/output"
239
- when :self then raise 'not tested'; "api#/shapes/#{resource_shape_name}"
240
- else raise "unhandled origin #{options[:origin].inspect}"
241
- end
242
- end
243
-
244
- def origin_exists?(options)
245
- case options[:origin]
246
- when :request then !!(api_operation && api_operation['input'])
247
- when :response then !!(api_operation && api_operation['output'])
248
- when :self then !!api['shapes'][resource_shape_name]
249
- else raise "unhandled origin #{options[:origin].inspect}"
250
- end
251
- end
252
-
253
- def operation_resource_name
254
- @operation['resource']['type']
255
- end
256
-
257
- def resolve(jamespath, from)
258
- ref = jamespath.scan(/\w+|\[.*?\]/).inject(from) do |ref, part|
259
- shape = api['shapes'][ref['shape']]
260
- if part[0] == '['
261
- return nil unless shape['type'] == 'list'
262
- shape['member']
263
- else
264
- return nil unless shape['type'] == 'structure'
265
- return nil unless shape['members'][part]
266
- shape['members'][part]
267
- end
268
- end
269
- ref && ref['shape']
270
- end
271
-
272
- def validate_request_set
273
- if @operation['request']
274
- true
275
- else
276
- error("'#{path}/request' is required in this context.")
277
- end
278
- end
279
-
280
- def validate_params
281
- if params = @operation['request']['params']
282
- if validate_operation_accepts_input
283
- params.each.with_index do |param, index|
284
- validate_request_param(param, index)
285
- end
286
- end
287
- end
288
- end
289
-
290
- def validate_operation_accepts_input
291
- if api_operation['input']
292
- true
293
- else
294
- error("'#{path}/request/params' is set but '#{operation_name}' does not accept input.")
295
- end
296
- end
297
-
298
- def validate_request_param(param, index)
299
- validate_request_param_target_resolves(param, index)
300
- validate_static_params_match_coral_type(param, index)
301
- end
302
-
303
- def validate_request_param_target_resolves(param, index)
304
- if resolve(param['target'], api_operation['input'])
305
- true
306
- else
307
- error("'#{path}/request/params/#{index}/target' has the expression '#{param['target']}' which does not resolve from 'api#/operations/#{operation_name}/input'.")
308
- end
309
- end
310
-
311
- def validate_static_params_match_coral_type(param, index)
312
- if %w(string integer boolean).include?(param['sourceType'])
313
- resolved_shape = resolve(param['target'], api_operation['input'])
314
- resolved_type = @api['shapes'][resolved_shape]['type']
315
- unless param['sourceType'] == resolved_type
316
- error("'#{path}/request/params/#{index}/sourceType' given as '#{param['sourceType']}' but resolves to a '#{resolved_type}' shape.")
317
- end
318
- end
319
- end
320
-
321
- def validate_operation_exists
322
- #if api_operation
323
- true
324
- #else
325
- # error("'#{path}/request/operation' is set but is not defined at 'api#/operations/#{operation_name}'.")
326
- #end
327
- end
328
-
329
- def resource_name
330
- @context.matches[1]
331
- end
332
-
333
- def resource
334
- definition['resources'][resource_name]
335
- end
336
-
337
- def resource_shape_name
338
- resource['shape']
339
- end
340
-
341
- def operation_name
342
- @operation['request']['operation']
343
- end
344
-
345
- def api_operation
346
- api['operations'][operation_name]
347
- end
348
-
349
- end
350
- end
351
- end
352
- end
@@ -1,34 +0,0 @@
1
- module Aws
2
- module Resources
3
- module Validator
4
- # @api private
5
- class PathResolver
6
-
7
- def initialize(api)
8
- @api = api
9
- end
10
-
11
- # @param [String<JMESPathExpression>] expression
12
- # @param [Hash<Shape Reference>] from The shape reference, typically
13
- # an operation, to resolve the path starting from.
14
- # @return [String, nil] Returns the class name resolved, or `nil`
15
- # if the path does not resolve in the model.
16
- def resolve(expression, from)
17
- ref = expression.scan(/\w+|\[.*?\]/).inject(from) do |ref, part|
18
- shape = @api['shapes'][ref['shape']]
19
- if part[0] == '['
20
- return nil unless shape['type'] == 'list'
21
- shape['member']
22
- else
23
- return nil unless shape['type'] == 'structure'
24
- return nil unless shape['members'][part]
25
- shape['members'][part]
26
- end
27
- end
28
- ref && ref['shape']
29
- end
30
-
31
- end
32
- end
33
- end
34
- end
@@ -1,23 +0,0 @@
1
- module Aws
2
- module Resources
3
- module Validator
4
- # @api private
5
- class Rule
6
-
7
- def initialize(pattern, &block)
8
- @pattern = Regexp.new('^' + pattern + '$')
9
- @block = block
10
- end
11
-
12
- def matches(path)
13
- path.match(@pattern)
14
- end
15
-
16
- def apply(context, matches)
17
- @block.call(context, matches)
18
- end
19
-
20
- end
21
- end
22
- end
23
- end