Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ public BlobDownloadDetails() { }
public string EncryptionKeySha256 { get { throw null; } }
public string EncryptionScope { get { throw null; } }
public Azure.ETag ETag { get { throw null; } }
public bool IsSealed { get { throw null; } }
public bool IsServerEncrypted { get { throw null; } }
public System.DateTimeOffset LastModified { get { throw null; } }
public Azure.Storage.Blobs.Models.LeaseDurationType LeaseDuration { get { throw null; } }
Expand Down Expand Up @@ -1007,6 +1008,16 @@ public enum SkuName
StandardZrs = 3,
PremiumLrs = 4,
}
public partial class StartCopyFromUriOptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this just be CopyFromUriOptions? The Start prefix is only to signify that it's an LRO and not part of the operation name. I'll ping @KrzysztofCwalina to see if he has a preference and get back to you ASAP.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote for CopyBlobFromUriOptions, it's less generic.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Krzysztof is in favor of shorter/simpler names when we can make sure we're not going to end up with conflicts down the road. I'm not worried about adding a CopyFromUriAsync that would take different parameters so that's fine.

I think you bring up a really good point that we may possibly end up adding other copy operations in the future. How about BlobCopyFromUriOptions since other copy operations would probably be operating on blobs and the pattern we've been going with is [Operation]Options when possible or [FooClient - Client][Operation]Options? This would leave us room for (BlobContainer/Service/????)CopyFromUriOptions if ever needed.

Does that sound reasonable? Ping me if you want to chat more to hopefully unblock this faster.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think BlobCopyFromUriOptions sounds good.

