Skip to content

Commit 8f808b2

Browse files
authored
Increased default maxRetries for download to help Connection reset by peer issues (Azure#22457)
1 parent 7335011 commit 8f808b2

File tree

12 files changed

+677
-111
lines changed

12 files changed

+677
-111
lines changed

sdk/storage/azure-storage-blob/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 12.13.0-beta.1 (Unreleased)
44
- Added support to get a blob client that uses an encryption scope and customer provided key.
5+
- Updated DownloadRetryOptions.maxRetryRequests to default downloads to retry 5 times.
56

67
## 12.12.0 (2021-06-09)
78
- GA release

sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/models/DownloadRetryOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public final class DownloadRetryOptions {
2323
issued and returned. This is in contrast to the retry policy options, which includes the initial try in its count,
2424
thus the difference in verbiage.
2525
*/
26-
private int maxRetryRequests = 0;
26+
private int maxRetryRequests = 5;
2727

2828
/**
2929
* Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a

sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/APISpec.groovy

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.azure.storage.common.implementation.Constants
3131
import com.azure.storage.common.policy.RequestRetryOptions
3232
import com.azure.storage.common.test.shared.StorageSpec
3333
import com.azure.storage.common.test.shared.TestAccount
34+
import com.azure.storage.common.test.shared.policy.MockDownloadHttpResponse
3435
import reactor.core.publisher.Flux
3536
import reactor.core.publisher.Mono
3637
import spock.lang.Timeout
@@ -684,60 +685,6 @@ class APISpec extends StorageSpec {
684685
}
685686
}
686687

687-
/*
688-
This is for stubbing responses that will actually go through the pipeline and autorest code. Autorest does not seem
689-
to play too nicely with mocked objects and the complex reflection stuff on both ends made it more difficult to work
690-
with than was worth it. Because this type is just for BlobDownload, we don't need to accept a header type.
691-
*/
692-
693-
class MockDownloadHttpResponse extends HttpResponse {
694-
private final int statusCode
695-
private final HttpHeaders headers
696-
private final Flux<ByteBuffer> body
697-
698-
MockDownloadHttpResponse(HttpResponse response, int statusCode, Flux<ByteBuffer> body) {
699-
super(response.getRequest())
700-
this.statusCode = statusCode
701-
this.headers = response.getHeaders()
702-
this.body = body
703-
}
704-
705-
@Override
706-
int getStatusCode() {
707-
return statusCode
708-
}
709-
710-
@Override
711-
String getHeaderValue(String s) {
712-
return headers.getValue(s)
713-
}
714-
715-
@Override
716-
HttpHeaders getHeaders() {
717-
return headers
718-
}
719-
720-
@Override
721-
Flux<ByteBuffer> getBody() {
722-
return body
723-
}
724-
725-
@Override
726-
Mono<byte[]> getBodyAsByteArray() {
727-
return Mono.error(new IOException())
728-
}
729-
730-
@Override
731-
Mono<String> getBodyAsString() {
732-
return Mono.error(new IOException())
733-
}
734-
735-
@Override
736-
Mono<String> getBodyAsString(Charset charset) {
737-
return Mono.error(new IOException())
738-
}
739-
}
740-
741688
/**
742689
* Injects one retry-able IOException failure per url.
743690
*/

sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobAPITest.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
package com.azure.storage.blob
55

6+
import com.azure.core.http.HttpPipelineCallContext
7+
import com.azure.core.http.HttpPipelineNextPolicy
8+
import com.azure.core.http.HttpResponse
69
import com.azure.core.http.RequestConditions
10+
import com.azure.core.http.policy.HttpPipelinePolicy
711
import com.azure.core.util.BinaryData
812
import com.azure.core.util.CoreUtils
913
import com.azure.core.util.polling.LongRunningOperationStatus
@@ -45,8 +49,11 @@ import com.azure.storage.common.implementation.Constants
4549
import com.azure.storage.common.test.shared.extensions.LiveOnly
4650
import com.azure.storage.common.test.shared.extensions.PlaybackOnly
4751
import com.azure.storage.common.test.shared.extensions.RequiredServiceVersion
52+
import com.azure.storage.common.test.shared.policy.MockFailureResponsePolicy
4853
import reactor.core.Exceptions
54+
import reactor.core.publisher.Flux
4955
import reactor.core.publisher.Hooks
56+
import reactor.core.publisher.Mono
5057
import reactor.test.StepVerifier
5158
import spock.lang.IgnoreIf
5259
import spock.lang.Requires
@@ -638,6 +645,19 @@ class BlobAPITest extends APISpec {
638645
contentMD5 == MessageDigest.getInstance("MD5").digest(data.defaultText.substring(0, 3).getBytes())
639646
}
640647

648+
def "Download retry default"() {
649+
setup:
650+
def failureBlobClient = getBlobClient(env.primaryAccount.credential, bc.getBlobUrl(), new MockFailureResponsePolicy(5))
651+
652+
when:
653+
def outStream = new ByteArrayOutputStream()
654+
failureBlobClient.download(outStream)
655+
String bodyStr = outStream.toString()
656+
657+
then:
658+
bodyStr == data.defaultText
659+
}
660+
641661
def "Download error"() {
642662
setup:
643663
bc = cc.getBlobClient(generateBlobName())
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
{
2+
"networkCallRecords" : [ {
3+
"Method" : "PUT",
4+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0?restype=container",
5+
"Headers" : {
6+
"x-ms-version" : "2020-08-04",
7+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
8+
"x-ms-client-request-id" : "617bc120-62e1-4c40-beb5-d80cc916f967"
9+
},
10+
"Response" : {
11+
"content-length" : "0",
12+
"x-ms-version" : "2020-08-04",
13+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
14+
"eTag" : "0x8D935CF2E7D5705",
15+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
16+
"retry-after" : "0",
17+
"StatusCode" : "201",
18+
"x-ms-request-id" : "1fc13a72-801e-007a-13b8-6750e0000000",
19+
"x-ms-client-request-id" : "617bc120-62e1-4c40-beb5-d80cc916f967",
20+
"Date" : "Tue, 22 Jun 2021 22:43:39 GMT"
21+
},
22+
"Exception" : null
23+
}, {
24+
"Method" : "PUT",
25+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
26+
"Headers" : {
27+
"x-ms-version" : "2020-08-04",
28+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
29+
"x-ms-client-request-id" : "7b80da98-e055-4f4b-acc7-8fb09c302f6d",
30+
"Content-Type" : "application/octet-stream"
31+
},
32+
"Response" : {
33+
"content-length" : "0",
34+
"x-ms-version" : "2020-08-04",
35+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
36+
"x-ms-content-crc64" : "6RYQPwaVsyQ=",
37+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
38+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
39+
"retry-after" : "0",
40+
"StatusCode" : "201",
41+
"x-ms-request-server-encrypted" : "true",
42+
"Date" : "Tue, 22 Jun 2021 22:43:40 GMT",
43+
"Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==",
44+
"eTag" : "0x8D935CF2EC22AA8",
45+
"x-ms-request-id" : "1fc13ad3-801e-007a-68b8-6750e0000000",
46+
"x-ms-client-request-id" : "7b80da98-e055-4f4b-acc7-8fb09c302f6d"
47+
},
48+
"Exception" : null
49+
}, {
50+
"Method" : "GET",
51+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
52+
"Headers" : {
53+
"x-ms-version" : "2020-08-04",
54+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
55+
"x-ms-client-request-id" : "aa84fdbf-d57a-49e6-9256-66126dc08e6a"
56+
},
57+
"Response" : {
58+
"x-ms-is-current-version" : "true",
59+
"content-length" : "7",
60+
"x-ms-version" : "2020-08-04",
61+
"x-ms-lease-status" : "unlocked",
62+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
63+
"x-ms-lease-state" : "available",
64+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
65+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
66+
"retry-after" : "0",
67+
"StatusCode" : "200",
68+
"Date" : "Tue, 22 Jun 2021 22:43:40 GMT",
69+
"Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==",
70+
"x-ms-blob-type" : "BlockBlob",
71+
"Accept-Ranges" : "bytes",
72+
"x-ms-server-encrypted" : "true",
73+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
74+
"eTag" : "0x8D935CF2EC22AA8",
75+
"x-ms-request-id" : "1fc13b04-801e-007a-14b8-6750e0000000",
76+
"Body" : "ZGVmYXVsdA==",
77+
"x-ms-client-request-id" : "aa84fdbf-d57a-49e6-9256-66126dc08e6a",
78+
"Content-Type" : "application/octet-stream"
79+
},
80+
"Exception" : null
81+
}, {
82+
"Method" : "GET",
83+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
84+
"Headers" : {
85+
"x-ms-version" : "2020-08-04",
86+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
87+
"x-ms-client-request-id" : "19fc7bdc-6436-4f6d-9a06-c1f24af21290"
88+
},
89+
"Response" : {
90+
"x-ms-is-current-version" : "true",
91+
"content-length" : "7",
92+
"x-ms-version" : "2020-08-04",
93+
"x-ms-lease-status" : "unlocked",
94+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
95+
"Content-Range" : "bytes 0-6/7",
96+
"x-ms-lease-state" : "available",
97+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
98+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
99+
"x-ms-blob-content-md5" : "wh+Wm18D0z1D4E+PE252gg==",
100+
"retry-after" : "0",
101+
"StatusCode" : "206",
102+
"Date" : "Tue, 22 Jun 2021 22:43:40 GMT",
103+
"x-ms-blob-type" : "BlockBlob",
104+
"Accept-Ranges" : "bytes",
105+
"x-ms-server-encrypted" : "true",
106+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
107+
"eTag" : "0x8D935CF2EC22AA8",
108+
"x-ms-request-id" : "1fc13b4d-801e-007a-59b8-6750e0000000",
109+
"Body" : "ZGVmYXVsdA==",
110+
"x-ms-client-request-id" : "19fc7bdc-6436-4f6d-9a06-c1f24af21290",
111+
"Content-Type" : "application/octet-stream"
112+
},
113+
"Exception" : null
114+
}, {
115+
"Method" : "GET",
116+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
117+
"Headers" : {
118+
"x-ms-version" : "2020-08-04",
119+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
120+
"x-ms-client-request-id" : "16e79460-293c-4001-9a92-838ddf6d9243"
121+
},
122+
"Response" : {
123+
"x-ms-is-current-version" : "true",
124+
"content-length" : "7",
125+
"x-ms-version" : "2020-08-04",
126+
"x-ms-lease-status" : "unlocked",
127+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
128+
"Content-Range" : "bytes 0-6/7",
129+
"x-ms-lease-state" : "available",
130+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
131+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
132+
"x-ms-blob-content-md5" : "wh+Wm18D0z1D4E+PE252gg==",
133+
"retry-after" : "0",
134+
"StatusCode" : "206",
135+
"Date" : "Tue, 22 Jun 2021 22:43:40 GMT",
136+
"x-ms-blob-type" : "BlockBlob",
137+
"Accept-Ranges" : "bytes",
138+
"x-ms-server-encrypted" : "true",
139+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
140+
"eTag" : "0x8D935CF2EC22AA8",
141+
"x-ms-request-id" : "1fc13b64-801e-007a-6db8-6750e0000000",
142+
"Body" : "ZGVmYXVsdA==",
143+
"x-ms-client-request-id" : "16e79460-293c-4001-9a92-838ddf6d9243",
144+
"Content-Type" : "application/octet-stream"
145+
},
146+
"Exception" : null
147+
}, {
148+
"Method" : "GET",
149+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
150+
"Headers" : {
151+
"x-ms-version" : "2020-08-04",
152+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
153+
"x-ms-client-request-id" : "f6bd90f5-5b7d-4933-a326-1f24abadc71b"
154+
},
155+
"Response" : {
156+
"x-ms-is-current-version" : "true",
157+
"content-length" : "7",
158+
"x-ms-version" : "2020-08-04",
159+
"x-ms-lease-status" : "unlocked",
160+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
161+
"Content-Range" : "bytes 0-6/7",
162+
"x-ms-lease-state" : "available",
163+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
164+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
165+
"x-ms-blob-content-md5" : "wh+Wm18D0z1D4E+PE252gg==",
166+
"retry-after" : "0",
167+
"StatusCode" : "206",
168+
"Date" : "Tue, 22 Jun 2021 22:43:40 GMT",
169+
"x-ms-blob-type" : "BlockBlob",
170+
"Accept-Ranges" : "bytes",
171+
"x-ms-server-encrypted" : "true",
172+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
173+
"eTag" : "0x8D935CF2EC22AA8",
174+
"x-ms-request-id" : "1fc13b7b-801e-007a-01b8-6750e0000000",
175+
"Body" : "ZGVmYXVsdA==",
176+
"x-ms-client-request-id" : "f6bd90f5-5b7d-4933-a326-1f24abadc71b",
177+
"Content-Type" : "application/octet-stream"
178+
},
179+
"Exception" : null
180+
}, {
181+
"Method" : "GET",
182+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
183+
"Headers" : {
184+
"x-ms-version" : "2020-08-04",
185+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
186+
"x-ms-client-request-id" : "45bc9f54-52ae-4d76-9d80-01f6842cb2a7"
187+
},
188+
"Response" : {
189+
"x-ms-is-current-version" : "true",
190+
"content-length" : "7",
191+
"x-ms-version" : "2020-08-04",
192+
"x-ms-lease-status" : "unlocked",
193+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
194+
"Content-Range" : "bytes 0-6/7",
195+
"x-ms-lease-state" : "available",
196+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
197+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
198+
"x-ms-blob-content-md5" : "wh+Wm18D0z1D4E+PE252gg==",
199+
"retry-after" : "0",
200+
"StatusCode" : "206",
201+
"Date" : "Tue, 22 Jun 2021 22:43:41 GMT",
202+
"x-ms-blob-type" : "BlockBlob",
203+
"Accept-Ranges" : "bytes",
204+
"x-ms-server-encrypted" : "true",
205+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
206+
"eTag" : "0x8D935CF2EC22AA8",
207+
"x-ms-request-id" : "1fc13b93-801e-007a-15b8-6750e0000000",
208+
"Body" : "ZGVmYXVsdA==",
209+
"x-ms-client-request-id" : "45bc9f54-52ae-4d76-9d80-01f6842cb2a7",
210+
"Content-Type" : "application/octet-stream"
211+
},
212+
"Exception" : null
213+
}, {
214+
"Method" : "GET",
215+
"Uri" : "https://REDACTED.blob.core.windows.net/8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0/8b0ad08318b0ad083462324176c17ac6dff534c3e8a3",
216+
"Headers" : {
217+
"x-ms-version" : "2020-08-04",
218+
"User-Agent" : "azsdk-java-azure-storage-blob/12.13.0-beta.1 (11.0.7; Windows 10; 10.0)",
219+
"x-ms-client-request-id" : "c0fef5ce-c90f-45cd-a308-50d33e40f8d9"
220+
},
221+
"Response" : {
222+
"x-ms-is-current-version" : "true",
223+
"content-length" : "7",
224+
"x-ms-version" : "2020-08-04",
225+
"x-ms-lease-status" : "unlocked",
226+
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
227+
"Content-Range" : "bytes 0-6/7",
228+
"x-ms-lease-state" : "available",
229+
"Last-Modified" : "Tue, 22 Jun 2021 22:43:40 GMT",
230+
"x-ms-version-id" : "2021-06-22T22:43:40.8615080Z",
231+
"x-ms-blob-content-md5" : "wh+Wm18D0z1D4E+PE252gg==",
232+
"retry-after" : "0",
233+
"StatusCode" : "206",
234+
"Date" : "Tue, 22 Jun 2021 22:43:41 GMT",
235+
"x-ms-blob-type" : "BlockBlob",
236+
"Accept-Ranges" : "bytes",
237+
"x-ms-server-encrypted" : "true",
238+
"x-ms-creation-time" : "Tue, 22 Jun 2021 22:43:40 GMT",
239+
"eTag" : "0x8D935CF2EC22AA8",
240+
"x-ms-request-id" : "1fc13ba5-801e-007a-26b8-6750e0000000",
241+
"Body" : "ZGVmYXVsdA==",
242+
"x-ms-client-request-id" : "c0fef5ce-c90f-45cd-a308-50d33e40f8d9",
243+
"Content-Type" : "application/octet-stream"
244+
},
245+
"Exception" : null
246+
} ],
247+
"variables" : [ "8b0ad08308b0ad083462453172cc2f9ec9f78478f9a0", "8b0ad08318b0ad083462324176c17ac6dff534c3e8a3" ]
248+
}

0 commit comments

Comments
 (0)