|
11 | 11 | import com.azure.core.http.HttpResponse; |
12 | 12 | import com.azure.core.http.rest.Response; |
13 | 13 | import com.azure.core.http.rest.SimpleResponse; |
| 14 | +import com.azure.core.util.BinaryData; |
14 | 15 | import com.azure.core.util.Context; |
15 | 16 | import com.azure.core.util.Contexts; |
16 | 17 | import com.azure.core.util.DateTimeRfc1123; |
|
66 | 67 | import java.util.HashSet; |
67 | 68 | import java.util.List; |
68 | 69 | import java.util.Map; |
| 70 | +import java.util.Objects; |
69 | 71 | import java.util.Set; |
70 | 72 | import java.util.function.BiFunction; |
71 | 73 | import java.util.function.Function; |
@@ -332,6 +334,36 @@ public Mono<PathInfo> upload(Flux<ByteBuffer> data, ParallelTransferOptions para |
332 | 334 | return upload(data, parallelTransferOptions, false); |
333 | 335 | } |
334 | 336 |
|
| 337 | + /** |
| 338 | + * Creates a new file and uploads content. |
| 339 | + * |
| 340 | + * <p><strong>Code Samples</strong></p> |
| 341 | + * |
| 342 | + * <!-- src_embed com.azure.storage.file.datalake.DataLakeFileAsyncClient.upload#BinaryData-ParallelTransferOptions --> |
| 343 | + * <pre> |
| 344 | + * Long blockSize = 100L * 1024L * 1024L; // 100 MB; |
| 345 | + * ParallelTransferOptions pto = new ParallelTransferOptions() |
| 346 | + * .setBlockSizeLong(blockSize) |
| 347 | + * .setProgressListener(bytesTransferred -> System.out.printf("Upload progress: %s bytes sent", bytesTransferred)); |
| 348 | + * |
| 349 | + * BinaryData.fromFlux(data, length, false) |
| 350 | + * .flatMap(binaryData -> client.upload(binaryData, pto)) |
| 351 | + * .doOnError(throwable -> System.err.printf("Failed to upload %s%n", throwable.getMessage())) |
| 352 | + * .subscribe(completion -> System.out.println("Upload succeeded")); |
| 353 | + * </pre> |
| 354 | + * <!-- end com.azure.storage.file.datalake.DataLakeFileAsyncClient.upload#BinaryData-ParallelTransferOptions --> |
| 355 | + * |
| 356 | + * @param data The data to write to the file. Unlike other upload methods, this method does not require that the |
| 357 | + * {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not expected |
| 358 | + * to produce the same values across subscriptions. |
| 359 | + * @param parallelTransferOptions {@link ParallelTransferOptions} used to configure buffered uploading. |
| 360 | + * @return A reactive response containing the information of the uploaded file. |
| 361 | + */ |
| 362 | + @ServiceMethod(returns = ReturnType.SINGLE) |
| 363 | + public Mono<PathInfo> upload(BinaryData data, ParallelTransferOptions parallelTransferOptions) { |
| 364 | + return upload(data, parallelTransferOptions, false); |
| 365 | + } |
| 366 | + |
335 | 367 | /** |
336 | 368 | * Creates a new file and uploads content. |
337 | 369 | * |
@@ -376,6 +408,54 @@ public Mono<PathInfo> upload(Flux<ByteBuffer> data, ParallelTransferOptions para |
376 | 408 | .flatMap(FluxUtil::toMono); |
377 | 409 | } |
378 | 410 |
|
| 411 | + /** |
| 412 | + * Creates a new file and uploads content. |
| 413 | + * |
| 414 | + * <p><strong>Code Samples</strong></p> |
| 415 | + * |
| 416 | + * <!-- src_embed com.azure.storage.file.datalake.DataLakeFileAsyncClient.upload#BinaryData-ParallelTransferOptions-boolean --> |
| 417 | + * <pre> |
| 418 | + * Long blockSize = 100L * 1024L * 1024L; // 100 MB; |
| 419 | + * ParallelTransferOptions pto = new ParallelTransferOptions() |
| 420 | + * .setBlockSizeLong(blockSize) |
| 421 | + * .setProgressListener(bytesTransferred -> System.out.printf("Upload progress: %s bytes sent", bytesTransferred)); |
| 422 | + * |
| 423 | + * BinaryData.fromFlux(data, length, false) |
| 424 | + * .flatMap(binaryData -> client.upload(binaryData, pto, true)) |
| 425 | + * .doOnError(throwable -> System.err.printf("Failed to upload %s%n", throwable.getMessage())) |
| 426 | + * .subscribe(completion -> System.out.println("Upload succeeded")); |
| 427 | + * </pre> |
| 428 | + * <!-- end com.azure.storage.file.datalake.DataLakeFileAsyncClient.upload#BinaryData-ParallelTransferOptions-boolean --> |
| 429 | + * |
| 430 | + * @param data The data to write to the file. Unlike other upload methods, this method does not require that the |
| 431 | + * {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not expected |
| 432 | + * to produce the same values across subscriptions. |
| 433 | + * @param parallelTransferOptions {@link ParallelTransferOptions} used to configure buffered uploading. |
| 434 | + * @param overwrite Whether to overwrite, should the file already exist. |
| 435 | + * @return A reactive response containing the information of the uploaded file. |
| 436 | + */ |
| 437 | + @ServiceMethod(returns = ReturnType.SINGLE) |
| 438 | + public Mono<PathInfo> upload(BinaryData data, ParallelTransferOptions parallelTransferOptions, boolean overwrite) { |
| 439 | + Mono<Void> overwriteCheck; |
| 440 | + DataLakeRequestConditions requestConditions; |
| 441 | + |
| 442 | + if (overwrite) { |
| 443 | + overwriteCheck = Mono.empty(); |
| 444 | + requestConditions = null; |
| 445 | + } else { |
| 446 | + overwriteCheck = exists().flatMap(exists -> exists |
| 447 | + ? monoError(LOGGER, new IllegalArgumentException(Constants.BLOB_ALREADY_EXISTS)) |
| 448 | + : Mono.empty()); |
| 449 | + requestConditions = new DataLakeRequestConditions() |
| 450 | + .setIfNoneMatch(Constants.HeaderConstants.ETAG_WILDCARD); |
| 451 | + } |
| 452 | + |
| 453 | + return overwriteCheck |
| 454 | + .then(uploadWithResponse(new FileParallelUploadOptions(data) |
| 455 | + .setParallelTransferOptions(parallelTransferOptions).setRequestConditions(requestConditions))) |
| 456 | + .flatMap(FluxUtil::toMono); |
| 457 | + } |
| 458 | + |
379 | 459 | /** |
380 | 460 | * Creates a new file. |
381 | 461 | * To avoid overwriting, pass "*" to {@link DataLakeRequestConditions#setIfNoneMatch(String)}. |
@@ -526,7 +606,10 @@ public Mono<Response<PathInfo>> uploadWithResponse(FileParallelUploadOptions opt |
526 | 606 | fileOffset, length, options.getHeaders(), validatedUploadRequestConditions, |
527 | 607 | validatedParallelTransferOptions.getProgressListener()); |
528 | 608 |
|
529 | | - Flux<ByteBuffer> data = options.getDataFlux(); |
| 609 | + BinaryData binaryData = options.getData(); |
| 610 | + |
| 611 | + // if BinaryData is present, convert it to Flux Byte Buffer |
| 612 | + Flux<ByteBuffer> data = binaryData != null ? binaryData.toFluxByteBuffer() : options.getDataFlux(); |
530 | 613 | // no specified length: use azure.core's converter |
531 | 614 | if (data == null && options.getOptionalLength() == null) { |
532 | 615 | // We can only buffer up to max int due to restrictions in ByteBuffer. |
@@ -843,6 +926,34 @@ public Mono<Void> append(Flux<ByteBuffer> data, long fileOffset, long length) { |
843 | 926 | return appendWithResponse(data, fileOffset, length, null, null).flatMap(FluxUtil::toMono); |
844 | 927 | } |
845 | 928 |
|
| 929 | + /** |
| 930 | + * Appends data to the specified resource to later be flushed (written) by a call to flush |
| 931 | + * |
| 932 | + * <p><strong>Code Samples</strong></p> |
| 933 | + * |
| 934 | + * <!-- src_embed com.azure.storage.file.datalake.DataLakeFileAsyncClient.append#Flux-long-long --> |
| 935 | + * <pre> |
| 936 | + * client.append(data, offset, length) |
| 937 | + * .subscribe( |
| 938 | + * response -> System.out.println("Append data completed"), |
| 939 | + * error -> System.out.printf("Error when calling append data: %s", error)); |
| 940 | + * </pre> |
| 941 | + * <!-- end com.azure.storage.file.datalake.DataLakeFileAsyncClient.append#Flux-long-long --> |
| 942 | + * |
| 943 | + * <p>For more information, see the |
| 944 | + * <a href="https://docs.microsoft.com/rest/api/storageservices/datalakestoragegen2/path/update">Azure |
| 945 | + * Docs</a></p> |
| 946 | + * |
| 947 | + * @param data The data to write to the file. |
| 948 | + * @param fileOffset The position where the data is to be appended. |
| 949 | + * |
| 950 | + * @return A reactive response signalling completion. |
| 951 | + */ |
| 952 | + @ServiceMethod(returns = ReturnType.SINGLE) |
| 953 | + public Mono<Void> append(BinaryData data, long fileOffset) { |
| 954 | + return appendWithResponse(data, fileOffset, null, null).flatMap(FluxUtil::toMono); |
| 955 | + } |
| 956 | + |
846 | 957 | /** |
847 | 958 | * Appends data to the specified resource to later be flushed (written) by a call to flush |
848 | 959 | * |
@@ -884,6 +995,47 @@ public Mono<Response<Void>> appendWithResponse(Flux<ByteBuffer> data, long fileO |
884 | 995 | } |
885 | 996 | } |
886 | 997 |
|
| 998 | + /** |
| 999 | + * Appends data to the specified resource to later be flushed (written) by a call to flush |
| 1000 | + * |
| 1001 | + * <p><strong>Code Samples</strong></p> |
| 1002 | + * |
| 1003 | + * <!-- src_embed com.azure.storage.file.datalake.DataLakeFileAsyncClient.appendWithResponse#Flux-long-long-byte-String --> |
| 1004 | + * <pre> |
| 1005 | + * FileRange range = new FileRange(1024, 2048L); |
| 1006 | + * DownloadRetryOptions options = new DownloadRetryOptions().setMaxRetryRequests(5); |
| 1007 | + * byte[] contentMd5 = new byte[0]; // Replace with valid md5 |
| 1008 | + * |
| 1009 | + * client.appendWithResponse(data, offset, length, contentMd5, leaseId).subscribe(response -> |
| 1010 | + * System.out.printf("Append data completed with status %d%n", response.getStatusCode())); |
| 1011 | + * </pre> |
| 1012 | + * <!-- end com.azure.storage.file.datalake.DataLakeFileAsyncClient.appendWithResponse#Flux-long-long-byte-String --> |
| 1013 | + * |
| 1014 | + * <p>For more information, see the |
| 1015 | + * <a href="https://docs.microsoft.com/rest/api/storageservices/datalakestoragegen2/path/update">Azure |
| 1016 | + * Docs</a></p> |
| 1017 | + * |
| 1018 | + * @param data The data to write to the file. |
| 1019 | + * @param fileOffset The position where the data is to be appended. |
| 1020 | + * @param contentMd5 An MD5 hash of the content of the data. If specified, the service will calculate the MD5 of the |
| 1021 | + * received data and fail the request if it does not match the provided MD5. |
| 1022 | + * @param leaseId By setting lease id, requests will fail if the provided lease does not match the active lease on |
| 1023 | + * the file. |
| 1024 | + * |
| 1025 | + * @return A reactive response signalling completion. |
| 1026 | + */ |
| 1027 | + @ServiceMethod(returns = ReturnType.SINGLE) |
| 1028 | + public Mono<Response<Void>> appendWithResponse(BinaryData data, long fileOffset, byte[] contentMd5, String leaseId) { |
| 1029 | + try { |
| 1030 | + Objects.requireNonNull(data); |
| 1031 | + Flux<ByteBuffer> fluxData = data.toFluxByteBuffer(); |
| 1032 | + long length = data.getLength(); |
| 1033 | + return withContext(context -> appendWithResponse(fluxData, fileOffset, length, contentMd5, leaseId, context)); |
| 1034 | + } catch (RuntimeException ex) { |
| 1035 | + return monoError(LOGGER, ex); |
| 1036 | + } |
| 1037 | + } |
| 1038 | + |
887 | 1039 | Mono<Response<Void>> appendWithResponse(Flux<ByteBuffer> data, long fileOffset, long length, |
888 | 1040 | byte[] contentMd5, String leaseId, Context context) { |
889 | 1041 |
|
|
0 commit comments