Skip to content

Commit 68e69d1

Browse files
authored
CreateIfNotExists & DeleteIfExists APIs (Azure#27555)
* adding createIfNotExists for AppendBlob, PageBlob, and BlobContainer with groovy tests * adding createifnotexists implementation for datalakefileclients * adding createifnotexists apis for datalake * adding remaining tests for datalake createifnotexists * adding file share directory sync and async tests * adding deleteifexists and queue createifnotexists * adding create/delete for directory and file for filesystemclient * added all java docs and tests * adding try catch in min overloads * adding createifnotexists and deleteifexists for blobserviceclient * removing wildcard import statements * adding new options parameters for file shares and datalake * changing method signatures to mono of boolean and fixing java docs * adding new recordings for tests in blob, datalake, shares, queues * fixing build issues * adding delete optiongs bag * fixing build issues with javadocs * removing append blob tags test * fixing javadoc issues * adding create tags test * removing unused imports * resolving javadoc issues * adding create if not exists tags tests * resolving javadoc warnings * resolving javadoc errors * adding create if not exists tag tests for pageblob * adding playback recordings of tests * changing test env variables from http to https * adding https * updating shareAPI tests * adding new tests for delete * adding delete if exist tests on clients that were already deleted * changing return type condition for blobs * fixing indentation * fixing indentation for pageblob * fixing indentation for appendblob * adding new test for serviceAPI * changing return type for datalake * adding fileshare return type changes * adding queue return type changes * adding shareAPI tests * fixing spotbugs * fixing indentation * fixing indentation for shareAsync * indentation fix for queue javadoc * adding deleteifexists response return value * removing imports * removing unused imports and fixing indentation * adding missing test for datalake
1 parent b271fca commit 68e69d1

File tree

449 files changed

+39375
-174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

449 files changed

+39375
-174
lines changed

sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.azure.storage.blob.models.StorageAccountInfo;
4141
import com.azure.storage.blob.models.TaggedBlobItem;
4242
import com.azure.storage.blob.models.UserDelegationKey;
43+
import com.azure.storage.blob.options.BlobContainerCreateOptions;
4344
import com.azure.storage.blob.options.FindBlobsOptions;
4445
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
4546
import com.azure.storage.common.StorageSharedKeyCredential;
@@ -428,6 +429,83 @@ Mono<Response<Void>> createWithResponse(Map<String, String> metadata, PublicAcce
428429
.map(response -> new SimpleResponse<>(response, null));
429430
}
430431

432+
/**
433+
* Creates a new container within a storage account if it does not exist. For more information, see the
434+
* <a href="https://docs.microsoft.com/rest/api/storageservices/create-container">Azure Docs</a>.
435+
*
436+
* <p><strong>Code Samples</strong></p>
437+
*
438+
* <!-- src_embed com.azure.storage.blob.BlobContainerAsyncClient.createIfNotExists -->
439+
* <pre>
440+
* client.createIfNotExists&#40;&#41;.subscribe&#40;created -&gt; &#123;
441+
* if &#40;created&#41; &#123;
442+
* System.out.println&#40;&quot;successfully created.&quot;&#41;;
443+
* &#125; else &#123;
444+
* System.out.println&#40;&quot;Already exists.&quot;&#41;;
445+
* &#125;
446+
* &#125;&#41;;
447+
* </pre>
448+
* <!-- end com.azure.storage.blob.BlobContainerAsyncClient.createIfNotExists -->
449+
*
450+
* @return A reactive response signaling completion. {@code true} indicates a new container was created,
451+
* {@code true} indicates a container already existed at this location.
452+
*/
453+
@ServiceMethod(returns = ReturnType.SINGLE)
454+
public Mono<Boolean> createIfNotExists() {
455+
return createIfNotExistsWithResponse(null).map(response -> response.getStatusCode() != 409);
456+
}
457+
458+
/**
459+
* Creates a new container within a storage account if it does not exist. For more information, see the
460+
* <a href="https://docs.microsoft.com/rest/api/storageservices/create-container">Azure Docs</a>.
461+
*
462+
* <p><strong>Code Samples</strong></p>
463+
*
464+
* <!-- src_embed com.azure.storage.blob.BlobContainerAsyncClient.createIfNotExistsWithResponse#Map-PublicAccessType -->
465+
* <pre>
466+
* Map&lt;String, String&gt; metadata = Collections.singletonMap&#40;&quot;metadata&quot;, &quot;value&quot;&#41;;
467+
* BlobContainerCreateOptions options = new BlobContainerCreateOptions&#40;&#41;.setMetadata&#40;metadata&#41;
468+
* .setPublicAccessType&#40;PublicAccessType.CONTAINER&#41;;
469+
*
470+
* client.createIfNotExistsWithResponse&#40;options&#41;.subscribe&#40;response -&gt; &#123;
471+
* if &#40;response.getStatusCode&#40;&#41; == 409&#41; &#123;
472+
* System.out.println&#40;&quot;Already exists.&quot;&#41;;
473+
* &#125; else &#123;
474+
* System.out.println&#40;&quot;successfully created.&quot;&#41;;
475+
* &#125;
476+
* &#125;&#41;;
477+
* </pre>
478+
* <!-- end com.azure.storage.blob.BlobContainerAsyncClient.createIfNotExistsWithResponse#Map-PublicAccessType -->
479+
*
480+
* @param options {@link BlobContainerCreateOptions}
481+
* @return A reactive response signaling completion. If {@link Response}'s status code is 201, a new container was
482+
* successfully created. If status code is 409, a container already existed at this location.
483+
*/
484+
@ServiceMethod(returns = ReturnType.SINGLE)
485+
public Mono<Response<Void>> createIfNotExistsWithResponse(BlobContainerCreateOptions options) {
486+
try {
487+
return createIfNotExistsWithResponse(options, null);
488+
} catch (RuntimeException ex) {
489+
return monoError(LOGGER, ex);
490+
}
491+
}
492+
493+
Mono<Response<Void>> createIfNotExistsWithResponse(BlobContainerCreateOptions options, Context context) {
494+
try {
495+
options = options == null ? new BlobContainerCreateOptions() : options;
496+
return createWithResponse(options.getMetadata(), options.getPublicAccessType(), context)
497+
.onErrorResume(t -> t instanceof BlobStorageException && ((BlobStorageException) t)
498+
.getStatusCode() == 409,
499+
t -> {
500+
HttpResponse response = ((BlobStorageException) t).getResponse();
501+
return Mono.just(new SimpleResponse<>(response.getRequest(), response.getStatusCode(),
502+
response.getHeaders(), null));
503+
});
504+
} catch (RuntimeException ex) {
505+
return monoError(LOGGER, ex);
506+
}
507+
}
508+
431509
/**
432510
* Marks the specified container for deletion. The container and any blobs contained within it are later deleted
433511
* during garbage collection. For more information, see the
@@ -500,6 +578,86 @@ Mono<Response<Void>> deleteWithResponse(BlobRequestConditions requestConditions,
500578
.map(response -> new SimpleResponse<>(response, null));
501579
}
502580

581+
/**
582+
* Marks the specified container for deletion if it exists. The container and any blobs contained within it are later deleted
583+
* during garbage collection. For more information, see the
584+
* <a href="https://docs.microsoft.com/rest/api/storageservices/delete-container">Azure Docs</a>.
585+
*
586+
* <p><strong>Code Samples</strong></p>
587+
*
588+
* <!-- src_embed com.azure.storage.blob.BlobContainerAsyncClient.deleteIfExists -->
589+
* <pre>
590+
* client.deleteIfExists&#40;&#41;.subscribe&#40;deleted -&gt; &#123;
591+
* if &#40;deleted&#41; &#123;
592+
* System.out.println&#40;&quot;Successfully deleted.&quot;&#41;;
593+
* &#125; else &#123;
594+
* System.out.println&#40;&quot;Does not exist.&quot;&#41;;
595+
* &#125;
596+
* &#125;&#41;;
597+
* </pre>
598+
* <!-- end com.azure.storage.blob.BlobContainerAsyncClient.deleteIfExists -->
599+
*
600+
* @return A reactive response signaling completion. {@code true} indicates the container was deleted,
601+
* {@code false} indicates the container does not exist.
602+
*/
603+
@ServiceMethod(returns = ReturnType.SINGLE)
604+
public Mono<Boolean> deleteIfExists() {
605+
return deleteIfExistsWithResponse(null).map(response -> response.getStatusCode() != 404);
606+
}
607+
608+
/**
609+
* Marks the specified container for deletion if it exists. The container and any blobs contained within it are
610+
* later deleted during garbage collection. For more information, see the
611+
* <a href="https://docs.microsoft.com/rest/api/storageservices/delete-container">Azure Docs</a>.
612+
*
613+
* <p><strong>Code Samples</strong></p>
614+
*
615+
* <!-- src_embed com.azure.storage.blob.BlobContainerAsyncClient.deleteIfExistsWithResponse#BlobRequestConditions -->
616+
* <pre>
617+
* BlobRequestConditions requestConditions = new BlobRequestConditions&#40;&#41;
618+
* .setLeaseId&#40;leaseId&#41;
619+
* .setIfUnmodifiedSince&#40;OffsetDateTime.now&#40;&#41;.minusDays&#40;3&#41;&#41;;
620+
*
621+
* client.deleteIfExistsWithResponse&#40;requestConditions&#41;.subscribe&#40;response -&gt; &#123;
622+
* if &#40;response.getStatusCode&#40;&#41; == 404&#41; &#123;
623+
* System.out.println&#40;&quot;Does not exist.&quot;&#41;;
624+
* &#125; else &#123;
625+
* System.out.println&#40;&quot;successfully deleted.&quot;&#41;;
626+
* &#125;
627+
* &#125;&#41;;
628+
* </pre>
629+
* <!-- end com.azure.storage.blob.BlobContainerAsyncClient.deleteIfExistsWithResponse#BlobRequestConditions -->
630+
*
631+
* @param requestConditions {@link BlobRequestConditions}
632+
* @return A reactive response signaling completion. If {@link Response}'s status code is 202, the container was
633+
* successfully deleted. If status code is 404, the container does not exist.
634+
* @throws UnsupportedOperationException If either {@link BlobRequestConditions#getIfMatch()} or
635+
* {@link BlobRequestConditions#getIfNoneMatch()} is set.
636+
*/
637+
@ServiceMethod(returns = ReturnType.SINGLE)
638+
public Mono<Response<Void>> deleteIfExistsWithResponse(BlobRequestConditions requestConditions) {
639+
try {
640+
return deleteIfExistsWithResponse(requestConditions, null);
641+
} catch (RuntimeException ex) {
642+
return monoError(LOGGER, ex);
643+
}
644+
}
645+
646+
Mono<Response<Void>> deleteIfExistsWithResponse(BlobRequestConditions requestConditions, Context context) {
647+
requestConditions = requestConditions == null ? new BlobRequestConditions() : requestConditions;
648+
try {
649+
return deleteWithResponse(requestConditions, context)
650+
.onErrorResume(t -> t instanceof BlobStorageException && ((BlobStorageException) t).getStatusCode() == 404,
651+
t -> {
652+
HttpResponse response = ((BlobStorageException) t).getResponse();
653+
return Mono.just(new SimpleResponse<>(response.getRequest(), response.getStatusCode(),
654+
response.getHeaders(), null));
655+
});
656+
} catch (RuntimeException ex) {
657+
return monoError(LOGGER, ex);
658+
}
659+
}
660+
503661
/**
504662
* Returns the container's metadata and system properties. For more information, see the
505663
* <a href="https://docs.microsoft.com/rest/api/storageservices/get-container-metadata">Azure Docs</a>.

sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerClient.java

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import com.azure.storage.blob.models.StorageAccountInfo;
2222
import com.azure.storage.blob.models.TaggedBlobItem;
2323
import com.azure.storage.blob.models.UserDelegationKey;
24+
import com.azure.storage.blob.options.BlobContainerCreateOptions;
2425
import com.azure.storage.blob.options.FindBlobsOptions;
2526
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
2627
import com.azure.storage.common.StorageSharedKeyCredential;
28+
import com.azure.storage.common.implementation.StorageImplUtils;
2729
import reactor.core.publisher.Mono;
2830

2931
import java.time.Duration;
@@ -318,6 +320,61 @@ public Response<Void> createWithResponse(Map<String, String> metadata, PublicAcc
318320
return blockWithOptionalTimeout(response, timeout);
319321
}
320322

323+
/**
324+
* Creates a new container within a storage account if it does not exist. For more information, see the
325+
* <a href="https://docs.microsoft.com/rest/api/storageservices/create-container">Azure Docs</a>.
326+
*
327+
* <p><strong>Code Samples</strong></p>
328+
*
329+
* <!-- src_embed com.azure.storage.blob.BlobContainerClient.createIfNotExists -->
330+
* <pre>
331+
* boolean result = client.createIfNotExists&#40;&#41;;
332+
* System.out.println&#40;&quot;Create completed: &quot; + result&#41;;
333+
* </pre>
334+
* <!-- end com.azure.storage.blob.BlobContainerClient.createIfNotExists -->
335+
*
336+
* @return {@code true} if container is successfully created, {@code false} if container already exists.
337+
*/
338+
@ServiceMethod(returns = ReturnType.SINGLE)
339+
public boolean createIfNotExists() {
340+
return createIfNotExistsWithResponse(null, null, null).getStatusCode() == 201;
341+
}
342+
343+
/**
344+
* Creates a new container within a storage account if it does not exist. For more information, see the
345+
* <a href="https://docs.microsoft.com/rest/api/storageservices/create-container">Azure Docs</a>.
346+
*
347+
* <p><strong>Code Samples</strong></p>
348+
*
349+
* <!-- src_embed com.azure.storage.blob.BlobContainerClient.createIfNotExistsWithResponse#BlobContainerCreateOptions-Duration-Context -->
350+
* <pre>
351+
* Map&lt;String, String&gt; metadata = Collections.singletonMap&#40;&quot;metadata&quot;, &quot;value&quot;&#41;;
352+
* Context context = new Context&#40;&quot;Key&quot;, &quot;Value&quot;&#41;;
353+
* BlobContainerCreateOptions options = new BlobContainerCreateOptions&#40;&#41;.setMetadata&#40;metadata&#41;
354+
* .setPublicAccessType&#40;PublicAccessType.CONTAINER&#41;;
355+
*
356+
* Response&lt;Void&gt; response = client.createIfNotExistsWithResponse&#40;options, timeout, context&#41;;
357+
* if &#40;response.getStatusCode&#40;&#41; == 409&#41; &#123;
358+
* System.out.println&#40;&quot;Already existed.&quot;&#41;;
359+
* &#125; else &#123;
360+
* System.out.printf&#40;&quot;Create completed with status %d%n&quot;, response.getStatusCode&#40;&#41;&#41;;
361+
* &#125;
362+
* </pre>
363+
* <!-- end com.azure.storage.blob.BlobContainerClient.createIfNotExistsWithResponse#BlobContainerCreateOptions-Duration-Context -->
364+
*
365+
* @param options {@link BlobContainerCreateOptions}
366+
* @param timeout An optional timeout value beyond which a {@link RuntimeException} will be raised.
367+
* @param context Additional context that is passed through the Http pipeline during the service call.
368+
* @return A response containing status code and HTTP headers. If {@link Response}'s status code is 201, a new
369+
* container was successfully created. If status code is 409, a container already existed at this location.
370+
*/
371+
@ServiceMethod(returns = ReturnType.SINGLE)
372+
public Response<Void> createIfNotExistsWithResponse(BlobContainerCreateOptions options, Duration timeout,
373+
Context context) {
374+
return StorageImplUtils.blockWithOptionalTimeout(client.
375+
createIfNotExistsWithResponse(options, context), timeout);
376+
}
377+
321378
/**
322379
* Marks the specified container for deletion. The container and any blobs contained within it are later deleted
323380
* during garbage collection. For more information, see the
@@ -375,6 +432,62 @@ public Response<Void> deleteWithResponse(BlobRequestConditions requestConditions
375432
return blockWithOptionalTimeout(response, timeout);
376433
}
377434

435+
/**
436+
* Marks the specified container for deletion if it exists. The container and any blobs contained within
437+
* it are later deleted during garbage collection. For more information, see the
438+
* <a href="https://docs.microsoft.com/rest/api/storageservices/delete-container">Azure Docs</a>.
439+
*
440+
* <p><strong>Code Samples</strong></p>
441+
*
442+
* <!-- src_embed com.azure.storage.blob.BlobContainerClient.deleteIfExists -->
443+
* <pre>
444+
* boolean result = client.deleteIfExists&#40;&#41;;
445+
* System.out.println&#40;&quot;Delete completed: &quot; + result&#41;;
446+
* </pre>
447+
* <!-- end com.azure.storage.blob.BlobContainerClient.deleteIfExists -->
448+
* @return {@code true} if container is successfully deleted, {@code false} if container does not exist.
449+
*/
450+
@ServiceMethod(returns = ReturnType.SINGLE)
451+
public boolean deleteIfExists() {
452+
Response<Void> response = deleteIfExistsWithResponse(null, null, Context.NONE);
453+
return response.getStatusCode() == 202;
454+
}
455+
456+
/**
457+
* Marks the specified container for deletion if it exists. The container and any blobs contained within it
458+
* are later deleted during garbage collection. For more information, see the
459+
* <a href="https://docs.microsoft.com/rest/api/storageservices/delete-container">Azure Docs</a>.
460+
*
461+
* <p><strong>Code Samples</strong></p>
462+
*
463+
* <!-- src_embed com.azure.storage.blob.BlobContainerClient.deleteIfExistsWithResponse#BlobRequestConditions-Duration-Context -->
464+
* <pre>
465+
* BlobRequestConditions requestConditions = new BlobRequestConditions&#40;&#41;
466+
* .setLeaseId&#40;leaseId&#41;
467+
* .setIfUnmodifiedSince&#40;OffsetDateTime.now&#40;&#41;.minusDays&#40;3&#41;&#41;;
468+
* Context context = new Context&#40;&quot;Key&quot;, &quot;Value&quot;&#41;;
469+
*
470+
* Response&lt;Void&gt; response = client.deleteIfExistsWithResponse&#40;requestConditions, timeout, context&#41;;
471+
* if &#40;response.getStatusCode&#40;&#41; == 404&#41; &#123;
472+
* System.out.println&#40;&quot;Does not exist.&quot;&#41;;
473+
* &#125; else &#123;
474+
* System.out.printf&#40;&quot;Delete completed with status %d%n&quot;, response.getStatusCode&#40;&#41;&#41;;
475+
* &#125;
476+
* </pre>
477+
* <!-- end com.azure.storage.blob.BlobContainerClient.deleteIfExistsWithResponse#BlobRequestConditions-Duration-Context -->
478+
*
479+
* @param requestConditions {@link BlobRequestConditions}
480+
* @param timeout An optional timeout value beyond which a {@link RuntimeException} will be raised.
481+
* @param context Additional context that is passed through the Http pipeline during the service call.
482+
* @return A response containing status code and HTTP headers. If {@link Response}'s status code is 202, the container
483+
* was successfully deleted. If status code is 404, the container does not exist.
484+
*/
485+
@ServiceMethod(returns = ReturnType.SINGLE)
486+
public Response<Void> deleteIfExistsWithResponse(BlobRequestConditions requestConditions, Duration timeout,
487+
Context context) {
488+
return blockWithOptionalTimeout(client.deleteIfExistsWithResponse(requestConditions, context), timeout);
489+
}
490+
378491
/**
379492
* Returns the container's metadata and system properties. For more information, see the
380493
* <a href="https://docs.microsoft.com/rest/api/storageservices/get-container-metadata">Azure Docs</a>.

0 commit comments

Comments
 (0)