Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 143 additions & 2 deletions sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,143 @@ await CreateInternal(
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The <see cref="CreateIfNotExists"/> operation creates a new 0-length
/// append blob. If the append blob already exists, the content of
/// the existing append blob will remain unchanged. To add content to the append
/// blob, call the <see cref="AppendBlockAsync"/> operation.
Comment thread
amnguye marked this conversation as resolved.
Outdated
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob" />.
/// </summary>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new append blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this append blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// newly created append blob.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual Response<BlobContentInfo> CreateIfNotExists(
BlobHttpHeaders? httpHeaders = default,
Metadata metadata = default,
CancellationToken cancellationToken = default) =>
CreateIfNotExistsInternal(
httpHeaders,
metadata,
false, // async
cancellationToken)
.EnsureCompleted();

/// <summary>
/// The <see cref="CreateIfNotExistsAsync"/> operation creates a new 0-length
/// append blob. If the append blob already exists, the content of
/// the existing append blob will remain unchanged. To add content to the append
/// blob, call the <see cref="AppendBlockAsync"/> operation.
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob" />.
/// </summary>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new append blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this append blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// newly created append blob.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual async Task<Response<BlobContentInfo>> CreateIfNotExistsAsync(
BlobHttpHeaders? httpHeaders = default,
Metadata metadata = default,
CancellationToken cancellationToken = default) =>
await CreateIfNotExistsInternal(
httpHeaders,
metadata,
true, // async
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The <see cref="CreateIfNotExistsInternal"/> operation creates a new 0-length
/// append blob. If the append blob already exists, the content of
/// the existing append blob will remain unchanged. To add content to the append
/// blob, call the <see cref="AppendBlockAsync"/> operation.
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob" />.
/// </summary>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new append blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this append blob.
/// </param>
/// <param name="async">
/// Whether to invoke the operation asynchronously.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// newly created append blob.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
private async Task<Response<BlobContentInfo>> CreateIfNotExistsInternal(
BlobHttpHeaders? httpHeaders,
Metadata metadata,
bool async,
CancellationToken cancellationToken)
{
AppendBlobAccessConditions accessConditions = new AppendBlobAccessConditions
{
HttpAccessConditions = new HttpAccessConditions
{
IfNoneMatch = new ETag(Constants.Wildcard)
}
};
try
{
return await CreateInternal(
httpHeaders,
metadata,
accessConditions,
async,
cancellationToken,
Constants.Blob.Append.CreateIfNotExistsOperationName)
.ConfigureAwait(false);
}
catch (StorageRequestFailedException storageRequestFailedException)
Comment thread
amnguye marked this conversation as resolved.
Outdated
when (storageRequestFailedException.ErrorCode == Constants.Blob.AlreadyExists)
{
return default;
}
}

/// <summary>
/// The <see cref="CreateInternal"/> operation creates a new 0-length
/// append blob. The content of any existing blob is overwritten with
Expand All @@ -356,6 +493,9 @@ await CreateInternal(
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <param name="operationName">
/// Optional. To indicate if the name of the operation.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// newly created append blob.
Expand All @@ -369,7 +509,8 @@ private async Task<Response<BlobContentInfo>> CreateInternal(
Metadata metadata,
AppendBlobAccessConditions? accessConditions,
bool async,
CancellationToken cancellationToken)
CancellationToken cancellationToken,
string operationName = Constants.Blob.Append.CreateOperationName)
Comment thread
amnguye marked this conversation as resolved.
Outdated
{
using (Pipeline.BeginLoggingScope(nameof(AppendBlobClient)))
{
Expand Down Expand Up @@ -403,7 +544,7 @@ private async Task<Response<BlobContentInfo>> CreateInternal(
ifMatch: accessConditions?.HttpAccessConditions?.IfMatch,
ifNoneMatch: accessConditions?.HttpAccessConditions?.IfNoneMatch,
async: async,
operationName: "Azure.Storage.Blobs.Specialized.AppendBlobClient.Create",
operationName: operationName,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
Expand Down
144 changes: 142 additions & 2 deletions sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,142 @@ await DeleteInternal(
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The <see cref="DeleteIfExists"/> operation marks the specified blob
/// or snapshot for deletion, if the blob exists. The blob is later deleted
/// during garbage collection.
///
/// Note that in order to delete a blob, you must delete all of its
/// snapshots. You can delete both at the same time using
/// <see cref="DeleteSnapshotsOption.Include"/>.
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob" />.
/// </summary>
/// <param name="deleteOptions">
/// Specifies options for deleting blob snapshots.
/// </param>
/// <param name="accessConditions">
/// Optional <see cref="BlobAccessConditions"/> to add conditions on
/// deleting this blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully deleting.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual Response<bool> DeleteIfExists(
DeleteSnapshotsOption? deleteOptions = default,
BlobAccessConditions? accessConditions = default,
CancellationToken cancellationToken = default) =>
DeleteIfExistsInternal(
deleteOptions,
accessConditions ?? default,
false, // async
cancellationToken)
.EnsureCompleted();

/// <summary>
/// The <see cref="DeleteIfExistsAsync"/> operation marks the specified blob
/// or snapshot for deletion, if the blob exists. The blob is later deleted
/// during garbage collection.
///
/// Note that in order to delete a blob, you must delete all of its
/// snapshots. You can delete both at the same time using
/// <see cref="DeleteSnapshotsOption.Include"/>.
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob" />.
/// </summary>
/// <param name="deleteOptions">
/// Specifies options for deleting blob snapshots.
/// </param>
/// <param name="accessConditions">
/// Optional <see cref="BlobAccessConditions"/> to add conditions on
/// deleting this blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully deleting.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual async Task<Response<bool>> DeleteIfExistsAsync(
DeleteSnapshotsOption? deleteOptions = default,
BlobAccessConditions? accessConditions = default,
CancellationToken cancellationToken = default) =>
await DeleteIfExistsInternal(
deleteOptions,
accessConditions ?? default,
true, // async
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The <see cref="DeleteIfExistsInternal"/> operation marks the specified blob
/// or snapshot for deletion, if the blob exists. The blob is later deleted
/// during garbage collection.
///
/// Note that in order to delete a blob, you must delete all of its
/// snapshots. You can delete both at the same time using
/// <see cref="DeleteSnapshotsOption.Include"/>.
///
/// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob" />.
/// </summary>
/// <param name="deleteOptions">
/// Specifies options for deleting blob snapshots.
/// </param>
/// <param name="accessConditions">
/// Optional <see cref="BlobAccessConditions"/> to add conditions on
/// deleting this blob.
/// </param>
/// <param name="async">
/// Whether to invoke the operation asynchronously.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully deleting.
/// </returns>
/// <remarks>
/// A <see cref="StorageRequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
private async Task<Response<bool>> DeleteIfExistsInternal(
DeleteSnapshotsOption? deleteOptions,
BlobAccessConditions accessConditions,
bool async,
CancellationToken cancellationToken)
{
try
{
Response response = await DeleteInternal(
deleteOptions,
accessConditions,
async,
cancellationToken,
Constants.Blob.Base.DeleteIfExists)
.ConfigureAwait(false);
return Response.FromValue(response, true);
}
catch (StorageRequestFailedException storageRequestFailedException)
when (storageRequestFailedException.ErrorCode == Constants.Blob.NotFound)
{
return Response.FromValue(default, false);
}
}

/// <summary>
/// The <see cref="DeleteInternal"/> operation marks the specified blob
/// or snapshot for deletion. The blob is later deleted during
Expand All @@ -1919,6 +2055,9 @@ await DeleteInternal(
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <param name="operationName">
/// Optional. To indicate if the name of the operation.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully deleting.
/// </returns>
Expand All @@ -1930,7 +2069,8 @@ private async Task<Response> DeleteInternal(
DeleteSnapshotsOption? deleteOptions,
BlobAccessConditions? accessConditions,
bool async,
CancellationToken cancellationToken)
CancellationToken cancellationToken,
string operationName = Constants.Blob.Base.Delete)
Comment thread
amnguye marked this conversation as resolved.
Outdated
{
using (Pipeline.BeginLoggingScope(nameof(BlobBaseClient)))
{
Expand All @@ -1952,7 +2092,7 @@ private async Task<Response> DeleteInternal(
ifMatch: accessConditions?.HttpAccessConditions?.IfMatch,
ifNoneMatch: accessConditions?.HttpAccessConditions?.IfNoneMatch,
async: async,
operationName: "Azure.Storage.Blobs.Specialized.BlobBaseClient.Delete",
operationName: operationName,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
Expand Down
Loading