diff --git a/ChangeLog.md b/ChangeLog.md index 0a277c77..a4875128 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,13 @@ +2016.09 - version 0.11.1-preview + +ALL +* Added the support for setting the client request ID via the "request_id" parameter. +* Added the retry for the timeout errors. +* Added the retry for the connection reset error. + +BLOB +* Fixed the issue where "list_blobs" doesn't work when delimiter is specified. (https://github.com/Azure/azure-storage-ruby/issues/41) + 2016.08 - version 0.11.0-preview ALL diff --git a/lib/azure/storage/blob/append.rb b/lib/azure/storage/blob/append.rb index 3cc23998..f0e3913d 100644 --- a/lib/azure/storage/blob/append.rb +++ b/lib/azure/storage/blob/append.rb @@ -47,6 +47,8 @@ module Blob # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -69,7 +71,7 @@ def create_append_blob(container, blob, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers # set x-ms-blob-type to AppendBlob StorageService.with_header headers, 'x-ms-blob-type', 'AppendBlob' @@ -90,7 +92,7 @@ def create_append_blob(container, blob, options={}) add_blob_conditional_headers options, headers # call PutBlob with empty body - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -116,6 +118,8 @@ def create_append_blob(container, blob, options={}) # * +:max_size+ - Integer. The max length in bytes permitted for the append blob # * +:append_position+ - Integer. A number indicating the byte offset to compare. It will succeed only if the append position is equal to this number # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to append a block only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -138,13 +142,13 @@ def append_blob_block(container, blob, content, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'Content-MD5', options[:content_md5] StorageService.with_header headers, 'x-ms-lease-id', options[:lease_id] add_blob_conditional_headers options, headers - response = call(:put, uri, content, headers) + response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob diff --git a/lib/azure/storage/blob/blob.rb b/lib/azure/storage/blob/blob.rb index 8377c259..c782339d 100644 --- a/lib/azure/storage/blob/blob.rb +++ b/lib/azure/storage/blob/blob.rb @@ -56,6 +56,8 @@ def initialize # * +:get_content_md5+ - Boolean. Return the MD5 hash for the range. This option only valid if # start_range and end_range are specified. (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -78,7 +80,7 @@ def get_blob(container, blob, options={}) StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers options[:start_range] = 0 if options[:end_range] and not options[:start_range] if options[:start_range] StorageService.with_header headers, 'x-ms-range', "bytes=#{options[:start_range]}-#{options[:end_range]}" @@ -86,7 +88,7 @@ def get_blob(container, blob, options={}) end add_blob_conditional_headers options, headers - response = call(:get, uri, nil, headers) + response = call(:get, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob unless result.name return result, response.body @@ -106,6 +108,8 @@ def get_blob(container, blob, options={}) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -127,14 +131,14 @@ def get_blob_properties(container, blob, options={}) StorageService.with_query query, 'snapshot', options[:snapshot] StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] - headers = StorageService.service_properties_headers + headers = StorageService.common_headers unless options.empty? add_blob_conditional_headers options, headers end uri = blob_uri(container, blob, query) - response = call(:head, uri, nil, headers) + response = call(:head, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) @@ -195,6 +199,8 @@ def get_blob_properties(container, blob, options={}) # To set the sequence number to a value of your choosing, this property must be specified # together with :sequence_number_action # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -241,7 +247,7 @@ def set_blob_properties(container, blob, options={}) StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers unless options.empty? StorageService.with_header headers, 'x-ms-blob-content-type', options[:content_type] @@ -263,7 +269,7 @@ def set_blob_properties(container, blob, options={}) add_blob_conditional_headers options, headers end - call(:put, uri, nil, headers) + call(:put, uri, nil, headers, options) nil end @@ -281,6 +287,8 @@ def set_blob_properties(container, blob, options={}) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to get the blob metadata # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -302,13 +310,13 @@ def get_blob_metadata(container, blob, options={}) StorageService.with_query query, 'snapshot', options[:snapshot] StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] - headers = StorageService.service_properties_headers + headers = StorageService.common_headers unless options.empty? add_blob_conditional_headers options, headers end uri = blob_uri(container, blob, query) - response = call(:get, uri, nil, headers) + response = call(:get, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -330,6 +338,8 @@ def get_blob_metadata(container, blob, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob metadata # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -352,13 +362,13 @@ def set_blob_metadata(container, blob, metadata, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.add_metadata_to_headers metadata, headers unless options.empty? add_blob_conditional_headers options, headers end - call(:put, uri, nil, headers) + call(:put, uri, nil, headers, options) nil end @@ -379,6 +389,8 @@ def set_blob_metadata(container, blob, metadata, options={}) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -417,6 +429,8 @@ def acquire_blob_lease(container, blob, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -451,6 +465,8 @@ def renew_blob_lease(container, blob, lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -485,6 +501,8 @@ def change_blob_lease(container, blob, lease, proposed_lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -531,6 +549,8 @@ def release_blob_lease(container, blob, lease, options={}) # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -565,6 +585,8 @@ def break_blob_lease(container, blob, options={}) # Accepted key/value pairs in options parameter are: # * +:metadata+ - Hash. Custom metadata values to store with the blob snapshot. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -587,13 +609,13 @@ def create_blob_snapshot(container, blob, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers unless options.empty? StorageService.add_metadata_to_headers(options[:metadata], headers) add_blob_conditional_headers(options, headers) end - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) response.headers['x-ms-snapshot'] end @@ -640,6 +662,8 @@ def create_blob_snapshot(container, blob, options={}) # blob's ETag value does not match the value specified. If the values are # identical, the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd894037.aspx # @@ -656,7 +680,7 @@ def copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] uri = blob_uri(destination_container, destination_blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-copy-source', source_blob_uri unless options.empty? @@ -664,7 +688,7 @@ def copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, StorageService.add_metadata_to_headers options[:metadata], headers end - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) return response.headers['x-ms-copy-id'], response.headers['x-ms-copy-status'] end @@ -711,6 +735,8 @@ def copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, # blob's ETag value does not match the value specified. If the values are # identical, the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd894037.aspx # @@ -742,6 +768,8 @@ def copy_blob(destination_container, destination_blob, source_container, source_ # Accepted key/value pairs in options parameter are: # * +:lease_id+ - String. The lease id if the destination blob has an active infinite lease # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx # @@ -752,14 +780,14 @@ def abort_copy_blob(container, blob, copy_id, options={}) StorageService.with_query query, 'copyid', copy_id uri = blob_uri(container, blob, query); - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-copy-action', 'abort'; unless options.empty? StorageService.with_header headers, 'x-ms-lease-id', options[:lease_id] end - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) nil end @@ -784,6 +812,8 @@ def abort_copy_blob(container, blob, copy_id, options={}) # * +:only+ - Deletes only the snapshots for the blob, but leaves the blob # * +:include+ - Deletes the blob and all of the snapshots for the blob # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create the blob snapshot # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -809,11 +839,11 @@ def delete_blob(container, blob, options={}) options[:delete_snapshots] = :include unless options[:delete_snapshots] - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-delete-snapshots', options[:delete_snapshots].to_s if options[:delete_snapshots] && options[:snapshot] == nil add_blob_conditional_headers options, headers - call(:delete, uri, nil, headers) + call(:delete, uri, nil, headers, options) nil end diff --git a/lib/azure/storage/blob/blob_service.rb b/lib/azure/storage/blob/blob_service.rb index 62192f4e..01ff4bc6 100644 --- a/lib/azure/storage/blob/blob_service.rb +++ b/lib/azure/storage/blob/blob_service.rb @@ -44,7 +44,7 @@ def initialize(options = {}) @host = client.storage_blob_host end - def call(method, uri, body=nil, headers={}) + def call(method, uri, body=nil, headers={}, options={}) # Force the request.body to the content encoding of specified in the header # (content encoding probably shouldn't be used this way) if headers && !body.nil? @@ -96,6 +96,9 @@ def call(method, uri, body=nil, headers={}) # # * +:timeout+ - Integer. A timeout in seconds. # + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. + # # NOTE: Metadata requested with the :metadata parameter must have been stored in # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob # service. Beginning with that version, all metadata names must adhere to the naming @@ -120,7 +123,7 @@ def list_containers(options={}) end uri = containers_uri(query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) Serialization.container_enumeration_results_from_xml(response.body) end @@ -142,6 +145,8 @@ def list_containers(options={}) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -174,13 +179,13 @@ def acquire_lease(container, blob, options={}) duration = -1 duration = options[:duration] if options[:duration] - headers = Service::StorageService.service_properties_headers + headers = Service::StorageService.common_headers Service::StorageService.with_header headers, 'x-ms-lease-action', 'acquire' Service::StorageService.with_header headers, 'x-ms-lease-duration', duration.to_s if duration Service::StorageService.with_header headers, 'x-ms-proposed-lease-id', options[:proposed_lease_id] add_blob_conditional_headers options, headers - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) response.headers['x-ms-lease-id'] end @@ -200,6 +205,8 @@ def acquire_lease(container, blob, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -228,12 +235,12 @@ def renew_lease(container, blob, lease, options={}) uri = container_uri(container, query) end - headers = Service::StorageService.service_properties_headers + headers = Service::StorageService.common_headers Service::StorageService.with_header headers, 'x-ms-lease-action', 'renew' Service::StorageService.with_header headers, 'x-ms-lease-id', lease add_blob_conditional_headers options, headers - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) response.headers['x-ms-lease-id'] end @@ -252,6 +259,8 @@ def renew_lease(container, blob, lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -281,13 +290,13 @@ def change_lease(container, blob, lease, proposed_lease, options={}) uri = container_uri(container, query) end - headers = Service::StorageService.service_properties_headers + headers = Service::StorageService.common_headers Service::StorageService.with_header headers, 'x-ms-lease-action', 'change' Service::StorageService.with_header headers, 'x-ms-lease-id', lease Service::StorageService.with_header headers, 'x-ms-proposed-lease-id', proposed_lease add_blob_conditional_headers options, headers - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) response.headers['x-ms-lease-id'] end @@ -306,6 +315,8 @@ def change_lease(container, blob, lease, proposed_lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -334,12 +345,12 @@ def release_lease(container, blob, lease, options={}) uri = container_uri(container, query) end - headers = Service::StorageService.service_properties_headers + headers = Service::StorageService.common_headers Service::StorageService.with_header headers, 'x-ms-lease-action', 'release' Service::StorageService.with_header headers, 'x-ms-lease-id', lease add_blob_conditional_headers options, headers - call(:put, uri, nil, headers) + call(:put, uri, nil, headers, options) nil end @@ -370,6 +381,8 @@ def release_lease(container, blob, lease, options={}) # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -400,12 +413,12 @@ def break_lease(container, blob, options={}) uri = container_uri(container, query) end - headers = Service::StorageService.service_properties_headers + headers = Service::StorageService.common_headers Service::StorageService.with_header headers, 'x-ms-lease-action', 'break' Service::StorageService.with_header headers, 'x-ms-lease-break-period', options[:break_period].to_s if options[:break_period] add_blob_conditional_headers options, headers - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) response.headers['x-ms-lease-time'].to_i end diff --git a/lib/azure/storage/blob/block.rb b/lib/azure/storage/blob/block.rb index 1412fc73..87d77b62 100644 --- a/lib/azure/storage/blob/block.rb +++ b/lib/azure/storage/blob/block.rb @@ -69,6 +69,8 @@ def initialize # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -91,7 +93,7 @@ def create_block_blob(container, blob, content, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers # set x-ms-blob-type to BlockBlob StorageService.with_header headers, 'x-ms-blob-type', 'BlockBlob' @@ -109,7 +111,7 @@ def create_block_blob(container, blob, content, options={}) add_blob_conditional_headers options, headers # call PutBlob with empty body - response = call(:put, uri, content, headers) + response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -132,6 +134,8 @@ def create_block_blob(container, blob, content, options={}) # Accepted key/value pairs in options parameter are: # * +:content_md5+ - String. Content MD5 for the request contents. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd135726.aspx # @@ -143,10 +147,10 @@ def put_blob_block(container, blob, block_id, content, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'Content-MD5', options[:content_md5] - response = call(:put, uri, content, headers) + response = call(:put, uri, content, headers, options) response.headers['Content-MD5'] end @@ -186,6 +190,8 @@ def put_blob_block(container, blob, block_id, content, options={}) # and also can be used to attach additional metadata # * +:metadata+ - Hash. Custom metadata values to store with the blob. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # This operation also supports the use of conditional headers to commit the block list if a specified condition is met. # For more information, see https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx @@ -199,7 +205,7 @@ def commit_blob_blocks(container, blob, block_list, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers unless options.empty? StorageService.with_header headers, 'Content-MD5', options[:transactional_md5] StorageService.with_header headers, 'x-ms-blob-content-type', options[:content_type] @@ -214,7 +220,7 @@ def commit_blob_blocks(container, blob, block_list, options={}) end body = Serialization.block_list_to_xml(block_list) - call(:put, uri, body, headers) + call(:put, uri, body, headers, options) nil end @@ -230,17 +236,19 @@ def commit_blob_blocks(container, blob, block_list, options={}) # # ==== Attributes # - # * +container+ - String. The container name. - # * +blob+ - String. The blob name. - # * +options+ - Hash. Optional parameters. + # * +container+ - String. The container name. + # * +blob+ - String. The blob name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional) - # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to - # retrieve information from. (optional) - # * +:timeout+ - Integer. A timeout in seconds. + # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional) + # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to + # retrieve information from. (optional) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179400.aspx # @@ -256,7 +264,7 @@ def list_blob_blocks(container, blob, options={}) uri = blob_uri(container, blob, query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) Serialization.block_list_from_xml(response.body) end diff --git a/lib/azure/storage/blob/container.rb b/lib/azure/storage/blob/container.rb index 9a602a01..ddea8b86 100644 --- a/lib/azure/storage/blob/container.rb +++ b/lib/azure/storage/blob/container.rb @@ -44,15 +44,17 @@ def initialize # # ==== Attributes # - # * +name+ - String. The name of the container. - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:metadata+ - Hash. User defined metadata for the container (optional). - # * +:public_access_level+ - String. One of "container" or "blob" (optional). - # * +:timeout+ - Integer. A timeout in seconds. + # * +:metadata+ - Hash. User defined metadata for the container (optional). + # * +:public_access_level+ - String. One of "container" or "blob" (optional). + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179468.aspx # @@ -66,12 +68,12 @@ def create_container(name, options={}) uri = container_uri(name, query) # Headers - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.add_metadata_to_headers(options[:metadata], headers) if options[:metadata] headers['x-ms-blob-public-access'] = options[:public_access_level].to_s if options[:public_access_level] # Call - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) # result container = Serialization.container_from_headers(response.headers) @@ -84,13 +86,15 @@ def create_container(name, options={}) # # ==== Attributes # - # * +name+ - String. The name of the container - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179370.aspx # @@ -101,7 +105,7 @@ def get_container_properties(name, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] # Call - response = call(:get, container_uri(name, query)) + response = call(:get, container_uri(name, query), nil, {}, options) # result container = Serialization.container_from_headers(response.headers) @@ -113,13 +117,15 @@ def get_container_properties(name, options={}) # # ==== Attributes # - # * +name+ - String. The name of the container - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/ee691976.aspx # @@ -130,7 +136,7 @@ def get_container_metadata(name, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] # Call - response = call(:get, container_uri(name, query)) + response = call(:get, container_uri(name, query), nil, {}, options) # result container = Serialization.container_from_headers(response.headers) @@ -142,14 +148,16 @@ def get_container_metadata(name, options={}) # # ==== Attributes # - # * +name+ - String. The name of the container - # * +metadata+ - Hash. A Hash of the metadata values - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container + # * +metadata+ - Hash. A Hash of the metadata values + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179362.aspx # @@ -160,11 +168,11 @@ def set_container_metadata(name, metadata, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] # Headers - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.add_metadata_to_headers(metadata, headers) if metadata # Call - call(:put, container_uri(name, query), nil, headers) + call(:put, container_uri(name, query), nil, headers, options) # Result nil @@ -175,13 +183,15 @@ def set_container_metadata(name, metadata, options={}) # # ==== Attributes # - # * +name+ - String. The name of the container - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179469.aspx # @@ -195,7 +205,7 @@ def get_container_acl(name, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] # Call - response = call(:get, container_uri(name, query)) + response = call(:get, container_uri(name, query), nil, {}, options) # Result container = Serialization.container_from_headers(response.headers) @@ -220,6 +230,8 @@ def get_container_acl(name, options={}) # Accepted key/value pairs in options parameter are: # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179391.aspx # @@ -236,7 +248,7 @@ def set_container_acl(name, public_access_level, options={}) uri = container_uri(name, query) # Headers + body - headers = StorageService.service_properties_headers + headers = StorageService.common_headers headers['x-ms-blob-public-access'] = public_access_level if public_access_level && public_access_level.to_s.length > 0 signed_identifiers = nil @@ -246,7 +258,7 @@ def set_container_acl(name, public_access_level, options={}) body = Serialization.signed_identifiers_to_xml(signed_identifiers) if signed_identifiers # Call - response = call(:put, uri, body, headers) + response = call(:put, uri, body, headers, options) # Result container = Serialization.container_from_headers(response.headers) @@ -260,13 +272,15 @@ def set_container_acl(name, public_access_level, options={}) # # ==== Attributes # - # * +name+ - String. The name of the container. - # * +options+ - Hash. Optional parameters. + # * +name+ - String. The name of the container. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179408.aspx # @@ -277,7 +291,7 @@ def delete_container(name, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] # Call - call(:delete, container_uri(name, query)) + call(:delete, container_uri(name, query), nil, {}, options) # result nil @@ -299,6 +313,8 @@ def delete_container(name, options={}) # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) # if the proposed lease ID is not in the correct format. (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -336,6 +352,8 @@ def acquire_container_lease(container, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -369,6 +387,8 @@ def renew_container_lease(container, lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -402,6 +422,8 @@ def change_container_lease(container, lease, proposed_lease, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -447,6 +469,8 @@ def release_container_lease(container, lease, options={}) # If this option is not used, a fixed-duration lease breaks after the remaining lease # period elapses, and an infinite lease breaks immediately. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to break the lease # only if the container has been modified since the specified date/time. If the container has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -508,6 +532,8 @@ def break_container_lease(container, options={}) # copy_blob operation should be included in the response. # (optional, Default=false) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # NOTE: Metadata requested with the :metadata parameter must have been stored in # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob @@ -542,7 +568,7 @@ def list_blobs(name, options={}) uri = container_uri(name, query) # Call - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) # Result if response.success? diff --git a/lib/azure/storage/blob/page.rb b/lib/azure/storage/blob/page.rb index abc5ade3..edd02998 100644 --- a/lib/azure/storage/blob/page.rb +++ b/lib/azure/storage/blob/page.rb @@ -53,6 +53,8 @@ module Blob # * +:sequence_number+ - Integer. The sequence number is a user-controlled value that you can use to track requests. # The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0. # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -75,7 +77,7 @@ def create_page_blob(container, blob, length, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers # set x-ms-blob-type to PageBlob StorageService.with_header headers, 'x-ms-blob-type', 'PageBlob' @@ -100,7 +102,7 @@ def create_page_blob(container, blob, length, options={}) add_blob_conditional_headers options, headers # call PutBlob with empty body - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -141,6 +143,8 @@ def create_page_blob(container, blob, length, options={}) # the blob's ETag value does not match the value specified. If the values are identical, # the Blob service returns status code 412 (Precondition Failed). # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/ee691975.aspx # @@ -150,7 +154,7 @@ def put_blob_pages(container, blob, start_range, end_range, content, options={}) StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout] uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-range', "bytes=#{start_range}-#{end_range}" StorageService.with_header headers, 'x-ms-page-write', 'update' @@ -162,7 +166,7 @@ def put_blob_pages(container, blob, start_range, end_range, content, options={}) add_blob_conditional_headers options, headers end - response = call(:put, uri, content, headers) + response = call(:put, uri, content, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -184,6 +188,8 @@ def put_blob_pages(container, blob, start_range, end_range, content, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to clear the page only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -206,7 +212,7 @@ def clear_blob_pages(container, blob, start_range, end_range, options={}) uri = blob_uri(container, blob, query) - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-range', "bytes=#{start_range}-#{end_range}" StorageService.with_header headers, 'x-ms-page-write', 'clear' @@ -218,7 +224,7 @@ def clear_blob_pages(container, blob, start_range, end_range, options={}) add_blob_conditional_headers options, headers end - response = call(:put, uri, nil, headers) + response = call(:put, uri, nil, headers, options) result = Serialization.blob_from_headers(response.headers) result.name = blob @@ -243,6 +249,8 @@ def clear_blob_pages(container, blob, start_range, end_range, options={}) # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to # retrieve information from. (optional) # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to list the pages only if # the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -271,11 +279,11 @@ def list_page_blob_ranges(container, blob, options={}) options[:start_range] = 0 if options[:end_range] and not options[:start_range] - headers = StorageService.service_properties_headers + headers = StorageService.common_headers StorageService.with_header headers, 'x-ms-range', "bytes=#{options[:start_range]}-#{options[:end_range]}" if options[:start_range] add_blob_conditional_headers options, headers - response = call(:get, uri, nil, headers) + response = call(:get, uri, nil, headers, options) pagelist = Serialization.page_list_from_xml(response.body) pagelist @@ -296,6 +304,8 @@ def list_page_blob_ranges(container, blob, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). @@ -356,6 +366,8 @@ def resize_page_blob(container, blob, size, options={}) # # Accepted key/value pairs in options parameter are: # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to set the blob properties # only if the blob has been modified since the specified date/time. If the blob has not been modified, # the Blob service returns status code 412 (Precondition Failed). diff --git a/lib/azure/storage/core/filter/retry_filter.rb b/lib/azure/storage/core/filter/retry_filter.rb index f066638c..46d3720a 100644 --- a/lib/azure/storage/core/filter/retry_filter.rb +++ b/lib/azure/storage/core/filter/retry_filter.rb @@ -79,20 +79,26 @@ def should_retry_on_local_error?(retry_data) retry_data[:retryable] = true; return true end + + error_message = retry_data[:error].inspect - if retry_data[:error].inspect.include?('SocketError: Hostname not known') + if error_message.include?('SocketError: Hostname not known') # Retry on local DNS resolving # When uses resolv-replace.rb to replace the libc resolver # Reference: # https://makandracards.com/ninjaconcept/30815-fixing-socketerror-getaddrinfo-name-or-service-not-known-with-ruby-s-resolv-replace-rb # http://www.subelsky.com/2014/05/fixing-socketerror-getaddrinfo-name-or.html retry_data[:retryable] = true; - elsif retry_data[:error].inspect.include?('getaddrinfo: Name or service not known') + elsif error_message.include?('getaddrinfo: Name or service not known') # When uses the default resolver retry_data[:retryable] = true; - elsif retry_data[:error].inspect.include?('Errno::EACCES') + elsif error_message.downcase.include?('timeout') + retry_data[:retryable] = true; + elsif error_message.include?('Errno::ECONNRESET') + retry_data[:retryable] = true; + elsif error_message.include?('Errno::EACCES') retry_data[:retryable] = false; - elsif retry_data[:error].inspect.include?('NOSUPPORT') + elsif error_message.include?('NOSUPPORT') retry_data[:retryable] = false; end diff --git a/lib/azure/storage/queue/queue_service.rb b/lib/azure/storage/queue/queue_service.rb index 38a81cda..311fb8d6 100644 --- a/lib/azure/storage/queue/queue_service.rb +++ b/lib/azure/storage/queue/queue_service.rb @@ -41,27 +41,29 @@ def initialize(options = {}) # # ==== Attributes # - # * +options+ - Hash. Optional parameters. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:prefix+ - String. Filters the results to return only containers - # whose name begins with the specified prefix. (optional) - # * +:marker+ - String. An identifier the specifies the portion of the - # list to be returned. This value comes from the property - # Azure::Service::EnumerationResults.continuation_token when there - # are more containers available than were returned. The - # marker value may then be used here to request the next set - # of list items. (optional) - # * +:max_results+ - Integer. Specifies the maximum number of containers to return. - # If max_results is not specified, or is a value greater than - # 5,000, the server will return up to 5,000 items. If it is set - # to a value less than or equal to zero, the server will return - # status code 400 (Bad Request). (optional) - # * +:metadata+ - Boolean. Specifies whether or not to return the container metadata. - # (optional, Default=false) - # * +:timeout+ - Integer. A timeout in seconds. + # * +:prefix+ - String. Filters the results to return only containers + # whose name begins with the specified prefix. (optional) + # * +:marker+ - String. An identifier the specifies the portion of the + # list to be returned. This value comes from the property + # Azure::Service::EnumerationResults.continuation_token when there + # are more containers available than were returned. The + # marker value may then be used here to request the next set + # of list items. (optional) + # * +:max_results+ - Integer. Specifies the maximum number of containers to return. + # If max_results is not specified, or is a value greater than + # 5,000, the server will return up to 5,000 items. If it is set + # to a value less than or equal to zero, the server will return + # status code 400 (Bad Request). (optional) + # * +:metadata+ - Boolean. Specifies whether or not to return the container metadata. + # (optional, Default=false) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # NOTE: Metadata requested with the :metadata parameter must have been stored in # accordance with the naming restrictions imposed by the 2009-09-19 version of the queue @@ -84,7 +86,7 @@ def list_queues(options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] uri = collection_uri(query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) Serialization.queue_enumeration_results_from_xml(response.body) end @@ -100,13 +102,15 @@ def list_queues(options={}) # # ==== Attributes # - # * +queue_name+ - String. The name of the queue. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The name of the queue. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179454 # @@ -115,7 +119,7 @@ def clear_messages(queue_name, options={}) query = { } query["timeout"] = options[:timeout].to_s if options[:timeout] uri = messages_uri(queue_name, query) - call(:delete, uri) + call(:delete, uri, nil, {}, options) nil end @@ -123,14 +127,16 @@ def clear_messages(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:metadata+ - Hash. A hash of user defined metadata. - # * +:timeout+ - Integer. A timeout in seconds. + # * +:metadata+ - Hash. A hash of user defined metadata. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179342 # @@ -144,7 +150,7 @@ def create_queue(queue_name, options={}) headers = { } Service::StorageService.add_metadata_to_headers(options[:metadata] || {}, headers) if options[:metadata] - call(:put, uri, nil, headers) + call(:put, uri, nil, headers, options) nil end @@ -152,13 +158,15 @@ def create_queue(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179436 # @@ -169,7 +177,7 @@ def delete_queue(queue_name, options={}) uri = queue_uri(queue_name, query) - call(:delete, uri) + call(:delete, uri, nil, {}, options) nil end @@ -177,13 +185,15 @@ def delete_queue(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179384 # @@ -198,7 +208,7 @@ def get_queue_metadata(queue_name, options={}) uri = queue_uri(queue_name, query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) approximate_messages_count = response.headers["x-ms-approximate-messages-count"] metadata = Serialization.metadata_from_headers(response.headers) @@ -211,14 +221,16 @@ def get_queue_metadata(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +metadata+ - Hash. A hash of user defined metadata - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +metadata+ - Hash. A hash of user defined metadata + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179348 # @@ -232,7 +244,7 @@ def set_queue_metadata(queue_name, metadata, options={}) headers ={} Service::StorageService.add_metadata_to_headers(metadata || {}, headers) - call(:put, uri, nil, headers) + call(:put, uri, nil, headers, options) nil end @@ -240,13 +252,15 @@ def set_queue_metadata(queue_name, metadata, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/jj159101 # @@ -255,7 +269,7 @@ def get_queue_acl(queue_name, options={}) query = { "comp" => "acl" } query["timeout"] = options[:timeout].to_s if options[:timeout] - response = call(:get, queue_uri(queue_name, query)) + response = call(:get, queue_uri(queue_name, query), nil, {}, options) signed_identifiers = [] signed_identifiers = Serialization.signed_identifiers_from_xml(response.body) unless response.body == nil or response.body.length < 1 @@ -266,14 +280,16 @@ def get_queue_acl(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances - # * +:timeout+ - Integer. A timeout in seconds. + # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/jj159099 # @@ -286,7 +302,7 @@ def set_queue_acl(queue_name, options={}) body = nil body = Serialization.signed_identifiers_to_xml(options[:signed_identifiers]) if options[:signed_identifiers] && options[:signed_identifiers].length > 0 - call(:put, uri, body, {}) + call(:put, uri, body, {}, options) nil end @@ -301,15 +317,17 @@ def set_queue_acl(queue_name, options={}) # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:visibility_timeout+ - Integer. Specifies the new visibility timeout value, in seconds, relative to server - # time. The new value must be larger than or equal to 0, and cannot be larger than 7 - # days. The visibility timeout of a message cannot be set to a value later than the - # expiry time. :visibility_timeout should be set to a value smaller than the - # time-to-live value. If not specified, the default value is 0. - # * +:message_ttl+ - Integer. Specifies the time-to-live interval for the message, in seconds. The maximum - # time-to-live allowed is 7 days. If not specified, the default time-to-live is 7 days. - # * +:encode+ - Boolean. If set to true, the message will be base64 encoded. - # * +:timeout+ - Integer. A timeout in seconds. + # * +:visibility_timeout+ - Integer. Specifies the new visibility timeout value, in seconds, relative to server + # time. The new value must be larger than or equal to 0, and cannot be larger than 7 + # days. The visibility timeout of a message cannot be set to a value later than the + # expiry time. :visibility_timeout should be set to a value smaller than the + # time-to-live value. If not specified, the default value is 0. + # * +:message_ttl+ - Integer. Specifies the time-to-live interval for the message, in seconds. The maximum + # time-to-live allowed is 7 days. If not specified, the default time-to-live is 7 days. + # * +:encode+ - Boolean. If set to true, the message will be base64 encoded. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179346 # @@ -326,7 +344,7 @@ def create_message(queue_name, message_text, options={}) uri = messages_uri(queue_name, query) body = Serialization.message_to_xml(message_text, options[:encode]) - call(:post, uri, body, {}) + call(:post, uri, body, {}, options) nil end @@ -334,16 +352,18 @@ def create_message(queue_name, message_text, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +message_id+ - String. The id of the message. - # * +pop_receipt+ - String. The valid pop receipt value returned from an earlier call to the Get Messages or - # Update Message operation. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +message_id+ - String. The id of the message. + # * +pop_receipt+ - String. The valid pop receipt value returned from an earlier call to the Get Messages or + # Update Message operation. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179347 # @@ -392,7 +412,7 @@ def delete_message(queue_name, message_id, pop_receipt, options={}) uri = message_uri(queue_name, message_id, query) - call(:delete, uri) + call(:delete, uri, nil, {}, options) nil end @@ -400,15 +420,17 @@ def delete_message(queue_name, message_id, pop_receipt, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:number_of_messages+ - Integer. How many messages to return. (optional, Default: 1) - # * +:decode+ - Boolean. Boolean value indicating if the message should be base64 decoded. - # * +:timeout+ - Integer. A timeout in seconds. + # * +:number_of_messages+ - Integer. How many messages to return. (optional, Default: 1) + # * +:decode+ - Boolean. Boolean value indicating if the message should be base64 decoded. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179472 # @@ -421,7 +443,7 @@ def peek_messages(queue_name, options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] uri = messages_uri(queue_name, query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) messages = Serialization.queue_messages_from_xml(response.body, options[:decode]) messages @@ -431,16 +453,18 @@ def peek_messages(queue_name, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +visibility_timeout+ - Integer. The new visibility timeout value, in seconds, relative to server time. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +visibility_timeout+ - Integer. The new visibility timeout value, in seconds, relative to server time. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:number_of_messages+ - Integer. How many messages to return. (optional, Default: 1) - # * +:timeout+ - Integer. A timeout in seconds. - # * +:decode+ - Boolean. Boolean value indicating if the message should be base64 decoded. + # * +:number_of_messages+ - Integer. How many messages to return. (optional, Default: 1) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. + # * +:decode+ - Boolean. Boolean value indicating if the message should be base64 decoded. # # See http://msdn.microsoft.com/en-us/library/azure/dd179474 # @@ -453,7 +477,7 @@ def list_messages(queue_name, visibility_timeout, options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] uri = messages_uri(queue_name, query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) messages = Serialization.queue_messages_from_xml(response.body, options[:decode]) messages @@ -463,20 +487,22 @@ def list_messages(queue_name, visibility_timeout, options={}) # # ==== Attributes # - # * +queue_name+ - String. The queue name. - # * +message_id+ - String. The id of the message. - # * +pop_receipt+ - String. The valid pop receipt value returned from an earlier call to the Get Messages or - # update Message operation. - # * +message_text+ - String. The message contents. Note that the message content must be in a format that may - # be encoded with UTF-8. - # * +visibility_timeout+ - Integer. The new visibility timeout value, in seconds, relative to server time. - # * +options+ - Hash. Optional parameters. + # * +queue_name+ - String. The queue name. + # * +message_id+ - String. The id of the message. + # * +pop_receipt+ - String. The valid pop receipt value returned from an earlier call to the Get Messages or + # update Message operation. + # * +message_text+ - String. The message contents. Note that the message content must be in a format that may + # be encoded with UTF-8. + # * +visibility_timeout+ - Integer. The new visibility timeout value, in seconds, relative to server time. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:encode+ - Boolean. If set to true, the message will be base64 encoded. - # * +:timeout+ - Integer. A timeout in seconds. + # * +:encode+ - Boolean. If set to true, the message will be base64 encoded. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/hh452234 # @@ -517,7 +543,7 @@ def update_message(queue_name, message_id, pop_receipt, message_text, visibility uri = message_uri(queue_name, message_id, query) body = Serialization.message_to_xml(message_text, options[:encode]) - response = call(:put, uri, body, {}) + response = call(:put, uri, body, {}, options) new_pop_receipt = response.headers["x-ms-popreceipt"] time_next_visible = response.headers["x-ms-time-next-visible"] return new_pop_receipt, time_next_visible diff --git a/lib/azure/storage/service/storage_service.rb b/lib/azure/storage/service/storage_service.rb index 65950cfd..d835577a 100644 --- a/lib/azure/storage/service/storage_service.rb +++ b/lib/azure/storage/service/storage_service.rb @@ -48,8 +48,8 @@ def initialize(signer=nil, account_name=nil, options = {}) super(signer, account_name, options) end - def call(method, uri, body=nil, headers={}) - super(method, uri, body, StorageService.service_properties_headers.merge(headers)) + def call(method, uri, body=nil, headers={}, options={}) + super(method, uri, body, StorageService.common_headers(options).merge(headers)) end # Public: Get Storage Service properties @@ -57,10 +57,15 @@ def call(method, uri, body=nil, headers={}) # See http://msdn.microsoft.com/en-us/library/azure/hh452239 # See http://msdn.microsoft.com/en-us/library/azure/hh452243 # + # ==== Options + # + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. + # # Returns a Hash with the service properties or nil if the operation failed - def get_service_properties + def get_service_properties(options={}) uri = service_properties_uri - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) Serialization.service_properties_from_xml response.body end @@ -71,11 +76,16 @@ def get_service_properties # See http://msdn.microsoft.com/en-us/library/azure/hh452235 # See http://msdn.microsoft.com/en-us/library/azure/hh452232 # + # ==== Options + # + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. + # # Returns boolean indicating success. - def set_service_properties(service_properties) + def set_service_properties(service_properties, options={}) body = Serialization.service_properties_to_xml service_properties uri = service_properties_uri - call(:put, uri, body) + call(:put, uri, body, {}, options) nil end @@ -144,11 +154,13 @@ def with_value(object, key, value) alias with_query with_value # Declares a default hash object for request headers - def service_properties_headers - { + def common_headers(options = {}) + headers = { 'x-ms-version' => Azure::Storage::Default::STG_VERSION, 'User-Agent' => Azure::Storage::Default::USER_AGENT } + headers.merge!({'x-ms-client-request-id' => options[:request_id]}) if options[:request_id] + headers end end diff --git a/lib/azure/storage/table/table_service.rb b/lib/azure/storage/table/table_service.rb index 1f1c4af0..d1736900 100644 --- a/lib/azure/storage/table/table_service.rb +++ b/lib/azure/storage/table/table_service.rb @@ -42,14 +42,16 @@ def initialize(options = {}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: # - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd135729 # @@ -59,7 +61,7 @@ def create_table(table_name, options={}) query['timeout'] = options[:timeout].to_s if options[:timeout] body = Table::Serialization.hash_to_entry_xml({"TableName" => table_name}).to_xml - call(:post, collection_uri(query), body) + call(:post, collection_uri(query), body, {}, options) nil end @@ -67,13 +69,15 @@ def create_table(table_name, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179387 # @@ -82,7 +86,7 @@ def delete_table(table_name, options={}) query = { } query["timeout"] = options[:timeout].to_s if options[:timeout] - call(:delete, table_uri(table_name, query)) + call(:delete, table_uri(table_name, query), nil, {}, options) nil end @@ -90,20 +94,22 @@ def delete_table(table_name, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # Returns the last updated time for the table def get_table(table_name, options={}) query = { } query["timeout"] = options[:timeout].to_s if options[:timeout] - response = call(:get, table_uri(table_name, query)) + response = call(:get, table_uri(table_name, query), nil, {}, options) results = Table::Serialization.hash_from_entry_xml(response.body) results[:updated] rescue => e @@ -114,14 +120,16 @@ def get_table(table_name, options={}) # # ==== Attributes # - # * +options+ - Hash. Optional parameters. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is - # larger than a single operation can return at once. (optional) - # * +:timeout+ - Integer. A timeout in seconds. + # * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is + # larger than a single operation can return at once. (optional) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179405 # @@ -132,7 +140,7 @@ def query_tables(options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] uri = collection_uri(query) - response = call(:get, uri) + response = call(:get, uri, nil, {}, options) entries = Table::Serialization.entries_from_feed_xml(response.body) || [] values = Azure::Service::EnumerationResults.new(entries) @@ -146,13 +154,15 @@ def query_tables(options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/jj159100 # @@ -161,7 +171,7 @@ def get_table_acl(table_name, options={}) query = { 'comp' => 'acl'} query['timeout'] = options[:timeout].to_s if options[:timeout] - response = call(:get, generate_uri(table_name, query), nil, {'x-ms-version' => '2012-02-12'}) + response = call(:get, generate_uri(table_name, query), nil, {'x-ms-version' => '2012-02-12'}, options) signed_identifiers = [] signed_identifiers = Table::Serialization.signed_identifiers_from_xml response.body unless response.body == nil or response.body.length < 1 @@ -174,14 +184,16 @@ def get_table_acl(table_name, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances - # * +:timeout+ - Integer. A timeout in seconds. + # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/jj159102 # @@ -194,7 +206,7 @@ def set_table_acl(table_name, options={}) body = nil body = Table::Serialization.signed_identifiers_to_xml options[:signed_identifiers] if options[:signed_identifiers] && options[:signed_identifiers].length > 0 - call(:put, uri, body, {'x-ms-version' => '2012-02-12'}) + call(:put, uri, body, {'x-ms-version' => '2012-02-12'}, options) nil end @@ -203,14 +215,16 @@ def set_table_acl(table_name, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179433 # @@ -221,7 +235,7 @@ def insert_entity(table_name, entity_values, options={}) query = { } query['timeout'] = options[:timeout].to_s if options[:timeout] - response = call(:post, entities_uri(table_name, nil, nil, query), body) + response = call(:post, entities_uri(table_name, nil, nil, query), body, {}, options) result = Table::Serialization.hash_from_entry_xml(response.body) @@ -239,19 +253,21 @@ def insert_entity(table_name, entity_values, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:partition_key+ - String. The partition key (optional) - # * +:row_key+ - String. The row key (optional) - # * +:select+ - Array. An array of property names to return (optional) - # * +:filter+ - String. A filter expression (optional) - # * +:top+ - Integer. A limit for the number of results returned (optional) - # * +:continuation_token+ - Hash. The continuation token. - # * +:timeout+ - Integer. A timeout in seconds. + # * +:partition_key+ - String. The partition key (optional) + # * +:row_key+ - String. The row key (optional) + # * +:select+ - Array. An array of property names to return (optional) + # * +:filter+ - String. A filter expression (optional) + # * +:top+ - Integer. A limit for the number of results returned (optional) + # * +:continuation_token+ - Hash. The continuation token. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179421 # @@ -266,7 +282,7 @@ def query_entities(table_name, options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] uri = entities_uri(table_name, options[:partition_key], options[:row_key], query) - response = call(:get, uri, nil, { "DataServiceVersion" => "2.0;NetFx"}) + response = call(:get, uri, nil, {"DataServiceVersion" => "2.0;NetFx"}, options) entities = Azure::Service::EnumerationResults.new @@ -298,17 +314,19 @@ def query_entities(table_name, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") - # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity, - # that entity will be inserted. If false, the operation will fail. (optional, Default=false) - # * +:timeout+ - Integer. A timeout in seconds. + # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") + # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity, + # that entity will be inserted. If false, the operation will fail. (optional, Default=false) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179427 # @@ -329,7 +347,7 @@ def update_entity(table_name, entity_values, options={}) body = Table::Serialization.hash_to_entry_xml(entity_values).to_xml - response = call(:put, uri, body, headers) + response = call(:put, uri, body, headers, options) response.headers["etag"] rescue => e raise_with_response(e, response) @@ -340,17 +358,19 @@ def update_entity(table_name, entity_values, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") - # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity, - # that entity will be inserted. If false, the operation will fail. (optional, Default=false) - # * +:timeout+ - Integer. A timeout in seconds. + # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") + # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity, + # that entity will be inserted. If false, the operation will fail. (optional, Default=false) + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd179392 # @@ -371,7 +391,7 @@ def merge_entity(table_name, entity_values, options={}) body = Table::Serialization.hash_to_entry_xml(entity_values).to_xml - response = call(:post, uri, body, headers) + response = call(:post, uri, body, headers, options) response.headers["etag"] rescue => e raise_with_response(e, response) @@ -381,14 +401,16 @@ def merge_entity(table_name, entity_values, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/hh452241 # @@ -402,14 +424,16 @@ def insert_or_merge_entity(table_name, entity_values, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +entity_values+ - Hash. A hash of the name/value pairs for the entity. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/hh452242 # @@ -423,16 +447,18 @@ def insert_or_replace_entity(table_name, entity_values, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +partition_key+ - String. The partition key - # * +row_key+ - String. The row key - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +partition_key+ - String. The partition key + # * +row_key+ - String. The row key + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") - # * +:timeout+ - Integer. A timeout in seconds. + # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*") + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd135727 # @@ -444,7 +470,7 @@ def delete_entity(table_name, partition_key, row_key, options={}) query = { } query["timeout"] = options[:timeout].to_s if options[:timeout] - call(:delete, entities_uri(table_name, partition_key, row_key, query), nil, { "If-Match"=> if_match }) + call(:delete, entities_uri(table_name, partition_key, row_key, query), nil, { "If-Match"=> if_match }, options) nil end @@ -452,13 +478,15 @@ def delete_entity(table_name, partition_key, row_key, options={}) # # ==== Attributes # - # * +batch+ - The Azure::Storage::Table::Batch instance to execute. - # * +options+ - Hash. Optional parameters. + # * +batch+ - The Azure::Storage::Table::Batch instance to execute. + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # See http://msdn.microsoft.com/en-us/library/azure/dd894038 # @@ -474,7 +502,7 @@ def execute_batch(batch, options={}) query["timeout"] = options[:timeout].to_s if options[:timeout] body = batch.to_body - response = call(:post, generate_uri('/$batch', query), body, headers) + response = call(:post, generate_uri('/$batch', query), body, headers, options) batch.parse_response(response) rescue => e raise_with_response(e, response) @@ -484,15 +512,17 @@ def execute_batch(batch, options={}) # # ==== Attributes # - # * +table_name+ - String. The table name - # * +partition_key+ - String. The partition key - # * +row_key+ - String. The row key - # * +options+ - Hash. Optional parameters. + # * +table_name+ - String. The table name + # * +partition_key+ - String. The partition key + # * +row_key+ - String. The row key + # * +options+ - Hash. Optional parameters. # # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:timeout+ - Integer. A timeout in seconds. + # * +:timeout+ - Integer. A timeout in seconds. + # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded + # in the analytics logs when storage analytics logging is enabled. # # Returns an Azure::Storage::Table::Entity instance on success def get_entity(table_name, partition_key, row_key, options={}) diff --git a/lib/azure/storage/version.rb b/lib/azure/storage/version.rb index 284e248c..ad75f013 100644 --- a/lib/azure/storage/version.rb +++ b/lib/azure/storage/version.rb @@ -28,7 +28,7 @@ class Version # Fields represent the parts defined in http://semver.org/ MAJOR = 0 unless defined? MAJOR MINOR = 11 unless defined? MINOR - UPDATE = 0 unless defined? UPDATE + UPDATE = 1 unless defined? UPDATE PRE = 'preview' unless defined? PRE class << self diff --git a/test/integration/table/delete_entity_batch_test.rb b/test/integration/table/delete_entity_batch_test.rb index 4f727ef5..a5cafcd6 100644 --- a/test/integration/table/delete_entity_batch_test.rb +++ b/test/integration/table/delete_entity_batch_test.rb @@ -90,7 +90,7 @@ end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new "this_table.cannot-exist!", entity_properties["PartitionKey"] batch.delete entity_properties["RowKey"] subject.execute_batch batch @@ -98,7 +98,7 @@ end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new table_name, "this_partition/key#is_invalid" batch.delete entity_properties["RowKey"] subject.execute_batch batch @@ -106,7 +106,7 @@ end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new table_name, entity_properties["PartitionKey"] batch.delete "thisrow/key#is_invalid" subject.execute_batch batch diff --git a/test/integration/table/insert_entity_batch_test.rb b/test/integration/table/insert_entity_batch_test.rb index 0c555b53..79b43a1d 100644 --- a/test/integration/table/insert_entity_batch_test.rb +++ b/test/integration/table/insert_entity_batch_test.rb @@ -77,7 +77,7 @@ def floor_to(num, x) end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new "this_table.cannot-exist!", entity_properties["PartitionKey"] batch.insert entity_properties["RowKey"], entity_properties results = subject.execute_batch batch @@ -85,7 +85,7 @@ def floor_to(num, x) end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["PartitionKey"] = "this/partition\\key#is?invalid" @@ -96,7 +96,7 @@ def floor_to(num, x) end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this/row\\key#is?invalid" diff --git a/test/integration/table/insert_or_merge_entity_batch_test.rb b/test/integration/table/insert_or_merge_entity_batch_test.rb index d6510eca..fbf3365c 100644 --- a/test/integration/table/insert_or_merge_entity_batch_test.rb +++ b/test/integration/table/insert_or_merge_entity_batch_test.rb @@ -132,7 +132,7 @@ end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "row_key" @@ -143,7 +143,7 @@ end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["PartitionKey"] = "this/partition_key#is?invalid" entity["RowKey"] = "row_key" @@ -155,7 +155,7 @@ end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this/partition_key#is?invalid" diff --git a/test/integration/table/insert_or_replace_entity_batch_test.rb b/test/integration/table/insert_or_replace_entity_batch_test.rb index be6259af..fefc9726 100644 --- a/test/integration/table/insert_or_replace_entity_batch_test.rb +++ b/test/integration/table/insert_or_replace_entity_batch_test.rb @@ -125,7 +125,7 @@ end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "row_key" @@ -136,7 +136,7 @@ end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["PartitionKey"] = "this/partition_key#is?invalid" entity["RowKey"] = "row_key" @@ -148,7 +148,7 @@ end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this/partition_key#is?invalid" diff --git a/test/integration/table/merge_entity_batch_test.rb b/test/integration/table/merge_entity_batch_test.rb index c0fecdf0..0a8c50a5 100644 --- a/test/integration/table/merge_entity_batch_test.rb +++ b/test/integration/table/merge_entity_batch_test.rb @@ -94,7 +94,7 @@ end it "errors on a non-existing row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this-row-key-does-not-exist" @@ -105,7 +105,7 @@ end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new "this_table.cannot-exist!", entity_properties["PartitionKey"] batch.merge entity_properties["RowKey"], entity_properties etags = subject.execute_batch batch @@ -113,7 +113,7 @@ end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["PartitionKey"] = "this/partition_key#is?invalid" @@ -124,7 +124,7 @@ end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this/row_key#is?invalid" diff --git a/test/integration/table/update_entity_batch_test.rb b/test/integration/table/update_entity_batch_test.rb index a7bbf8bf..58de77f5 100644 --- a/test/integration/table/update_entity_batch_test.rb +++ b/test/integration/table/update_entity_batch_test.rb @@ -115,7 +115,7 @@ end it "errors on a non-existing row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this-row-key-does-not-exist" @@ -126,7 +126,7 @@ end it "errors on an invalid table name" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do batch = Azure::Storage::Table::Batch.new "this_table.cannot-exist!", entity_properties["PartitionKey"] batch.update entity_properties["RowKey"], entity_properties etags = subject.execute_batch batch @@ -134,7 +134,7 @@ end it "errors on an invalid partition key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["PartitionKey"] = "this/partition_key#is?invalid" @@ -145,7 +145,7 @@ end it "errors on an invalid row key" do - assert_raises(Azure::Core::Http::HTTPError) do + assert_raises(RuntimeError) do entity = entity_properties.dup entity["RowKey"] = "this/row_key#is?invalid" diff --git a/test/integration/test_helper.rb b/test/integration/test_helper.rb index a51d2cf4..78fd1e3e 100644 --- a/test/integration/test_helper.rb +++ b/test/integration/test_helper.rb @@ -28,4 +28,6 @@ config.storage_access_key = ENV.fetch('AZURE_STORAGE_ACCESS_KEY') config.storage_account_name = ENV.fetch('AZURE_STORAGE_ACCOUNT') Azure::Storage.client(:storage_account_name => config.storage_account_name, :storage_access_key => config.storage_access_key) + require "azure/core/http/debug_filter" + Azure::Storage.client.blob_client.with_filter Azure::Core::Http::DebugFilter.new end diff --git a/test/unit/blob/blob_service_test.rb b/test/unit/blob/blob_service_test.rb index 19a2c8fa..b9532514 100644 --- a/test/unit/blob/blob_service_test.rb +++ b/test/unit/blob/blob_service_test.rb @@ -55,7 +55,7 @@ before { subject.stubs(:containers_uri).with({}).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) serialization.stubs(:container_enumeration_results_from_xml).with(response_body).returns(container_enumeration_result) } @@ -65,7 +65,6 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) subject.list_containers end @@ -81,7 +80,6 @@ describe 'when the options Hash is used' do before { - subject.expects(:call).with(:get, uri).returns(response) serialization.expects(:container_enumeration_results_from_xml).with(response_body).returns(container_enumeration_result) } @@ -90,6 +88,7 @@ subject.expects(:containers_uri).with(query).returns(uri) options = {:prefix => 'pre'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end @@ -98,6 +97,7 @@ subject.expects(:containers_uri).with(query).returns(uri) options = {:marker => 'mark'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end @@ -106,6 +106,7 @@ subject.expects(:containers_uri).with(query).returns(uri) options = {:max_results => 5} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end @@ -114,6 +115,7 @@ subject.expects(:containers_uri).with(query).returns(uri) options = {:metadata => true} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end @@ -122,12 +124,15 @@ subject.expects(:containers_uri).with(query).returns(uri) options = {:timeout => 37} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end + it 'does not modify the URI query parameters when provided an unknown value' do subject.expects(:containers_uri).with({}).returns(uri) options = {:unknown_key => 'some_value'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_containers options end end @@ -142,7 +147,7 @@ let(:verb) { :put } before { subject.stubs(:container_uri).with(container_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:container_from_headers).with(response_headers).returns(container) } @@ -152,7 +157,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.create_container container_name end @@ -185,27 +190,28 @@ } subject.stubs(:container_uri).with(container_name, {}).returns(uri) serialization.stubs(:container_from_headers).with(response_headers).returns(container) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) end it 'adds metadata to the request headers' do + subject.stubs(:call).with(verb, uri, nil, request_headers, container_metadata).returns(response) subject.create_container container_name, container_metadata end end describe 'when optional public_access_level parameter is used' do let(:public_access_level) { 'public-access-level-value' } + let(:options) { {:public_access_level => public_access_level} } - before { + before do request_headers = {'x-ms-blob-public-access' => public_access_level, 'x-ms-version' => x_ms_version, 'User-Agent' => user_agent} - subject.stubs(:container_uri).with(container_name, {}).returns(uri) + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) serialization.stubs(:container_from_headers).with(response_headers).returns(container) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) - } + end it 'adds public_access_level to the request headers' do - subject.create_container container_name, {:public_access_level => public_access_level} + subject.create_container container_name, options end end end @@ -215,7 +221,7 @@ before { response.stubs(:success?).returns(true) subject.stubs(:container_uri).with(container_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) } it 'assembles a URI for the request' do @@ -224,7 +230,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {}).returns(response) subject.delete_container container_name end @@ -242,7 +248,7 @@ container.properties = container_properties response_headers = {} subject.stubs(:container_uri).with(container_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) serialization.stubs(:container_from_headers).with(response_headers).returns(container) } @@ -252,7 +258,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {}).returns(response) subject.get_container_properties container_name end @@ -278,7 +284,7 @@ query.update({'comp' => 'metadata'}) response.stubs(:headers).returns(response_headers) subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) container.metadata = container_metadata serialization.stubs(:container_from_headers).with(response_headers).returns(container) @@ -290,7 +296,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {}).returns(response) subject.get_container_metadata container_name end @@ -317,7 +323,7 @@ response.stubs(:headers).returns({}) response_body.stubs(:length).returns(37) subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) serialization.stubs(:container_from_headers).with(response_headers).returns(container) serialization.stubs(:signed_identifiers_from_xml).with(response_body).returns(signed_identifiers) @@ -329,7 +335,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {}).returns(response) subject.get_container_acl container_name end @@ -360,7 +366,7 @@ response.stubs(:headers).returns({}) subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:container_from_headers).with(response_headers).returns(container) } @@ -370,7 +376,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_container_acl container_name, public_access_level end @@ -397,7 +403,7 @@ } it 'sets the x-ms-blob-public-access header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_container_acl container_name, public_access_level end @@ -405,17 +411,21 @@ let(:signed_identifier) { Azure::Storage::Service::SignedIdentifier.new } let(:signed_identifiers) { [signed_identifier] } before { - subject.stubs(:call).with(verb, uri, request_body, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, request_body, request_headers, {}).returns(response) serialization.stubs(:signed_identifiers_to_xml).with(signed_identifiers).returns(request_body) } it 'serializes the request contents' do serialization.expects(:signed_identifiers_to_xml).with(signed_identifiers).returns(request_body) - subject.set_container_acl container_name, public_access_level, {:signed_identifiers => signed_identifiers} + options = {:signed_identifiers => signed_identifiers} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.set_container_acl container_name, public_access_level, options end it 'returns a container and an ACL' do - returned_container, returned_acl = subject.set_container_acl container_name, public_access_level, {:signed_identifiers => signed_identifiers} + options = {:signed_identifiers => signed_identifiers} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + returned_container, returned_acl = subject.set_container_acl container_name, public_access_level, options returned_container.must_be_kind_of Azure::Storage::Blob::Container::Container returned_container.name.must_equal container_name @@ -434,7 +444,7 @@ } it 'sets the x-ms-blob-public-access header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_container_acl container_name, public_access_level end end @@ -446,7 +456,7 @@ } it 'sets the x-ms-blob-public-access header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_container_acl container_name, public_access_level end end @@ -467,7 +477,7 @@ query.update({'comp' => 'metadata'}) response.stubs(:success?).returns(true) subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -476,7 +486,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_container_metadata container_name, container_metadata end @@ -493,7 +503,7 @@ before { subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {}).returns(response) response.stubs(:success?).returns(true) serialization.stubs(:blob_enumeration_results_from_xml).with(response_body).returns(blob_enumeration_results) } @@ -504,7 +514,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {}).returns(response) subject.list_blobs container_name end @@ -520,7 +530,6 @@ describe 'when the options Hash is used' do before { - subject.expects(:call).with(:get, uri).returns(response) response.expects(:success?).returns(true) serialization.expects(:blob_enumeration_results_from_xml).with(response_body).returns(blob_enumeration_results) subject.expects(:container_uri).with(container_name, query).returns(uri) @@ -529,72 +538,81 @@ it 'modifies the URI query parameters when provided a :prefix value' do query['prefix']= 'pre' options = {:prefix => 'pre'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :delimiter value' do query['delimiter'] = 'delim' options = {:delimiter => 'delim'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :marker value' do query['marker'] = 'mark' options = {:marker => 'mark'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :max_results value' do query['maxresults'] = '5' options = {:max_results => 5} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :metadata value' do query['include'] = 'metadata' options = {:metadata => true} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :snapshots value' do query['include'] = 'snapshots' options = {:snapshots => true} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :uncommittedblobs value' do query['include'] = 'uncommittedblobs' options = {:uncommittedblobs => true} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :copy value' do query['include'] = 'copy' options = {:copy => true} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided more than one of :metadata, :snapshots, :uncommittedblobs or :copy values' do query['include'] = 'metadata,snapshots,uncommittedblobs,copy' - options = { :copy => true, :metadata => true, :snapshots => true, :uncommittedblobs => true } - + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'modifies the URI query parameters when provided a :timeout value' do query['timeout'] = '37' options = {:timeout => 37} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end it 'does not modify the URI query parameters when provided an unknown value' do options = {:unknown_key => 'some_value'} + subject.expects(:call).with(:get, uri, nil, {}, options).returns(response) subject.list_blobs container_name, options end end @@ -620,7 +638,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -630,7 +648,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.create_page_blob container_name, blob_name, blob_length end @@ -644,53 +662,72 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :sequence_number value' do request_headers['x-ms-sequence-number'] = 37.to_s - subject.create_page_blob container_name, blob_name, blob_length, {:sequence_number => 37.to_s} + options = {:sequence_number => 37.to_s} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :content_type value' do request_headers['x-ms-blob-content-type'] = 'bct-value' - subject.create_page_blob container_name, blob_name, blob_length, {:content_type => 'bct-value'} + options = {:content_type => 'bct-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :content_encoding value' do request_headers['x-ms-blob-content-encoding'] = 'bce-value' - subject.create_page_blob container_name, blob_name, blob_length, {:content_encoding => 'bce-value'} + options = {:content_encoding => 'bce-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :content_language value' do request_headers['x-ms-blob-content-language'] = 'bcl-value' - subject.create_page_blob container_name, blob_name, blob_length, {:content_language => 'bcl-value'} + options = {:content_language => 'bcl-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :content_md5 value' do request_headers['x-ms-blob-content-md5'] = 'bcm-value' - subject.create_page_blob container_name, blob_name, blob_length, {:content_md5 => 'bcm-value'} + options = {:content_md5 => 'bcm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :cache_control value' do request_headers['x-ms-blob-cache-control'] = 'bcc-value' - subject.create_page_blob container_name, blob_name, blob_length, {:cache_control => 'bcc-value'} + options = {:cache_control => 'bcc-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :content_disposition value' do request_headers['x-ms-blob-content-disposition'] = 'bcd-value' - subject.create_page_blob container_name, blob_name, blob_length, {:content_disposition => 'bcd-value'} + options = {:content_disposition => 'bcd-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :transactional_md5 value' do request_headers['Content-MD5'] = 'tm-value' - subject.create_page_blob container_name, blob_name, blob_length, {:transactional_md5 => 'tm-value'} + options = {:transactional_md5 => 'tm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.create_page_blob container_name, blob_name, blob_length, options end it 'does not modify the request headers when provided an unknown value' do - subject.create_page_blob container_name, blob_name, blob_length, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_page_blob container_name, blob_name, blob_length, options end end end @@ -713,7 +750,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, content, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, content, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -723,7 +760,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, content, request_headers).returns(response) + subject.expects(:call).with(verb, uri, content, request_headers, {}).returns(response) subject.put_blob_pages container_name, blob_name, start_range, end_range, content end @@ -737,42 +774,58 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :if_sequence_number_eq value' do request_headers['x-ms-if-sequence-number-eq'] = 'isne-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_sequence_number_eq => 'isne-value'} + options = {:if_sequence_number_eq => 'isne-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_sequence_number_lt value' do request_headers['x-ms-if-sequence-number-lt'] = 'isnlt-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_sequence_number_lt => 'isnlt-value'} + options = {:if_sequence_number_lt => 'isnlt-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_sequence_number_le value' do request_headers['x-ms-if-sequence-number-le'] = 'isnle-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_sequence_number_le => 'isnle-value'} + options = {:if_sequence_number_le => 'isnle-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end it 'does not modify the request headers when provided an unknown value' do - subject.put_blob_pages container_name, blob_name, start_range, end_range, content, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_pages container_name, blob_name, start_range, end_range, content, options end end end @@ -794,7 +847,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -804,7 +857,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.clear_blob_pages container_name, blob_name, start_range, end_range end @@ -858,7 +911,7 @@ query.update({'comp' => 'block', 'blockid' => Base64.strict_encode64(block_id)}) response_headers['Content-MD5'] = server_generated_content_md5 subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, content, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, content, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -867,7 +920,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, content, request_headers).returns(response) + subject.expects(:call).with(verb, uri, content, request_headers, {}).returns(response) subject.put_blob_block container_name, blob_name, block_id, content end @@ -879,11 +932,15 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :content_md5 value' do request_headers['Content-MD5'] = 'content-md5' - subject.put_blob_block container_name, blob_name, block_id, content, {:content_md5 => 'content-md5'} + options = {:content_md5 => 'content-md5'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_block container_name, blob_name, block_id, content, options end it 'does not modify the request headers when provided an unknown value' do - subject.put_blob_block container_name, blob_name, block_id, content, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.put_blob_block container_name, blob_name, block_id, content, options end end end @@ -901,17 +958,16 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri, content, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, content, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } it 'assembles a URI for the request' do - subject.expects(:blob_uri).with(container_name, blob_name, {}).returns(uri) subject.create_block_blob container_name, blob_name, content end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, content, request_headers).returns(response) + subject.expects(:call).with(verb, uri, content, request_headers, {}).returns(response) subject.create_block_blob container_name, blob_name, content end @@ -925,48 +981,65 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :content_type value' do request_headers['x-ms-blob-content-type'] = 'bct-value' - subject.create_block_blob container_name, blob_name, content, {:content_type => 'bct-value'} + options = {:content_type => 'bct-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :content_encoding value' do request_headers['x-ms-blob-content-encoding'] = 'bce-value' - subject.create_block_blob container_name, blob_name, content, {:content_encoding => 'bce-value'} + options = {:content_encoding => 'bce-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :content_language value' do request_headers['x-ms-blob-content-language'] = 'bcl-value' - subject.create_block_blob container_name, blob_name, content, {:content_language => 'bcl-value'} + options = {:content_language => 'bcl-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :content_md5 value' do request_headers['x-ms-blob-content-md5'] = 'bcm-value' - subject.create_block_blob container_name, blob_name, content, {:content_md5 => 'bcm-value'} + options = {:content_md5 => 'bcm-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :cache_control value' do request_headers['x-ms-blob-cache-control'] = 'bcc-value' - subject.create_block_blob container_name, blob_name, content, {:cache_control => 'bcc-value'} + options = {:cache_control => 'bcc-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :content_disposition value' do request_headers['x-ms-blob-content-disposition'] = 'bcd-value' - subject.create_block_blob container_name, blob_name, content, {:content_disposition => 'bcd-value'} + options = {:content_disposition => 'bcd-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :transactional_md5 value' do request_headers['Content-MD5'] = 'tm-value' - subject.create_block_blob container_name, blob_name, content, {:transactional_md5 => 'tm-value'} + options = {:transactional_md5 => 'tm-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) subject.create_block_blob container_name, blob_name, content, options end it 'does not modify the request headers when provided an unknown value' do - subject.create_block_blob container_name, blob_name, content, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.create_block_blob container_name, blob_name, content, options end end end @@ -982,7 +1055,7 @@ response.stubs(:success?).returns(true) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) serialization.stubs(:block_list_to_xml).with(block_list).returns(request_body) - subject.stubs(:call).with(verb, uri, request_body, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, request_body, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -991,7 +1064,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, request_body, request_headers).returns(response) + subject.expects(:call).with(verb, uri, request_body, request_headers, {}).returns(response) subject.commit_blob_blocks container_name, blob_name, block_list end @@ -1008,68 +1081,93 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :transactional_md5 value' do request_headers['Content-MD5'] = 'tm-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:transactional_md5 => 'tm-value'} + options = {:transactional_md5 => 'tm-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :content_type value' do request_headers['x-ms-blob-content-type'] = 'bct-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:content_type => 'bct-value'} + options = {:content_type => 'bct-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :content_encoding value' do request_headers['x-ms-blob-content-encoding'] = 'bce-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:content_encoding => 'bce-value'} + options = {:content_encoding => 'bce-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :content_language value' do request_headers['x-ms-blob-content-language'] = 'bcl-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:content_language => 'bcl-value'} + options = {:content_language => 'bcl-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :content_md5 value' do request_headers['x-ms-blob-content-md5'] = 'bcm-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:content_md5 => 'bcm-value'} + options = {:content_md5 => 'bcm-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :cache_control value' do request_headers['x-ms-blob-cache-control'] = 'bcc-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:cache_control => 'bcc-value'} + options = {:cache_control => 'bcc-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :content_disposition value' do request_headers['x-ms-blob-content-disposition'] = 'bcd-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:content_disposition => 'bcd-value'} + options = {:content_disposition => 'bcd-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.commit_blob_blocks container_name, blob_name, block_list, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) subject.commit_blob_blocks container_name, blob_name, block_list, options end it 'does not modify the request headers when provided an unknown value' do - subject.commit_blob_blocks container_name, blob_name, block_list, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, request_body, request_headers, options).returns(response) + subject.commit_blob_blocks container_name, blob_name, block_list, options end end end @@ -1081,7 +1179,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri).returns(response) + subject.stubs(:call).with(verb, uri, nil, {}, {:blocklist_type => :all}).returns(response) serialization.stubs(:block_list_from_xml).with(response_body).returns(blob_block_list) } @@ -1091,7 +1189,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri).returns(response) + subject.expects(:call).with(verb, uri, nil, {}, {:blocklist_type => :all}).returns(response) subject.list_blob_blocks container_name, blob_name end @@ -1109,24 +1207,32 @@ describe 'when blocklist_type is provided' do it 'modifies the request query when the value is :all' do query['blocklisttype'] = 'all' - subject.list_blob_blocks container_name, blob_name, {:blocklist_type => :all} + options = {:blocklist_type => :all} + subject.stubs(:call).with(verb, uri, nil, {}, options).returns(response) + subject.list_blob_blocks container_name, blob_name, options end it 'modifies the request query when the value is :uncommitted' do query['blocklisttype'] = 'uncommitted' - subject.list_blob_blocks container_name, blob_name, {:blocklist_type => :uncommitted} + options = {:blocklist_type => :uncommitted} + subject.stubs(:call).with(verb, uri, nil, {}, options).returns(response) + subject.list_blob_blocks container_name, blob_name, options end it 'modifies the request query when the value is :committed' do query['blocklisttype'] = 'committed' - subject.list_blob_blocks container_name, blob_name, {:blocklist_type => :committed} + options = {:blocklist_type => :committed} + subject.stubs(:call).with(verb, uri, nil, {}, options).returns(response) + subject.list_blob_blocks container_name, blob_name, options end end describe 'when snapshot is provided' do it 'modifies the request query with the provided value' do query['snapshot'] = 'snapshot-id' - subject.list_blob_blocks container_name, blob_name, {:snapshot => 'snapshot-id'} + options = {:snapshot => 'snapshot-id'} + subject.stubs(:call).with(verb, uri, nil, {}, options).returns(response) + subject.list_blob_blocks container_name, blob_name, options end end end @@ -1138,7 +1244,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:page_list_from_xml).with(response_body).returns(page_list) } @@ -1148,7 +1254,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.list_page_blob_ranges container_name, blob_name end @@ -1191,38 +1297,49 @@ let(:request_headers) { {'x-ms-version' => x_ms_version, 'User-Agent' => user_agent} } it 'modifies the request headers with the desired range' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) request_headers['x-ms-range'] = "bytes=#{start_range}-#{end_range}" - subject.list_page_blob_ranges container_name, blob_name, {:start_range => start_range, :end_range => end_range} + options = {:start_range => start_range, :end_range => end_range} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end end describe 'when snapshot is provided' do it 'modifies the request query with the provided value' do query['snapshot'] = 'snapshot-id' - subject.list_page_blob_ranges container_name, blob_name, {:snapshot => 'snapshot-id'} + options = {:snapshot => 'snapshot-id'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end end describe 'when the option hash is used' do it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.list_page_blob_ranges container_name, blob_name, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.list_page_blob_ranges container_name, blob_name, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.list_page_blob_ranges container_name, blob_name, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.list_page_blob_ranges container_name, blob_name, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.list_page_blob_ranges container_name, blob_name, options end end end @@ -1235,33 +1352,41 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'resizes the page blob' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {:content_length => size}).returns(response) subject.resize_page_blob container_name, blob_name, size end describe 'when the option hash is used' do it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.resize_page_blob container_name, blob_name, size, {:if_modified_since => 'ims-value'} + options = {:content_length => size, :if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.resize_page_blob container_name, blob_name, size, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.resize_page_blob container_name, blob_name, size, {:if_unmodified_since => 'iums-value'} + options = {:content_length => size, :if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.resize_page_blob container_name, blob_name, size, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.resize_page_blob container_name, blob_name, size, {:if_match => 'im-value'} + options = {:content_length => size, :if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.resize_page_blob container_name, blob_name, size, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.resize_page_blob container_name, blob_name, size, {:if_none_match => 'inm-value'} + options = {:content_length => size, :if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.resize_page_blob container_name, blob_name, size, options end end end @@ -1275,34 +1400,38 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'set the page blob\'s sequence number' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + options = { :sequence_number_action => action, :sequence_number => number } + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) request_headers['x-ms-blob-sequence-number-action'] = action.to_s request_headers['x-ms-blob-sequence-number'] = number.to_s subject.set_sequence_number container_name, blob_name, action, number end it 'set the page blob\'s sequence number to the higher of current or the value in the request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) action = :max + options = { :sequence_number_action => action, :sequence_number => number } + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) request_headers['x-ms-blob-sequence-number-action'] = action.to_s request_headers['x-ms-blob-sequence-number'] = number.to_s subject.set_sequence_number container_name, blob_name, action, number end it 'increase the page blob\'s sequence number by 1' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) action = :increment + options = { :sequence_number_action => action, :sequence_number => nil } + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) request_headers['x-ms-blob-sequence-number-action'] = action.to_s subject.set_sequence_number container_name, blob_name, action, nil end it 'increase the page blob\'s sequence number should ignore the number' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) action = :increment + options = { :sequence_number_action => action, :sequence_number => number } + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) request_headers['x-ms-blob-sequence-number-action'] = action.to_s subject.set_sequence_number container_name, blob_name, action, number end @@ -1315,22 +1444,30 @@ it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.set_sequence_number container_name, blob_name, action, number, {:if_modified_since => 'ims-value'} + options = {:sequence_number_action => action, :sequence_number => number, :if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_sequence_number container_name, blob_name, action, number, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.set_sequence_number container_name, blob_name, action, number, {:if_unmodified_since => 'iums-value'} + options = {:sequence_number_action => action, :sequence_number => number, :if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_sequence_number container_name, blob_name, action, number, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.set_sequence_number container_name, blob_name, action, number, {:if_match => 'im-value'} + options = {:sequence_number_action => action, :sequence_number => number, :if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_sequence_number container_name, blob_name, action, number, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.set_sequence_number container_name, blob_name, action, number, {:if_none_match => 'inm-value'} + options = {:sequence_number_action => action, :sequence_number => number, :if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_sequence_number container_name, blob_name, action, number, options end end end @@ -1348,7 +1485,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -1358,7 +1495,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.create_append_blob container_name, blob_name end @@ -1372,69 +1509,94 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :content_type value' do request_headers['x-ms-blob-content-type'] = 'bct-value' - subject.create_append_blob container_name, blob_name, {:content_type => 'bct-value'} + options = {:content_type => 'bct-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :content_encoding value' do request_headers['x-ms-blob-content-encoding'] = 'bce-value' - subject.create_append_blob container_name, blob_name, {:content_encoding => 'bce-value'} + options = {:content_encoding => 'bce-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :content_language value' do request_headers['x-ms-blob-content-language'] = 'bcl-value' - subject.create_append_blob container_name, blob_name, {:content_language => 'bcl-value'} + options = {:content_language => 'bcl-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :content_md5 value' do request_headers['x-ms-blob-content-md5'] = 'bcm-value' - subject.create_append_blob container_name, blob_name, {:content_md5 => 'bcm-value'} + options = {:content_md5 => 'bcm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :cache_control value' do request_headers['x-ms-blob-cache-control'] = 'bcc-value' - subject.create_append_blob container_name, blob_name, {:cache_control => 'bcc-value'} + options = {:cache_control => 'bcc-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :content_disposition value' do request_headers['x-ms-blob-content-disposition'] = 'bcd-value' - subject.create_append_blob container_name, blob_name, {:content_disposition => 'bcd-value'} + options = {:content_disposition => 'bcd-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :transactional_md5 value' do request_headers['Content-MD5'] = 'tm-value' - subject.create_append_blob container_name, blob_name, {:transactional_md5 => 'tm-value'} + options = {:transactional_md5 => 'tm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.create_append_blob container_name, blob_name, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.create_append_blob container_name, blob_name, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.create_append_blob container_name, blob_name, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.create_append_blob container_name, blob_name, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.create_append_blob container_name, blob_name, options end it 'does not modify the request headers when provided an unknown value' do - subject.create_append_blob container_name, blob_name, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_append_blob container_name, blob_name, options end end end @@ -1451,7 +1613,7 @@ before { query.update({'comp' => 'appendblock'}) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, content, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, content, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -1460,53 +1622,71 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, content, request_headers).returns(response) + subject.expects(:call).with(verb, uri, content, request_headers, {}).returns(response) subject.append_blob_block container_name, blob_name, content end describe 'when the options Hash is used' do it 'modifies the request headers when provided a :content_md5 value' do request_headers['Content-MD5'] = content_md5 - subject.append_blob_block container_name, blob_name, content, {:content_md5 => content_md5} + options = {:content_md5 => content_md5} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :lease_id value' do request_headers['x-ms-lease-id'] = lease_id - subject.append_blob_block container_name, blob_name, content, {:lease_id => lease_id} + options = {:lease_id => lease_id} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :max_size value' do request_headers['x-ms-blob-condition-maxsize'] = max_size - subject.append_blob_block container_name, blob_name, content, {:max_size => max_size} + options = {:max_size => max_size} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :append_position value' do request_headers['x-ms-blob-condition-appendpos'] = append_position - subject.append_blob_block container_name, blob_name, content, {:append_position => append_position} + options = {:append_position => append_position} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.append_blob_block container_name, blob_name, content, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.append_blob_block container_name, blob_name, content, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.append_blob_block container_name, blob_name, content, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.append_blob_block container_name, blob_name, content, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end it 'does not modify the request headers when provided an unknown value' do - subject.append_blob_block container_name, blob_name, content, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, content, request_headers, options).returns(response) + subject.append_blob_block container_name, blob_name, content, options end end end @@ -1519,7 +1699,7 @@ query.update({'comp' => 'properties'}) response.stubs(:success?).returns(true) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -1528,7 +1708,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_blob_properties container_name, blob_name end @@ -1540,52 +1720,72 @@ describe 'when the options Hash is used' do it 'modifies the request headers when provided a :content_type value' do request_headers['x-ms-blob-content-type'] = 'bct-value' - subject.set_blob_properties container_name, blob_name, {:content_type => 'bct-value'} + options = {:content_type => 'bct-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :content_encoding value' do request_headers['x-ms-blob-content-encoding'] = 'bce-value' - subject.set_blob_properties container_name, blob_name, {:content_encoding => 'bce-value'} + options = {:content_encoding => 'bce-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :content_language value' do request_headers['x-ms-blob-content-language'] = 'bcl-value' - subject.set_blob_properties container_name, blob_name, {:content_language => 'bcl-value'} + options = {:content_language => 'bcl-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :content_md5 value' do request_headers['x-ms-blob-content-md5'] = 'bcm-value' - subject.set_blob_properties container_name, blob_name, {:content_md5 => 'bcm-value'} + options = {:content_md5 => 'bcm-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :cache_control value' do request_headers['x-ms-blob-cache-control'] = 'bcc-value' - subject.set_blob_properties container_name, blob_name, {:cache_control => 'bcc-value'} + options = {:cache_control => 'bcc-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :content_length value' do request_headers['x-ms-blob-content-length'] = '37' - subject.set_blob_properties container_name, blob_name, {:content_length => 37.to_s} + options = {:content_length => 37.to_s} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :content_disposition value' do request_headers['x-ms-blob-content-disposition'] = 'bcd-value' - subject.set_blob_properties container_name, blob_name, {:content_disposition => 'bcd-value'} + options = {:content_disposition => 'bcd-value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :sequence_number_action value' do request_headers['x-ms-blob-sequence-number-action'] = 'anyvalue' - subject.set_blob_properties container_name, blob_name, {:sequence_number_action => :anyvalue} + options = {:sequence_number_action => :anyvalue} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'modifies the request headers when provided a :sequence_number value' do request_headers['x-ms-blob-sequence-number-action'] = :max.to_s request_headers['x-ms-blob-sequence-number'] = '37' - subject.set_blob_properties container_name, blob_name, {:sequence_number_action => :max, :sequence_number => 37} + options = {:sequence_number_action => :max, :sequence_number => 37} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end it 'does not modify the request headers when provided an unknown value' do - subject.set_blob_properties container_name, blob_name, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.set_blob_properties container_name, blob_name, options end end end @@ -1599,7 +1799,7 @@ query.update({'comp' => 'metadata'}) response.stubs(:success?).returns(true) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -1608,7 +1808,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.set_blob_metadata container_name, blob_name, blob_metadata end @@ -1624,7 +1824,7 @@ before { subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -1634,7 +1834,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.get_blob_properties container_name, blob_name end @@ -1651,12 +1851,16 @@ before { query['snapshot']=snapshot } it 'modifies the blob uri query string with the snapshot' do + options = {:snapshot => snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.get_blob_properties container_name, blob_name, {:snapshot => snapshot} + subject.get_blob_properties container_name, blob_name, options end it 'sets the snapshot value on the returned blob' do - result = subject.get_blob_properties container_name, blob_name, {:snapshot => snapshot} + options = {:snapshot => snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + result = subject.get_blob_properties container_name, blob_name, options result.snapshot.must_equal snapshot end end @@ -1670,7 +1874,7 @@ query['comp']='metadata' subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -1680,7 +1884,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.get_blob_metadata container_name, blob_name end @@ -1701,11 +1905,15 @@ it 'modifies the blob uri query string with the snapshot' do subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.get_blob_metadata container_name, blob_name, {:snapshot => snapshot} + options = {:snapshot => snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.get_blob_metadata container_name, blob_name, options end it 'sets the snapshot value on the returned blob' do - result = subject.get_blob_metadata container_name, blob_name, {:snapshot => snapshot} + options = {:snapshot => snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + result = subject.get_blob_metadata container_name, blob_name, options result.snapshot.must_equal snapshot end end @@ -1719,7 +1927,7 @@ response_body = 'body-contents' subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) serialization.stubs(:blob_from_headers).with(response_headers).returns(blob) } @@ -1729,7 +1937,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.get_blob container_name, blob_name end @@ -1748,7 +1956,9 @@ it 'modifies the blob uri query string with the snapshot' do subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.get_blob container_name, blob_name, {:snapshot => source_snapshot} + options = {:snapshot => source_snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.get_blob container_name, blob_name, options end end @@ -1780,8 +1990,9 @@ } it 'modifies the request headers with the desired range' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.get_blob container_name, blob_name, {:start_range => start_range, :end_range => end_range} + options = {:start_range => start_range, :end_range => end_range} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.get_blob container_name, blob_name, options end end @@ -1797,15 +2008,17 @@ } it 'modifies the request headers to include the x-ms-range-get-content-md5 header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.get_blob container_name, blob_name, {:start_range => start_range, :end_range => end_range, :get_content_md5 => true} + options = {:start_range => start_range, :end_range => end_range, :get_content_md5 => true} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.get_blob container_name, blob_name, options end end describe 'and a range is NOT specified' do it 'does not modify the request headers' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.get_blob container_name, blob_name, {:get_content_md5 => true} + options = {:get_content_md5 => true} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.get_blob container_name, blob_name, options end end end @@ -1820,7 +2033,7 @@ request_headers['x-ms-version'] = x_ms_version subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {:delete_snapshots => :include}).returns(response) } it 'assembles a URI for the request' do @@ -1829,7 +2042,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {:delete_snapshots => :include}).returns(response) subject.delete_blob container_name, blob_name end @@ -1846,13 +2059,16 @@ } it 'modifies the blob uri query string with the snapshot' do + options = {:snapshot => source_snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.delete_blob container_name, blob_name, {:snapshot => source_snapshot} + subject.delete_blob container_name, blob_name, options end it 'does not include a x-ms-delete-snapshots header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.delete_blob container_name, blob_name, {:snapshot => source_snapshot} + options = {:snapshot => source_snapshot} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.delete_blob container_name, blob_name, options end end @@ -1861,8 +2077,9 @@ before { request_headers['x-ms-delete-snapshots']=delete_snapshots.to_s } it 'modifies the request headers with the provided value' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.delete_blob container_name, blob_name, {:delete_snapshots => delete_snapshots} + options = {:delete_snapshots => delete_snapshots} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.delete_blob container_name, blob_name, options end end @@ -1875,13 +2092,17 @@ } it 'modifies the blob uri query string with the snapshot' do + options = {:snapshot => source_snapshot, :delete_snapshots => delete_snapshots} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.delete_blob container_name, blob_name, {:snapshot => source_snapshot, :delete_snapshots => delete_snapshots} + subject.delete_blob container_name, blob_name, options end it 'does not include a x-ms-delete-snapshots header' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.delete_blob container_name, blob_name, {:snapshot => source_snapshot, :delete_snapshots => delete_snapshots} + options = {:snapshot => source_snapshot, :delete_snapshots => delete_snapshots} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.delete_blob container_name, blob_name, options end end end @@ -1896,7 +2117,7 @@ response_headers['x-ms-snapshot'] = snapshot_id subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -1905,7 +2126,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.create_blob_snapshot container_name, blob_name end @@ -1916,39 +2137,46 @@ end describe 'when the options Hash is used' do - before { - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - } - it 'modifies the request headers when provided a :if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.create_blob_snapshot container_name, blob_name, {:if_modified_since => 'ims-value'} + options = {:if_modified_since => 'ims-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_blob_snapshot container_name, blob_name, options end it 'modifies the request headers when provided a :if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.create_blob_snapshot container_name, blob_name, {:if_unmodified_since => 'iums-value'} + options = {:if_unmodified_since => 'iums-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_blob_snapshot container_name, blob_name, options end it 'modifies the request headers when provided a :if_match value' do request_headers['If-Match'] = 'im-value' - subject.create_blob_snapshot container_name, blob_name, {:if_match => 'im-value'} + options = {:if_match => 'im-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_blob_snapshot container_name, blob_name, options end it 'modifies the request headers when provided a :if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.create_blob_snapshot container_name, blob_name, {:if_none_match => 'inm-value'} + options = {:if_none_match => 'inm-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_blob_snapshot container_name, blob_name, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.create_blob_snapshot container_name, blob_name, options end it 'does not modify the request headers when provided an unknown value' do - subject.create_blob_snapshot container_name, blob_name, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.create_blob_snapshot container_name, blob_name, options end end end @@ -1970,7 +2198,7 @@ subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri) subject.stubs(:blob_uri).with(source_container_name, source_blob_name, query).returns(source_uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } it 'assembles a URI for the request' do @@ -1985,12 +2213,12 @@ it 'calls with source URI' do subject.expects(:blob_uri).with(container_name, blob_name, {}).returns(uri) - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.copy_blob_from_uri container_name, blob_name, source_uri.to_s end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.copy_blob container_name, blob_name, source_container_name, source_blob_name end @@ -2008,64 +2236,81 @@ it 'modifies the source blob uri query string with the snapshot' do subject.expects(:blob_uri).with(source_container_name, source_blob_name, query).returns(source_uri) - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:source_snapshot => source_snapshot} + options = {:source_snapshot => source_snapshot} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end end describe 'when the options Hash is used' do - before { - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - } - it 'modifies the request headers when provided a :dest_if_modified_since value' do request_headers['If-Modified-Since'] = 'ims-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:dest_if_modified_since => 'ims-value'} + options = {:dest_if_modified_since => 'ims-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :dest_if_unmodified_since value' do request_headers['If-Unmodified-Since'] = 'iums-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:dest_if_unmodified_since => 'iums-value'} + options = {:dest_if_unmodified_since => 'iums-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :dest_if_match value' do request_headers['If-Match'] = 'im-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:dest_if_match => 'im-value'} + options = {:dest_if_match => 'im-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :dest_if_none_match value' do request_headers['If-None-Match'] = 'inm-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:dest_if_none_match => 'inm-value'} + options = {:dest_if_none_match => 'inm-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :source_if_modified_since value' do request_headers['x-ms-source-if-modified-since'] = 'ims-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:source_if_modified_since => 'ims-value'} + options = {:source_if_modified_since => 'ims-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :source_if_unmodified_since value' do request_headers['x-ms-source-if-unmodified-since'] = 'iums-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:source_if_unmodified_since => 'iums-value'} + options = {:source_if_unmodified_since => 'iums-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :source_if_match value' do request_headers['x-ms-source-if-match'] = 'im-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:source_if_match => 'im-value'} + options = {:source_if_match => 'im-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :source_if_none_match value' do request_headers['x-ms-source-if-none-match'] = 'inm-value' - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:source_if_none_match => 'inm-value'} + options = {:source_if_none_match => 'inm-value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'modifies the request headers when provided a :metadata value' do request_headers['x-ms-meta-MetadataKey'] = 'MetaDataValue' request_headers['x-ms-meta-MetadataKey1'] = 'MetaDataValue1' options = {:metadata => {'MetadataKey' => 'MetaDataValue', 'MetadataKey1' => 'MetaDataValue1'}} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end it 'does not modify the request headers when provided an unknown value' do - subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, {:unknown_key => 'some_value'} + options = {:unknown_key => 'some_value'} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options end end end @@ -2080,7 +2325,7 @@ query.update({'comp' => 'copy', 'copyid' => copy_id}) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + } it 'abort copy a blob' do @@ -2091,7 +2336,9 @@ it 'abort copy a blob with an active lease' do request_headers['x-ms-lease-id'] = lease_id subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri) - subject.abort_copy_blob container_name, blob_name, copy_id, {:lease_id => lease_id} + options = {:lease_id => lease_id} + subject.stubs(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.abort_copy_blob container_name, blob_name, copy_id, options end end @@ -2103,7 +2350,7 @@ query.update({'comp' => 'lease'}) subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri) subject.stubs(:container_uri).with(container_name, query).returns(uri) - subject.stubs(:call).with(verb, uri, nil, request_headers).returns(response) + subject.stubs(:call).with(verb, uri, nil, request_headers, {}).returns(response) } describe '#acquire_blob_lease' do @@ -2121,7 +2368,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.acquire_blob_lease container_name, blob_name end @@ -2135,8 +2382,9 @@ before { request_headers['x-ms-lease-duration'] = '37' } it 'modifies the headers to include the provided duration value' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.acquire_blob_lease container_name, blob_name, {:duration => duration} + options = {:duration => duration} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.acquire_blob_lease container_name, blob_name, options end end @@ -2146,8 +2394,9 @@ before { request_headers['x-ms-proposed-lease-id'] = proposed_lease_id } it 'modifies the headers to include the proposed lease id' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.acquire_blob_lease container_name, blob_name, {:duration => default_duration, :proposed_lease_id => proposed_lease_id} + options = {:duration => default_duration, :proposed_lease_id => proposed_lease_id} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.acquire_blob_lease container_name, blob_name, options end end end @@ -2167,7 +2416,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.renew_blob_lease container_name, blob_name, lease_id end @@ -2194,7 +2443,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.change_blob_lease container_name, blob_name, lease_id, proposed_lease_id end @@ -2218,7 +2467,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.release_blob_lease container_name, blob_name, lease_id end @@ -2243,7 +2492,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.break_blob_lease container_name, blob_name end @@ -2257,8 +2506,9 @@ before { request_headers['x-ms-lease-break-period'] = break_period.to_s } it 'modifies the request headers to include a break period' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.break_blob_lease container_name, blob_name, {:break_period => break_period} + option = {:break_period => break_period} + subject.expects(:call).with(verb, uri, nil, request_headers, option).returns(response) + subject.break_blob_lease container_name, blob_name, option end end end @@ -2278,7 +2528,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.acquire_container_lease container_name end @@ -2292,8 +2542,9 @@ before { request_headers['x-ms-lease-duration'] = '37' } it 'modifies the headers to include the provided duration value' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.acquire_container_lease container_name, {:duration => duration} + options = {:duration => duration} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.acquire_container_lease container_name, options end end @@ -2303,8 +2554,9 @@ before { request_headers['x-ms-proposed-lease-id'] = proposed_lease_id } it 'modifies the headers to include the proposed lease id' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.acquire_container_lease container_name, {:duration => default_duration, :proposed_lease_id => proposed_lease_id} + options = {:duration => default_duration, :proposed_lease_id => proposed_lease_id} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.acquire_container_lease container_name, options end end end @@ -2324,7 +2576,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.renew_container_lease container_name, lease_id end @@ -2348,7 +2600,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.release_container_lease container_name, lease_id end @@ -2373,7 +2625,7 @@ end it 'calls StorageService#call with the prepared request' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) + subject.expects(:call).with(verb, uri, nil, request_headers, {}).returns(response) subject.break_container_lease container_name end @@ -2387,8 +2639,9 @@ before { request_headers['x-ms-lease-break-period'] = break_period.to_s } it 'modifies the request headers to include a break period' do - subject.expects(:call).with(verb, uri, nil, request_headers).returns(response) - subject.break_container_lease container_name, {:break_period => break_period} + options = {:break_period => break_period} + subject.expects(:call).with(verb, uri, nil, request_headers, options).returns(response) + subject.break_container_lease container_name, options end end end diff --git a/test/unit/service/storage_service_test.rb b/test/unit/service/storage_service_test.rb index cbd60516..8b2a2111 100644 --- a/test/unit/service/storage_service_test.rb +++ b/test/unit/service/storage_service_test.rb @@ -56,6 +56,18 @@ mock_request.expects(:call) end + it 'adds a client request id' do + Azure::Core::Http::HttpRequest.stubs(:new).with(verb, + uri, + { + body: nil, + headers: {'x-ms-client-request-id' => 'client-request-id'}, + client: nil + }).returns(mock_request) + mock_request.expects(:with_filter).with(mock_signer_filter) + subject.call(verb, uri, nil, {}, {:request_id => 'client-request-id'}) + end + it 'adds a SignerFilter to the HTTP pipeline' do mock_request.expects(:with_filter).with(mock_signer_filter) subject.call(verb, uri) @@ -160,7 +172,7 @@ before do Azure::Storage::Service::Serialization.stubs(:service_properties_from_xml).with(service_properties_xml).returns(service_properties) subject.stubs(:service_properties_uri).returns(service_properties_uri) - subject.stubs(:call).with(:get, service_properties_uri).returns(response) + subject.stubs(:call).with(:get, service_properties_uri, nil, {}, {}).returns(response) end it 'calls the service_properties_uri method to determine the correct uri' do @@ -169,7 +181,7 @@ end it 'gets the response from the HTTP API' do - subject.expects(:call).with(:get, service_properties_uri).returns(response) + subject.expects(:call).with(:get, service_properties_uri, nil, {}, {}).returns(response) subject.get_service_properties end @@ -198,7 +210,7 @@ before do Azure::Storage::Service::Serialization.stubs(:service_properties_to_xml).with(service_properties).returns(service_properties_xml) subject.stubs(:service_properties_uri).returns(service_properties_uri) - subject.stubs(:call).with(:put, service_properties_uri, service_properties_xml).returns(response) + subject.stubs(:call).with(:put, service_properties_uri, service_properties_xml, {}, {}).returns(response) end it 'calls the service_properties_uri method to determine the correct uri' do @@ -207,7 +219,7 @@ end it 'posts to the HTTP API' do - subject.expects(:call).with(:put, service_properties_uri, service_properties_xml).returns(response) + subject.expects(:call).with(:put, service_properties_uri, service_properties_xml, {}, {}).returns(response) subject.set_service_properties service_properties end