azure-storage-blob 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,530 +1,530 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
-
27
- require "base64"
28
-
29
- module Azure::Storage
30
- module Blob
31
- # Represents a Block as part of a BlockList
32
- # The type should be one of :uncommitted, :committed or :latest
33
- class Block
34
- def initialize
35
- @type = :latest
36
- yield self if block_given?
37
- end
38
-
39
- attr_accessor :name
40
- attr_accessor :size
41
- attr_accessor :type
42
- end
43
-
44
- # Public: Creates a new block blob or updates the content of an existing block blob.
45
- #
46
- # Updating an existing block blob overwrites any existing metadata on the blob
47
- # Partial updates are not supported with create_block_blob the content of the
48
- # existing blob is overwritten with the content of the new blob. To perform a
49
- # partial update of the content of a block blob, use the create_block_list
50
- # method.
51
- #
52
- # Note that the default content type is application/octet-stream.
53
- #
54
- # ==== Attributes
55
- #
56
- # * +container+ - String. The container name.
57
- # * +blob+ - String. The blob name.
58
- # * +content+ - IO or String. The content of the blob.
59
- # * +options+ - Hash. Optional parameters.
60
- #
61
- # ==== Options
62
- #
63
- # Accepted key/value pairs in options parameter are:
64
- # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
65
- # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
66
- # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
67
- # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used.
68
- # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
69
- # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
70
- # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
71
- # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
72
- # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
73
- # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
74
- # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
75
- # and also can be used to attach additional metadata
76
- # * +:metadata+ - Hash. Custom metadata values to store with the blob.
77
- # * +:timeout+ - Integer. A timeout in seconds.
78
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
79
- # in the analytics logs when storage analytics logging is enabled.
80
- # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
81
- # only if the blob has been modified since the specified date/time. If the blob has not been modified,
82
- # the Blob service returns status code 412 (Precondition Failed).
83
- # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
84
- # only if the blob has not been modified since the specified date/time. If the blob has been modified,
85
- # the Blob service returns status code 412 (Precondition Failed).
86
- # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
87
- # only if the blob's ETag value matches the value specified. If the values do not match,
88
- # the Blob service returns status code 412 (Precondition Failed).
89
- # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
90
- # only if the blob's ETag value does not match the value specified. If the values are identical,
91
- # the Blob service returns status code 412 (Precondition Failed).
92
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
93
- # specify the valid lease ID for this header.
94
- #
95
- # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
96
- #
97
- # Returns a Blob
98
- def create_block_blob(container, blob, content, options = {})
99
- size = if content.respond_to? :size
100
- content.size
101
- elsif options[:content_length]
102
- options[:content_length]
103
- else
104
- raise ArgumentError, "Either optional parameter 'content_length' should be set or 'content' should implement 'size' method to get payload's size."
105
- end
106
-
107
- threshold = get_single_upload_threshold(options[:single_upload_threshold])
108
- if size > threshold
109
- create_block_blob_multiple_put(container, blob, content, size, options)
110
- else
111
- create_block_blob_single_put(container, blob, content, options)
112
- end
113
- end
114
-
115
- # Public: Creates a new block to be committed as part of a block blob.
116
- #
117
- # ==== Attributes
118
- #
119
- # * +container+ - String. The container name.
120
- # * +blob+ - String. The blob name.
121
- # * +block_id+ - String. The block id. Note: this should be the raw block id, not Base64 encoded.
122
- # * +content+ - IO or String. The content of the blob.
123
- # * +options+ - Hash. Optional parameters.
124
- #
125
- # ==== Options
126
- #
127
- # Accepted key/value pairs in options parameter are:
128
- # * +:content_md5+ - String. Content MD5 for the request contents.
129
- # * +:timeout+ - Integer. A timeout in seconds.
130
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
131
- # in the analytics logs when storage analytics logging is enabled.
132
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an
133
- # active lease, specify the valid lease ID for this header.
134
- #
135
- # See http://msdn.microsoft.com/en-us/library/azure/dd135726.aspx
136
- #
137
- # Returns response of the operation
138
- def put_blob_block(container, blob, block_id, content, options = {})
139
- query = { "comp" => "block" }
140
- StorageService.with_query query, "blockid", Base64.strict_encode64(block_id)
141
- StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
142
-
143
- uri = blob_uri(container, blob, query)
144
-
145
- headers = {}
146
- StorageService.with_header headers, "Content-MD5", options[:content_md5]
147
- headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id]
148
-
149
- response = call(:put, uri, content, headers, options)
150
- response.headers["Content-MD5"]
151
- end
152
-
153
- # Public: Commits existing blob blocks to a blob.
154
- #
155
- # This method writes a blob by specifying the list of block IDs that make up the
156
- # blob. In order to be written as part of a blob, a block must have been
157
- # successfully written to the server in a prior put_blob_block method.
158
- #
159
- # You can call Put Block List to update a blob by uploading only those blocks
160
- # that have changed, then committing the new and existing blocks together.
161
- # You can do this by specifying whether to commit a block from the committed
162
- # block list or from the uncommitted block list, or to commit the most recently
163
- # uploaded version of the block, whichever list it may belong to.
164
- #
165
- # ==== Attributes
166
- #
167
- # * +container+ - String. The container name.
168
- # * +blob+ - String. The blob name.
169
- # * +block_list+ - Array. A ordered list of lists in the following format:
170
- # [ ["block_id1", :committed], ["block_id2", :uncommitted], ["block_id3"], ["block_id4", :committed]... ]
171
- # The first element of the inner list is the block_id, the second is optional
172
- # and can be either :committed or :uncommitted to indicate in which group of blocks
173
- # the id should be looked for. If it is omitted, the latest of either group will be used.
174
- # * +options+ - Hash. Optional parameters.
175
- #
176
- # ==== Options
177
- #
178
- # Accepted key/value pairs in options parameter are:
179
- # * +:transactional_md5+ - String. Content MD5 for the request contents (not the blob contents!)
180
- # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
181
- # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
182
- # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
183
- # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
184
- # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
185
- # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
186
- # and also can be used to attach additional metadata
187
- # * +:metadata+ - Hash. Custom metadata values to store with the blob.
188
- # * +:timeout+ - Integer. A timeout in seconds.
189
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
190
- # in the analytics logs when storage analytics logging is enabled.
191
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an
192
- # active lease, specify the valid lease ID for this header.
193
- #
194
- # This operation also supports the use of conditional headers to commit the block list if a specified condition is met.
195
- # For more information, see https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx
196
- #
197
- # See http://msdn.microsoft.com/en-us/library/azure/dd179467.aspx
198
- #
199
- # Returns nil on success
200
- def commit_blob_blocks(container, blob, block_list, options = {})
201
- query = { "comp" => "blocklist" }
202
- StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
203
-
204
- uri = blob_uri(container, blob, query)
205
-
206
- headers = {}
207
- unless options.empty?
208
- StorageService.with_header headers, "Content-MD5", options[:transactional_md5]
209
- StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type]
210
- StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding]
211
- StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language]
212
- StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5]
213
- StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control]
214
- StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition]
215
-
216
- StorageService.add_metadata_to_headers(options[:metadata], headers)
217
- add_blob_conditional_headers(options, headers)
218
- headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id]
219
- end
220
- headers["x-ms-blob-content-type"] = Default::CONTENT_TYPE_VALUE unless headers["x-ms-blob-content-type"]
221
- body = Serialization.block_list_to_xml(block_list)
222
- call(:put, uri, body, headers, options)
223
- nil
224
- end
225
-
226
- # Public: Retrieves the list of blocks that have been uploaded as part of a block blob.
227
- #
228
- # There are two block lists maintained for a blob:
229
- # 1) Committed Block List: The list of blocks that have been successfully
230
- # committed to a given blob with commitBlobBlocks.
231
- # 2) Uncommitted Block List: The list of blocks that have been uploaded for a
232
- # blob using Put Block (REST API), but that have not yet been committed.
233
- # These blocks are stored in Microsoft Azure in association with a blob, but do
234
- # not yet form part of the blob.
235
- #
236
- # ==== Attributes
237
- #
238
- # * +container+ - String. The container name.
239
- # * +blob+ - String. The blob name.
240
- # * +options+ - Hash. Optional parameters.
241
- #
242
- # ==== Options
243
- #
244
- # Accepted key/value pairs in options parameter are:
245
- # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional)
246
- # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
247
- # retrieve information from. (optional)
248
- # * +:timeout+ - Integer. A timeout in seconds.
249
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
250
- # in the analytics logs when storage analytics logging is enabled.
251
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
252
- # which location the request should be sent to.
253
- # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the
254
- # following conditions are met:
255
- # - The blob's lease is currently active.
256
- # - The lease ID specified in the request matches that of the blob.
257
- # If this header is specified and both of these conditions are not met, the request will fail
258
- # and the operation will fail with status code 412 (Precondition Failed).
259
- #
260
- # See http://msdn.microsoft.com/en-us/library/azure/dd179400.aspx
261
- #
262
- # Returns a list of Azure::Storage::Entity::Blob::Block instances
263
- def list_blob_blocks(container, blob, options = {})
264
- options[:blocklist_type] = options[:blocklist_type] || :all
265
-
266
- query = { "comp" => "blocklist" }
267
- StorageService.with_query query, "snapshot", options[:snapshot]
268
- StorageService.with_query query, "blocklisttype", options[:blocklist_type].to_s if options[:blocklist_type]
269
- StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
270
-
271
- headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {}
272
-
273
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
274
- uri = blob_uri(container, blob, query, options)
275
-
276
- response = call(:get, uri, nil, headers, options)
277
-
278
- Serialization.block_list_from_xml(response.body)
279
- end
280
-
281
- # Public: Creates a new block blob or updates the content of an existing block blob.
282
- #
283
- # Updating an existing block blob overwrites any existing metadata on the blob
284
- # Partial updates are not supported with create_block_blob the content of the
285
- # existing blob is overwritten with the content of the new blob. To perform a
286
- # partial update of the content of a block blob, use the create_block_list
287
- # method.
288
- #
289
- # Note that the default content type is application/octet-stream.
290
- #
291
- # ==== Attributes
292
- #
293
- # * +container+ - String. The container name.
294
- # * +blob+ - String. The blob name.
295
- # * +content+ - IO or String. The content of the blob.
296
- # * +options+ - Hash. Optional parameters.
297
- #
298
- # ==== Options
299
- #
300
- # Accepted key/value pairs in options parameter are:
301
- # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
302
- # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
303
- # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
304
- # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used.
305
- # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
306
- # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
307
- # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
308
- # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
309
- # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
310
- # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
311
- # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
312
- # and also can be used to attach additional metadata
313
- # * +:metadata+ - Hash. Custom metadata values to store with the blob.
314
- # * +:timeout+ - Integer. A timeout in seconds.
315
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
316
- # in the analytics logs when storage analytics logging is enabled.
317
- # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
318
- # only if the blob has been modified since the specified date/time. If the blob has not been modified,
319
- # the Blob service returns status code 412 (Precondition Failed).
320
- # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
321
- # only if the blob has not been modified since the specified date/time. If the blob has been modified,
322
- # the Blob service returns status code 412 (Precondition Failed).
323
- # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
324
- # only if the blob's ETag value matches the value specified. If the values do not match,
325
- # the Blob service returns status code 412 (Precondition Failed).
326
- # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
327
- # only if the blob's ETag value does not match the value specified. If the values are identical,
328
- # the Blob service returns status code 412 (Precondition Failed).
329
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
330
- # specify the valid lease ID for this header.
331
- #
332
- # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
333
- #
334
- # Returns a Blob
335
- alias create_block_blob_from_content create_block_blob
336
-
337
- # Protected: Creates a new block blob or updates the content of an existing block blob with single API call
338
- #
339
- # Updating an existing block blob overwrites any existing metadata on the blob
340
- # Partial updates are not supported with create_block_blob the content of the
341
- # existing blob is overwritten with the content of the new blob. To perform a
342
- # partial update of the content of a block blob, use the create_block_list
343
- # method.
344
- #
345
- # Note that the default content type is application/octet-stream.
346
- #
347
- # ==== Attributes
348
- #
349
- # * +container+ - String. The container name.
350
- # * +blob+ - String. The blob name.
351
- # * +content+ - IO or String. The content of the blob.
352
- # * +options+ - Hash. Optional parameters.
353
- #
354
- # ==== Options
355
- #
356
- # Accepted key/value pairs in options parameter are:
357
- # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
358
- # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
359
- # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
360
- # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
361
- # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
362
- # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
363
- # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
364
- # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
365
- # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
366
- # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
367
- # and also can be used to attach additional metadata
368
- # * +:metadata+ - Hash. Custom metadata values to store with the blob.
369
- # * +:timeout+ - Integer. A timeout in seconds.
370
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
371
- # in the analytics logs when storage analytics logging is enabled.
372
- # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
373
- # only if the blob has been modified since the specified date/time. If the blob has not been modified,
374
- # the Blob service returns status code 412 (Precondition Failed).
375
- # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
376
- # only if the blob has not been modified since the specified date/time. If the blob has been modified,
377
- # the Blob service returns status code 412 (Precondition Failed).
378
- # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
379
- # only if the blob's ETag value matches the value specified. If the values do not match,
380
- # the Blob service returns status code 412 (Precondition Failed).
381
- # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
382
- # only if the blob's ETag value does not match the value specified. If the values are identical,
383
- # the Blob service returns status code 412 (Precondition Failed).
384
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
385
- # specify the valid lease ID for this header.
386
- #
387
- # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
388
- #
389
- # Returns a Blob
390
- protected
391
- def create_block_blob_single_put(container, blob, content, options = {})
392
- query = {}
393
- StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
394
-
395
- uri = blob_uri(container, blob, query)
396
-
397
- headers = {}
398
-
399
- # set x-ms-blob-type to BlockBlob
400
- StorageService.with_header headers, "x-ms-blob-type", "BlockBlob"
401
-
402
- # set the rest of the optional headers
403
- StorageService.with_header headers, "Content-MD5", options[:transactional_md5]
404
- StorageService.with_header headers, "Content-Length", options[:content_length]
405
- StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding]
406
- StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language]
407
- StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5]
408
- StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control]
409
- StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition]
410
- StorageService.with_header headers, "x-ms-lease-id", options[:lease_id]
411
-
412
- StorageService.add_metadata_to_headers options[:metadata], headers
413
- add_blob_conditional_headers options, headers
414
- headers["x-ms-blob-content-type"] = get_or_apply_content_type(content, options[:content_type])
415
- # call PutBlob
416
- response = call(:put, uri, content, headers, options)
417
-
418
- result = Serialization.blob_from_headers(response.headers)
419
- result.name = blob
420
- result.metadata = options[:metadata] if options[:metadata]
421
-
422
- result
423
- end
424
-
425
- # Protected: Creates a new block blob or updates the content of an existing block blob with multiple upload
426
- #
427
- # Updating an existing block blob overwrites any existing metadata on the blob
428
- # Partial updates are not supported with create_block_blob the content of the
429
- # existing blob is overwritten with the content of the new blob. To perform a
430
- # partial update of the content of a block blob, use the create_block_list
431
- # method.
432
- #
433
- # Note that the default content type is application/octet-stream.
434
- #
435
- # ==== Attributes
436
- #
437
- # * +container+ - String. The container name.
438
- # * +blob+ - String. The blob name.
439
- # * +content+ - IO or String. The content of the blob.
440
- # * +size+ - Integer. The size of the content.
441
- # * +options+ - Hash. Optional parameters.
442
- #
443
- # ==== Options
444
- #
445
- # Accepted key/value pairs in options parameter are:
446
- # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
447
- # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
448
- # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
449
- # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
450
- # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
451
- # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
452
- # and also can be used to attach additional metadata
453
- # * +:metadata+ - Hash. Custom metadata values to store with the blob.
454
- # * +:timeout+ - Integer. A timeout in seconds.
455
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
456
- # in the analytics logs when storage analytics logging is enabled.
457
- # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
458
- # specify the valid lease ID for this header.
459
- #
460
- # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
461
- #
462
- # Returns a Blob
463
- protected
464
- def create_block_blob_multiple_put(container, blob, content, size, options = {})
465
- content_type = get_or_apply_content_type(content, options[:content_type])
466
- content = StringIO.new(content) if content.is_a? String
467
- block_size = get_block_size(size)
468
- # Get the number of blocks
469
- block_count = (Float(size) / Float(block_size)).ceil
470
- block_list = []
471
- for block_id in 0...block_count
472
- id = block_id.to_s.rjust(6, "0")
473
- put_blob_block(container, blob, id, content.read(block_size), timeout: options[:timeout], lease_id: options[:lease_id])
474
- block_list.push([id])
475
- end
476
-
477
- # Commit the blocks put
478
- commit_options = {}
479
- commit_options[:content_type] = content_type
480
- commit_options[:content_encoding] = options[:content_encoding] if options[:content_encoding]
481
- commit_options[:content_language] = options[:content_language] if options[:content_language]
482
- commit_options[:content_md5] = options[:content_md5] if options[:content_md5]
483
- commit_options[:cache_control] = options[:cache_control] if options[:cache_control]
484
- commit_options[:content_disposition] = options[:content_disposition] if options[:content_disposition]
485
- commit_options[:metadata] = options[:metadata] if options[:metadata]
486
- commit_options[:timeout] = options[:timeout] if options[:timeout]
487
- commit_options[:request_id] = options[:request_id] if options[:request_id]
488
- commit_options[:lease_id] = options[:lease_id] if options[:lease_id]
489
-
490
- commit_blob_blocks(container, blob, block_list, commit_options)
491
-
492
- get_properties_options = {}
493
- get_properties_options[:lease_id] = options[:lease_id] if options[:lease_id]
494
-
495
- # Get the blob properties
496
- get_blob_properties(container, blob, get_properties_options)
497
- end
498
-
499
- # Protected: Gets the single upload threshold according to user's preference
500
- #
501
- # ==== Attributes
502
- #
503
- # * +container+ - String. The container name.
504
- #
505
- # Returns an Integer
506
- protected
507
- def get_single_upload_threshold(userThreshold)
508
- if userThreshold.nil?
509
- BlobConstants::DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES
510
- elsif userThreshold <= 0
511
- raise ArgumentError, "Single Upload Threshold should be positive number"
512
- elsif userThreshold < BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES
513
- userThreshold
514
- else
515
- BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES
516
- end
517
- end
518
-
519
- protected
520
- def get_block_size(size)
521
- if size > BlobConstants::MAX_BLOCK_BLOB_SIZE
522
- raise ArgumentError, "Block blob size should be less than #{BlobConstants::MAX_BLOCK_BLOB_SIZE} bytes in size"
523
- elsif (size / BlobConstants::MAX_BLOCK_COUNT) < BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES
524
- BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES
525
- else
526
- BlobConstants::MAX_BLOCK_SIZE
527
- end
528
- end
529
- end
530
- end
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+
27
+ require "base64"
28
+
29
+ module Azure::Storage
30
+ module Blob
31
+ # Represents a Block as part of a BlockList
32
+ # The type should be one of :uncommitted, :committed or :latest
33
+ class Block
34
+ def initialize
35
+ @type = :latest
36
+ yield self if block_given?
37
+ end
38
+
39
+ attr_accessor :name
40
+ attr_accessor :size
41
+ attr_accessor :type
42
+ end
43
+
44
+ # Public: Creates a new block blob or updates the content of an existing block blob.
45
+ #
46
+ # Updating an existing block blob overwrites any existing metadata on the blob
47
+ # Partial updates are not supported with create_block_blob the content of the
48
+ # existing blob is overwritten with the content of the new blob. To perform a
49
+ # partial update of the content of a block blob, use the create_block_list
50
+ # method.
51
+ #
52
+ # Note that the default content type is application/octet-stream.
53
+ #
54
+ # ==== Attributes
55
+ #
56
+ # * +container+ - String. The container name.
57
+ # * +blob+ - String. The blob name.
58
+ # * +content+ - IO or String. The content of the blob.
59
+ # * +options+ - Hash. Optional parameters.
60
+ #
61
+ # ==== Options
62
+ #
63
+ # Accepted key/value pairs in options parameter are:
64
+ # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
65
+ # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
66
+ # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
67
+ # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used.
68
+ # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
69
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
70
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
71
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
72
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
73
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
74
+ # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
75
+ # and also can be used to attach additional metadata
76
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
77
+ # * +:timeout+ - Integer. A timeout in seconds.
78
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
79
+ # in the analytics logs when storage analytics logging is enabled.
80
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
81
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
82
+ # the Blob service returns status code 412 (Precondition Failed).
83
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
84
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
85
+ # the Blob service returns status code 412 (Precondition Failed).
86
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
87
+ # only if the blob's ETag value matches the value specified. If the values do not match,
88
+ # the Blob service returns status code 412 (Precondition Failed).
89
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
90
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
91
+ # the Blob service returns status code 412 (Precondition Failed).
92
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
93
+ # specify the valid lease ID for this header.
94
+ #
95
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
96
+ #
97
+ # Returns a Blob
98
+ def create_block_blob(container, blob, content, options = {})
99
+ size = if content.respond_to? :size
100
+ content.size
101
+ elsif options[:content_length]
102
+ options[:content_length]
103
+ else
104
+ raise ArgumentError, "Either optional parameter 'content_length' should be set or 'content' should implement 'size' method to get payload's size."
105
+ end
106
+
107
+ threshold = get_single_upload_threshold(options[:single_upload_threshold])
108
+ if size > threshold
109
+ create_block_blob_multiple_put(container, blob, content, size, options)
110
+ else
111
+ create_block_blob_single_put(container, blob, content, options)
112
+ end
113
+ end
114
+
115
+ # Public: Creates a new block to be committed as part of a block blob.
116
+ #
117
+ # ==== Attributes
118
+ #
119
+ # * +container+ - String. The container name.
120
+ # * +blob+ - String. The blob name.
121
+ # * +block_id+ - String. The block id. Note: this should be the raw block id, not Base64 encoded.
122
+ # * +content+ - IO or String. The content of the blob.
123
+ # * +options+ - Hash. Optional parameters.
124
+ #
125
+ # ==== Options
126
+ #
127
+ # Accepted key/value pairs in options parameter are:
128
+ # * +:content_md5+ - String. Content MD5 for the request contents.
129
+ # * +:timeout+ - Integer. A timeout in seconds.
130
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
131
+ # in the analytics logs when storage analytics logging is enabled.
132
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an
133
+ # active lease, specify the valid lease ID for this header.
134
+ #
135
+ # See http://msdn.microsoft.com/en-us/library/azure/dd135726.aspx
136
+ #
137
+ # Returns response of the operation
138
+ def put_blob_block(container, blob, block_id, content, options = {})
139
+ query = { "comp" => "block" }
140
+ StorageService.with_query query, "blockid", Base64.strict_encode64(block_id)
141
+ StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
142
+
143
+ uri = blob_uri(container, blob, query)
144
+
145
+ headers = {}
146
+ StorageService.with_header headers, "Content-MD5", options[:content_md5]
147
+ headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id]
148
+
149
+ response = call(:put, uri, content, headers, options)
150
+ response.headers["Content-MD5"]
151
+ end
152
+
153
+ # Public: Commits existing blob blocks to a blob.
154
+ #
155
+ # This method writes a blob by specifying the list of block IDs that make up the
156
+ # blob. In order to be written as part of a blob, a block must have been
157
+ # successfully written to the server in a prior put_blob_block method.
158
+ #
159
+ # You can call Put Block List to update a blob by uploading only those blocks
160
+ # that have changed, then committing the new and existing blocks together.
161
+ # You can do this by specifying whether to commit a block from the committed
162
+ # block list or from the uncommitted block list, or to commit the most recently
163
+ # uploaded version of the block, whichever list it may belong to.
164
+ #
165
+ # ==== Attributes
166
+ #
167
+ # * +container+ - String. The container name.
168
+ # * +blob+ - String. The blob name.
169
+ # * +block_list+ - Array. A ordered list of lists in the following format:
170
+ # [ ["block_id1", :committed], ["block_id2", :uncommitted], ["block_id3"], ["block_id4", :committed]... ]
171
+ # The first element of the inner list is the block_id, the second is optional
172
+ # and can be either :committed or :uncommitted to indicate in which group of blocks
173
+ # the id should be looked for. If it is omitted, the latest of either group will be used.
174
+ # * +options+ - Hash. Optional parameters.
175
+ #
176
+ # ==== Options
177
+ #
178
+ # Accepted key/value pairs in options parameter are:
179
+ # * +:transactional_md5+ - String. Content MD5 for the request contents (not the blob contents!)
180
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
181
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
182
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
183
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
184
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
185
+ # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
186
+ # and also can be used to attach additional metadata
187
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
188
+ # * +:timeout+ - Integer. A timeout in seconds.
189
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
190
+ # in the analytics logs when storage analytics logging is enabled.
191
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an
192
+ # active lease, specify the valid lease ID for this header.
193
+ #
194
+ # This operation also supports the use of conditional headers to commit the block list if a specified condition is met.
195
+ # For more information, see https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx
196
+ #
197
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179467.aspx
198
+ #
199
+ # Returns nil on success
200
+ def commit_blob_blocks(container, blob, block_list, options = {})
201
+ query = { "comp" => "blocklist" }
202
+ StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
203
+
204
+ uri = blob_uri(container, blob, query)
205
+
206
+ headers = {}
207
+ unless options.empty?
208
+ StorageService.with_header headers, "Content-MD5", options[:transactional_md5]
209
+ StorageService.with_header headers, "x-ms-blob-content-type", options[:content_type]
210
+ StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding]
211
+ StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language]
212
+ StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5]
213
+ StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control]
214
+ StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition]
215
+
216
+ StorageService.add_metadata_to_headers(options[:metadata], headers)
217
+ add_blob_conditional_headers(options, headers)
218
+ headers["x-ms-lease-id"] = options[:lease_id] if options[:lease_id]
219
+ end
220
+ headers["x-ms-blob-content-type"] = Default::CONTENT_TYPE_VALUE unless headers["x-ms-blob-content-type"]
221
+ body = Serialization.block_list_to_xml(block_list)
222
+ call(:put, uri, body, headers, options)
223
+ nil
224
+ end
225
+
226
+ # Public: Retrieves the list of blocks that have been uploaded as part of a block blob.
227
+ #
228
+ # There are two block lists maintained for a blob:
229
+ # 1) Committed Block List: The list of blocks that have been successfully
230
+ # committed to a given blob with commitBlobBlocks.
231
+ # 2) Uncommitted Block List: The list of blocks that have been uploaded for a
232
+ # blob using Put Block (REST API), but that have not yet been committed.
233
+ # These blocks are stored in Microsoft Azure in association with a blob, but do
234
+ # not yet form part of the blob.
235
+ #
236
+ # ==== Attributes
237
+ #
238
+ # * +container+ - String. The container name.
239
+ # * +blob+ - String. The blob name.
240
+ # * +options+ - Hash. Optional parameters.
241
+ #
242
+ # ==== Options
243
+ #
244
+ # Accepted key/value pairs in options parameter are:
245
+ # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional)
246
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
247
+ # retrieve information from. (optional)
248
+ # * +:timeout+ - Integer. A timeout in seconds.
249
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
250
+ # in the analytics logs when storage analytics logging is enabled.
251
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
252
+ # which location the request should be sent to.
253
+ # * +:lease_id+ - String. If this header is specified, the operation will be performed only if both of the
254
+ # following conditions are met:
255
+ # - The blob's lease is currently active.
256
+ # - The lease ID specified in the request matches that of the blob.
257
+ # If this header is specified and both of these conditions are not met, the request will fail
258
+ # and the operation will fail with status code 412 (Precondition Failed).
259
+ #
260
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179400.aspx
261
+ #
262
+ # Returns a list of Azure::Storage::Entity::Blob::Block instances
263
+ def list_blob_blocks(container, blob, options = {})
264
+ options[:blocklist_type] = options[:blocklist_type] || :all
265
+
266
+ query = { "comp" => "blocklist" }
267
+ StorageService.with_query query, "snapshot", options[:snapshot]
268
+ StorageService.with_query query, "blocklisttype", options[:blocklist_type].to_s if options[:blocklist_type]
269
+ StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
270
+
271
+ headers = options[:lease_id] ? { "x-ms-lease-id" => options[:lease_id] } : {}
272
+
273
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
274
+ uri = blob_uri(container, blob, query, options)
275
+
276
+ response = call(:get, uri, nil, headers, options)
277
+
278
+ Serialization.block_list_from_xml(response.body)
279
+ end
280
+
281
+ # Public: Creates a new block blob or updates the content of an existing block blob.
282
+ #
283
+ # Updating an existing block blob overwrites any existing metadata on the blob
284
+ # Partial updates are not supported with create_block_blob the content of the
285
+ # existing blob is overwritten with the content of the new blob. To perform a
286
+ # partial update of the content of a block blob, use the create_block_list
287
+ # method.
288
+ #
289
+ # Note that the default content type is application/octet-stream.
290
+ #
291
+ # ==== Attributes
292
+ #
293
+ # * +container+ - String. The container name.
294
+ # * +blob+ - String. The blob name.
295
+ # * +content+ - IO or String. The content of the blob.
296
+ # * +options+ - Hash. Optional parameters.
297
+ #
298
+ # ==== Options
299
+ #
300
+ # Accepted key/value pairs in options parameter are:
301
+ # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
302
+ # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
303
+ # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
304
+ # * +:single_upload_threshold+ - Integer. Threshold in bytes for single upload, must be lower than 256MB or 256MB will be used.
305
+ # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
306
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
307
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
308
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
309
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
310
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
311
+ # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
312
+ # and also can be used to attach additional metadata
313
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
314
+ # * +:timeout+ - Integer. A timeout in seconds.
315
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
316
+ # in the analytics logs when storage analytics logging is enabled.
317
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
318
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
319
+ # the Blob service returns status code 412 (Precondition Failed).
320
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
321
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
322
+ # the Blob service returns status code 412 (Precondition Failed).
323
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
324
+ # only if the blob's ETag value matches the value specified. If the values do not match,
325
+ # the Blob service returns status code 412 (Precondition Failed).
326
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
327
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
328
+ # the Blob service returns status code 412 (Precondition Failed).
329
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
330
+ # specify the valid lease ID for this header.
331
+ #
332
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
333
+ #
334
+ # Returns a Blob
335
+ alias create_block_blob_from_content create_block_blob
336
+
337
+ # Protected: Creates a new block blob or updates the content of an existing block blob with single API call
338
+ #
339
+ # Updating an existing block blob overwrites any existing metadata on the blob
340
+ # Partial updates are not supported with create_block_blob the content of the
341
+ # existing blob is overwritten with the content of the new blob. To perform a
342
+ # partial update of the content of a block blob, use the create_block_list
343
+ # method.
344
+ #
345
+ # Note that the default content type is application/octet-stream.
346
+ #
347
+ # ==== Attributes
348
+ #
349
+ # * +container+ - String. The container name.
350
+ # * +blob+ - String. The blob name.
351
+ # * +content+ - IO or String. The content of the blob.
352
+ # * +options+ - Hash. Optional parameters.
353
+ #
354
+ # ==== Options
355
+ #
356
+ # Accepted key/value pairs in options parameter are:
357
+ # * +:transactional_md5+ - String. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport.
358
+ # When this header is specified, the storage service checks the hash that has arrived with the one that was sent.
359
+ # If the two hashes do not match, the operation will fail with error code 400 (Bad Request).
360
+ # * +:content_length+ - Integer. Length of the content to upload, must be specified if 'content' does not implement 'size'.
361
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
362
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
363
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
364
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
365
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
366
+ # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
367
+ # and also can be used to attach additional metadata
368
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
369
+ # * +:timeout+ - Integer. A timeout in seconds.
370
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
371
+ # in the analytics logs when storage analytics logging is enabled.
372
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
373
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
374
+ # the Blob service returns status code 412 (Precondition Failed).
375
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to create a new blob
376
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
377
+ # the Blob service returns status code 412 (Precondition Failed).
378
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
379
+ # only if the blob's ETag value matches the value specified. If the values do not match,
380
+ # the Blob service returns status code 412 (Precondition Failed).
381
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to create a new blob
382
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
383
+ # the Blob service returns status code 412 (Precondition Failed).
384
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
385
+ # specify the valid lease ID for this header.
386
+ #
387
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
388
+ #
389
+ # Returns a Blob
390
+ protected
391
+ def create_block_blob_single_put(container, blob, content, options = {})
392
+ query = {}
393
+ StorageService.with_query query, "timeout", options[:timeout].to_s if options[:timeout]
394
+
395
+ uri = blob_uri(container, blob, query)
396
+
397
+ headers = {}
398
+
399
+ # set x-ms-blob-type to BlockBlob
400
+ StorageService.with_header headers, "x-ms-blob-type", "BlockBlob"
401
+
402
+ # set the rest of the optional headers
403
+ StorageService.with_header headers, "Content-MD5", options[:transactional_md5]
404
+ StorageService.with_header headers, "Content-Length", options[:content_length]
405
+ StorageService.with_header headers, "x-ms-blob-content-encoding", options[:content_encoding]
406
+ StorageService.with_header headers, "x-ms-blob-content-language", options[:content_language]
407
+ StorageService.with_header headers, "x-ms-blob-content-md5", options[:content_md5]
408
+ StorageService.with_header headers, "x-ms-blob-cache-control", options[:cache_control]
409
+ StorageService.with_header headers, "x-ms-blob-content-disposition", options[:content_disposition]
410
+ StorageService.with_header headers, "x-ms-lease-id", options[:lease_id]
411
+
412
+ StorageService.add_metadata_to_headers options[:metadata], headers
413
+ add_blob_conditional_headers options, headers
414
+ headers["x-ms-blob-content-type"] = get_or_apply_content_type(content, options[:content_type])
415
+ # call PutBlob
416
+ response = call(:put, uri, content, headers, options)
417
+
418
+ result = Serialization.blob_from_headers(response.headers)
419
+ result.name = blob
420
+ result.metadata = options[:metadata] if options[:metadata]
421
+
422
+ result
423
+ end
424
+
425
+ # Protected: Creates a new block blob or updates the content of an existing block blob with multiple upload
426
+ #
427
+ # Updating an existing block blob overwrites any existing metadata on the blob
428
+ # Partial updates are not supported with create_block_blob the content of the
429
+ # existing blob is overwritten with the content of the new blob. To perform a
430
+ # partial update of the content of a block blob, use the create_block_list
431
+ # method.
432
+ #
433
+ # Note that the default content type is application/octet-stream.
434
+ #
435
+ # ==== Attributes
436
+ #
437
+ # * +container+ - String. The container name.
438
+ # * +blob+ - String. The blob name.
439
+ # * +content+ - IO or String. The content of the blob.
440
+ # * +size+ - Integer. The size of the content.
441
+ # * +options+ - Hash. Optional parameters.
442
+ #
443
+ # ==== Options
444
+ #
445
+ # Accepted key/value pairs in options parameter are:
446
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
447
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
448
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
449
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
450
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
451
+ # * +:content_disposition+ - String. Conveys additional information about how to process the response payload,
452
+ # and also can be used to attach additional metadata
453
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
454
+ # * +:timeout+ - Integer. A timeout in seconds.
455
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
456
+ # in the analytics logs when storage analytics logging is enabled.
457
+ # * +:lease_id+ - String. Required if the blob has an active lease. To perform this operation on a blob with an active lease,
458
+ # specify the valid lease ID for this header.
459
+ #
460
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179451.aspx
461
+ #
462
+ # Returns a Blob
463
+ protected
464
+ def create_block_blob_multiple_put(container, blob, content, size, options = {})
465
+ content_type = get_or_apply_content_type(content, options[:content_type])
466
+ content = StringIO.new(content) if content.is_a? String
467
+ block_size = get_block_size(size)
468
+ # Get the number of blocks
469
+ block_count = (Float(size) / Float(block_size)).ceil
470
+ block_list = []
471
+ for block_id in 0...block_count
472
+ id = block_id.to_s.rjust(6, "0")
473
+ put_blob_block(container, blob, id, content.read(block_size), timeout: options[:timeout], lease_id: options[:lease_id])
474
+ block_list.push([id])
475
+ end
476
+
477
+ # Commit the blocks put
478
+ commit_options = {}
479
+ commit_options[:content_type] = content_type
480
+ commit_options[:content_encoding] = options[:content_encoding] if options[:content_encoding]
481
+ commit_options[:content_language] = options[:content_language] if options[:content_language]
482
+ commit_options[:content_md5] = options[:content_md5] if options[:content_md5]
483
+ commit_options[:cache_control] = options[:cache_control] if options[:cache_control]
484
+ commit_options[:content_disposition] = options[:content_disposition] if options[:content_disposition]
485
+ commit_options[:metadata] = options[:metadata] if options[:metadata]
486
+ commit_options[:timeout] = options[:timeout] if options[:timeout]
487
+ commit_options[:request_id] = options[:request_id] if options[:request_id]
488
+ commit_options[:lease_id] = options[:lease_id] if options[:lease_id]
489
+
490
+ commit_blob_blocks(container, blob, block_list, commit_options)
491
+
492
+ get_properties_options = {}
493
+ get_properties_options[:lease_id] = options[:lease_id] if options[:lease_id]
494
+
495
+ # Get the blob properties
496
+ get_blob_properties(container, blob, get_properties_options)
497
+ end
498
+
499
+ # Protected: Gets the single upload threshold according to user's preference
500
+ #
501
+ # ==== Attributes
502
+ #
503
+ # * +container+ - String. The container name.
504
+ #
505
+ # Returns an Integer
506
+ protected
507
+ def get_single_upload_threshold(userThreshold)
508
+ if userThreshold.nil?
509
+ BlobConstants::DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES
510
+ elsif userThreshold <= 0
511
+ raise ArgumentError, "Single Upload Threshold should be positive number"
512
+ elsif userThreshold < BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES
513
+ userThreshold
514
+ else
515
+ BlobConstants::MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES
516
+ end
517
+ end
518
+
519
+ protected
520
+ def get_block_size(size)
521
+ if size > BlobConstants::MAX_BLOCK_BLOB_SIZE
522
+ raise ArgumentError, "Block blob size should be less than #{BlobConstants::MAX_BLOCK_BLOB_SIZE} bytes in size"
523
+ elsif (size / BlobConstants::MAX_BLOCK_COUNT) < BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES
524
+ BlobConstants::DEFAULT_WRITE_BLOCK_SIZE_IN_BYTES
525
+ else
526
+ BlobConstants::MAX_BLOCK_SIZE
527
+ end
528
+ end
529
+ end
530
+ end