public CompletableFuture<Boolean> downloadBlobAsync(BlobId blobId, OutputStream outputStream) {
    azureMetrics.blobDownloadRequestCount.inc();
    Timer.Context storageTimer = azureMetrics.blobDownloadTime.time();
    BlobLayout blobLayout = blobLayoutStrategy.getDataBlobLayout(blobId);
    return downloadFileAsync(blobLayout.containerName, blobLayout.blobFilePath, blobId, outputStream,
        true).whenComplete((downloadSuccess, throwable) -> {
      storageTimer.stop();
      if (throwable != null) {
        azureMetrics.blobDownloadErrorCount.inc();
      } else {
        if (downloadSuccess) {
          azureMetrics.blobDownloadSuccessCount.inc();
        }
      }
    });
  }
Download the blob from Azure storage asynchronously.
@param blobId id of the Ambry blob to be downloaded
@param outputStream outputstream to populate the downloaded data with
@return a CompletableFuture of type {@link Boolean} that will eventually be {@code true} if the blob was downloaded
        successfully or {@code false} if the blob was not found.  If there was an error on ABS side, it will
        complete exceptionally containing the BlobStorageException.
ambry-cloud/src/main/java/com/github/ambry/cloud/azure/AzureBlobDataAccessor.java