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 +4 -4
- data/lib/aws-sdk-resources.rb +15 -26
- data/lib/aws-sdk-resources/request.rb +2 -2
- metadata +6 -14
- data/lib/aws-sdk-resources/services/sqs.rb +0 -5
- data/lib/aws-sdk-resources/services/sqs/queue.rb +0 -102
- data/lib/aws-sdk-resources/validator.rb +0 -239
- data/lib/aws-sdk-resources/validator/context.rb +0 -56
- data/lib/aws-sdk-resources/validator/dsl.rb +0 -88
- data/lib/aws-sdk-resources/validator/operation_validator.rb +0 -352
- data/lib/aws-sdk-resources/validator/path_resolver.rb +0 -34
- data/lib/aws-sdk-resources/validator/rule.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 406e521dc5e2fa2e3036612ca85bf81dafb64838
|
4
|
+
data.tar.gz: 220362ebb755c163929c895b3067a75c878284d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b0215e8a68171958a3433faceb54c06ce5a455663931b710b5a2cdc39166ac93357ef41ad9675c7cf33fac39d7e4a4bb1c4597dce9df3dd90de94371e6d0fc7
|
7
|
+
data.tar.gz: b22a0721824c84b24340aa4dce0b24125edd0fdbb38d2342b45a4e85d6cb44c7c10355f58a77cc133c7318e87eacda1d1eb55aea6f2cbbd60ee77fceb49648c4
|
data/lib/aws-sdk-resources.rb
CHANGED
@@ -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
|
-
|
25
|
-
|
26
|
-
|
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
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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.
|
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.
|
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:
|
97
|
+
version: '0'
|
106
98
|
requirements: []
|
107
99
|
rubyforge_project:
|
108
100
|
rubygems_version: 2.2.2
|
@@ -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
|