From c6982117832d24f878f168f4438ae9307d37504b Mon Sep 17 00:00:00 2001 From: Rick Ley Date: Tue, 14 Jul 2020 10:26:01 -0700 Subject: [PATCH 1/4] Fixed a couple bugs --- sdk/storage/azure-storage-blob/CHANGELOG.md | 3 +- .../azure/storage/blob/BlobAsyncClient.java | 4 +- .../com/azure/storage/blob/BlobAPITest.groovy | 35 ++++++-- .../BlobAPITestuploadincorrectsize[0].json | 90 +++++++++++++++++++ .../BlobAPITestuploadincorrectsize[1].json | 90 +++++++++++++++++++ .../BlobAPITestuploadincorrectsize[2].json | 90 +++++++++++++++++++ .../BlobAPITestuploadincorrectsize[3].json | 90 +++++++++++++++++++ .../common/implementation/UploadUtils.java | 5 ++ 8 files changed, 397 insertions(+), 10 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[0].json create mode 100644 sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[1].json create mode 100644 sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[2].json create mode 100644 sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[3].json diff --git a/sdk/storage/azure-storage-blob/CHANGELOG.md b/sdk/storage/azure-storage-blob/CHANGELOG.md index 3b4cc6ce59c2..6cf72b742aa9 100644 --- a/sdk/storage/azure-storage-blob/CHANGELOG.md +++ b/sdk/storage/azure-storage-blob/CHANGELOG.md @@ -1,7 +1,8 @@ # Release History ## 12.8.0-beta.2 (Unreleased) - +- Fixed a bug that, when the data length parameter did not match the actual length of the data in BlobClient.upload, caused a zero length blob to be uploaded rather than throwing an exception. +- Fixed a bug that ignored the customer's specified block size when determining buffer sizes in BlobClient.upload ## 12.8.0-beta.1 (2020-07-07) - Added support for the 2019-12-12 service version. diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobAsyncClient.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobAsyncClient.java index 6548b3a8824d..7410eac63e0a 100644 --- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobAsyncClient.java +++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobAsyncClient.java @@ -439,7 +439,9 @@ public Mono> uploadWithResponse(BlobParallelUploadOption .setTier(options.getTier()).setRequestConditions(options.getRequestConditions())); Flux data = options.getDataFlux() == null ? Utility.convertStreamToByteBuffer( - options.getDataStream(), options.getLength(), BLOB_DEFAULT_UPLOAD_BLOCK_SIZE) + options.getDataStream(), options.getLength(), + // We can only buffer up to max int due to restrictions in ByteBuffer. + (int) Math.min(Integer.MAX_VALUE, validatedParallelTransferOptions.getBlockSizeLong())) : options.getDataFlux(); return UploadUtils.uploadFullOrChunked(data, ModelHelper.wrapBlobOptions(validatedParallelTransferOptions), uploadInChunksFunction, uploadFullBlobMethod); diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobAPITest.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobAPITest.groovy index e0443ee9fb69..669564ca2640 100644 --- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobAPITest.groovy +++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobAPITest.groovy @@ -85,8 +85,9 @@ class BlobAPITest extends APISpec { } /* Tests an issue found where buffered upload would not deep copy buffers while determining what upload path to take. */ + @Unroll - def "Upload input stream single upload" () { + def "Upload input stream single upload"() { setup: def randomData = getRandomByteArray(20 * Constants.KB) def input = new ByteArrayInputStream(randomData) @@ -100,15 +101,15 @@ class BlobAPITest extends APISpec { stream.toByteArray() == randomData where: - size || _ - 1 * Constants.KB || _ /* Less than copyToOutputStream buffer size, Less than maxSingleUploadSize */ - 8 * Constants.KB || _ /* Equal to copyToOutputStream buffer size, Less than maxSingleUploadSize */ - 20 * Constants.KB || _ /* Greater than copyToOutputStream buffer size, Less than maxSingleUploadSize */ + size || _ + 1 * Constants.KB || _ /* Less than copyToOutputStream buffer size, Less than maxSingleUploadSize */ + 8 * Constants.KB || _ /* Equal to copyToOutputStream buffer size, Less than maxSingleUploadSize */ + 20 * Constants.KB || _ /* Greater than copyToOutputStream buffer size, Less than maxSingleUploadSize */ } /* TODO (gapra): Add more tests to test large data sizes. */ - @Requires( { liveMode() } ) + @Requires({ liveMode() }) def "Upload input stream large data"() { setup: def randomData = getRandomByteArray(20 * Constants.MB) @@ -124,6 +125,22 @@ class BlobAPITest extends APISpec { notThrown(BlobStorageException) } + @Unroll + def "Upload incorrect size"() { + when: + bc.upload(defaultInputStream.get(), dataSize, true) + + then: + thrown(IllegalStateException) + + where: + dataSize | threshold + defaultDataSize + 1 | null + defaultDataSize - 1 | null + defaultDataSize + 1 | 1 // Test the chunked case as well + defaultDataSize - 1 | 1 + } + @Unroll def "Upload numBlocks"() { setup: @@ -156,7 +173,8 @@ class BlobAPITest extends APISpec { .getValue().getETag() != null } - @Requires({ liveMode() }) // Reading from recordings will not allow for the timing of the test to work correctly. + @Requires({ liveMode() }) + // Reading from recordings will not allow for the timing of the test to work correctly. def "Upload timeout"() { setup: def size = 1024 @@ -973,7 +991,8 @@ class BlobAPITest extends APISpec { This test requires two accounts that are configured in a very specific way. It is not feasible to setup that relationship programmatically, so we have recorded a successful interaction and only test recordings. */ - @Requires( {playbackMode()}) + + @Requires({ playbackMode() }) def "Get properties ORS"() { setup: def sourceBlob = primaryBlobServiceClient.getBlobContainerClient("test1") diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[0].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[0].json new file mode 100644 index 000000000000..4ad94f6f9120 --- /dev/null +++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[0].json @@ -0,0 +1,90 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize61a372717?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "6bf35f33-b5b3-409c-8dc2-5f130fb97710" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "ETag" : "0x8D82819FF1A5384", + "Last-Modified" : "Tue, 14 Jul 2020 17:18:59 GMT", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "201", + "x-ms-request-id" : "d46d6efa-901e-0054-2b02-5abe5e000000", + "Date" : "Tue, 14 Jul 2020 17:18:59 GMT", + "x-ms-client-request-id" : "6bf35f33-b5b3-409c-8dc2-5f130fb97710" + }, + "Exception" : null + }, { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize61a372717/javablobuploadincorrectsize192960ae99c1dbb885442", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "0addb259-10d1-4120-888b-ca7ae000dbb7", + "Content-Type" : "application/octet-stream" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-content-crc64" : "6RYQPwaVsyQ=", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:00 GMT", + "retry-after" : "0", + "StatusCode" : "201", + "x-ms-request-server-encrypted" : "true", + "Date" : "Tue, 14 Jul 2020 17:18:59 GMT", + "Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==", + "ETag" : "0x8D82819FFBE88FD", + "Content-Length" : "0", + "x-ms-request-id" : "b2e2badf-b01e-0061-7402-5a100b000000", + "x-ms-client-request-id" : "0addb259-10d1-4120-888b-ca7ae000dbb7" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcuploadincorrectsize&comp=list", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "3062524d-62b2-4ecf-8aa6-b0466c650321" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "StatusCode" : "200", + "x-ms-request-id" : "3bcebc16-c01e-006e-3e02-5afdfd000000", + "Body" : "jtcuploadincorrectsizejtcuploadincorrectsize0blobapitestuploadincorrectsize61a372717Tue, 14 Jul 2020 17:18:59 GMT\"0x8D82819FF1A5384\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "Date" : "Tue, 14 Jul 2020 17:19:00 GMT", + "x-ms-client-request-id" : "3062524d-62b2-4ecf-8aa6-b0466c650321", + "Content-Type" : "application/xml" + }, + "Exception" : null + }, { + "Method" : "DELETE", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize61a372717?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "bf4ee0d9-d744-4434-86cd-d42dae8ef27a" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "202", + "x-ms-request-id" : "8f04ebd6-801e-0040-0402-5a7d3a000000", + "Date" : "Tue, 14 Jul 2020 17:19:01 GMT", + "x-ms-client-request-id" : "bf4ee0d9-d744-4434-86cd-d42dae8ef27a" + }, + "Exception" : null + } ], + "variables" : [ "jtcuploadincorrectsize0blobapitestuploadincorrectsize61a372717", "javablobuploadincorrectsize192960ae99c1dbb885442" ] +} \ No newline at end of file diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[1].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[1].json new file mode 100644 index 000000000000..37e09ec0556d --- /dev/null +++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[1].json @@ -0,0 +1,90 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizec47250537?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "3357dd18-4743-45cc-8c81-678638cd39d0" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "ETag" : "0x8D8281A00C3DE5B", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:02 GMT", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "201", + "x-ms-request-id" : "4e84195f-e01e-009c-5b02-5a2f69000000", + "Date" : "Tue, 14 Jul 2020 17:19:01 GMT", + "x-ms-client-request-id" : "3357dd18-4743-45cc-8c81-678638cd39d0" + }, + "Exception" : null + }, { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizec47250537/javablobuploadincorrectsize105800ad666ed1358e41c", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "b65064d9-44e9-4637-8afc-f1c27f9f1a99", + "Content-Type" : "application/octet-stream" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-content-crc64" : "6RYQPwaVsyQ=", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:02 GMT", + "retry-after" : "0", + "StatusCode" : "201", + "x-ms-request-server-encrypted" : "true", + "Date" : "Tue, 14 Jul 2020 17:19:01 GMT", + "Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==", + "ETag" : "0x8D8281A00F2D3DC", + "Content-Length" : "0", + "x-ms-request-id" : "b9dba07a-101e-000a-1102-5a4d5d000000", + "x-ms-client-request-id" : "b65064d9-44e9-4637-8afc-f1c27f9f1a99" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcuploadincorrectsize&comp=list", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "039695a3-cdd6-4f4f-bf61-0607b7441c14" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "StatusCode" : "200", + "x-ms-request-id" : "919d11bb-201e-002b-5202-5a206c000000", + "Body" : "jtcuploadincorrectsizejtcuploadincorrectsize0blobapitestuploadincorrectsizec47250537Tue, 14 Jul 2020 17:19:02 GMT\"0x8D8281A00C3DE5B\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "Date" : "Tue, 14 Jul 2020 17:19:02 GMT", + "x-ms-client-request-id" : "039695a3-cdd6-4f4f-bf61-0607b7441c14", + "Content-Type" : "application/xml" + }, + "Exception" : null + }, { + "Method" : "DELETE", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizec47250537?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "44c31a46-1731-4413-a8a8-08a3dee3d7c6" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "202", + "x-ms-request-id" : "77df9095-901e-0010-4502-5a6232000000", + "Date" : "Tue, 14 Jul 2020 17:19:02 GMT", + "x-ms-client-request-id" : "44c31a46-1731-4413-a8a8-08a3dee3d7c6" + }, + "Exception" : null + } ], + "variables" : [ "jtcuploadincorrectsize0blobapitestuploadincorrectsizec47250537", "javablobuploadincorrectsize105800ad666ed1358e41c" ] +} \ No newline at end of file diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[2].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[2].json new file mode 100644 index 000000000000..5a5e1216e04b --- /dev/null +++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[2].json @@ -0,0 +1,90 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizea0271001d?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "d37e8d0e-2ed0-4aff-817f-5aecbe772444" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "ETag" : "0x8D8281A01899BB6", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:03 GMT", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "201", + "x-ms-request-id" : "167610af-a01e-0031-6502-5a0f03000000", + "Date" : "Tue, 14 Jul 2020 17:19:03 GMT", + "x-ms-client-request-id" : "d37e8d0e-2ed0-4aff-817f-5aecbe772444" + }, + "Exception" : null + }, { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizea0271001d/javablobuploadincorrectsize1958500e125872c20b445", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "70a6acea-8a74-46ec-a8bf-dd19d4162bbe", + "Content-Type" : "application/octet-stream" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-content-crc64" : "6RYQPwaVsyQ=", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:03 GMT", + "retry-after" : "0", + "StatusCode" : "201", + "x-ms-request-server-encrypted" : "true", + "Date" : "Tue, 14 Jul 2020 17:19:03 GMT", + "Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==", + "ETag" : "0x8D8281A01B9A32A", + "Content-Length" : "0", + "x-ms-request-id" : "d2c931c3-d01e-00f2-7c02-5a8640000000", + "x-ms-client-request-id" : "70a6acea-8a74-46ec-a8bf-dd19d4162bbe" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcuploadincorrectsize&comp=list", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "bdd56435-50ac-4727-9134-747e0bed473e" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "StatusCode" : "200", + "x-ms-request-id" : "8193fad7-d01e-003e-6d02-5ae2f5000000", + "Body" : "jtcuploadincorrectsizejtcuploadincorrectsize0blobapitestuploadincorrectsizea0271001dTue, 14 Jul 2020 17:19:03 GMT\"0x8D8281A01899BB6\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "Date" : "Tue, 14 Jul 2020 17:19:03 GMT", + "x-ms-client-request-id" : "bdd56435-50ac-4727-9134-747e0bed473e", + "Content-Type" : "application/xml" + }, + "Exception" : null + }, { + "Method" : "DELETE", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsizea0271001d?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "cc682a78-2410-4fa2-b4af-8489aeb9b645" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "202", + "x-ms-request-id" : "a98ba26c-301e-013b-0902-5a50df000000", + "Date" : "Tue, 14 Jul 2020 17:19:03 GMT", + "x-ms-client-request-id" : "cc682a78-2410-4fa2-b4af-8489aeb9b645" + }, + "Exception" : null + } ], + "variables" : [ "jtcuploadincorrectsize0blobapitestuploadincorrectsizea0271001d", "javablobuploadincorrectsize1958500e125872c20b445" ] +} \ No newline at end of file diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[3].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[3].json new file mode 100644 index 000000000000..8577b8efce5c --- /dev/null +++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/BlobAPITestuploadincorrectsize[3].json @@ -0,0 +1,90 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize427036766?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "8df45dbd-50b9-4d73-99b5-bd2404f101e5" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "ETag" : "0x8D8281A023E3FBF", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:04 GMT", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "201", + "x-ms-request-id" : "56b2105f-d01e-00d0-0e02-5ae876000000", + "Date" : "Tue, 14 Jul 2020 17:19:04 GMT", + "x-ms-client-request-id" : "8df45dbd-50b9-4d73-99b5-bd2404f101e5" + }, + "Exception" : null + }, { + "Method" : "PUT", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize427036766/javablobuploadincorrectsize1366272b06ad9df88a401", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "9f5fdea6-cca6-40d3-b436-202a2cf5b9cc", + "Content-Type" : "application/octet-stream" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-content-crc64" : "6RYQPwaVsyQ=", + "Last-Modified" : "Tue, 14 Jul 2020 17:19:04 GMT", + "retry-after" : "0", + "StatusCode" : "201", + "x-ms-request-server-encrypted" : "true", + "Date" : "Tue, 14 Jul 2020 17:19:04 GMT", + "Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==", + "ETag" : "0x8D8281A0270DF3E", + "Content-Length" : "0", + "x-ms-request-id" : "2f53615d-e01e-003d-0702-5ae1f2000000", + "x-ms-client-request-id" : "9f5fdea6-cca6-40d3-b436-202a2cf5b9cc" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcuploadincorrectsize&comp=list", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "429137e8-db49-453b-afe9-d423893e0e63" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "StatusCode" : "200", + "x-ms-request-id" : "09b7b005-401e-009a-1102-5ad811000000", + "Body" : "jtcuploadincorrectsizejtcuploadincorrectsize0blobapitestuploadincorrectsize427036766Tue, 14 Jul 2020 17:19:04 GMT\"0x8D8281A023E3FBF\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "Date" : "Tue, 14 Jul 2020 17:19:04 GMT", + "x-ms-client-request-id" : "429137e8-db49-453b-afe9-d423893e0e63", + "Content-Type" : "application/xml" + }, + "Exception" : null + }, { + "Method" : "DELETE", + "Uri" : "https://REDACTED.blob.core.windows.net/jtcuploadincorrectsize0blobapitestuploadincorrectsize427036766?restype=container", + "Headers" : { + "x-ms-version" : "2019-12-12", + "User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)", + "x-ms-client-request-id" : "2ddecade-681e-4e3b-8085-81c4f82d0b00" + }, + "Response" : { + "x-ms-version" : "2019-12-12", + "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "retry-after" : "0", + "Content-Length" : "0", + "StatusCode" : "202", + "x-ms-request-id" : "f65a13c8-701e-00bb-4b02-5ab520000000", + "Date" : "Tue, 14 Jul 2020 17:19:04 GMT", + "x-ms-client-request-id" : "2ddecade-681e-4e3b-8085-81c4f82d0b00" + }, + "Exception" : null + } ], + "variables" : [ "jtcuploadincorrectsize0blobapitestuploadincorrectsize427036766", "javablobuploadincorrectsize1366272b06ad9df88a401" ] +} \ No newline at end of file diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java index 6c97ce64d2f0..79412101b7b2 100644 --- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java +++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java @@ -8,6 +8,7 @@ import com.azure.storage.common.ParallelTransferOptions; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.core.publisher.SignalType; import java.io.IOException; import java.io.UncheckedIOException; @@ -47,6 +48,10 @@ public static Mono> uploadFullOrChunked(final Flux d // First buffer is emitted after threshold is breached or there's no more data. // Therefore we can make a decision how to upload data on first element. .switchOnFirst((signal, flux) -> { + // If there is an error before the threshold is reached, propogate the error + if (signal.getType().equals(SignalType.ON_ERROR)) { + return Flux.error(signal.getThrowable()); + } if (gate.isThresholdBreached()) { // In this case we can pass a flux that can have just one subscriber because // the chunked upload is going to cache the data downstream before sending chunks over the wire. From 530d3bf47cae2824aaa6383f49585f429e4d8cab Mon Sep 17 00:00:00 2001 From: Rick Ley Date: Tue, 14 Jul 2020 10:51:27 -0700 Subject: [PATCH 2/4] CI --- .../storage/common/implementation/UploadUtils.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java index 79412101b7b2..89c831f66f15 100644 --- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java +++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java @@ -48,9 +48,13 @@ public static Mono> uploadFullOrChunked(final Flux d // First buffer is emitted after threshold is breached or there's no more data. // Therefore we can make a decision how to upload data on first element. .switchOnFirst((signal, flux) -> { - // If there is an error before the threshold is reached, propogate the error - if (signal.getType().equals(SignalType.ON_ERROR)) { - return Flux.error(signal.getThrowable()); + // If there is an error before the threshold is reached, propagate the error + if (signal.isOnError()) { + if (signal.getThrowable() != null) { + return Flux.error(signal.getThrowable()); + } else { + return Flux.error(new IllegalStateException("Source flux failed but cause is unretrievable")); + } } if (gate.isThresholdBreached()) { // In this case we can pass a flux that can have just one subscriber because From 49e5efc4368ca38ada92c4ff3c101df22faae139 Mon Sep 17 00:00:00 2001 From: Rick Ley Date: Tue, 14 Jul 2020 11:27:17 -0700 Subject: [PATCH 3/4] CI --- .../com/azure/storage/common/implementation/UploadUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java index 89c831f66f15..9c58d5e33f6b 100644 --- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java +++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java @@ -8,7 +8,6 @@ import com.azure.storage.common.ParallelTransferOptions; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import reactor.core.publisher.SignalType; import java.io.IOException; import java.io.UncheckedIOException; From 4e368048767d561761265e12e1e62ca11be71869 Mon Sep 17 00:00:00 2001 From: Rick Ley Date: Tue, 14 Jul 2020 15:49:22 -0700 Subject: [PATCH 4/4] CI --- .../com/azure/storage/common/implementation/UploadUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java index 9c58d5e33f6b..607d5a0f3223 100644 --- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java +++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/UploadUtils.java @@ -49,8 +49,9 @@ public static Mono> uploadFullOrChunked(final Flux d .switchOnFirst((signal, flux) -> { // If there is an error before the threshold is reached, propagate the error if (signal.isOnError()) { - if (signal.getThrowable() != null) { - return Flux.error(signal.getThrowable()); + Throwable t = signal.getThrowable(); + if (t != null) { + return Flux.error(t); } else { return Flux.error(new IllegalStateException("Source flux failed but cause is unretrievable")); }