azure-storage 0.13.0.preview → 0.14.0.preview

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/azure/storage.rb +14 -13
  3. data/lib/azure/storage/autoload.rb +31 -31
  4. data/lib/azure/storage/blob/append.rb +43 -41
  5. data/lib/azure/storage/blob/blob.rb +150 -147
  6. data/lib/azure/storage/blob/blob_service.rb +186 -184
  7. data/lib/azure/storage/blob/block.rb +56 -56
  8. data/lib/azure/storage/blob/container.rb +93 -92
  9. data/lib/azure/storage/blob/page.rb +187 -104
  10. data/lib/azure/storage/blob/serialization.rb +32 -18
  11. data/lib/azure/storage/client.rb +18 -17
  12. data/lib/azure/storage/client_options.rb +192 -193
  13. data/lib/azure/storage/client_options_error.rb +5 -5
  14. data/lib/azure/storage/configurable.rb +39 -39
  15. data/lib/azure/storage/core.rb +6 -4
  16. data/lib/azure/storage/core/auth/shared_access_signature.rb +5 -3
  17. data/lib/azure/storage/core/auth/shared_access_signature_generator.rb +34 -33
  18. data/lib/azure/storage/core/auth/shared_access_signature_signer.rb +5 -5
  19. data/lib/azure/storage/core/auth/shared_key.rb +17 -15
  20. data/lib/azure/storage/core/autoload.rb +15 -13
  21. data/lib/azure/storage/core/error.rb +3 -1
  22. data/lib/azure/storage/core/filter/exponential_retry_filter.rb +13 -11
  23. data/lib/azure/storage/core/filter/linear_retry_filter.rb +10 -8
  24. data/lib/azure/storage/core/filter/retry_filter.rb +30 -29
  25. data/lib/azure/storage/core/http_client.rb +18 -16
  26. data/lib/azure/storage/core/sr.rb +50 -48
  27. data/lib/azure/storage/core/utility.rb +19 -17
  28. data/lib/azure/storage/default.rb +371 -361
  29. data/lib/azure/storage/file/directory.rb +36 -31
  30. data/lib/azure/storage/file/file.rb +103 -100
  31. data/lib/azure/storage/file/file_service.rb +42 -40
  32. data/lib/azure/storage/file/serialization.rb +9 -6
  33. data/lib/azure/storage/file/share.rb +48 -46
  34. data/lib/azure/storage/queue/message.rb +3 -1
  35. data/lib/azure/storage/queue/queue.rb +3 -2
  36. data/lib/azure/storage/queue/queue_service.rb +152 -151
  37. data/lib/azure/storage/queue/serialization.rb +7 -5
  38. data/lib/azure/storage/service/access_policy.rb +3 -1
  39. data/lib/azure/storage/service/cors.rb +4 -2
  40. data/lib/azure/storage/service/cors_rule.rb +3 -1
  41. data/lib/azure/storage/service/enumeration_results.rb +3 -1
  42. data/lib/azure/storage/service/logging.rb +5 -3
  43. data/lib/azure/storage/service/metrics.rb +5 -3
  44. data/lib/azure/storage/service/retention_policy.rb +3 -1
  45. data/lib/azure/storage/service/serialization.rb +31 -30
  46. data/lib/azure/storage/service/signed_identifier.rb +5 -4
  47. data/lib/azure/storage/service/storage_service.rb +33 -32
  48. data/lib/azure/storage/service/storage_service_properties.rb +6 -4
  49. data/lib/azure/storage/table/auth/shared_key.rb +9 -8
  50. data/lib/azure/storage/table/batch.rb +55 -55
  51. data/lib/azure/storage/table/batch_response.rb +17 -17
  52. data/lib/azure/storage/table/edmtype.rb +9 -7
  53. data/lib/azure/storage/table/entity.rb +4 -3
  54. data/lib/azure/storage/table/guid.rb +3 -1
  55. data/lib/azure/storage/table/query.rb +17 -19
  56. data/lib/azure/storage/table/serialization.rb +14 -12
  57. data/lib/azure/storage/table/table_service.rb +79 -80
  58. data/lib/azure/storage/version.rb +7 -5
  59. metadata +2 -2
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #-------------------------------------------------------------------------
2
4
  # # Copyright (c) Microsoft and contributors. All rights reserved.
3
5
  #
@@ -21,13 +23,13 @@
21
23
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
24
  # THE SOFTWARE.
23
25
  #--------------------------------------------------------------------------
24
- require 'azure/storage/service/serialization'
26
+ require "azure/storage/service/serialization"
25
27
 
26
- require 'azure/storage/blob/container'
27
- require 'azure/storage/blob/blob'
28
- require 'azure/storage/blob/block'
28
+ require "azure/storage/blob/container"
29
+ require "azure/storage/blob/blob"
30
+ require "azure/storage/blob/block"
29
31
 
