Skip to content

Commit 035d6ea

Browse files
Refactor to minimize branching and consolidate download methods into single code path
Co-authored-by: gunjansingh-msft <[email protected]>
1 parent 2a7155f commit 035d6ea

File tree

1 file changed

+7
-87
lines changed

1 file changed

+7
-87
lines changed

sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java

Lines changed: 7 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,102 +1305,22 @@ public Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponse(Downlo
13051305
private Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponseHelper(DownloadRetryOptions options,
13061306
BlobRequestConditions requestConditions, DownloadContentValidationOptions contentValidationOptions, Context context) {
13071307

1308-
// Determine if content validation is needed
1309-
boolean hasContentValidation = contentValidationOptions != null &&
1310-
(contentValidationOptions.isStructuredMessageValidationEnabled() || contentValidationOptions.isMd5ValidationEnabled());
1311-
1312-
if (hasContentValidation) {
1313-
return downloadStreamWithResponse(null, options, requestConditions, false, contentValidationOptions, context)
1314-
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1315-
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1316-
data, r.getDeserializedHeaders())));
1317-
} else {
1318-
return downloadStreamWithResponse(null, options, requestConditions, false, context)
1319-
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1320-
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1321-
data, r.getDeserializedHeaders())));
1322-
}
1308+
// Call the unified downloadStreamWithResponse method directly - it handles validation options internally
1309+
return downloadStreamWithResponse(null, options, requestConditions, false, contentValidationOptions, context)
1310+
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1311+
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1312+
data, r.getDeserializedHeaders())));
13231313
}
13241314

13251315
Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, DownloadRetryOptions options,
13261316
BlobRequestConditions requestConditions, boolean getRangeContentMd5, Context context) {
1327-
BlobRange finalRange = range == null ? new BlobRange(0) : range;
1328-
Boolean getMD5 = getRangeContentMd5 ? getRangeContentMd5 : null;
1329-
BlobRequestConditions finalRequestConditions
1330-
= requestConditions == null ? new BlobRequestConditions() : requestConditions;
1331-
DownloadRetryOptions finalOptions = (options == null) ? new DownloadRetryOptions() : options;
1332-
1333-
// The first range should eagerly convert headers as they'll be used to create response types.
1334-
Context firstRangeContext = context == null
1335-
? new Context("azure-eagerly-convert-headers", true)
1336-
: context.addData("azure-eagerly-convert-headers", true);
1337-
1338-
return downloadRange(finalRange, finalRequestConditions, finalRequestConditions.getIfMatch(), getMD5,
1339-
firstRangeContext).map(response -> {
1340-
BlobsDownloadHeaders blobsDownloadHeaders = new BlobsDownloadHeaders(response.getHeaders());
1341-
String eTag = blobsDownloadHeaders.getETag();
1342-
BlobDownloadHeaders blobDownloadHeaders = ModelHelper.populateBlobDownloadHeaders(blobsDownloadHeaders,
1343-
ModelHelper.getErrorCode(response.getHeaders()));
1344-
1345-
/*
1346-
* If the customer did not specify a count, they are reading to the end of the blob. Extract this value
1347-
* from the response for better book-keeping towards the end.
1348-
*/
1349-
long finalCount;
1350-
long initialOffset = finalRange.getOffset();
1351-
if (finalRange.getCount() == null) {
1352-
long blobLength = ModelHelper.getBlobLength(blobDownloadHeaders);
1353-
finalCount = blobLength - initialOffset;
1354-
} else {
1355-
finalCount = finalRange.getCount();
1356-
}
1357-
1358-
// The resume function takes throwable and offset at the destination.
1359-
// I.e. offset is relative to the starting point.
1360-
BiFunction<Throwable, Long, Mono<StreamResponse>> onDownloadErrorResume = (throwable, offset) -> {
1361-
if (!(throwable instanceof IOException || throwable instanceof TimeoutException)) {
1362-
return Mono.error(throwable);
1363-
}
1364-
1365-
long newCount = finalCount - offset;
1366-
1367-
/*
1368-
* It's possible that the network stream will throw an error after emitting all data but before
1369-
* completing. Issuing a retry at this stage would leave the download in a bad state with
1370-
* incorrect count and offset values. Because we have read the intended amount of data, we can
1371-
* ignore the error at the end of the stream.
1372-
*/
1373-
if (newCount == 0) {
1374-
LOGGER.warning("Exception encountered in ReliableDownload after all data read from the network "
1375-
+ "but before stream signaled completion. Returning success as all data was downloaded. "
1376-
+ "Exception message: " + throwable.getMessage());
1377-
return Mono.empty();
1378-
}
1379-
1380-
try {
1381-
return downloadRange(new BlobRange(initialOffset + offset, newCount), finalRequestConditions,
1382-
eTag, getMD5, context);
1383-
} catch (Exception e) {
1384-
return Mono.error(e);
1385-
}
1386-
};
1387-
1388-
return BlobDownloadAsyncResponseConstructorProxy.create(response, onDownloadErrorResume, finalOptions);
1389-
});
1317+
// Delegate to the overload with null content validation options
1318+
return downloadStreamWithResponse(range, options, requestConditions, getRangeContentMd5, null, context);
13901319
}
13911320

13921321
Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, DownloadRetryOptions options,
13931322
BlobRequestConditions requestConditions, boolean getRangeContentMd5, DownloadContentValidationOptions contentValidationOptions, Context context) {
13941323

1395-
// Consolidate validation logic - check if any content validation is needed
1396-
boolean hasContentValidation = contentValidationOptions != null &&
1397-
(contentValidationOptions.isStructuredMessageValidationEnabled() || contentValidationOptions.isMd5ValidationEnabled());
1398-
1399-
// For backward compatibility, if no content validation options are provided, use the original method
1400-
if (!hasContentValidation) {
1401-
return downloadStreamWithResponse(range, options, requestConditions, getRangeContentMd5, context);
1402-
}
1403-
14041324
BlobRange finalRange = range == null ? new BlobRange(0) : range;
14051325

14061326
// Determine MD5 validation: properly consider both getRangeContentMd5 parameter and validation options

0 commit comments

Comments
 (0)