/// <summary> /// Puts the lease on the given container in a renewed state. /// </summary> /// <param name="container">The container with the lease.</param> /// <param name="leaseTime">The amount of time on the renewed lease.</param> /// <returns>The lease ID of the current lease.</returns> internal static async Task<string> SetRenewedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) { string leaseId = await SetLeasedStateAsync(container, leaseTime); await container.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); return leaseId; }
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>); } }