30
- require 'base64'
32
+ require "base64"
31
33
 
32
34
  module Azure::Storage
33
35
  module Blob
@@ -39,7 +41,7 @@ module Azure::Storage
39
41
  expect_node("EnumerationResults", xml)
40
42
 
41
43
  results = enumeration_results_from_xml(xml, Azure::Service::EnumerationResults.new)
42
-
44
+
43
45
  return results unless (xml > "Containers").any? && ((xml > "Containers") > "Container").any?
44
46
 
45
47
  if xml.Containers.Container.count == 0
@@ -61,6 +63,7 @@ module Azure::Storage
61
63
  container.name = xml.Name.text if (xml > "Name").any?
62
64
  container.properties = container_properties_from_xml(xml.Properties) if (xml > "Properties").any?
63
65
  container.metadata = metadata_from_xml(xml.Metadata) if (xml > "Metadata").any?
66
+ container.public_access_level = public_access_level_from_properties_xml(xml.Properties) if (xml > "Properties").any?
64
67
  end
65
68
  end
66
69
 
@@ -90,7 +93,7 @@ module Azure::Storage
90
93
  def self.container_properties_from_headers(headers)
91
94
  props = {}
92
95
 
93
- props[:last_modified] = headers["Last-Modified"]
96
+ props[:last_modified] = headers["Last-Modified"]
94
97
  props[:etag] = headers["Etag"]
95
98
  props[:lease_status] = headers["x-ms-lease-status"]
96
99
  props[:lease_state] = headers["x-ms-lease-state"]
@@ -103,8 +106,11 @@ module Azure::Storage
103
106
  headers["x-ms-blob-public-access"]
104
107
  end
105
108
 
109
+ def self.public_access_level_from_properties_xml(xml)
110
+ (xml > "PublicAccess").any? ? xml.PublicAccess.text : nil
111
+ end
112
+
106
113
  def self.blob_enumeration_results_from_xml(xml)
107
-
108
114
  xml = slopify(xml)
109
115
  expect_node("EnumerationResults", xml)
110
116
 
@@ -142,7 +148,7 @@ module Azure::Storage
142
148
  name = xml.Name.text if (xml > "Name").any?
143
149
  name
144
150
  end
145
-
151
+
146
152
  def self.blob_from_xml(xml)
147
153
  xml = slopify(xml)
148
154
  expect_node("Blob", xml)
@@ -151,8 +157,11 @@ module Azure::Storage
151
157
  blob.name = xml.Name.text if (xml > "Name").any?
152
158
  blob.snapshot = xml.Snapshot.text if (xml > "Snapshot").any?
153
159
 
154
- blob.properties = blob_properties_from_xml(xml.Properties) if (xml > "Properties").any?
155
160
  blob.metadata = metadata_from_xml(xml.Metadata) if (xml > "Metadata").any?
161
+ if (xml > "Properties").any?
162
+ blob.properties = blob_properties_from_xml(xml.Properties)
163
+ blob.encrypted = xml.Properties.ServerEncrypted.text == "true" if (xml.Properties > "ServerEncrypted").any?
164
+ end
156
165
  end
157
166
  end
158
167
 
@@ -160,6 +169,8 @@ module Azure::Storage
160
169
  Blob.new do |blob|
161
170
  blob.properties = blob_properties_from_headers(headers)
162
171
  blob.metadata = metadata_from_headers(headers)
172
+ blob.encrypted = headers[HeaderConstants::REQUEST_SERVER_ENCRYPTED] || headers[HeaderConstants::SERVER_ENCRYPTED]
173
+ blob.encrypted = blob.encrypted.to_s == "true" unless blob.encrypted.nil?
163
174
  end
164
175
  end
165
176
 
@@ -189,6 +200,7 @@ module Azure::Storage
189
200
  props[:copy_progress] = xml.CopyProgress.text if (xml > "CopyProgress").any?
190
201
  props[:copy_completion_time] = xml.CopyCompletionTime.text if (xml > "CopyCompletionTime").any?
191
202
  props[:copy_status_description] = xml.CopyStatusDescription.text if (xml > "CopyStatusDescription").any?
203
+ props[:incremental_copy] = xml.IncrementalCopy.text == "true" if (xml > "IncrementalCopy").any?
192
204
 
193
205
  props
194
206
  end
@@ -204,12 +216,13 @@ module Azure::Storage
204
216
 
205
217
  props[:content_length] = headers["x-ms-blob-content-length"] || headers["Content-Length"]
206
218
  props[:content_length] = props[:content_length].to_i if props[:content_length]
207
-
219
+
208
220
  props[:content_type] = headers["x-ms-blob-content-type"] || headers["Content-Type"]
