Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/storage/put blob from url #15978

Merged
Show file tree
Hide file tree
Changes from 5 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 @@ -372,6 +372,11 @@ internal BlobCopyInfo() { }
public System.DateTimeOffset LastModified { get { throw null; } }
public string VersionId { get { throw null; } }
}
public enum BlobCopySourceBlobPropertiesOption
{
Copy = 0,
Overwrite = 1,
}
public partial class BlobCorsRule
{
public BlobCorsRule() { }
Expand Down Expand Up @@ -726,6 +731,16 @@ public BlobProperties() { }
public long TagCount { get { throw null; } }
public string VersionId { get { throw null; } }
}
public partial class BlobPutBlobFromUrlOptions
{
public BlobPutBlobFromUrlOptions() { }
public Azure.Storage.Blobs.Models.AccessTier? AccessTier { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.BlobCopySourceBlobPropertiesOption CopySourceBlobPropertiesOption { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.BlobRequestConditions DestinationConditions { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.BlobHttpHeaders HttpHeaders { get { throw null; } set { } }
public Azure.Storage.Blobs.Models.BlobRequestConditions SourceConditions { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, string> Tags { get { throw null; } set { } }
}
public partial class BlobQueryArrowField
{
public BlobQueryArrowField() { }
Expand Down Expand Up @@ -1352,6 +1367,8 @@ public BlockBlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredent
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlockList>> GetBlockListAsync(Azure.Storage.Blobs.Models.BlockListTypes blockListTypes = Azure.Storage.Blobs.Models.BlockListTypes.All, string snapshot = null, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.IO.Stream OpenWrite(bool overwrite, Azure.Storage.Blobs.Models.BlockBlobOpenWriteOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<System.IO.Stream> OpenWriteAsync(bool overwrite, Azure.Storage.Blobs.Models.BlockBlobOpenWriteOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo> PutBlobFromUrl(System.Uri copySource, Azure.Storage.Blobs.Models.BlobPutBlobFromUrlOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo>> PutBlobFromUrlAsync(System.Uri copySource, Azure.Storage.Blobs.Models.BlobPutBlobFromUrlOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlobDownloadInfo> Query(string querySqlExpression, Azure.Storage.Blobs.Models.BlobQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Storage.Blobs.Models.BlobDownloadInfo>> QueryAsync(string querySqlExpression, Azure.Storage.Blobs.Models.BlobQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Storage.Blobs.Models.BlockInfo> StageBlock(string base64BlockId, System.IO.Stream content, byte[] transactionalContentHash = null, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = null, System.IProgress<long> progressHandler = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down
189 changes: 189 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,195 @@ private async Task<Stream> OpenWriteInternal(
}
#endregion OpenWrite

#region PutBlobFromUrl
Copy link
Contributor

Choose a reason for hiding this comment

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

nit. region name is out of date.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed.

/// <summary>
/// The Put Blob from URL operation creates a new Block Blob where the contents of the
Copy link
Member

Choose a reason for hiding this comment

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

Should this be updated to "The Upload From URL operation", or should we stick with what the REST API operation is called?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

/// blob are read from a given URL. This API is supported beginning with the 2020-04-08 version.
///
/// Partial updates are not supported with Put Blob from URL; the content of an existing blob is
/// overwritten with the content of the new blob.To perform partial updates to a block blob’s
/// contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.
/// </summary>
/// <param name="copySource">
/// Required. Specifies the URL of the source blob. he source blob may be of any type,
/// including a block blob, append blob, or page blob.The value may be a URL of up to 2
/// KiB in length that specifies a blob. The value should be URL-encoded as it would appear
/// in a request URI. The source blob must either be public or must be authorized via a
/// shared access signature. If the source blob is public, no authorization is required
/// to perform the operation.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </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
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual Response<BlobContentInfo> PutBlobFromUrl(
Uri copySource,
BlobPutBlobFromUrlOptions options = default,
CancellationToken cancellationToken = default)
=> PutBlobFromUrlInternal(
copySource,
options,
async: false,
cancellationToken)
.EnsureCompleted();

/// <summary>
/// The Put Blob from URL operation creates a new Block Blob where the contents of the
/// blob are read from a given URL. This API is supported beginning with the 2020-04-08 version.
///
/// Partial updates are not supported with Put Blob from URL; the content of an existing blob is
/// overwritten with the content of the new blob.To perform partial updates to a block blob’s
/// contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.
/// </summary>
/// <param name="copySource">
/// Required. Specifies the URL of the source blob. he source blob may be of any type,
/// including a block blob, append blob, or page blob.The value may be a URL of up to 2
/// KiB in length that specifies a blob. The value should be URL-encoded as it would appear
/// in a request URI. The source blob must either be public or must be authorized via a
/// shared access signature. If the source blob is public, no authorization is required
/// to perform the operation.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </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
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public virtual async Task<Response<BlobContentInfo>> PutBlobFromUrlAsync(
Uri copySource,
BlobPutBlobFromUrlOptions options = default,
CancellationToken cancellationToken = default)
=> await PutBlobFromUrlInternal(
copySource,
options,
async: true,
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The Put Blob from URL operation creates a new Block Blob where the contents of the
/// blob are read from a given URL. This API is supported beginning with the 2020-04-08 version.
///
/// Partial updates are not supported with Put Blob from URL; the content of an existing blob is
/// overwritten with the content of the new blob.To perform partial updates to a block blob’s
/// contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.
/// </summary>
/// <param name="copySource">
/// Required. Specifies the URL of the source blob. he source blob may be of any type,
/// including a block blob, append blob, or page blob.The value may be a URL of up to 2
/// KiB in length that specifies a blob. The value should be URL-encoded as it would appear
/// in a request URI. The source blob must either be public or must be authorized via a
/// shared access signature. If the source blob is public, no authorization is required
/// to perform the operation.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </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
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
internal virtual async Task<Response<BlobContentInfo>> PutBlobFromUrlInternal(
Uri copySource,
BlobPutBlobFromUrlOptions options,
bool async,
CancellationToken cancellationToken)
{
using (Pipeline.BeginLoggingScope(nameof(BlockBlobClient)))
{
Pipeline.LogMethodEnter(
nameof(BlockBlobClient),
message:
$"{nameof(Uri)}: {Uri}\n" +
$"{nameof(options.HttpHeaders)}: {options?.HttpHeaders}\n" +
$"{nameof(options.DestinationConditions)}: {options?.DestinationConditions}");
try
{
return await BlobRestClient.BlockBlob.PutBlobFromUrlAsync(
clientDiagnostics: ClientDiagnostics,
pipeline: Pipeline,
resourceUri: Uri,
contentLength: 0,
version: Version.ToVersionString(),
copySource: copySource,
timeout: default,
transactionalContentHash: default,
blobContentType: options?.HttpHeaders?.ContentType,
blobContentEncoding: options?.HttpHeaders?.ContentEncoding,
blobContentLanguage: options?.HttpHeaders?.ContentLanguage,
blobContentHash: options?.HttpHeaders?.ContentHash,
blobCacheControl: options?.HttpHeaders?.CacheControl,
// TODO service bug. https://github.com/Azure/azure-sdk-for-net/issues/15969
// metadata: options?.Metadata,
leaseId: options?.DestinationConditions?.LeaseId,
blobContentDisposition: options?.HttpHeaders?.ContentDisposition,
encryptionKey: CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: CustomerProvidedKey?.EncryptionAlgorithm,
encryptionScope: EncryptionScope,
tier: options?.AccessTier,
ifModifiedSince: options?.DestinationConditions?.IfModifiedSince,
ifUnmodifiedSince: options?.DestinationConditions?.IfUnmodifiedSince,
ifMatch: options?.DestinationConditions?.IfMatch,
ifNoneMatch: options?.DestinationConditions?.IfNoneMatch,
ifTags: options?.DestinationConditions?.TagConditions,
sourceIfModifiedSince: options?.SourceConditions?.IfModifiedSince,
sourceIfUnmodifiedSince: options?.SourceConditions?.IfUnmodifiedSince,
sourceIfMatch: options?.SourceConditions?.IfMatch,
sourceIfNoneMatch: options?.SourceConditions?.IfNoneMatch,
sourceIfTags: options?.SourceConditions?.TagConditions,
requestId: default,
blobTagsString: options?.Tags?.ToTagsString(),
copySourceBlobProperties: options?.CopySourceBlobPropertiesOption == BlobCopySourceBlobPropertiesOption.Overwrite ? false : true,
async: async,
operationName: $"{nameof(BlockBlobClient)}.{nameof(PutBlobFromUrl)}",
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
catch (Exception ex)
{
Pipeline.LogException(ex);
throw;
}
finally
{
Pipeline.LogMethodExit(nameof(BlockBlobClient));
}
}
}
#endregion PutBlobFromUrl

#region PartitionedUploader
internal PartitionedUploader<BlobUploadOptions, BlobContentInfo> GetPartitionedUploader(
StorageTransferOptions transferOptions,
Expand Down
Loading