{
public StartCopyFromUriOptions() { }
public Azure.Storage.Blobs.Models.AccessTier? AccessTier { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.BlobRequestConditions DestinationConditions { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, string> Metadata { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.RehydratePriority? RehydratePriority { get { throw null; } set { } }
public bool? SealBlob { get { throw null; } set { } }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make this IsSealed to match the other uses of the property?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that seems reasonable.

public Azure.Storage.Blobs.Models.BlobRequestConditions SourceConditions { get { throw null; } set { } }
}
public partial class UserDelegationKey
{
internal UserDelegationKey() { }
Expand Down Expand Up @@ -1039,6 +1050,8 @@ public AppendBlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCreden
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo>> CreateAsync(Azure.Storage.Blobs.Models.BlobHttpHeaders httpHeaders = null, System.Collections.Generic.IDictionary<string, string> metadata = null, Azure.Storage.Blobs.Models.AppendBlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo> CreateIfNotExists(Azure.Storage.Blobs.Models.BlobHttpHeaders httpHeaders = null, System.Collections.Generic.IDictionary<string, string> metadata = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo>> CreateIfNotExistsAsync(Azure.Storage.Blobs.Models.BlobHttpHeaders httpHeaders = null, System.Collections.Generic.IDictionary<string, string> metadata = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlobInfo> Seal(Azure.Storage.Blobs.Models.AppendBlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobInfo>> SealAsync(Azure.Storage.Blobs.Models.AppendBlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public new Azure.Storage.Blobs.Specialized.AppendBlobClient WithSnapshot(string snapshot) { throw null; }
}
public partial class BlobBaseClient
Expand Down Expand Up @@ -1089,7 +1102,11 @@ public BlobBaseClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredenti
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobInfo>> SetHttpHeadersAsync(Azure.Storage.Blobs.Models.BlobHttpHeaders httpHeaders = null, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlobInfo> SetMetadata(System.Collections.Generic.IDictionary<string, string> metadata, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobInfo>> SetMetadataAsync(System.Collections.Generic.IDictionary<string, string> metadata, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Storage.Blobs.Models.CopyFromUriOperation StartCopyFromUri(System.Uri source, Azure.Storage.Blobs.Models.StartCopyFromUriOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public virtual Azure.Storage.Blobs.Models.CopyFromUriOperation StartCopyFromUri(System.Uri source, System.Collections.Generic.IDictionary<string, string> metadata = null, Azure.Storage.Blobs.Models.AccessTier? accessTier = default(Azure.Storage.Blobs.Models.AccessTier?), Azure.Storage.Blobs.Models.BlobRequestConditions sourceConditions = null, Azure.Storage.Blobs.Models.BlobRequestConditions destinationConditions = null, Azure.Storage.Blobs.Models.RehydratePriority? rehydratePriority = default(Azure.Storage.Blobs.Models.RehydratePriority?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Storage.Blobs.Models.CopyFromUriOperation> StartCopyFromUriAsync(System.Uri source, Azure.Storage.Blobs.Models.StartCopyFromUriOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public virtual System.Threading.Tasks.Task<Azure.Storage.Blobs.Models.CopyFromUriOperation> StartCopyFromUriAsync(System.Uri source, System.Collections.Generic.IDictionary<string, string> metadata = null, Azure.Storage.Blobs.Models.AccessTier? accessTier = default(Azure.Storage.Blobs.Models.AccessTier?), Azure.Storage.Blobs.Models.BlobRequestConditions sourceConditions = null, Azure.Storage.Blobs.Models.BlobRequestConditions destinationConditions = null, Azure.Storage.Blobs.Models.RehydratePriority? rehydratePriority = default(Azure.Storage.Blobs.Models.RehydratePriority?), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response Undelete(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response> UndeleteAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down
128 changes: 128 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,134 @@ private async Task<Response<BlobAppendInfo>> AppendBlockFromUriInternal(
}
}
#endregion AppendBlockFromUri

#region Seal
/// <summary>
/// Seals the append blob, making it read only.
/// Any subsequent appends will fail.
/// </summary>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the sealing of 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{BlobInfo}"/> describing the
/// state of the sealed append blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual Response<BlobInfo> Seal(
AppendBlobRequestConditions conditions = default,
CancellationToken cancellationToken = default)
=> SealInternal(
conditions,
async: false,
cancellationToken: cancellationToken)
.EnsureCompleted();

/// <summary>
/// Seals the append blob, making it read only.
/// Any subsequent appends will fail.
/// </summary>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the sealing of 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{BlobInfo}"/> describing the
/// state of the sealed append blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual async Task<Response<BlobInfo>> SealAsync(
AppendBlobRequestConditions conditions = default,
CancellationToken cancellationToken = default)
=> await SealInternal(
conditions,
async: true,
cancellationToken: cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// Seals the append blob, making it read only.
/// Any subsequent appends will fail.
/// </summary>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the sealing of 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{BlobInfo}"/> describing the
/// state of the sealed append blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
private async Task<Response<BlobInfo>> SealInternal(
AppendBlobRequestConditions conditions,
bool async,
CancellationToken cancellationToken)
{
using (Pipeline.BeginLoggingScope(nameof(AppendBlobClient)))
{
try
{
Response<AppendBlobSealInternal> response = await BlobRestClient.AppendBlob.SealAsync(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing AppendBlobSealInternal defined in this PR. Are there any additional interesting properties outside of what's provided by BlobInfo on it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it's just ETag, LastModified, and a boolean IsSealed.

ClientDiagnostics,
Pipeline,
Uri,
Version.ToVersionString(),
leaseId: conditions?.LeaseId,
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
ifMatch: conditions?.IfMatch,
ifNoneMatch: conditions?.IfNoneMatch,
appendPosition: conditions?.IfAppendPositionEqual,
async: async,
operationName: $"{nameof(AppendBlobClient)}.{nameof(Seal)}",
cancellationToken: cancellationToken)
.ConfigureAwait(false);

return Response.FromValue(
new BlobInfo
{
ETag = response.Value.ETag,
LastModified = response.Value.LastModified
},
response.GetRawResponse());
}
catch (Exception ex)
{
Pipeline.LogException(ex);
throw;
}
finally
{
Pipeline.LogMethodExit(nameof(AppendBlobClient));
}
}
}
#endregion Seal
}

/// <summary>
Expand Down
Loading