209
221
  props[:content_encoding] = headers["x-ms-blob-content-encoding"] || headers["Content-Encoding"]
210
222
  props[:content_language] = headers["x-ms-blob-content-language"] || headers["Content-Language"]
211
223
  props[:content_disposition] = headers["x-ms-blob-content-disposition"] || headers["Content-Disposition"]
212
224
  props[:content_md5] = headers["x-ms-blob-content-md5"] || headers["Content-MD5"]
225
+ props[:range_md5] = headers["Content-MD5"] if headers["x-ms-blob-content-md5"] && headers["Content-MD5"]
213
226
 
214
227
  props[:cache_control] = headers["x-ms-blob-cache-control"] || headers["Cache-Control"]
215
228
  props[:sequence_number] = headers["x-ms-blob-sequence-number"].to_i if headers["x-ms-blob-sequence-number"]
@@ -223,15 +236,16 @@ module Azure::Storage
223
236
  props[:copy_status_description] = headers["x-ms-copy-status-description"]
224
237
 
225
238
  props[:accept_ranges] = headers["Accept-Ranges"].to_i if headers["Accept-Ranges"]
226
-
239
+
227
240
  props[:append_offset] = headers["x-ms-blob-append-offset"].to_i if headers["x-ms-blob-append-offset"]
228
241
  props[:committed_count] = headers["x-ms-blob-committed-block-count"].to_i if headers["x-ms-blob-committed-block-count"]
242
+ props[:incremental_copy] = headers["x-ms-incremental-copy"].to_s == "true" if headers["x-ms-incremental-copy"]
229
243
 
230
244
  props
231
245
  end
232
246
 
233
247
  def self.block_list_to_xml(block_list)
