public CompletableFuture<Boolean> uploadAsyncIfNotExists(BlobId blobId, long inputLength,
      CloudBlobMetadata cloudBlobMetadata, InputStream blobInputStream) {
    BlobRequestConditions blobRequestConditions = new BlobRequestConditions().setIfNoneMatch("*");
    azureMetrics.blobUploadRequestCount.inc();
    Timer.Context storageTimer = azureMetrics.blobUploadTime.time();
    return FutureUtils.orTimeout(
        storageClient.uploadWithResponse(blobId, blobInputStream, inputLength, null, cloudBlobMetadata.toMap(), null,
            null, blobRequestConditions), uploadTimeout).handle((response, throwable) -> {
      storageTimer.stop();
      if (throwable != null) {
        Exception ex = Utils.extractFutureExceptionCause(throwable);
        if (ex instanceof BlobStorageException
            && ((BlobStorageException) ex).getErrorCode() == BlobErrorCode.BLOB_ALREADY_EXISTS) {
          // Received exception due to blob being already present
          logger.debug("Skipped upload of existing blob {}", blobId);
          azureMetrics.blobUploadConflictCount.inc();
          return false;
        }
        throw throwable instanceof CompletionException ? (CompletionException) throwable
            : new CompletionException(throwable);
      }
      // Blob uploaded successfully
      logger.debug("Uploaded blob {} to ABS", blobId);
      azureMetrics.blobUploadSuccessCount.inc();
      return true;
    });
  }
Upload the blob to Azure storage asynchronously if it does not already exist in the designated container.
@param blobId the blobId to upload
@param inputLength the input stream length, if known (-1 if not)
@param cloudBlobMetadata the blob metadata
@param blobInputStream the input stream
@return a CompletableFuture of type {@link Boolean} that will eventually be {@code true} if the upload was successful,
        or {@code false} if the blob already exists. 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