azure-storage-common 1.1.0 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/lib/azure/core/auth/authorizer.rb +36 -0
  3. data/lib/azure/core/auth/shared_key.rb +125 -0
  4. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  5. data/lib/azure/core/auth/signer.rb +51 -0
  6. data/lib/azure/core/default.rb +23 -0
  7. data/lib/azure/core/error.rb +21 -0
  8. data/lib/azure/core/filtered_service.rb +45 -0
  9. data/lib/azure/core/http/debug_filter.rb +36 -0
  10. data/lib/azure/core/http/http_error.rb +135 -0
  11. data/lib/azure/core/http/http_filter.rb +53 -0
  12. data/lib/azure/core/http/http_request.rb +195 -0
  13. data/lib/azure/core/http/http_response.rb +102 -0
  14. data/lib/azure/core/http/retry_policy.rb +84 -0
  15. data/lib/azure/core/http/signer_filter.rb +33 -0
  16. data/lib/azure/core/service.rb +46 -0
  17. data/lib/azure/core/signed_service.rb +45 -0
  18. data/lib/azure/core/utility.rb +244 -0
  19. data/lib/azure/core/version.rb +33 -0
  20. data/lib/azure/core.rb +47 -0
  21. data/lib/azure/http_response_helper.rb +38 -0
  22. data/lib/azure/storage/common/autoload.rb +62 -61
  23. data/lib/azure/storage/common/client.rb +162 -162
  24. data/lib/azure/storage/common/client_options.rb +363 -363
  25. data/lib/azure/storage/common/client_options_error.rb +41 -41
  26. data/lib/azure/storage/common/configurable.rb +212 -212
  27. data/lib/azure/storage/common/core/auth/anonymous_signer.rb +43 -43
  28. data/lib/azure/storage/common/core/auth/shared_access_signature.rb +30 -30
  29. data/lib/azure/storage/common/core/auth/shared_access_signature_generator.rb +399 -352
  30. data/lib/azure/storage/common/core/auth/shared_access_signature_signer.rb +57 -57
  31. data/lib/azure/storage/common/core/auth/shared_key.rb +60 -60
  32. data/lib/azure/storage/common/core/auth/token_signer.rb +43 -43
  33. data/lib/azure/storage/common/core/autoload.rb +53 -53
  34. data/lib/azure/storage/common/core/error.rb +43 -43
  35. data/lib/azure/storage/common/core/filter/exponential_retry_filter.rb +64 -64
  36. data/lib/azure/storage/common/core/filter/linear_retry_filter.rb +55 -55
  37. data/lib/azure/storage/common/core/filter/retry_filter.rb +300 -300
  38. data/lib/azure/storage/common/core/http_client.rb +82 -69
  39. data/lib/azure/storage/common/core/sr.rb +85 -85
  40. data/lib/azure/storage/common/core/token_credential.rb +64 -64
  41. data/lib/azure/storage/common/core/utility.rb +261 -255
  42. data/lib/azure/storage/common/core.rb +35 -35
  43. data/lib/azure/storage/common/default.rb +868 -868
  44. data/lib/azure/storage/common/service/access_policy.rb +37 -37
  45. data/lib/azure/storage/common/service/cors.rb +38 -38
  46. data/lib/azure/storage/common/service/cors_rule.rb +48 -48
  47. data/lib/azure/storage/common/service/enumeration_results.rb +32 -32
  48. data/lib/azure/storage/common/service/geo_replication.rb +40 -40
  49. data/lib/azure/storage/common/service/logging.rb +47 -47
  50. data/lib/azure/storage/common/service/metrics.rb +45 -45
  51. data/lib/azure/storage/common/service/retention_policy.rb +37 -37
  52. data/lib/azure/storage/common/service/serialization.rb +335 -335
  53. data/lib/azure/storage/common/service/signed_identifier.rb +40 -40
  54. data/lib/azure/storage/common/service/storage_service.rb +322 -322
  55. data/lib/azure/storage/common/service/storage_service_properties.rb +48 -48
  56. data/lib/azure/storage/common/service/storage_service_stats.rb +39 -39
  57. data/lib/azure/storage/common/service/user_delegation_key.rb +50 -0
  58. data/lib/azure/storage/common/version.rb +49 -49
  59. data/lib/azure/storage/common.rb +26 -26
  60. metadata +85 -17