234
- builder = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
248
+ builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
235
249
  xml.BlockList {
236
250
  block_list.each { |block|
237
251
  encoded_id = Base64.strict_encode64(block[0])
@@ -253,9 +267,9 @@ module Azure::Storage
253
267
  xml = slopify(xml)
254
268
  expect_node("BlockList", xml)
255
269
 
256
- block_list = {
257
- :committed => [],
258
- :uncommitted => []
270
+ block_list = {
271
+ committed: [],
272
+ uncommitted: []
259
273
  }
260
274
 
261
275
  if ((xml > "CommittedBlocks") > "Block").any?
@@ -291,7 +305,7 @@ module Azure::Storage
291
305
  end
292
306
  block_list[type].push block
293
307
  end
294
-
308
+
295
309
  def self.page_list_from_xml(xml)
296
310
  xml = slopify(xml)
297
311
  expect_node("PageList", xml)
@@ -312,4 +326,4 @@ module Azure::Storage
312
326
  end
313
327
  end
314
328
  end
315
- end
329
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #-------------------------------------------------------------------------
2
4
  # # Copyright (c) Microsoft and contributors. All rights reserved.
3
5
  #
@@ -22,16 +24,16 @@
22
24
  # THE SOFTWARE.
23
25
  #--------------------------------------------------------------------------
24
26
 
25
- require 'azure/storage/core'
26
- require 'azure/storage/core/http_client'
27
+ require "azure/storage/core"
28
+ require "azure/storage/core/http_client"
27
29
 
28
- require 'azure/storage/client_options'
30
+ require "azure/storage/client_options"
29
31
 
30
- require 'azure/storage/service/storage_service'
31
- require 'azure/storage/blob/blob_service'
32
- require 'azure/storage/table/table_service'
33
- require 'azure/storage/queue/queue_service'
34
- require 'azure/storage/file/file_service'
32
+ require "azure/storage/service/storage_service"
33
+ require "azure/storage/blob/blob_service"
34
+ require "azure/storage/table/table_service"
35
+ require "azure/storage/queue/queue_service"
36
+ require "azure/storage/file/file_service"
35
37
 
36
38
  module Azure::Storage
37
39
  class Client
@@ -81,7 +83,7 @@ module Azure::Storage
81
83
  #
82
84
  # @return [Azure::Storage::Client]
83
85
  def initialize(options = {}, &block)
84
- if options.is_a?(Hash) and options.has_key?(:user_agent_prefix)
86
+ if options.is_a?(Hash) && options.has_key?(:user_agent_prefix)
85
87
  Azure::Storage::Service::StorageService.user_agent_prefix = options[:user_agent_prefix]
86
88
  options.delete :user_agent_prefix
87
89
  end
@@ -154,7 +156,7 @@ module Azure::Storage
154
156
  # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::ClientOptions.env_vars_mapping] for the mapping relationship
155
157
  #
156
158
  # @return [Azure::Storage::Client]
157
- def create(options={}, &block)
159
+ def create(options = {}, &block)
158
160
  Client.new(options, &block)
159
161
  end
160
162
 
@@ -165,9 +167,9 @@ module Azure::Storage
165
167
  # * +proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
166
168
  #
167
169
  # @return [Azure::Storage::Client]
168
- def create_development(proxy_uri=nil, &block)
170
+ def create_development(proxy_uri = nil, &block)
169
171
  proxy_uri ||= StorageServiceClientConstants::DEV_STORE_URI
170
- create(:use_development_storage => true, :development_storage_proxy_uri => proxy_uri, &block)
172
+ create(use_development_storage: true, development_storage_proxy_uri: proxy_uri, &block)
171
173
  end
172
174
 
173
175
  # Public: Creates an instance of [Azure::Storage::Client] from Environment Variables
@@ -191,9 +193,8 @@ module Azure::Storage
191
193
 
192
194
  private
193
195
 
194
- def default_client(opts)
195
- !opts.empty? ? {client: Azure::Storage.client(opts)} : {client: self}
196
- end
197
-
196
+ def default_client(opts)
197
+ !opts.empty? ? { client: Azure::Storage.client(opts) } : { client: self }
198
+ end
198
199
  end
199
- end
200
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #-------------------------------------------------------------------------
2
4
  # # Copyright (c) Microsoft and contributors. All rights reserved.
3
5
  #
@@ -22,12 +24,11 @@
22
24
  # THE SOFTWARE.
23
25
  #--------------------------------------------------------------------------
24
26
 
25
- require 'uri'
26
- require 'azure/storage/client_options_error'
27
+ require "uri"
28
+ require "azure/storage/client_options_error"
27
29
 
28
30
  module Azure::Storage
29
31
  module ClientOptions
30
-
31
32
  attr_accessor :ca_file
32
33
 
33
34
  # Public: Reset options for [Azure::Storage::Client]
@@ -75,7 +76,7 @@ module Azure::Storage
75
76
  elsif options.is_a? Hash
76
77
  # When the options are provided via singlton setup: Azure::Storage.setup()
77
78
  options = setup_options if options.length == 0
78
-
79
+
79
80
  options = parse_connection_string(options[:storage_connection_string]) if options[:storage_connection_string]
80
81
  end
81
82
 
@@ -90,7 +91,7 @@ module Azure::Storage
90
91
 
91
92
  # Check if this client is configured with the same options
92
93
  def same_options?(opts)
93
- opts.length == 0 || opts.hash == options.hash
94
+ opts.length == 0 || opts.hash == options.hash
94
95
  end
95
96
 
96
97
  # The options after validated and normalized
@@ -126,16 +127,16 @@ module Azure::Storage
126
127
  # @return [Hash]
127
128
  def self.env_vars_mapping
128
129
  @env_vars_mapping ||= {
129
- 'EMULATED' => :use_development_storage,
130
- 'AZURE_STORAGE_ACCOUNT' => :storage_account_name,
131
- 'AZURE_STORAGE_ACCESS_KEY' => :storage_access_key,
132
- 'AZURE_STORAGE_CONNECTION_STRING' => :storage_connection_string,
133
- 'AZURE_STORAGE_BLOB_HOST' => :storage_blob_host,
134
- 'AZURE_STORAGE_TABLE_HOST' => :storage_table_host,
135
- 'AZURE_STORAGE_QUEUE_HOST' => :storage_queue_host,
136
- 'AZURE_STORAGE_FILE_HOST' => :storage_file_host,
137
- 'AZURE_STORAGE_SAS_TOKEN' => :storage_sas_token,
138
- 'AZURE_STORAGE_DNS_SUFFIX' => :storage_dns_suffix
130
+ "EMULATED" => :use_development_storage,
131
+ "AZURE_STORAGE_ACCOUNT" => :storage_account_name,
132
+ "AZURE_STORAGE_ACCESS_KEY" => :storage_access_key,
133
+ "AZURE_STORAGE_CONNECTION_STRING" => :storage_connection_string,
134
+ "AZURE_STORAGE_BLOB_HOST" => :storage_blob_host,
135
+ "AZURE_STORAGE_TABLE_HOST" => :storage_table_host,
136
+ "AZURE_STORAGE_QUEUE_HOST" => :storage_queue_host,
137
+ "AZURE_STORAGE_FILE_HOST" => :storage_file_host,
138
+ "AZURE_STORAGE_SAS_TOKEN" => :storage_sas_token,
139
+ "AZURE_STORAGE_DNS_SUFFIX" => :storage_dns_suffix
139
140
  }
140
141
  end
141
142
 
@@ -144,211 +145,209 @@ module Azure::Storage
144
145
  # @return [Hash]
145
146
  def self.connection_string_mapping
146
147
  @connection_string_mapping ||= {
147
- 'UseDevelopmentStorage' => :use_development_storage,
148
- 'DevelopmentStorageProxyUri' => :development_storage_proxy_uri,
149
- 'DefaultEndpointsProtocol' => :default_endpoints_protocol,
150
- 'AccountName' => :storage_account_name,
151
- 'AccountKey' => :storage_access_key,
152
- 'BlobEndpoint' => :storage_blob_host,
153
- 'TableEndpoint' => :storage_table_host,
154
- 'QueueEndpoint' => :storage_queue_host,
155
- 'FileEndpoint' => :storage_file_host,
156
- 'SharedAccessSignature' => :storage_sas_token,
157
- 'EndpointSuffix' => :storage_dns_suffix
148
+ "UseDevelopmentStorage" => :use_development_storage,
149
+ "DevelopmentStorageProxyUri" => :development_storage_proxy_uri,
150
+ "DefaultEndpointsProtocol" => :default_endpoints_protocol,
151
+ "AccountName" => :storage_account_name,
152
+ "AccountKey" => :storage_access_key,
153
+ "BlobEndpoint" => :storage_blob_host,
154
+ "TableEndpoint" => :storage_table_host,
155
+ "QueueEndpoint" => :storage_queue_host,
156
+ "FileEndpoint" => :storage_file_host,
157
+ "SharedAccessSignature" => :storage_sas_token,
158
+ "EndpointSuffix" => :storage_dns_suffix
158
159
  }
159
160
  end
160
161
 
161
162
  private
162
163
 
163
- def method_missing(method_name)
164
- return super unless options.key? method_name
165
- options[method_name]
166
- end
167
-
168
- def filter(opts={})
169
- results = {}
170
-
171
- # P1 - develpoment storage
172
- begin
173
- results = validated_options(opts,
174
- :required => [:use_development_storage],
175
- :optional => [:development_storage_proxy_uri])
176
- results[:use_development_storage] = true
177
- proxy_uri = results[:development_storage_proxy_uri] ||= StorageServiceClientConstants::DEV_STORE_URI
178
- results.merge!({:storage_account_name => StorageServiceClientConstants::DEVSTORE_STORAGE_ACCOUNT,
179
- :storage_access_key => StorageServiceClientConstants::DEVSTORE_STORAGE_ACCESS_KEY,
180
- :storage_blob_host => "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_BLOB_HOST_PORT}",
181
- :storage_table_host => "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_TABLE_HOST_PORT}",
182
- :storage_queue_host => "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_QUEUE_HOST_PORT}",
183
- :storage_file_host => "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_FILE_HOST_PORT}",
184
- :use_path_style_uri => true})
185
- return results
186
- rescue InvalidOptionsError => e
187
- end
188
-
189
- # P2 - explicit hosts with account connection string
190
- begin
191
- results = validated_options(opts,
192
- :required => [:storage_connection_string],
193
- :optional => [:use_path_style_uri])
194
- results[:use_path_style_uri] = results.key?(:use_path_style_uri)
195
- normalize_hosts(results)
196
- return results
197
- rescue InvalidOptionsError => e
164
+ def method_missing(method_name)
165
+ return super unless options.key? method_name
166
+ options[method_name]
198
167
  end
199
168
 
200
- # P3 - account name and key or sas with default hosts or an end suffix
201
- begin
202
- results = validated_options(opts,
203
- :required => [:storage_account_name],
204
- :only_one => [:storage_access_key, :storage_sas_token],
205
- :optional => [:default_endpoints_protocol, :storage_dns_suffix])
206
- protocol = results[:default_endpoints_protocol] ||= StorageServiceClientConstants::DEFAULT_PROTOCOL
207
- suffix = results[:storage_dns_suffix] ||= StorageServiceClientConstants::DEFAULT_ENDPOINT_SUFFIX
208
- account = results[:storage_account_name]
209
- results.merge!({:storage_blob_host => "#{protocol}://#{account}.#{ServiceType::BLOB}.#{suffix}",
210
- :storage_table_host => "#{protocol}://#{account}.#{ServiceType::TABLE}.#{suffix}",
211
- :storage_queue_host => "#{protocol}://#{account}.#{ServiceType::QUEUE}.#{suffix}",
212
- :storage_file_host => "#{protocol}://#{account}.#{ServiceType::FILE}.#{suffix}",
213
- :use_path_style_uri => false})
214
- return results
215
- rescue InvalidOptionsError => e
216
- end
169
+ def filter(opts = {})
170
+ results = {}
171
+
172
+ # P1 - develpoment storage
173
+ begin
174
+ results = validated_options(opts,
175
+ required: [:use_development_storage],
176
+ optional: [:development_storage_proxy_uri])
177
+ results[:use_development_storage] = true
178
+ proxy_uri = results[:development_storage_proxy_uri] ||= StorageServiceClientConstants::DEV_STORE_URI
179
+ results.merge!(storage_account_name: StorageServiceClientConstants::DEVSTORE_STORAGE_ACCOUNT,
180
+ storage_access_key: StorageServiceClientConstants::DEVSTORE_STORAGE_ACCESS_KEY,
181
+ storage_blob_host: "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_BLOB_HOST_PORT}",
182
+ storage_table_host: "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_TABLE_HOST_PORT}",
183
+ storage_queue_host: "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_QUEUE_HOST_PORT}",
184
+ storage_file_host: "#{proxy_uri}:#{StorageServiceClientConstants::DEVSTORE_FILE_HOST_PORT}",
185
+ use_path_style_uri: true)
186
+ return results
187
+ rescue InvalidOptionsError => e
188
+ end
217
189
 
218
- # P4 - explicit hosts with account name and key
219
- begin
220
- results = validated_options(opts,
221
- :required => [:storage_account_name, :storage_access_key],
222
- :at_least_one => [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host],
223
- :optional => [:use_path_style_uri, :default_endpoints_protocol])
224
- results[:use_path_style_uri] = results.key?(:use_path_style_uri)
225
- normalize_hosts(results)
226
- return results
227
- rescue InvalidOptionsError => e
228
- end
190
+ # P2 - explicit hosts with account connection string
191
+ begin
192
+ results = validated_options(opts,
193
+ required: [:storage_connection_string],
194
+ optional: [:use_path_style_uri])
195
+ results[:use_path_style_uri] = results.key?(:use_path_style_uri)
196
+ normalize_hosts(results)
197
+ return results
198
+ rescue InvalidOptionsError => e
199
+ end
229
200
 
230
- # P5 - anonymous or sas only for one or more particular services, options with account name/key + hosts should be already validated in P4
231
- begin
232
- results = validated_options(opts,
233
- :at_least_one => [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host],
234
- :optional => [:use_path_style_uri, :default_endpoints_protocol, :storage_sas_token])
235
- results[:use_path_style_uri] = results.key?(:use_path_style_uri)
236
- normalize_hosts(results)
237
- return results
238
- rescue InvalidOptionsError => e
239
- end
201
+ # P3 - account name and key or sas with default hosts or an end suffix
202
+ begin
203
+ results = validated_options(opts,
204
+ required: [:storage_account_name],
205
+ only_one: [:storage_access_key, :storage_sas_token],
206
+ optional: [:default_endpoints_protocol, :storage_dns_suffix])
207
+ protocol = results[:default_endpoints_protocol] ||= StorageServiceClientConstants::DEFAULT_PROTOCOL
208
+ suffix = results[:storage_dns_suffix] ||= StorageServiceClientConstants::DEFAULT_ENDPOINT_SUFFIX
209
+ account = results[:storage_account_name]
210
+ results.merge!(storage_blob_host: "#{protocol}://#{account}.#{ServiceType::BLOB}.#{suffix}",
211
+ storage_table_host: "#{protocol}://#{account}.#{ServiceType::TABLE}.#{suffix}",
212
+ storage_queue_host: "#{protocol}://#{account}.#{ServiceType::QUEUE}.#{suffix}",
213
+ storage_file_host: "#{protocol}://#{account}.#{ServiceType::FILE}.#{suffix}",
214
+ use_path_style_uri: false)
215
+ return results
216
+ rescue InvalidOptionsError => e
217
+ end
240
218
 
241
- # P6 - account name and key or sas with explicit hosts
242
- begin
243
- results = validated_options(opts,
244
- :required => [:storage_account_name],
245
- :only_one => [:storage_access_key, :storage_sas_token],
246
- :at_least_one => [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host])
247
- results[:use_path_style_uri] = results.key?(:use_path_style_uri)
248
- normalize_hosts(results)
249
- return results
250
- rescue InvalidOptionsError => e
251
- end
219
+ # P4 - explicit hosts with account name and key
220
+ begin
221
+ results = validated_options(opts,
222
+ required: [:storage_account_name, :storage_access_key],
223
+ at_least_one: [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host],
224
+ optional: [:use_path_style_uri, :default_endpoints_protocol])
225
+ results[:use_path_style_uri] = results.key?(:use_path_style_uri)
226
+ normalize_hosts(results)
227
+ return results
228
+ rescue InvalidOptionsError => e
229
+ end
252
230
 
253
- raise InvalidOptionsError,"options provided are not valid set: #{opts}" # wrong opts if move to this line
254
- end
231
+ # P5 - anonymous or sas only for one or more particular services, options with account name/key + hosts should be already validated in P4
232
+ begin
233
+ results = validated_options(opts,
234
+ at_least_one: [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host],
235
+ optional: [:use_path_style_uri, :default_endpoints_protocol, :storage_sas_token])
236
+ results[:use_path_style_uri] = results.key?(:use_path_style_uri)
237
+ normalize_hosts(results)
238
+ return results
239
+ rescue InvalidOptionsError => e
240
+ end
255
241
 
256
- def normalize_hosts(options)
257
- if options[:default_endpoints_protocol]
258
- [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host].each do |k|
259
- if options[k]
260
- raise InvalidOptionsError,'Explict host cannot contain scheme if default_endpoints_protocol is set.' if options[k] =~ /^https?/
261
- options[k] = "#{options[:default_endpoints_protocol]}://#{options[k]}"
262
- end
242
+ # P6 - account name and key or sas with explicit hosts
243
+ begin
244
+ results = validated_options(opts,
245
+ required: [:storage_account_name],
246
+ only_one: [:storage_access_key, :storage_sas_token],
247
+ at_least_one: [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host])
248
+ results[:use_path_style_uri] = results.key?(:use_path_style_uri)
249
+ normalize_hosts(results)
250
+ return results
251
+ rescue InvalidOptionsError => e
263
252
  end
264
- end
265
- end
266
253
 
267
- def is_base64_encoded
268
- Proc.new do |i|
269
- i.is_a?(String) && i =~ /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$/
254
+ raise InvalidOptionsError, "options provided are not valid set: #{opts}" # wrong opts if move to this line
270
255
  end
271
- end
272
256
 
273
- def is_url
274
- Proc.new do |i|
275
- i = 'http://'+i unless i =~ /\Ahttps?:\/\//
276
- i =~ URI.regexp(['http', 'https'])
257
+ def normalize_hosts(options)
258
+ if options[:default_endpoints_protocol]
259
+ [:storage_blob_host, :storage_table_host, :storage_file_host, :storage_queue_host].each do |k|
260
+ if options[k]
261
+ raise InvalidOptionsError, "Explict host cannot contain scheme if default_endpoints_protocol is set." if options[k] =~ /^https?/
262
+ options[k] = "#{options[:default_endpoints_protocol]}://#{options[k]}"
263
+ end
264
+ end
265
+ end
277
266
  end
278
- end
279
267
 
280
- def is_true
281
- Proc.new { |i| i == true || (i.is_a?(String) && i.downcase == 'true') }
282
- end
268
+ def is_base64_encoded
269
+ Proc.new do |i|
270
+ i.is_a?(String) && i =~ /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$/
271
+ end
272
+ end
283
273
 
284
- def is_non_empty_string
285
- Proc.new { |i| i && i.is_a?(String) && i.strip.length }
286
- end
274
+ def is_url
275
+ Proc.new do |i|
276
+ i = "http://" + i unless i =~ /\Ahttps?:\/\//
277
+ i =~ URI.regexp(["http", "https"])
278
+ end
279
+ end
287
280
 
288
- def validated_options(opts, requirements = {})
289
- raise InvalidOptionsError,'nil is not allowed for option\'s value' if opts.values.any? { |v| v == nil }
290
- required = requirements[:required] || []
291
- at_least_one = requirements[:at_least_one] || []
292
- only_one = requirements[:only_one] || []
293
- optional = requirements[:optional] || []
294
-
295
- raise InvalidOptionsError,"Not all required keys are provided: #{required}" if required.any? { |k| !opts.key? k}
296
- raise InvalidOptionsError,"Only one of #{only_one} is required" unless only_one.length == 0 || only_one.count { |k| opts.key? k} == 1
297
- raise InvalidOptionsError,"At least one of #{at_least_one} is required" unless at_least_one.length == 0 || at_least_one.any? { |k| opts.key? k}
298
-
299
- @@option_validators ||= {
300
- :use_development_storage => is_true,
301
- :development_storage_proxy_uri => is_url,
302
- :storage_account_name => lambda { |i| i.is_a?(String) },
303
- :storage_access_key => is_base64_encoded,
304
- :storage_sas_token => lambda { |i| i.is_a?(String) },
305
- :storage_blob_host => is_url,
306
- :storage_table_host => is_url,
307
- :storage_queue_host => is_url,
308
- :storage_file_host => is_url,
309
- :storage_dns_suffix => is_url,
310
- :default_endpoints_protocol => lambda { |i| ['http', 'https'].include? i.downcase },
311
- :use_path_style_uri => is_true
312
- }
281
+ def is_true
282
+ Proc.new { |i| i == true || (i.is_a?(String) && i.downcase == "true") }
283
+ end
313
284
 
314
- valid_options = required + at_least_one + only_one + optional
315
- results = {}
285
+ def is_non_empty_string
286
+ Proc.new { |i| i && i.is_a?(String) && i.strip.length }
287
+ end
316
288
 
317
- opts.each do |k,v|
318
- raise InvalidOptionsError,"#{k} is not included in valid options" unless valid_options.length == 0 || valid_options.include?(k)
319
- unless @@option_validators.key?(k) && @@option_validators[k].call(v)
320
- raise InvalidOptionsError,"#{k} is invalid"
289
+ def validated_options(opts, requirements = {})
290
+ raise InvalidOptionsError, 'nil is not allowed for option\'s value' if opts.values.any? { |v| v == nil }
291
+ required = requirements[:required] || []
292
+ at_least_one = requirements[:at_least_one] || []
293
+ only_one = requirements[:only_one] || []
294
+ optional = requirements[:optional] || []
295
+
296
+ raise InvalidOptionsError, "Not all required keys are provided: #{required}" if required.any? { |k| !opts.key? k }
297
+ raise InvalidOptionsError, "Only one of #{only_one} is required" unless only_one.length == 0 || only_one.count { |k| opts.key? k } == 1
298
+ raise InvalidOptionsError, "At least one of #{at_least_one} is required" unless at_least_one.length == 0 || at_least_one.any? { |k| opts.key? k }
299
+
300
+ @@option_validators ||= {
301
+ use_development_storage: is_true,
302
+ development_storage_proxy_uri: is_url,
303
+ storage_account_name: lambda { |i| i.is_a?(String) },
304
+ storage_access_key: is_base64_encoded,
305
+ storage_sas_token: lambda { |i| i.is_a?(String) },
306
+ storage_blob_host: is_url,
307
+ storage_table_host: is_url,
308
+ storage_queue_host: is_url,
309
+ storage_file_host: is_url,
310
+ storage_dns_suffix: is_url,
311
+ default_endpoints_protocol: lambda { |i| ["http", "https"].include? i.downcase },
312
+ use_path_style_uri: is_true
313
+ }
314
+
315
+ valid_options = required + at_least_one + only_one + optional
316
+ results = {}
317
+
318
+ opts.each do |k, v|
319
+ raise InvalidOptionsError, "#{k} is not included in valid options" unless valid_options.length == 0 || valid_options.include?(k)
320
+ unless @@option_validators.key?(k) && @@option_validators[k].call(v)
321
+ raise InvalidOptionsError, "#{k} is invalid"
322
+ end
323
+ results[k] = v
321
324
  end
322
- results[k] = v
325
+ results
323
326
  end
324
- results
325
- end
326
-
327
- def load_env
328
- cs = ENV['AZURE_STORAGE_CONNECTION_STRING']
329
- return parse_connection_string(cs) if cs
330
327
 
331
- opts = {}
332
- ClientOptions.env_vars_mapping.each { |k,v| opts[v] = ENV[k] if ENV[k] }
333
- opts
334
- end
328
+ def load_env
329
+ cs = ENV["AZURE_STORAGE_CONNECTION_STRING"]
330
+ return parse_connection_string(cs) if cs
335
331
 
336
- def parse_connection_string(connection_string)
337
- opts = {}
338
- connection_string.split(';').each do |i|
339
- e = i.index('=')
340
- raise InvalidConnectionStringError,SR::INVALID_CONNECTION_STRING if e < 0 || e == i.length - 1
341
- key,value = i[0..e-1],i[e+1..i.length-1]
342
- raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_BAD_KEY % key unless ClientOptions.connection_string_mapping.key? key
343
- raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_EMPTY_KEY % key if value.length == 0
344
- raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_DUPLICATE_KEY % key if opts.key? key
345
- opts[ClientOptions.connection_string_mapping[key]] = value
332
+ opts = {}
333
+ ClientOptions.env_vars_mapping.each { |k, v| opts[v] = ENV[k] if ENV[k] }
334
+ opts
346
335
  end
347
- raise InvalidConnectionStringError,SR::INVALID_CONNECTION_STRING if opts.length == 0
348
336
 
349
- opts
350
- end
337
+ def parse_connection_string(connection_string)
338
+ opts = {}
339
+ connection_string.split(";").each do |i|
340
+ e = i.index("=")
341
+ raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING if e < 0 || e == i.length - 1
342
+ key, value = i[0..e - 1], i[e + 1..i.length - 1]
343
+ raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_BAD_KEY % key unless ClientOptions.connection_string_mapping.key? key
344
+ raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_EMPTY_KEY % key if value.length == 0
345
+ raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING_DUPLICATE_KEY % key if opts.key? key
346
+ opts[ClientOptions.connection_string_mapping[key]] = value
347
+ end
348
+ raise InvalidConnectionStringError, SR::INVALID_CONNECTION_STRING if opts.length == 0
351
349
 
350
+ opts
351
+ end
352
352
  end
353
-
354
- end
353
+ end