public static CloudBlob GetBlobReferenceFromServer( CloudBlobContainer container, string blobName, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) { CloudBlob blob = container.GetBlobReference(blobName); return GetBlobReferenceFromServer(blob, accessCondition, options, operationContext); }
public CloudStreamProvider(CloudBlobContainer container, string kind, string path) { if(path == null) throw new ArgumentNullException("path"); if (String.IsNullOrWhiteSpace(path)) throw new ArgumentException("path"); if (container == null) throw new ArgumentNullException("container"); Container = container; Kind = kind; Path = path; if (!Container.GetBlobReference(Path).Exists()) throw new FileNotFoundException(); BlobType = container.GetBlobReference(path).BlobType; }
/// <summary> /// Return a task that asynchronously get the blob reference from server /// </summary> /// <param name="container">CloudBlobContainer object</param> /// <param name="blobName">Blob name</param> /// <param name="accessCondition">Access condition</param> /// <param name="options">Blob request options</param> /// <param name="operationContext">Operation context</param> /// <param name="cmdletCancellationToken">Cancellation token</param> /// <returns>A task object that asynchronously get the blob reference from server</returns> public async Task<CloudBlob> GetBlobReferenceFromServerAsync(CloudBlobContainer container, string blobName, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) { try { CloudBlob blob = container.GetBlobReference(blobName); await blob.FetchAttributesAsync(accessCondition, options, operationContext, cancellationToken); return Util.GetCorrespondingTypeBlobReference(blob); } catch (StorageException e) { if (e.IsNotFoundException()) { return null; } else { throw; } } }
private async Task TransferBlob( CloudBlobContainer fromContainer, CloudBlobContainer toContainer, string blobName, CancellationToken cancellationToken) { var requestOptions = new BlobRequestOptions() { RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(2), 5) }; var destBlobRef = toContainer.GetBlobReference(blobName); var blob = fromContainer.GetBlobReference(blobName); await destBlobRef.StartCopyAsync( blob.Uri, AccessCondition.GenerateEmptyCondition(), AccessCondition.GenerateEmptyCondition(), requestOptions, null, cancellationToken); var allCopied = false; var copyFailed = false; do { var blobRef = await toContainer.GetBlobReferenceFromServerAsync(blobName, cancellationToken); if (blobRef.CopyState.Status == CopyStatus.Aborted || blobRef.CopyState.Status == CopyStatus.Failed) { this.logger.LogError($"Cannot copy {blobRef.Uri}"); copyFailed = true; } allCopied = blobRef.CopyState.Status != CopyStatus.Pending; } while (!allCopied || copyFailed); await blob.DeleteAsync(cancellationToken); }
// Deleting and recreating a container can result in a 409 as the container name is not // immediately available. Instead, use this helper to clear a container. public static void ClearContainer(CloudBlobContainer container) { foreach (IListBlobItem blobItem in container.ListBlobs()) { CloudBlockBlob blockBlob = blobItem as CloudBlockBlob; if (blockBlob != null) { container.GetBlobReference(blockBlob.Name).DeleteIfExists(); } } }
private async Task<IEnumerable<IListBlobItem>> TransferBlobs( bool rename, CloudBlobContainer fromContainer, CloudBlobContainer toContainer, CancellationToken cancellationToken) { var requestOptions = new BlobRequestOptions() { RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(2), 5) }; var leaseId = Guid.NewGuid().ToString(); var leaseResult = string.Empty; var autoEvent = new AutoResetEvent(false); var waitEvent = new AutoResetEvent(false); var leaseTimer = new Timer( async s => { try { if (string.IsNullOrEmpty(leaseResult)) { leaseResult = await fromContainer.AcquireLeaseAsync( TimeSpan.FromSeconds(60), leaseId, null, requestOptions, null, cancellationToken); waitEvent.Set(); } else { await fromContainer.RenewLeaseAsync( AccessCondition.GenerateLeaseCondition(leaseId), requestOptions, null, cancellationToken); } } catch (StorageException exception) { if (exception.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) { this.logger.LogInformation("Staging container already has a lease."); } } }, autoEvent, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(50)); waitEvent.WaitOne(); try { BlobContinuationToken token = null; var blobList = new List<CopySpec>(); do { var result = await fromContainer.ListBlobsSegmentedAsync(token, cancellationToken); token = result.ContinuationToken; blobList.AddRange(result.Results.OfType<CloudBlob>().Select(b => new CopySpec() {SourceBlob = b})); } while (token != null); // Copy var copiedBlobList = new List<CopySpec>(); foreach (var blob in blobList) { var srcBlobName = blob.SourceBlob.Uri.Segments[2]; var blobName = rename ? $"{Path.GetFileNameWithoutExtension(srcBlobName)}{Guid.NewGuid().ToString().Replace("-", "")}{Path.GetExtension(srcBlobName)}" : srcBlobName; var destBlobRef = toContainer.GetBlobReference(blobName); blob.DestBlob = destBlobRef; try { await destBlobRef.StartCopyAsync( blob.SourceBlob.Uri, AccessCondition.GenerateEmptyCondition(), AccessCondition.GenerateEmptyCondition(), requestOptions, null, cancellationToken); copiedBlobList.Add(blob); } catch (Exception e) { this.logger.LogError($"Error while copying {blobName}. {e.ToString()}"); } } this.logger.LogInformation($"Started copying {copiedBlobList.Count} blobs"); var blobsToRemove = new List<CopySpec>(); var blobsToCheck = copiedBlobList.Select(b => b.SourceBlob.Uri.AbsoluteUri).ToList(); do { var withProperties = copiedBlobList.Select(b => { b.DestBlob.FetchAttributes(AccessCondition.GenerateEmptyCondition(), requestOptions, null); return b; }).ToList(); foreach (var blob in withProperties) { if (blob.DestBlob.CopyState.Status == CopyStatus.Aborted || blob.DestBlob.CopyState.Status == CopyStatus.Failed) { this.logger.LogError($"Cannot copy {blob.DestBlob.Uri}"); blobsToCheck.Remove(blob.SourceBlob.Uri.AbsoluteUri); } if (blob.DestBlob.CopyState.Status != CopyStatus.Success) continue; blobsToRemove.Add(blob); blobsToCheck.Remove(blob.SourceBlob.Uri.AbsoluteUri); } } while (blobsToCheck.Any()); this.logger.LogInformation($"{blobsToRemove.Count} blobs copied."); foreach (var blob in blobsToRemove) { try { await blob.SourceBlob.DeleteAsync( DeleteSnapshotsOption.IncludeSnapshots, AccessCondition.GenerateEmptyCondition(), requestOptions, null, cancellationToken); this.logger.LogInformation($"Deleted {blob.SourceBlob.Uri.AbsoluteUri}"); } catch (StorageException e) { if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) { this.logger.LogInformation($"Blob not found {blob.SourceBlob.Uri}"); } else { this.logger.LogError(e.ToString()); } } catch (Exception exception) { this.logger.LogError(exception.ToString()); } }; leaseTimer.Dispose(); await fromContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), requestOptions, null, cancellationToken); this.logger.LogInformation($"{blobsToRemove.Count} blobs deleted."); return copiedBlobList.Where(b => b.DestBlob.CopyState.Status == CopyStatus.Success).Select(b => b.DestBlob); } catch (Exception exception) { this.logger.LogCritical(exception.ToString()); return default(IEnumerable<IListBlobItem>); } }
public void CloudBlobSoftDeleteSnapshotTask() { CloudBlobContainer container = GetRandomContainerReference(); try { //Enables a delete retention policy on the blob with 1 day of default retention days container.ServiceClient.EnableSoftDelete(); container.CreateAsync().Wait(); // Upload some data to the blob. MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.UploadFromStreamAsync(originalData).Wait(); CloudBlob blob = container.GetBlobReference(BlobName); //create snapshot via api CloudBlob snapshot = blob.SnapshotAsync().Result; //create snapshot via write protection appendBlob.UploadFromStreamAsync(originalData).Wait(); //we should have 2 snapshots 1 regular and 1 deleted: there is no way to get only the deleted snapshots but the below listing will get both snapshot types int blobCount = 0; int deletedSnapshotCount = 0; int snapShotCount = 0; BlobContinuationToken ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.Snapshots | BlobListingDetails.Deleted, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); if (blobItem.IsSnapshot) { snapShotCount++; } if (blobItem.IsDeleted) { Assert.IsNotNull(blobItem.Properties.DeletedTime); Assert.AreEqual(blobItem.Properties.RemainingDaysBeforePermanentDelete, 0); deletedSnapshotCount++; } blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 3); Assert.AreEqual(deletedSnapshotCount, 1); Assert.AreEqual(snapShotCount, 2); blobCount = 0; ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.Snapshots, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsFalse(blobItem.IsDeleted); Assert.IsNull(blobItem.Properties.DeletedTime); Assert.IsNull(blobItem.Properties.RemainingDaysBeforePermanentDelete); blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 2); //Delete Blob and snapshots blob.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots, null, null, null).Wait(); Assert.IsFalse(blob.ExistsAsync().Result); Assert.IsFalse(snapshot.ExistsAsync().Result); blobCount = 0; ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.All, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsTrue(blobItem.IsDeleted); Assert.IsNotNull(blobItem.Properties.DeletedTime); Assert.AreEqual(blobItem.Properties.RemainingDaysBeforePermanentDelete, 0); blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 3); blob.UndeleteAsync().Wait(); blob.FetchAttributesAsync().Wait(); Assert.IsFalse(blob.IsDeleted); Assert.IsNull(blob.Properties.DeletedTime); Assert.IsNull(blob.Properties.RemainingDaysBeforePermanentDelete); blobCount = 0; ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.All, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsFalse(blobItem.IsDeleted); Assert.IsNull(blobItem.Properties.DeletedTime); Assert.IsNull(blobItem.Properties.RemainingDaysBeforePermanentDelete); blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 3); } finally { container.ServiceClient.DisableSoftDelete(); container.DeleteIfExistsAsync().Wait(); } }
public async Task CloudBlobSnapshotAsync() { CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudBlockBlob blockBlob = container.GetBlockBlobReference(BlobName); await blockBlob.UploadFromStreamAsync(originalData); CloudBlob blob = container.GetBlobReference(BlobName); await blob.FetchAttributesAsync(); Assert.IsFalse(blob.IsSnapshot); Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); CloudBlob snapshot1 = await blob.SnapshotAsync(); Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); Assert.IsTrue(snapshot1.IsSnapshot); Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); Assert.AreEqual(blob.Uri, snapshot1.Uri); Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); CloudBlob snapshot2 = await blob.SnapshotAsync(); Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); await snapshot1.FetchAttributesAsync(); await snapshot2.FetchAttributesAsync(); await blob.FetchAttributesAsync(); AssertAreEqual(snapshot1.Properties, blob.Properties); CloudBlob snapshot1Clone = new CloudBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); await snapshot1Clone.FetchAttributesAsync(); AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); // The query parser should not be case sensitive in detecting a snapshot in the query string CloudBlob snapshotParseVerifier = new CloudBlob(new Uri(blob.Uri + "?sNapshOt=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshotParseVerifier.SnapshotTime, "Snapshot parse verifier did not successfully detect the snapshot time"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshotParseVerifier.SnapshotTime.Value); CloudBlob snapshotCopy = container.GetBlobReference("blob2"); await snapshotCopy.StartCopyAsync(TestHelper.Defiddler(snapshot1.Uri)); await WaitForCopyAsync(snapshotCopy); Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } await blockBlob.PutBlockListAsync(new List <string>()); await blob.FetchAttributesAsync(); using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null); List <IListBlobItem> blobs = resultSegment.Results.ToList(); Assert.AreEqual(4, blobs.Count); AssertAreEqual(snapshot1, (CloudBlob)blobs[0]); AssertAreEqual(snapshot2, (CloudBlob)blobs[1]); AssertAreEqual(blob, (CloudBlob)blobs[2]); AssertAreEqual(snapshotCopy, (CloudBlob)blobs[3]); } finally { container.DeleteIfExistsAsync().Wait(); } }
public void CloudBlobSoftDeleteNoSnapshotTask() { CloudBlobContainer container = GetRandomContainerReference(); try { //Enables a delete retention policy on the blob with 1 day of default retention days container.ServiceClient.EnableSoftDelete(); container.CreateAsync().Wait(); // Upload some data to the blob. MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.CreateOrReplaceAsync().Wait(); appendBlob.AppendBlockAsync(originalData, null).Wait(); CloudBlob blob = container.GetBlobReference(BlobName); Assert.IsTrue(blob.ExistsAsync().Result); Assert.IsFalse(blob.IsDeleted); blob.DeleteAsync().Wait(); Assert.IsFalse(blob.ExistsAsync().Result); int blobCount = 0; BlobContinuationToken ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.All, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsTrue(blobItem.IsDeleted); Assert.IsNotNull(blobItem.Properties.DeletedTime); Assert.AreEqual(blobItem.Properties.RemainingDaysBeforePermanentDelete, 0); blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 1); blob.UndeleteAsync().Wait(); blob.FetchAttributesAsync().Wait(); Assert.IsFalse(blob.IsDeleted); Assert.IsNull(blob.Properties.DeletedTime); Assert.IsNull(blob.Properties.RemainingDaysBeforePermanentDelete); blobCount = 0; ct = null; do { foreach (IListBlobItem item in container.ListBlobsSegmentedAsync (null, true, BlobListingDetails.All, null, ct, null, null) .Result .Results .ToList()) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsFalse(blobItem.IsDeleted); Assert.IsNull(blobItem.Properties.DeletedTime); Assert.IsNull(blobItem.Properties.RemainingDaysBeforePermanentDelete); blobCount++; } } while (ct != null); Assert.AreEqual(blobCount, 1); } finally { container.ServiceClient.DisableSoftDelete(); container.DeleteIfExistsAsync().Wait(); } }
public void CloudBlobSoftDeleteNoSnapshotAPM() { CloudBlobContainer container = GetRandomContainerReference(); try { //Enables a delete retention policy on the blob with 1 day of default retention days container.ServiceClient.EnableSoftDelete(); container.Create(); // Upload some data to the blob. MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.CreateOrReplace(); appendBlob.AppendBlock(originalData, null); CloudBlob blob = container.GetBlobReference(BlobName); Assert.IsFalse(blob.IsDeleted); IAsyncResult result; using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { result = blob.BeginDelete(DeleteSnapshotsOption.None, null, null, null, ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndDelete(result); } Assert.IsFalse(blob.Exists()); int blobCount = 0; foreach (IListBlobItem item in container.ListBlobs(null, true, BlobListingDetails.All)) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsTrue(blobItem.IsDeleted); Assert.IsNotNull(blobItem.Properties.DeletedTime); Assert.AreEqual(blobItem.Properties.RemainingDaysBeforePermanentDelete, 0); blobCount++; } Assert.AreEqual(blobCount, 1); using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { result = blob.BeginUndelete(ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndUndelete(result); } blob.FetchAttributes(); Assert.IsFalse(blob.IsDeleted); Assert.IsNull(blob.Properties.DeletedTime); Assert.IsNull(blob.Properties.RemainingDaysBeforePermanentDelete); blobCount = 0; foreach (IListBlobItem item in container.ListBlobs(null, true, BlobListingDetails.All)) { CloudAppendBlob blobItem = (CloudAppendBlob)item; Assert.AreEqual(blobItem.Name, BlobName); Assert.IsFalse(blobItem.IsDeleted); Assert.IsNull(blobItem.Properties.DeletedTime); Assert.IsNull(blobItem.Properties.RemainingDaysBeforePermanentDelete); blobCount++; } Assert.AreEqual(blobCount, 1); } finally { container.ServiceClient.DisableSoftDelete(); container.DeleteIfExists(); } }
public void CloudBlobSnapshot() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); // Upload some data to the blob. MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.CreateOrReplace(); appendBlob.AppendBlock(originalData, null); CloudBlob blob = container.GetBlobReference(BlobName); blob.FetchAttributes(); Assert.IsFalse(blob.IsSnapshot); Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); CloudBlob snapshot1 = blob.Snapshot(); Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); Assert.IsTrue(snapshot1.IsSnapshot); Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); Assert.AreEqual(blob.Uri, snapshot1.Uri); Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); CloudBlob snapshot2 = blob.Snapshot(); Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); snapshot1.FetchAttributes(); snapshot2.FetchAttributes(); blob.FetchAttributes(); AssertAreEqual(snapshot1.Properties, blob.Properties, false); CloudBlob snapshot1Clone = new CloudBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); snapshot1Clone.FetchAttributes(); AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties, false); // The query parser should not be case sensitive in detecting a snapshot in the query string CloudBlob snapshotParseVerifier = new CloudBlob(new Uri(blob.Uri + "?sNapshOt=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshotParseVerifier.SnapshotTime, "Snapshot parse verifier did not successfully detect the snapshot time"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshotParseVerifier.SnapshotTime.Value); CloudBlob snapshotCopy = container.GetBlobReference("blob2"); snapshotCopy.StartCopy(TestHelper.Defiddler(snapshot1.Uri)); WaitForCopy(snapshotCopy); Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); using (Stream snapshotStream = snapshot1.OpenRead()) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } //overwriting the blob and creating the 5th snapshot appendBlob.CreateOrReplace(); blob.FetchAttributes(); using (Stream snapshotStream = snapshot1.OpenRead()) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } List <IListBlobItem> blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); Assert.AreEqual(4, blobs.Count); AssertAreEqual(snapshot1, (CloudBlob)blobs[0]); AssertAreEqual(snapshot2, (CloudBlob)blobs[1]); AssertAreEqual(blob, (CloudBlob)blobs[2]); AssertAreEqual(snapshotCopy, (CloudBlob)blobs[3]); } finally { container.DeleteIfExists(); } }
public void CloudBlobSnapshotTask() { CloudBlobContainer container = GetRandomContainerReference(); try { container.CreateAsync().Wait(); MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.CreateOrReplaceAsync().Wait(); appendBlob.AppendBlockAsync(originalData, null).Wait(); CloudBlob blob = container.GetBlobReference(BlobName); blob.FetchAttributesAsync().Wait(); CloudBlob snapshot1 = blob.SnapshotAsync().Result; Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); Assert.IsTrue(snapshot1.IsSnapshot); Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); Assert.AreEqual(blob.Uri, snapshot1.Uri); Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); CloudBlob snapshot2 = blob.SnapshotAsync().Result; Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); snapshot1.FetchAttributesAsync().Wait(); snapshot2.FetchAttributesAsync().Wait(); blob.FetchAttributesAsync().Wait(); AssertAreEqual(snapshot1.Properties, blob.Properties); CloudBlob snapshot1Clone = new CloudBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); snapshot1Clone.FetchAttributesAsync().Wait(); AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); CloudBlob snapshotCopy = container.GetBlobReference("blob2"); snapshotCopy.StartCopyAsync(snapshot1.Uri, null, null, null, null).Wait(); WaitForCopy(snapshotCopy); Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } //overwriting will create another snapshot appendBlob.CreateOrReplaceAsync().Wait(); blob.FetchAttributesAsync().Wait(); using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } List <IListBlobItem> blobs = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null) .Result .Results .ToList(); Assert.AreEqual(4, blobs.Count); AssertAreEqual(snapshot1, (CloudBlob)blobs[0]); AssertAreEqual(snapshot2, (CloudBlob)blobs[1]); AssertAreEqual(blob, (CloudBlob)blobs[2]); AssertAreEqual(snapshotCopy, (CloudBlob)blobs[3]); } finally { container.DeleteIfExistsAsync().Wait(); } }
public void CloudBlobSnapshotAPM() { CloudBlobContainer container = GetRandomContainerReference(); try { container.Create(); MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudAppendBlob appendBlob = container.GetAppendBlobReference(BlobName); appendBlob.CreateOrReplace(); appendBlob.AppendBlock(originalData, null); CloudBlob blob = container.GetBlobReference(BlobName); blob.FetchAttributes(); IAsyncResult result; using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { result = blob.BeginSnapshot(ar => waitHandle.Set(), null); waitHandle.WaitOne(); CloudBlob snapshot1 = blob.EndSnapshot(result); Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); Assert.IsTrue(snapshot1.IsSnapshot); Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); Assert.AreEqual(blob.Uri, snapshot1.Uri); Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); result = blob.BeginSnapshot(ar => waitHandle.Set(), null); waitHandle.WaitOne(); CloudBlob snapshot2 = blob.EndSnapshot(result); Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); snapshot1.FetchAttributes(); snapshot2.FetchAttributes(); blob.FetchAttributes(); AssertAreEqual(snapshot1.Properties, blob.Properties); CloudBlob snapshotCopy = container.GetBlobReference("blob2"); result = snapshotCopy.BeginStartCopy(snapshot1.Uri, null, null, null, null, ar => waitHandle.Set(), null); waitHandle.WaitOne(); snapshotCopy.EndStartCopy(result); WaitForCopy(snapshotCopy); Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); waitHandle.WaitOne(); using (Stream snapshotStream = snapshot1.EndOpenRead(result)) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } result = appendBlob.BeginCreateOrReplace(ar => waitHandle.Set(), null); waitHandle.WaitOne(); appendBlob.EndCreateOrReplace(result); result = blob.BeginFetchAttributes(ar => waitHandle.Set(), null); waitHandle.WaitOne(); blob.EndFetchAttributes(result); result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); waitHandle.WaitOne(); using (Stream snapshotStream = snapshot1.EndOpenRead(result)) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } List <IListBlobItem> blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); Assert.AreEqual(4, blobs.Count); AssertAreEqual(snapshot1, (CloudBlob)blobs[0]); AssertAreEqual(snapshot2, (CloudBlob)blobs[1]); AssertAreEqual(blob, (CloudBlob)blobs[2]); AssertAreEqual(snapshotCopy, (CloudBlob)blobs[3]); } } finally { container.DeleteIfExists(); } }