@@ -1,335 +1,335 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
- require "nokogiri"
27
- require "time"
28
-
29
- require "azure/storage/common/service/enumeration_results"
30
- require "azure/storage/common/service/signed_identifier"
31
- require "azure/storage/common/service/access_policy"
32
- require "azure/storage/common/service/storage_service_properties"
33
- require "azure/storage/common/service/logging"
34
- require "azure/storage/common/service/metrics"
35
- require "azure/storage/common/service/retention_policy"
36
- require "azure/storage/common/service/cors"
37
- require "azure/storage/common/service/cors_rule"
38
- require "azure/storage/common/service/storage_service_stats"
39
-
40
- module Azure::Storage::Common
41
- module Service
42
- module Serialization
43
- module ClassMethods
44
- def signed_identifiers_from_xml(xml)
45
- xml = slopify(xml)
46
- expect_node("SignedIdentifiers", xml)
47
-
48
- identifiers = []
49
- return identifiers unless (xml > "SignedIdentifier").any?
50
-
51
- if xml.SignedIdentifier.count == 0
52
- identifiers.push(signed_identifier_from_xml(xml.SignedIdentifier))
53
- else
54
- xml.SignedIdentifier.each { |identifier_node|
55
- identifiers.push(signed_identifier_from_xml(identifier_node))
56
- }
57
- end
58
-
59
- identifiers
60
- end
61
-
62
- def signed_identifiers_to_xml(signed_identifiers)
63
- builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
64
- xml.SignedIdentifiers {
65
- signed_identifiers.each do |identifier|
66
- xml.SignedIdentifier {
67
- xml.Id identifier.id
68
- xml.AccessPolicy {
69
- xml.Start identifier.access_policy.start
70
- xml.Expiry identifier.access_policy.expiry
71
- xml.Permission identifier.access_policy.permission
72
- }
73
- }
74
- end
75
- }
76
- end
77
- builder.to_xml
78
- end
79
-
80
- def signed_identifier_from_xml(xml)
81
- xml = slopify(xml)
82
- expect_node("SignedIdentifier", xml)
83
-
84
- SignedIdentifier.new do |identifier|
85
- identifier.id = xml.Id.text if (xml > "Id").any?
86
- identifier.access_policy = access_policy_from_xml(xml.AccessPolicy) if (xml > "AccessPolicy").any?
87
- end
88
- end
89
-
90
- def access_policy_from_xml(xml)
91
- xml = slopify(xml)
92
- expect_node("AccessPolicy", xml)
93
-
94
- AccessPolicy.new do |policy|
95
- policy.start = xml.Start.text if (xml > "Start").any?
96
- policy.expiry = xml.Expiry.text if (xml > "Expiry").any?
97
- policy.permission = xml.Permission.text if (xml > "Permission").any?
98
- end
99
- end
100
-
101
- def enumeration_results_from_xml(xml, results)
102
- xml = slopify(xml)
103
- expect_node("EnumerationResults", xml)
104
-
105
- results = results || Service::EnumerationResults.new;
106
-
107
- results.continuation_token = xml.NextMarker.text if (xml > "NextMarker").any?
108
- results
109
- end
110
-
111
- def metadata_from_xml(xml)
112
- xml = slopify(xml)
113
- expect_node("Metadata", xml)
114
-
115
- metadata = {}
116
-
117
- xml.children.each { |meta_node|
118
-
119
- key = meta_node.name.downcase
120
- if metadata.has_key? key
121
- metadata[key] = [metadata[key]] unless metadata[key].respond_to? :push
122
- metadata[key].push(meta_node.text)
123
- else
124
- metadata[key] = meta_node.text
125
- end
126
- }
127
- metadata
128
- end
129
-
130
- def metadata_from_headers(headers)
131
- metadata = {}
132
-
133
- headers.each { |k, v|
134
- if key = k[/^x-ms-meta-(.*)/, 1]
135
- if metadata.has_key? key
136
- metadata[key] = [metadata[key]] unless metadata[key].respond_to? :push
137
- metadata[key].push(v)
138
- else
139
- metadata[key] = v
140
- end
141
- end
142
- }
143
-
144
- metadata
145
- end
146
-
147
- def retention_policy_to_xml(retention_policy, xml)
148
- xml.RetentionPolicy {
149
- xml.Enabled retention_policy.enabled
150
- xml.Days retention_policy.days if retention_policy.enabled && retention_policy.days
151
- } if retention_policy
152
- end
153
-
154
- def retention_policy_from_xml(xml)
155
- xml = slopify(xml)
156
- expect_node("RetentionPolicy", xml)
157
-
158
- RetentionPolicy.new do |policy|
159
- policy.enabled = to_bool(xml.Enabled.text) if (xml > "Enabled").any?
160
- policy.days = xml.Days.text.to_i if (xml > "Days").any?
161
- end
162
- end
163
-
164
- def metrics_to_xml_children(metrics, xml)
165
- return unless metrics
166
- xml.Version metrics.version
167
- xml.Enabled metrics.enabled
168
- xml.IncludeAPIs metrics.include_apis if metrics.enabled
169
- retention_policy_to_xml(metrics.retention_policy, xml) if metrics.retention_policy
170
- end
171
-
172
- def hour_metrics_to_xml(metrics, xml)
173
- xml.HourMetrics {
174
- metrics_to_xml_children(metrics, xml)
175
- } if metrics
176
- end
177
-
178
- def minute_metrics_to_xml(metrics, xml)
179
- xml.MinuteMetrics {
180
- metrics_to_xml_children(metrics, xml)
181
- } if metrics
182
- end
183
-
184
- def metrics_from_xml(xml)
185
- xml = slopify(xml)
186
-
187
- Metrics.new do |metrics|
188
- metrics.version = xml.Version.text if (xml > "Version").any?
189
- metrics.enabled = to_bool(xml.Enabled.text) if (xml > "Enabled").any?
190
- metrics.include_apis = to_bool(xml.IncludeAPIs.text) if (xml > "IncludeAPIs").any?
191
- metrics.retention_policy = retention_policy_from_xml(xml.RetentionPolicy)
192
- end
193
- end
194
-
195
- def logging_to_xml(logging, xml)
196
- xml.Logging {
197
- xml.Version logging.version
198
- xml.Delete logging.delete
199
- xml.Read logging.read
200
- xml.Write logging.write
201
- retention_policy_to_xml(logging.retention_policy, xml)
202
- } if logging
203
- end
204
-
205
- def logging_from_xml(xml)
206
- xml = slopify(xml)
207
- expect_node("Logging", xml)
208
-
209
- Logging.new do |logging|
210
- logging.version = xml.Version.text if (xml > "Version").any?
211
- logging.delete = to_bool(xml.Delete.text) if (xml > "Delete").any?
212
- logging.read = to_bool(xml.Read.text) if (xml > "Read").any?
213
- logging.write = to_bool(xml.Write.text) if (xml > "Write").any?
214
- logging.retention_policy = retention_policy_from_xml(xml.RetentionPolicy)
215
- end
216
- end
217
-
218
- def cors_to_xml(cors, xml)
219
- xml.Cors {
220
- cors.cors_rules.to_a.each do |cors_rule|
221
- cors_rule_to_xml(cors_rule, xml)
222
- end
223
- }
224
- end
225
-
226
- def cors_rule_to_xml(cors_rule, xml)
227
- xml.CorsRule {
228
- xml.AllowedOrigins cors_rule.allowed_origins.join(",") if cors_rule.allowed_origins
229
- xml.AllowedMethods cors_rule.allowed_methods.join(",") if cors_rule.allowed_methods
230
- xml.MaxAgeInSeconds cors_rule.max_age_in_seconds if cors_rule.max_age_in_seconds
231
- xml.ExposedHeaders cors_rule.exposed_headers.join(",") if cors_rule.exposed_headers
232
- xml.AllowedHeaders cors_rule.allowed_headers.join(",") if cors_rule.allowed_headers
233
- }
234
- end
235
-
236
- def cors_from_xml(xml)
237
- xml = slopify(xml)
238
- expect_node("Cors", xml)
239
-
240
- Cors.new do |cors|
241
- cors.cors_rules = xml.children.to_a.map { |child| cors_rule_from_xml(child) }
242
- end
243
- end
244
-
245
- def cors_rule_from_xml(xml)
246
- xml = slopify(xml)
247
- expect_node("CorsRule", xml)
248
-
249
- CorsRule.new do |cors_rule|
250
- cors_rule.allowed_origins = ary_from_node(xml.AllowedOrigins) if (xml > "AllowedOrigins").any?
251
- cors_rule.allowed_methods = ary_from_node(xml.AllowedMethods) if (xml > "AllowedMethods").any?
252
- cors_rule.max_age_in_seconds = xml.MaxAgeInSeconds.text.to_i if (xml > "MaxAgeInSeconds").any?
253
- cors_rule.exposed_headers = ary_from_node(xml.ExposedHeaders) if (xml > "ExposedHeaders").any?
254
- cors_rule.allowed_headers = ary_from_node(xml.AllowedHeaders) if (xml > "AllowedHeaders").any?
255
- end
256
- end
257
-
258
- def geo_replication_from_xml(xml)
259
- xml = slopify(xml)
260
- expect_node("GeoReplication", xml)
261
-
262
- GeoReplication.new do |geo_replication|
263
- geo_replication.status = xml.Status.text if (xml > "Status").any?
264
- geo_replication.last_sync_time =
265
- begin
266
- Time.parse(xml.LastSyncTime.text) if (xml > "LastSyncTime").any?
267
- rescue
268
- nil
269
- end
270
- end
271
- end
272
-
273
- def ary_from_node(node)
274
- node.text.split(",").map { |s| s.strip }
275
- end
276
-
277
- def service_properties_to_xml(properties)
278
- builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
279
- xml.StorageServiceProperties {
280
- xml.DefaultServiceVersion(properties.default_service_version) if properties.default_service_version
281
- logging_to_xml(properties.logging, xml) if properties.logging
282
- hour_metrics_to_xml(properties.hour_metrics, xml) if properties.hour_metrics
283
- minute_metrics_to_xml(properties.minute_metrics, xml) if properties.minute_metrics
284
- cors_to_xml(properties.cors, xml) if properties.cors
285
- }
286
- end
287
- builder.to_xml
288
- end
289
-
290
- def service_properties_from_xml(xml)
291
- xml = slopify(xml)
292
- expect_node("StorageServiceProperties", xml)
293
-
294
- StorageServiceProperties.new do |props|
295
- props.default_service_version = xml.DefaultServiceVersion.text if (xml > "DefaultServiceVersion").any?
296
- props.logging = logging_from_xml(xml.Logging) if (xml > "Logging").any?
297
- props.hour_metrics = metrics_from_xml(xml.HourMetrics) if (xml > "HourMetrics").any?
298
- props.minute_metrics = metrics_from_xml(xml.MinuteMetrics) if (xml > "MinuteMetrics").any?
299
- props.cors = cors_from_xml(xml.Cors) if (xml > "Cors").any?
300
- end
301
- end
302
-
303
- def service_stats_from_xml(xml)
304
- xml = slopify(xml)
305
- expect_node("StorageServiceStats", xml)
306
-
307
- StorageServiceStats.new do |stats|
308
- stats.geo_replication = geo_replication_from_xml(xml.GeoReplication)
309
- end
310
- end
311
-
312
- def to_bool(s)
313
- (s || "").downcase == "true"
314
- end
315
-
316
- def slopify(xml)
317
- node = (xml.is_a? String) ? Nokogiri.Slop(xml).root : xml
318
- node.slop! if node.is_a? Nokogiri::XML::Document unless node.respond_to? :method_missing
319
- node = node.root if node.is_a? Nokogiri::XML::Document
320
- node
321
- end
322
-
323
- def expect_node(node_name, xml)
324
- raise "Xml is not a #{node_name} node. xml:\n#{xml}" unless xml.name == node_name
325
- end
326
- end
327
-
328
- extend ClassMethods
329
-
330
- def self.included(other)
331
- other.extend(ClassMethods)
332
- end
333
- end
334
- end
335
- end
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+ require "nokogiri"
27
+ require "time"
28
+
29
+ require "azure/storage/common/service/enumeration_results"
30
+ require "azure/storage/common/service/signed_identifier"
31
+ require "azure/storage/common/service/access_policy"
32
+ require "azure/storage/common/service/storage_service_properties"
33
+ require "azure/storage/common/service/logging"
34
+ require "azure/storage/common/service/metrics"
35
+ require "azure/storage/common/service/retention_policy"
36
+ require "azure/storage/common/service/cors"
37
+ require "azure/storage/common/service/cors_rule"
38
+ require "azure/storage/common/service/storage_service_stats"
39
+
40
+ module Azure::Storage::Common
41
+ module Service
42
+ module Serialization
43
+ module ClassMethods
44
+ def signed_identifiers_from_xml(xml)
45
+ xml = slopify(xml)
46
+ expect_node("SignedIdentifiers", xml)
47
+
48
+ identifiers = []
49
+ return identifiers unless (xml > "SignedIdentifier").any?
50
+
51
+ if xml.SignedIdentifier.count == 0
52
+ identifiers.push(signed_identifier_from_xml(xml.SignedIdentifier))
53
+ else
54
+ xml.SignedIdentifier.each { |identifier_node|
55
+ identifiers.push(signed_identifier_from_xml(identifier_node))
56
+ }
57
+ end
58
+
59
+ identifiers
60
+ end
61
+
62
+ def signed_identifiers_to_xml(signed_identifiers)
63
+ builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
64
+ xml.SignedIdentifiers {
65
+ signed_identifiers.each do |identifier|
66
+ xml.SignedIdentifier {
67
+ xml.Id identifier.id
68
+ xml.AccessPolicy {
69
+ xml.Start identifier.access_policy.start
70
+ xml.Expiry identifier.access_policy.expiry
71
+ xml.Permission identifier.access_policy.permission
72
+ }
73
+ }
74
+ end
75
+ }
76
+ end
77
+ builder.to_xml
78
+ end
79
+
80
+ def signed_identifier_from_xml(xml)
81
+ xml = slopify(xml)
82
+ expect_node("SignedIdentifier", xml)
83
+
84
+ SignedIdentifier.new do |identifier|
85
+ identifier.id = xml.Id.text if (xml > "Id").any?
86
+ identifier.access_policy = access_policy_from_xml(xml.AccessPolicy) if (xml > "AccessPolicy").any?
87
+ end
88
+ end
89
+
90
+ def access_policy_from_xml(xml)
91
+ xml = slopify(xml)
92
+ expect_node("AccessPolicy", xml)
93
+
94
+ AccessPolicy.new do |policy|
95
+ policy.start = xml.Start.text if (xml > "Start").any?
96
+ policy.expiry = xml.Expiry.text if (xml > "Expiry").any?
97
+ policy.permission = xml.Permission.text if (xml > "Permission").any?
98
+ end
99
+ end
100
+
101
+ def enumeration_results_from_xml(xml, results)
102
+ xml = slopify(xml)
103
+ expect_node("EnumerationResults", xml)
104
+
105
+ results = results || Service::EnumerationResults.new;
106
+
107
+ results.continuation_token = xml.NextMarker.text if (xml > "NextMarker").any?
108
+ results
109
+ end
110
+
111
+ def metadata_from_xml(xml)
112
+ xml = slopify(xml)
113
+ expect_node("Metadata", xml)
114
+
115
+ metadata = {}
116
+
117
+ xml.children.each { |meta_node|
118
+
119
+ key = meta_node.name.downcase
120
+ if metadata.has_key? key
121
+ metadata[key] = [metadata[key]] unless metadata[key].respond_to? :push
122
+ metadata[key].push(meta_node.text)
123
+ else
124
+ metadata[key] = meta_node.text
125
+ end
126
+ }
127
+ metadata
128
+ end
129
+
130
+ def metadata_from_headers(headers)
131
+ metadata = {}
132
+
133
+ headers.each { |k, v|
134
+ if key = k[/^x-ms-meta-(.*)/, 1]
135
+ if metadata.has_key? key
136
+ metadata[key] = [metadata[key]] unless metadata[key].respond_to? :push
137
+ metadata[key].push(v)
138
+ else
139
+ metadata[key] = v
140
+ end
141
+ end
142
+ }
143
+
144
+ metadata
145
+ end
146
+
147
+ def retention_policy_to_xml(retention_policy, xml)
148
+ xml.RetentionPolicy {
149
+ xml.Enabled retention_policy.enabled
150
+ xml.Days retention_policy.days if retention_policy.enabled && retention_policy.days
151
+ } if retention_policy
152
+ end
153
+
154
+ def retention_policy_from_xml(xml)
155
+ xml = slopify(xml)
156
+ expect_node("RetentionPolicy", xml)
157
+
158
+ RetentionPolicy.new do |policy|
159
+ policy.enabled = to_bool(xml.Enabled.text) if (xml > "Enabled").any?
160
+ policy.days = xml.Days.text.to_i if (xml > "Days").any?
161
+ end
162
+ end
163
+
164
+ def metrics_to_xml_children(metrics, xml)
165
+ return unless metrics
166
+ xml.Version metrics.version
167
+ xml.Enabled metrics.enabled
168
+ xml.IncludeAPIs metrics.include_apis if metrics.enabled
169
+ retention_policy_to_xml(metrics.retention_policy, xml) if metrics.retention_policy
170
+ end
171
+
172
+ def hour_metrics_to_xml(metrics, xml)
173
+ xml.HourMetrics {
174
+ metrics_to_xml_children(metrics, xml)
175
+ } if metrics
176
+ end
177
+
178
+ def minute_metrics_to_xml(metrics, xml)
179
+ xml.MinuteMetrics {
180
+ metrics_to_xml_children(metrics, xml)
181
+ } if metrics
182
+ end
183
+
184
+ def metrics_from_xml(xml)
185
+ xml = slopify(xml)
186
+
187
+ Metrics.new do |metrics|
188
+ metrics.version = xml.Version.text if (xml > "Version").any?
189
+ metrics.enabled = to_bool(xml.Enabled.text) if (xml > "Enabled").any?
190
+ metrics.include_apis = to_bool(xml.IncludeAPIs.text) if (xml > "IncludeAPIs").any?
191
+ metrics.retention_policy = retention_policy_from_xml(xml.RetentionPolicy)
192
+ end
193
+ end
194
+
195
+ def logging_to_xml(logging, xml)
196
+ xml.Logging {
197
+ xml.Version logging.version
198
+ xml.Delete logging.delete
199
+ xml.Read logging.read
200
+ xml.Write logging.write
201
+ retention_policy_to_xml(logging.retention_policy, xml)
202
+ } if logging
203
+ end
204
+
205
+ def logging_from_xml(xml)
206
+ xml = slopify(xml)
207
+ expect_node("Logging", xml)
208
+
209
+ Logging.new do |logging|
210
+ logging.version = xml.Version.text if (xml > "Version").any?
211
+ logging.delete = to_bool(xml.Delete.text) if (xml > "Delete").any?
212
+ logging.read = to_bool(xml.Read.text) if (xml > "Read").any?
213
+ logging.write = to_bool(xml.Write.text) if (xml > "Write").any?
214
+ logging.retention_policy = retention_policy_from_xml(xml.RetentionPolicy)
215
+ end
216
+ end
217
+
218
+ def cors_to_xml(cors, xml)
219
+ xml.Cors {
220
+ cors.cors_rules.to_a.each do |cors_rule|
221
+ cors_rule_to_xml(cors_rule, xml)
222
+ end
223
+ }
224
+ end
225
+
226
+ def cors_rule_to_xml(cors_rule, xml)
227
+ xml.CorsRule {
228
+ xml.AllowedOrigins cors_rule.allowed_origins.join(",") if cors_rule.allowed_origins
229
+ xml.AllowedMethods cors_rule.allowed_methods.join(",") if cors_rule.allowed_methods
230
+ xml.MaxAgeInSeconds cors_rule.max_age_in_seconds if cors_rule.max_age_in_seconds
231
+ xml.ExposedHeaders cors_rule.exposed_headers.join(",") if cors_rule.exposed_headers
232
+ xml.AllowedHeaders cors_rule.allowed_headers.join(",") if cors_rule.allowed_headers
233
+ }
234
+ end
235
+
236
+ def cors_from_xml(xml)
237
+ xml = slopify(xml)
238
+ expect_node("Cors", xml)
239
+
240
+ Cors.new do |cors|
241
+ cors.cors_rules = xml.children.to_a.map { |child| cors_rule_from_xml(child) }
242
+ end
243
+ end
244
+
245
+ def cors_rule_from_xml(xml)
246
+ xml = slopify(xml)
247
+ expect_node("CorsRule", xml)
248
+
249
+ CorsRule.new do |cors_rule|
250
+ cors_rule.allowed_origins = ary_from_node(xml.AllowedOrigins) if (xml > "AllowedOrigins").any?
251
+ cors_rule.allowed_methods = ary_from_node(xml.AllowedMethods) if (xml > "AllowedMethods").any?
252
+ cors_rule.max_age_in_seconds = xml.MaxAgeInSeconds.text.to_i if (xml > "MaxAgeInSeconds").any?
253
+ cors_rule.exposed_headers = ary_from_node(xml.ExposedHeaders) if (xml > "ExposedHeaders").any?
254
+ cors_rule.allowed_headers = ary_from_node(xml.AllowedHeaders) if (xml > "AllowedHeaders").any?
255
+ end
256
+ end
257
+
258
+ def geo_replication_from_xml(xml)
259
+ xml = slopify(xml)
260
+ expect_node("GeoReplication", xml)
261
+
262
+ GeoReplication.new do |geo_replication|
263
+ geo_replication.status = xml.Status.text if (xml > "Status").any?
264
+ geo_replication.last_sync_time =
265
+ begin
266
+ Time.parse(xml.LastSyncTime.text) if (xml > "LastSyncTime").any?
267
+ rescue
268
+ nil
269
+ end
270
+ end
271
+ end
272
+
273
+ def ary_from_node(node)
274
+ node.text.split(",").map { |s| s.strip }
275
+ end
276
+
277
+ def service_properties_to_xml(properties)
278
+ builder = Nokogiri::XML::Builder.new(encoding: "utf-8") do |xml|
279
+ xml.StorageServiceProperties {
280
+ xml.DefaultServiceVersion(properties.default_service_version) if properties.default_service_version
281
+ logging_to_xml(properties.logging, xml) if properties.logging
282
+ hour_metrics_to_xml(properties.hour_metrics, xml) if properties.hour_metrics
283
+ minute_metrics_to_xml(properties.minute_metrics, xml) if properties.minute_metrics
284
+ cors_to_xml(properties.cors, xml) if properties.cors
285
+ }
286
+ end
287
+ builder.to_xml
288
+ end
289
+
290
+ def service_properties_from_xml(xml)
291
+ xml = slopify(xml)
292
+ expect_node("StorageServiceProperties", xml)
293
+
294
+ StorageServiceProperties.new do |props|
295
+ props.default_service_version = xml.DefaultServiceVersion.text if (xml > "DefaultServiceVersion").any?
296
+ props.logging = logging_from_xml(xml.Logging) if (xml > "Logging").any?
297
+ props.hour_metrics = metrics_from_xml(xml.HourMetrics) if (xml > "HourMetrics").any?
298
+ props.minute_metrics = metrics_from_xml(xml.MinuteMetrics) if (xml > "MinuteMetrics").any?
299
+ props.cors = cors_from_xml(xml.Cors) if (xml > "Cors").any?
300
+ end
301
+ end
302
+
303
+ def service_stats_from_xml(xml)
304
+ xml = slopify(xml)
305
+ expect_node("StorageServiceStats", xml)
306
+
307
+ StorageServiceStats.new do |stats|
308
+ stats.geo_replication = geo_replication_from_xml(xml.GeoReplication)
309
+ end
310
+ end
311
+
312
+ def to_bool(s)
313
+ (s || "").downcase == "true"
314
+ end
315
+
316
+ def slopify(xml)
317
+ node = (xml.is_a? String) ? Nokogiri.Slop(xml).root : xml
318
+ node.slop! if node.is_a? Nokogiri::XML::Document unless node.respond_to? :method_missing
319
+ node = node.root if node.is_a? Nokogiri::XML::Document
320
+ node
321
+ end
322
+
323
+ def expect_node(node_name, xml)
324
+ raise "Xml is not a #{node_name} node. xml:\n#{xml}" unless xml.name == node_name
325
+ end
326
+ end
327
+
328
+ extend ClassMethods
329
+
330
+ def self.included(other)
331
+ other.extend(ClassMethods)
332
+ end
333
+ end
334
+ end
335
+ end