Azure / Azure/azure-sdk-for-net

[Storage] Docs: Document snapshot and version transfer support in Azure.Storage.DataMovement.Blobs

Open
#58,331 2 comments 1 reaction 2 assignees Claimed by @christothes View on GitHub
bot Client Service Attention Storage
Dominant language
C#
Stars
6.1k
Forks
5.2k
Avg merge
1d 16h
Merged PRs (30d)
407

Description

## Documentation Gap

**Package:** `Azure.Storage.DataMovement.Blobs`
**Service directory:** `sdk/storage/Azure.Storage.DataMovement.Blobs/`
**Triggered by:** commit 44777ce3 (PR #57368) by `@amnguye`

## What Changed

PR #57368 added snapshot and versioning support to the `Azure.Storage.DataMovement.Blobs` package (targeting 12.4.0-beta.1). Two new properties were added to `BlobStorageResourceOptions`:

- `public string Snapshot { get; set; }` — specifies a blob snapshot identifier to use as the transfer source
- `public string VersionId { get; set; }` — specifies a blob version identifier to use as the transfer source

The CHANGELOG correctly lists these features:
> - Added support for snapshot transfers as the source. This includes the ability to copy a snapshot to a new blob, download a snapshot, and pause/resume snapshot transfers.
> - Added support for versioning transfers as the source. This includes the ability to copy a version to a new blob, download a version, and pause/resume version transfers.

## Gaps Found

- The `README.md` has no section or examples showing how to use `BlobStorageResourceOptions.Snapshot` to transfer from a blob snapshot
- The `README.md` has no section or examples showing how to use `BlobStorageResourceOptions.VersionId` to transfer from a blob version
- No sample test file (`tests/Samples/`) contains snippet-backed examples for snapshot or version transfer scenarios
- The existing `ResourceConstruction_Blobs_WithOptions_BlockBlob` snippet shows `BlockBlobStorageResourceOptions` but does not demonstrate the new `Snapshot`/`VersionId` properties

📐 Implementation Guide

This section contains step-by-step instructions for a coding agent to implement the changes described above.

### Step 1: Modify files

No existing files need structural changes. The README and sample test file need additions only.

### Step 2: Add or update code snippets

#### 2a. Create/update the sample test file

**Edit** `sdk/storage/Azure.Storage.DataMovement.Blobs/tests/Samples/Sample2_Snapshot.cs` (create if it does not exist):

````csharp
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Azure.Core;
using Azure.Storage.DataMovement;
using Azure.Storage.DataMovement.Blobs;
using NUnit.Framework;

namespace Azure.Storage.DataMovement.Blobs.Tests.Samples
{
public class Sample2_Snapshot : SamplesBase
{
[Test]
public async Task CopyBlobSnapshotAsync()
{
TokenCredential tokenCredential = TestEnvironment.Credential;
BlobsStorageResourceProvider blobs = new(tokenCredential);
TransferManager transferManager = new TransferManager();
Uri sourceBlobUri = new Uri("(myaccount.blob.core.windows.net/redacted)
Uri destinationBlobUri = new Uri("(myaccount.blob.core.windows.net/redacted)
string snapshotId = "";
string downloadPath = System.IO.Path.GetTempFileName();

#region Snippet:BlobSnapshotTransfer
// Copy a blob snapshot to a new blob
BlockBlobStorageResourceOptions sourceSnapshotOptions = new BlockBlobStorageResourceOptions
{
Snapshot = snapshotId
};
TransferOperation copyOperation = await transferManager.StartTransferAsync(
sourceResource: await blobs.FromBlobAsync(sourceBlobUri, sourceSnapshotOptions),
destinationResource: await blobs.FromBlobAsync(destinationBlobUri));
await copyOperation.WaitForCompletionAsync();
#endregion

#region Snippet:BlobSnapshotDownload
// Download a blob snapshot to a local file
BlockBlobStorageResourceOptions snapshotOptions = new BlockBlobStorageResourceOptions
{
Snapshot = snapshotId
};
TransferOperation downloadOperation = await transferManager.StartTransferAsync(
sourceResource: await blobs.FromBlobAsync(sourceBlobUri, snapshotOptions),
destinationResource: LocalFilesStorageResourceProvider.FromFile(downloadPath));
await downloadOperation.WaitForCompletionAsync();
#endregion
}

[Test]
public async Task CopyBlobVersionAsync()
{
TokenCredential tokenCredential = TestEnvironment.Credential;
BlobsStorageResourceProvider blobs = new(tokenCredential);
TransferManager transferManager = new TransferManager();
Uri sourceBlobUri = new Uri("(myaccount.blob.core.windows.net/redacted)
Uri destinationBlobUri = new Uri("(myaccount.blob.core.windows.net/redacted)
string versionId = "";
string downloadPath = System.IO.Path.GetTempFileName();

#region Snippet:BlobVersionTransfer
// Copy a specific blob version to a new blob
BlockBlobStorageResourceOptions sourceVersionOptions = new BlockBlobStorageResourceOptions
{
VersionId = versionId
};
TransferOperation copyOperation = await transferManager.StartTransferAsync(
sourceResource: await blobs.FromBlobAsync(sourceBlobUri, sourceVersionOptions),
destinationResource: await blobs.FromBlobAsync(destinationBlobUri));
await copyOperation.WaitForCompletionAsync();
#endregion

#region Snippet:BlobVersionDownload
// Download a specific blob version to a local file
BlockBlobStorageResourceOptions versionOptions = new BlockBlobStorageResourceOptions
{
VersionId = versionId
};
TransferOperation downloadOperation = await transferManager.StartTransferAsync(
sourceResource: await blobs.FromBlobAsync(sourceBlobUri, versionOptions),
destinationResource: LocalFilesStorageResourceProvider.FromFile(downloadPath));
await downloadOperation.WaitForCompletionAsync();
#endregion
}
}
}
````

Snippet names to use:
- `BlobSnapshotTransfer` — copying from a snapshot
- `BlobSnapshotDownload` — downloading a snapshot
- `BlobVersionTransfer` — copying from a version
- `BlobVersionDownload` — downloading a version

#### 2b. Add snippet placeholders to the README

In `sdk/storage/Azure.Storage.DataMovement.Blobs/README.md`, insert a new sub-section after the existing **Blob Copy** section and before the **Resume** section:

````markdown
### Blob Snapshot and Version Transfers

You can use a blob snapshot or a specific blob version as the source of a transfer by setting `Snapshot` or `VersionId` on the `BlobStorageResourceOptions` (or any derived options class).

Copy a blob snapshot to a new blob:

```C# Snippet:BlobSnapshotTransfer
```

Download a blob snapshot to a local file:

```C# Snippet:BlobSnapshotDownload
```

Copy a specific blob version to a new blob:

```C# Snippet:BlobVersionTransfer
```

Download a specific blob version to a local file:

```C# Snippet:BlobVersionDownload
```

> **Note:** `Snapshot` and `VersionId` are source-only options. Setting them on the destination resource options has no effect.
````

### Step 3: Verify README structure

The current README at `sdk/storage/Azure.Storage.DataMovement.Blobs/README.md` already has all required sections:
1. ✅ Getting started (Install, Prerequisites, Authenticate)
2. ✅ Key concepts
3. ✅ Examples — **needs new sub-section for snapshot/version transfers**
4. ✅ Troubleshooting
5. ✅ Next steps
6. ✅ Contributing

Only the **Examples** section needs the new sub-section added.

### Step 4: Validate

Run these commands in order:

1. `dotnet build sdk/storage/Azure.Storage.DataMovement.Blobs/`
2. `dotnet test sdk/storage/Azure.Storage.DataMovement.Blobs/ --filter TestCategory!=Live`
3. `eng/scripts/Update-Snippets.ps1 storage` — injects snippet code from the test file into README placeholder blocks; verify `git diff` shows the README updated with actual code
4. `eng/scripts/Export-API.ps1 storage` — no new public types were added in this change, but run to confirm no drift
5. `dotnet format sdk/storage/Azure.Storage.DataMovement.Blobs/`

## Next Steps

> [!TIP]
> **Ready for automated implementation?** Assign this issue to **`@copilot`** to have Copilot coding agent implement the changes described in the Implementation Guide above

> [!WARNING]
>
> ⚠️ Firewall blocked 2 domains
>
> The following domains were blocked by the firewall during workflow execution:
>
> - `pkgs.dev.azure.com`
> - `releaseassets.githubusercontent.com`
>
> To allow these domains, add them to the `network.allowed` list in your workflow frontmatter:
>
> ```yaml
> network:
> allowed:
> - defaults
> - "pkgs.dev.azure.com"
> - "releaseassets.githubusercontent.com"
> ```
>
> See [Network Configuration](https://github.github.com/gh-aw/reference/network/) for more information.
>
>

> Generated by [Update Docs](https://github.com/Azure/azure-sdk-for-net/actions/runs/24610528919/agentic_workflow) · ● 468.1K · [◷](https://github.com/search?q=repo%3AAzure%2Fazure-sdk-for-net+is%3Aissue+%22gh-aw-workflow-call-id%3A+Azure%2Fazure-sdk-for-net%2Fupdate-samples-and-docs%22&type=issues)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.