aws-sdk 1.3.2 → 1.3.3
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.
- data/lib/aws/api_config/{IAM-2010-07-15.yml → IAM-2010-05-08.yml} +56 -4
- data/lib/aws/api_config/SNS-2010-03-31.yml +90 -81
- data/lib/aws/core.rb +26 -11
- data/lib/aws/core/client.rb +12 -4
- data/lib/aws/core/collection.rb +5 -12
- data/lib/aws/core/collection/limitable.rb +10 -3
- data/lib/aws/core/collection/simple.rb +1 -0
- data/lib/aws/core/configuration.rb +2 -0
- data/lib/aws/core/configured_json_client_methods.rb +5 -2
- data/lib/aws/core/http/httparty_handler.rb +1 -1
- data/lib/aws/core/http/net_http_handler.rb +2 -1
- data/lib/aws/core/http/request.rb +27 -0
- data/lib/aws/core/json_client.rb +41 -0
- data/lib/aws/core/lazy_error_classes.rb +2 -0
- data/lib/aws/core/option_grammar.rb +1 -1
- data/lib/aws/core/resource.rb +12 -14
- data/lib/aws/core/session_signer.rb +0 -5
- data/lib/aws/core/xml_grammar.rb +12 -2
- data/lib/aws/dynamo_db.rb +4 -1
- data/lib/aws/dynamo_db/client.rb +4 -17
- data/lib/aws/dynamo_db/item_collection.rb +15 -0
- data/lib/aws/ec2/security_group.rb +2 -1
- data/lib/aws/ec2/security_group/ip_permission.rb +2 -3
- data/lib/aws/elb/listener.rb +2 -2
- data/lib/aws/iam.rb +17 -0
- data/lib/aws/iam/client.rb +9 -6
- data/lib/aws/iam/mfa_device.rb +4 -2
- data/lib/aws/iam/mfa_device_collection.rb +14 -3
- data/lib/aws/iam/user.rb +10 -0
- data/lib/aws/iam/virtual_mfa_device.rb +139 -0
- data/lib/aws/iam/virtual_mfa_device_collection.rb +73 -0
- data/lib/aws/record/abstract_base.rb +1 -0
- data/lib/aws/record/hash_model/attributes.rb +8 -8
- data/lib/aws/record/hash_model/finder_methods.rb +10 -15
- data/lib/aws/record/model.rb +1 -3
- data/lib/aws/record/model/finder_methods.rb +3 -3
- data/lib/aws/s3.rb +1 -0
- data/lib/aws/s3/bucket.rb +83 -16
- data/lib/aws/s3/bucket_lifecycle_configuration.rb +360 -0
- data/lib/aws/s3/client.rb +50 -0
- data/lib/aws/s3/client/xml.rb +10 -0
- data/lib/aws/s3/object_version.rb +5 -0
- data/lib/aws/s3/object_version_collection.rb +15 -1
- data/lib/aws/s3/request.rb +1 -1
- data/lib/aws/s3/s3_object.rb +56 -1
- data/lib/aws/sns.rb +1 -0
- data/lib/aws/sns/has_delivery_policy.rb +68 -0
- data/lib/aws/sns/subscription.rb +62 -14
- data/lib/aws/sns/subscription_collection.rb +1 -1
- data/lib/aws/sns/topic.rb +22 -4
- data/lib/aws/sts.rb +3 -2
- data/lib/net/http/connection_pool.rb +1 -1
- metadata +27 -25
- data/lib/aws/core/collection/batchable.rb +0 -133
data/lib/aws/s3/client.rb
CHANGED
@@ -152,6 +152,45 @@ module AWS
|
|
152
152
|
# * +:bucket_name+ -- The name of the bucket.
|
153
153
|
bucket_method(:delete_bucket, :delete)
|
154
154
|
|
155
|
+
bucket_method(:set_bucket_lifecycle_configuration, :put) do
|
156
|
+
|
157
|
+
configure_request do |req, options|
|
158
|
+
xml = options[:lifecycle_configuration]
|
159
|
+
md5 = Base64.encode64(Digest::MD5.digest(xml)).strip
|
160
|
+
req.add_param('lifecycle')
|
161
|
+
req.body = xml
|
162
|
+
req.headers['content-md5'] = md5
|
163
|
+
super(req, options)
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
bucket_method(:get_bucket_lifecycle_configuration, :get) do
|
169
|
+
|
170
|
+
configure_request do |req, options|
|
171
|
+
req.add_param('lifecycle')
|
172
|
+
super(req, options)
|
173
|
+
end
|
174
|
+
|
175
|
+
process_response do |resp|
|
176
|
+
xml = resp.http_response.body
|
177
|
+
data = XML::GetBucketLifecycleConfiguration.parse(xml)
|
178
|
+
Core::MetaUtils.extend_method(resp, :data) { ResponseData.new(data) }
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
bucket_method(:delete_bucket_lifecycle_configuration, :delete) do
|
184
|
+
|
185
|
+
configure_request do |req, options|
|
186
|
+
req.add_param('lifecycle')
|
187
|
+
super(req, options)
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
# delete_bucket_lifecycle_configuration
|
193
|
+
|
155
194
|
##
|
156
195
|
# Lists the buckets in the account.
|
157
196
|
add_client_request_method(:list_buckets) do
|
@@ -623,6 +662,17 @@ module AWS
|
|
623
662
|
meta
|
624
663
|
end
|
625
664
|
|
665
|
+
if expiry = resp.http_response.headers['x-amz-expiration']
|
666
|
+
expiry.first =~ /^expiry-date="(.+)", rule-id="(.+)"$/
|
667
|
+
date = DateTime.parse($1)
|
668
|
+
rule_id = $2
|
669
|
+
else
|
670
|
+
date = nil
|
671
|
+
rule_id = nil
|
672
|
+
end
|
673
|
+
Core::MetaUtils.extend_method(resp, :expiration_date) { date }
|
674
|
+
Core::MetaUtils.extend_method(resp, :expiration_rule_id) { rule_id }
|
675
|
+
|
626
676
|
# create methods for standard response headers
|
627
677
|
{
|
628
678
|
'x-amz-version-id' => :version_id,
|
data/lib/aws/s3/client/xml.rb
CHANGED
@@ -188,6 +188,16 @@ module AWS
|
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
|
+
GetBucketLifecycleConfiguration = Core::XmlGrammar.customize do
|
192
|
+
element("Rule") do
|
193
|
+
list
|
194
|
+
rename("Rules")
|
195
|
+
element("Expiration") do
|
196
|
+
element("Days") { integer_value }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
191
201
|
end
|
192
202
|
end
|
193
203
|
end
|
@@ -23,7 +23,21 @@ module AWS
|
|
23
23
|
# object.write('3')
|
24
24
|
#
|
25
25
|
# object.versions.collect(&:read)
|
26
|
-
# #=> ['1', '2', '3']
|
26
|
+
# #=> ['1', '2', '3']
|
27
|
+
#
|
28
|
+
# To see all the version id for a particular object, access the any particular version,
|
29
|
+
# and see the latest version:
|
30
|
+
#
|
31
|
+
# object.versions.each do |version| puts version.version_id end
|
32
|
+
# #=> T2TwAiZ3SmNr7tOfe0QBa4RZnSb3GSLq
|
33
|
+
# #=> kAEHC_ysT65bT4P3zyYOP1ELA6ajar_6
|
34
|
+
# #=> itHPX6m8na_sog0cAtkgP3QITEE8v5ij
|
35
|
+
#
|
36
|
+
# object.versions['itHPX6m8na_sog0cAtkgP3QITEE8v5ij']
|
37
|
+
# #=> <AWS::S3::ObjectVersion:<<bucket>>:myobj:itHPX6m8na_sog0cAtkgP3QITEE8v5ij>
|
38
|
+
#
|
39
|
+
# object.versions.latest
|
40
|
+
# #=> <AWS::S3::ObjectVersion:<<bucket>>:myobj:T2TwAiZ3SmNr7tOfe0QBa4RZnSb3GSLq>
|
27
41
|
#
|
28
42
|
# If you know the id of a particular version you can get that object.
|
29
43
|
#
|
data/lib/aws/s3/request.rb
CHANGED
@@ -184,7 +184,7 @@ module AWS
|
|
184
184
|
def sub_resources
|
185
185
|
%w(acl location logging notification partNumber policy
|
186
186
|
requestPayment torrent uploadId uploads versionId
|
187
|
-
versioning versions delete)
|
187
|
+
versioning versions delete lifecycle)
|
188
188
|
end
|
189
189
|
|
190
190
|
def query_parameters
|
data/lib/aws/s3/s3_object.rb
CHANGED
@@ -126,6 +126,16 @@ module AWS
|
|
126
126
|
head.content_type
|
127
127
|
end
|
128
128
|
|
129
|
+
# @return [DateTime,nil]
|
130
|
+
def expiration_date
|
131
|
+
head.expiration_date
|
132
|
+
end
|
133
|
+
|
134
|
+
# @return [String,nil]
|
135
|
+
def expiration_rule_id
|
136
|
+
head.expiration_date
|
137
|
+
end
|
138
|
+
|
129
139
|
# @return [Symbol, nil] Returns the algorithm used to encrypt
|
130
140
|
# the object on the server side, or +nil+ if SSE was not used
|
131
141
|
# when storing the object.
|
@@ -431,6 +441,48 @@ module AWS
|
|
431
441
|
ObjectUploadCollection.new(self)
|
432
442
|
end
|
433
443
|
|
444
|
+
# Moves an object to a new key.
|
445
|
+
#
|
446
|
+
# This works by copying the object to a new key and then
|
447
|
+
# deleting the old object. This function returns the
|
448
|
+
# new object once this is done.
|
449
|
+
#
|
450
|
+
# bucket = s3.buckets['old-bucket']
|
451
|
+
# old_obj = bucket.objets['old-key']
|
452
|
+
#
|
453
|
+
# # renaming an object returns a new object
|
454
|
+
# new_obj = old_obj.move_to('new-key')
|
455
|
+
#
|
456
|
+
# old_obj.key #=> 'old-key'
|
457
|
+
# old_obj.exists? #=> false
|
458
|
+
#
|
459
|
+
# new_obj.key #=> 'new-key'
|
460
|
+
# new_obj.exists? #=> true
|
461
|
+
#
|
462
|
+
# If you need to move an object to a different bucket, pass
|
463
|
+
# +:bucket+ or +:bucket_name+.
|
464
|
+
#
|
465
|
+
# obj = s3.buckets['old-bucket'].objects['old-key]
|
466
|
+
# obj.move_to('new-key', :bucket_name => 'new_bucket')
|
467
|
+
#
|
468
|
+
# If the copy succedes, but the then the delete fails, an error
|
469
|
+
# will be raised.
|
470
|
+
#
|
471
|
+
# @param [String] target The key to move this object to.
|
472
|
+
#
|
473
|
+
# @param [Hash] options
|
474
|
+
#
|
475
|
+
# @option (see #copy_to)
|
476
|
+
#
|
477
|
+
# @return [S3Object] Returns a new objet with the new key.
|
478
|
+
#
|
479
|
+
def move_to target, options = {}
|
480
|
+
copy = copy_to(target, options)
|
481
|
+
delete
|
482
|
+
copy
|
483
|
+
end
|
484
|
+
alias_method :rename_to, :move_to
|
485
|
+
|
434
486
|
# Copies data from one S3 object to another.
|
435
487
|
#
|
436
488
|
# S3 handles the copy so the clients does not need to fetch the data
|
@@ -594,7 +646,8 @@ module AWS
|
|
594
646
|
# option in the current configuration; for more information,
|
595
647
|
# see {AWS.config}.
|
596
648
|
#
|
597
|
-
# @return (
|
649
|
+
# @return [S3Object] Returns the copy (target) object.
|
650
|
+
#
|
598
651
|
def copy_to target, options = {}
|
599
652
|
|
600
653
|
unless target.is_a?(S3Object)
|
@@ -614,6 +667,7 @@ module AWS
|
|
614
667
|
copy_opts.delete(:bucket_name)
|
615
668
|
|
616
669
|
target.copy_from(self, copy_opts)
|
670
|
+
target
|
617
671
|
|
618
672
|
end
|
619
673
|
|
@@ -785,6 +839,7 @@ module AWS
|
|
785
839
|
method = http_method(method)
|
786
840
|
expires = expiration_timestamp(options[:expires])
|
787
841
|
req.add_param("AWSAccessKeyId", config.signer.access_key_id)
|
842
|
+
req.add_param("versionId", options[:version_id]) if options[:version_id]
|
788
843
|
req.add_param("Signature", signature(method, expires, req))
|
789
844
|
req.add_param("Expires", expires)
|
790
845
|
req.add_param("x-amz-security-token", config.signer.session_token) if
|
data/lib/aws/sns.rb
CHANGED
@@ -47,6 +47,7 @@ module AWS
|
|
47
47
|
autoload :Client, 'client'
|
48
48
|
autoload :Errors, 'errors'
|
49
49
|
autoload :Policy, 'policy'
|
50
|
+
autoload :HasDeliveryPolicy, 'has_delivery_policy'
|
50
51
|
autoload :Request, 'request'
|
51
52
|
autoload :Subscription, 'subscription'
|
52
53
|
autoload :SubscriptionCollection, 'subscription_collection'
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class SNS
|
16
|
+
|
17
|
+
# A module shared between {Topic} and {Subscription}. Provides methods
|
18
|
+
# for getting and setting the delivery policy and for getting the
|
19
|
+
# effective delivery policy.
|
20
|
+
module HasDeliveryPolicy
|
21
|
+
|
22
|
+
# @return [nil,Hash] Returns the delivery policy.
|
23
|
+
def delivery_policy
|
24
|
+
parse_delivery_policy(delivery_policy_json)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Hash] Returns the effective delivery policy.
|
28
|
+
def effective_delivery_policy
|
29
|
+
parse_delivery_policy(effective_delivery_policy_json)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param [nil,Hash,String<JSON>] policy A delivery policy. You can
|
33
|
+
# pass a JSON string, A policy hash or nil.
|
34
|
+
def delivery_policy= policy
|
35
|
+
|
36
|
+
policy_json = case policy
|
37
|
+
when nil then ''
|
38
|
+
when String then policy
|
39
|
+
else policy.to_json
|
40
|
+
end
|
41
|
+
|
42
|
+
update_delivery_policy(policy_json)
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [nil,String] Returns the delivery policy JSON string.
|
47
|
+
def delivery_policy_json
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String] Returns the effective delivery policy JSON string.
|
52
|
+
def effective_delivery_policy_json
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def parse_delivery_policy policy_json
|
58
|
+
policy_json.nil? ? nil : JSON.parse(policy_json)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def update_delivery_policy policy_json
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/aws/sns/subscription.rb
CHANGED
@@ -21,11 +21,12 @@ module AWS
|
|
21
21
|
class Subscription
|
22
22
|
|
23
23
|
include Core::Model
|
24
|
+
include HasDeliveryPolicy
|
24
25
|
|
25
26
|
# @private
|
26
27
|
def initialize(arn, opts = {})
|
27
28
|
@arn = arn
|
28
|
-
@
|
29
|
+
@topic_arn = opts[:topic_arn]
|
29
30
|
@endpoint = opts[:endpoint]
|
30
31
|
@protocol = opts[:protocol]
|
31
32
|
@owner_id = opts[:owner_id]
|
@@ -35,9 +36,6 @@ module AWS
|
|
35
36
|
# @return [String] The ARN of the subscription.
|
36
37
|
attr_reader :arn
|
37
38
|
|
38
|
-
# @return [Topic] The topic to which the endpoint is subscribed.
|
39
|
-
attr_reader :topic
|
40
|
-
|
41
39
|
# @return [String] The endpoint. This can be an HTTP or HTTPS
|
42
40
|
# URL, an e-mail address, or a queue ARN.
|
43
41
|
attr_reader :endpoint
|
@@ -52,7 +50,19 @@ module AWS
|
|
52
50
|
attr_reader :protocol
|
53
51
|
|
54
52
|
# @return [String] The AWS account ID of the subscription owner.
|
55
|
-
|
53
|
+
def owner_id
|
54
|
+
@owner_id ||= get_attributes['Owner']
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [String]
|
58
|
+
def topic_arn
|
59
|
+
@topic_arn ||= get_attributes['TopicArn']
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Topic]
|
63
|
+
def topic
|
64
|
+
Topic.new(topic_arn, :config => config)
|
65
|
+
end
|
56
66
|
|
57
67
|
# Deletes this subscription.
|
58
68
|
# @return [nil]
|
@@ -61,6 +71,32 @@ module AWS
|
|
61
71
|
nil
|
62
72
|
end
|
63
73
|
|
74
|
+
# @return [Boolean] Returns true if the subscription confirmation
|
75
|
+
# request was authenticated.
|
76
|
+
def confirmation_authenticated?
|
77
|
+
|
78
|
+
return true if @authenticated
|
79
|
+
|
80
|
+
if authenticated = get_attributes['ConfirmationWasAuthenticated']
|
81
|
+
@authenticated = true
|
82
|
+
else
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
# You can get the parsed JSON hash from {#delivery_policy}.
|
89
|
+
# @return [nil,String] Returns the delivery policy JSON string.
|
90
|
+
def delivery_policy_json
|
91
|
+
get_attributes['DeliveryPolicy']
|
92
|
+
end
|
93
|
+
|
94
|
+
# You can get the parsed JSON hash from {#effective_delivery_policy}.
|
95
|
+
# @return [nil,String] Returns the effective delivery policy JSON string.
|
96
|
+
def effective_delivery_policy_json
|
97
|
+
get_attributes['EffectiveDeliveryPolicy']
|
98
|
+
end
|
99
|
+
|
64
100
|
# @note This method requests the entire list of subscriptions
|
65
101
|
# for the topic (if known) or the account (if the topic is not
|
66
102
|
# known). It can be expensive if the number of subscriptions
|
@@ -68,19 +104,17 @@ module AWS
|
|
68
104
|
#
|
69
105
|
# @return [Boolean] Returns true if the subscription exists.
|
70
106
|
def exists?
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
collection.include?(self)
|
107
|
+
begin
|
108
|
+
get_attributes
|
109
|
+
true
|
110
|
+
rescue Errors::NotFound, Errors::InvalidParameter
|
111
|
+
false
|
112
|
+
end
|
79
113
|
end
|
80
114
|
|
81
115
|
# @private
|
82
116
|
def inspect
|
83
|
-
"<#{self.class}:#{arn}>"
|
117
|
+
"<#{self.class} arn:#{arn}>"
|
84
118
|
end
|
85
119
|
|
86
120
|
# @return [Boolean] Returns true if the subscriptions have the same
|
@@ -90,6 +124,20 @@ module AWS
|
|
90
124
|
end
|
91
125
|
alias_method :eql?, :==
|
92
126
|
|
127
|
+
protected
|
128
|
+
def update_delivery_policy policy_json
|
129
|
+
client_opts = {}
|
130
|
+
client_opts[:subscription_arn] = arn
|
131
|
+
client_opts[:attribute_name] = 'DeliveryPolicy'
|
132
|
+
client_opts[:attribute_value] = policy_json
|
133
|
+
client.set_subscription_attributes(client_opts)
|
134
|
+
end
|
135
|
+
|
136
|
+
protected
|
137
|
+
def get_attributes
|
138
|
+
client.get_subscription_attributes(:subscription_arn => arn).attributes
|
139
|
+
end
|
140
|
+
|
93
141
|
end
|
94
142
|
|
95
143
|
end
|
data/lib/aws/sns/topic.rb
CHANGED
@@ -19,6 +19,7 @@ module AWS
|
|
19
19
|
class Topic
|
20
20
|
|
21
21
|
include Core::Model
|
22
|
+
include HasDeliveryPolicy
|
22
23
|
|
23
24
|
# @param [String] arn The topic ARN.
|
24
25
|
def initialize arn, options = {}
|
@@ -140,7 +141,7 @@ module AWS
|
|
140
141
|
resp = client.confirm_subscription(confirm_opts)
|
141
142
|
Subscription.new(
|
142
143
|
resp.subscription_arn,
|
143
|
-
:
|
144
|
+
:topic_arn => arn,
|
144
145
|
:config => config)
|
145
146
|
end
|
146
147
|
|
@@ -203,6 +204,17 @@ module AWS
|
|
203
204
|
nil
|
204
205
|
end
|
205
206
|
|
207
|
+
# @return [nil,String<JSON>] The delivery policy JSON string.
|
208
|
+
def delivery_policy_json
|
209
|
+
to_h[:delivery_policy_json]
|
210
|
+
end
|
211
|
+
|
212
|
+
# @return [String<JSON>] The effective delivery policy JSON string.
|
213
|
+
# into account system defaults.
|
214
|
+
def effective_delivery_policy_json
|
215
|
+
to_h[:effective_delivery_policy_json]
|
216
|
+
end
|
217
|
+
|
206
218
|
# Publishes a message to this SNS topic.
|
207
219
|
#
|
208
220
|
# topic.publish('a short message')
|
@@ -297,17 +309,23 @@ module AWS
|
|
297
309
|
:num_subscriptions_confirmed => attributes['SubscriptionsConfirmed'].to_i,
|
298
310
|
:num_subscriptions_pending => attributes['SubscriptionsPending'].to_i,
|
299
311
|
:num_subscriptions_deleted => attributes['SubscriptionsDeleted'].to_i,
|
312
|
+
:delivery_policy_json => attributes['DeliveryPolicy'],
|
313
|
+
:effective_delivery_policy_json => attributes['EffectiveDeliveryPolicy'],
|
300
314
|
}
|
301
315
|
end
|
302
316
|
|
303
317
|
# @return [Boolean] Returns true if compared to another {Topic}
|
304
318
|
# with the same ARN.
|
305
|
-
def
|
319
|
+
def eql? other
|
306
320
|
other.kind_of?(Topic) and other.arn == arn
|
307
321
|
end
|
308
|
-
alias_method :eql
|
322
|
+
alias_method :==, :eql?
|
323
|
+
|
324
|
+
protected
|
325
|
+
def update_delivery_policy policy_json
|
326
|
+
set_attribute('DeliveryPolicy', policy_json)
|
327
|
+
end
|
309
328
|
|
310
|
-
# @private
|
311
329
|
protected
|
312
330
|
def parse_policy policy_json
|
313
331
|
if policy_json
|