Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merge blob copy branch

  • Loading branch information...
commit da21d2c6fe321c511fa15a66604eb55aa4996cb0 2 parents c3b2d83 + 352a420
@xmbms xmbms authored
View
5 WindowsAzurePowershell/src/Management.Storage.Test/Service/MockStorageBlobManagement.cs
@@ -401,5 +401,10 @@ public void SetBlobMetadata(ICloudBlob blob, AccessCondition accessCondition, Bl
{
return;
}
+
+ public void AbortCopy(ICloudBlob blob, string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
+ {
+ throw new NotImplementedException();
+ }
}
}
View
253 WindowsAzurePowershell/src/Management.Storage/Blob/Cmdlet/GetAzureStorageBlobCopyState.cs
@@ -0,0 +1,253 @@
+using Microsoft.WindowsAzure.Management.Storage.Common;
+using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.ResourceModel;
+using Microsoft.WindowsAzure.Storage;
+using Microsoft.WindowsAzure.Storage.Blob;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Management.Automation;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.WindowsAzure.Management.Storage.Blob.Cmdlet
+{
+ [Cmdlet(VerbsCommon.Get, StorageNouns.CopyBlobStatus, DefaultParameterSetName = NameParameterSet),
+ OutputType(typeof(AzureStorageBlob))]
+ public class GetAzureStorageBlobCopyState : StorageCloudBlobCmdletBase
+ {
+ /// <summary>
+ /// Blob Pipeline parameter set name
+ /// </summary>
+ private const string BlobPipelineParameterSet = "BlobPipeline";
+
+ /// <summary>
+ /// container pipeline paremeter set name
+ /// </summary>
+ private const string ContainerPipelineParmeterSet = "ContainerPipeline";
+
+ /// <summary>
+ /// blob name and container name parameter set
+ /// </summary>
+ private const string NameParameterSet = "NamePipeline";
+
+ [Parameter(HelpMessage = "ICloudBlob Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = BlobPipelineParameterSet)]
+ public ICloudBlob ICloudBlob { get; set; }
+
+ [Parameter(HelpMessage = "CloudBlobContainer Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = ContainerPipelineParmeterSet)]
+ public CloudBlobContainer CloudBlobContainer { get; set; }
+
+ [Parameter(ParameterSetName = ContainerPipelineParmeterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ [Parameter(ParameterSetName = NameParameterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ public string Blob
+ {
+ get { return BlobName; }
+ set { BlobName = value; }
+ }
+ private string BlobName = String.Empty;
+
+ [Parameter(HelpMessage = "Container name", Mandatory = true, Position = 1,
+ ParameterSetName = NameParameterSet)]
+ [ValidateNotNullOrEmpty]
+ public string Container
+ {
+ get { return ContainerName; }
+ set { ContainerName = value; }
+ }
+ private string ContainerName = String.Empty;
+
+ [Parameter(HelpMessage = "Wait for copy task complete")]
+ public SwitchParameter WaitForComplete
+ {
+ get { return waitForComplete;}
+ set { waitForComplete = value; }
+ }
+ private bool waitForComplete;
+
+ private List<ICloudBlob> remaindJobs = new List<ICloudBlob>();
+ private int total = 0;
+ private int failed = 0;
+ private int finished = 0;
+
+ public override void ExecuteCmdlet()
+ {
+ ICloudBlob blob = default(ICloudBlob);
+ switch (ParameterSetName)
+ {
+ case NameParameterSet:
+ blob = GetBlobWithCopyStatus(ContainerName, BlobName);
+ break;
+ case ContainerPipelineParmeterSet:
+ blob = GetBlobWithCopyStatus(CloudBlobContainer, BlobName);
+ break;
+ case BlobPipelineParameterSet:
+ blob = GetBlobWithCopyStatus(ICloudBlob);
+ break;
+ }
+
+ total++;
+
+ if (blob.CopyState == null)
+ {
+ throw new ArgumentException(String.Format(Resources.CopyTaskNotFound, blob.Name, blob.Container.Name));
+ }
+ else
+ {
+ UpdateTaskCount(blob.CopyState.Status);
+
+ if (blob.CopyState.Status == CopyStatus.Pending && waitForComplete)
+ {
+ remaindJobs.Add(blob);
+ }
+ else
+ {
+ WriteCopyState(blob);
+ }
+ }
+ }
+
+ private void UpdateTaskCount(CopyStatus status)
+ {
+ switch (status)
+ {
+ case CopyStatus.Invalid:
+ case CopyStatus.Failed:
+ case CopyStatus.Aborted:
+ failed++;
+ break;
+ case CopyStatus.Pending:
+ break;
+ case CopyStatus.Success:
+ default:
+ finished++;
+ break;
+ }
+ }
+
+ internal void WriteCopyState(ICloudBlob blob)
+ {
+ WriteObject(blob.CopyState);
+ }
+
+ internal void WriteCopyProgress(ICloudBlob blob, ProgressRecord progress)
+ {
+ long bytesCopied = blob.CopyState.BytesCopied ?? 0;
+ long totalBytes = blob.CopyState.TotalBytes ?? 0;
+ int percent = 0;
+
+ if (totalBytes != 0)
+ {
+ percent = (int)(bytesCopied * 100 / totalBytes);
+ int lowestPercent = 0;
+ int highestPercent = 100;
+ percent = Math.Max(lowestPercent, percent);
+ percent = Math.Min(percent, highestPercent);
+ progress.PercentComplete = percent;
+ }
+
+ string activity = String.Format(Resources.CopyBlobStatus, blob.CopyState.Status.ToString(), blob.Name, blob.Container.Name, blob.CopyState.Source.ToString());
+ progress.Activity = activity;
+ string message = String.Format(Resources.CopyBlobPendingStatus, percent, blob.CopyState.BytesCopied, blob.CopyState.TotalBytes);
+ progress.StatusDescription = message;
+ WriteProgress(progress);
+ }
+
+ private ICloudBlob GetBlobWithCopyStatus(string containerName, string blobName)
+ {
+ CloudBlobContainer container = Channel.GetContainerReference(containerName);
+ return GetBlobWithCopyStatus(container, blobName);
+ }
+
+ private ICloudBlob GetBlobWithCopyStatus(CloudBlobContainer container, string blobName)
+ {
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ ICloudBlob blob = Channel.GetBlobReferenceFromServer(container, blobName, accessCondition, options, OperationContext);
+
+ if (blob == null)
+ {
+ throw new ResourceNotFoundException(String.Format(Resources.BlobNotFound, blobName, container.Name));
+ }
+
+ return GetBlobWithCopyStatus(blob);
+ }
+
+ private ICloudBlob GetBlobWithCopyStatus(ICloudBlob blob)
+ {
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ Channel.FetchBlobAttributes(blob, accessCondition, options, OperationContext);
+ return blob;
+ }
+
+ protected override void EndProcessing()
+ {
+ if (remaindJobs.Count >= 0)
+ {
+ List<ProgressRecord> records = new List<ProgressRecord>();
+ int taskRecordCount = 5;
+ string summary = String.Format(Resources.CopyBlobSummaryCount, total, finished, remaindJobs.Count, failed);
+ ProgressRecord summaryRecord = new ProgressRecord(0, Resources.CopyBlobSummaryActivity, summary);
+ records.Add(summaryRecord);
+
+ for (int i = 1; i <= taskRecordCount; i++)
+ {
+ ProgressRecord record = new ProgressRecord(i, Resources.CopyBlobActivity, "Copy");
+ records.Add(record);
+ }
+
+ int workerPtr = 0;
+ int taskRecordStartIndex = 1;
+
+ while (remaindJobs.Count > 0)
+ {
+ summary = String.Format(Resources.CopyBlobSummaryCount, total, finished, remaindJobs.Count, failed);
+ WriteProgress(summaryRecord);
+
+ for (int i = taskRecordStartIndex; i <= taskRecordCount && !ShouldForceQuit; i++)
+ {
+ ICloudBlob blob = remaindJobs[workerPtr];
+ GetBlobWithCopyStatus(blob);
+ WriteCopyProgress(blob, records[i]);
+ UpdateTaskCount(blob.CopyState.Status);
+
+ if (blob.CopyState.Status != CopyStatus.Pending)
+ {
+ WriteCopyState(blob);
+ remaindJobs.RemoveAt(workerPtr);
+ }
+ else
+ {
+ workerPtr++;
+ }
+
+ if (remaindJobs.Count == 0)
+ {
+ break;
+ }
+
+ if (workerPtr >= remaindJobs.Count)
+ {
+ workerPtr = 0;
+ break;
+ }
+ }
+
+ if (ShouldForceQuit)
+ {
+ break;
+ }
+ else
+ {
+ //status update interval
+ int interval = 1 * 1000; //in millisecond
+ Thread.Sleep(interval);
+ }
+ }
+ }
+
+ base.EndProcessing();
+ }
+ }
+}
View
1  WindowsAzurePowershell/src/Management.Storage/Blob/Cmdlet/RemoveAzureStorageContainer.cs
@@ -91,6 +91,7 @@ internal void RemoveAzureContainer(string name)
CloudBlobContainer container = Channel.GetContainerReference(name);
if (!Channel.DoesContainerExist(container, requestOptions, OperationContext))
+
{
throw new ResourceNotFoundException(String.Format(Resources.ContainerNotFound, name));
}
View
271 WindowsAzurePowershell/src/Management.Storage/Blob/Cmdlet/StartCopyAzureStorageBlob.cs
@@ -0,0 +1,271 @@
+
+namespace Microsoft.WindowsAzure.Management.Storage.Blob.Cmdlet
+{
+ using Microsoft.WindowsAzure.Management.Storage.Common;
+ using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.Contract;
+ using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.ResourceModel;
+ using Microsoft.WindowsAzure.ServiceManagement.Storage.Common.ResourceModel;
+ using Microsoft.WindowsAzure.Storage;
+ using Microsoft.WindowsAzure.Storage.Blob;
+ using Microsoft.WindowsAzure.Storage.DataMovement;
+ using System;
+ using System.Management.Automation;
+ using System.Security.Permissions;
+ using System.Threading;
+
+ [Cmdlet(VerbsLifecycle.Start, StorageNouns.CopyBlob, DefaultParameterSetName = NameParameterSet),
+ OutputType(typeof(AzureStorageBlob))]
+ public class StartCopyAzureStorageBlob : StorageCloudBlobCmdletBase
+ {
+ /// <summary>
+ /// Blob Pipeline parameter set name
+ /// </summary>
+ private const string SrcBlobParameterSet = "BlobPipeline";
+
+ /// <summary>
+ /// Blob Pipeline parameter set name
+ /// </summary>
+ private const string DestBlobPipelineParameterSet = "DestBlobPipeline";
+
+ /// <summary>
+ /// Container pipeline paremeter set name
+ /// </summary>
+ private const string ContainerPipelineParmeterSet = "ContainerPipeline";
+
+ /// <summary>
+ /// Blob name and container name parameter set
+ /// </summary>
+ private const string NameParameterSet = "NamePipeline";
+
+ /// <summary>
+ /// Source uri parameter set
+ /// </summary>
+ private const string UriParameterSet = "UriPipeline";
+
+ [Parameter(HelpMessage = "ICloudBlob Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = SrcBlobParameterSet)]
+ [Parameter(HelpMessage = "ICloudBlob Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = DestBlobPipelineParameterSet)]
+ public ICloudBlob ICloudBlob { get; set; }
+
+ [Parameter(HelpMessage = "CloudBlobContainer Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = ContainerPipelineParmeterSet)]
+ public CloudBlobContainer CloudBlobContainer { get; set; }
+
+ [Parameter(ParameterSetName = ContainerPipelineParmeterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ [Parameter(ParameterSetName = NameParameterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ public string SrcBlob
+ {
+ get { return BlobName; }
+ set { BlobName = value; }
+ }
+ private string BlobName = String.Empty;
+
+ [Parameter(HelpMessage = "Container name", Mandatory = true, Position = 1,
+ ParameterSetName = NameParameterSet)]
+ [ValidateNotNullOrEmpty]
+ public string SrcContainer
+ {
+ get { return ContainerName; }
+ set { ContainerName = value; }
+ }
+ private string ContainerName = String.Empty;
+
+ [Parameter(HelpMessage = "Force to remove the blob and its snapshot without confirm")]
+ public SwitchParameter Force
+ {
+ get { return force; }
+ set { force = value; }
+ }
+ private bool force = false;
+
+ [Parameter(HelpMessage = "source blob uri", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = UriParameterSet)]
+ public string SrcUri { get; set; }
+
+ [Parameter(HelpMessage = "Destination container name", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)]
+ [Parameter(HelpMessage = "Destination container name", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = UriParameterSet)]
+ [Parameter(HelpMessage = "Destination container name", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = SrcBlobParameterSet)]
+ public string destContainer { get; set; }
+
+ [Parameter(HelpMessage = "Destination blob name", Mandatory = false,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)]
+ [Parameter(HelpMessage = "Destination blob name", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = UriParameterSet)]
+ [Parameter(HelpMessage = "Destination blob name", Mandatory = false,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = SrcBlobParameterSet)]
+ public string DestBlob { get; set; }
+
+ [Parameter(HelpMessage = "Destination ICloudBlob object", Mandatory = true,
+ ParameterSetName = DestBlobPipelineParameterSet)]
+ public ICloudBlob DestICloudBlob { get; set; }
+
+ [Parameter(HelpMessage = "Destination Storage context object", Mandatory = false)]
+ public AzureStorageContext DestContext { get; set; }
+
+ private IStorageBlobManagement destChannel;
+
+ public override void ExecuteCmdlet()
+ {
+ if(destChannel == null)
+ {
+ if (DestContext == null)
+ {
+ destChannel = Channel;
+ }
+ else
+ {
+ destChannel = CreateChannel(DestContext.StorageAccount);
+ }
+ }
+
+ switch (ParameterSetName)
+ {
+ case NameParameterSet:
+ StartCopyBlob(SrcContainer, SrcBlob, destContainer, DestBlob);
+ break;
+
+ case UriParameterSet:
+ StartCopyBlob(SrcUri, destContainer, DestBlob);
+ break;
+
+ case SrcBlobParameterSet:
+ StartCopyBlob(ICloudBlob, destContainer, DestBlob);
+ break;
+
+ case DestBlobPipelineParameterSet:
+ StartCopyBlob(ICloudBlob, DestICloudBlob);
+ break;
+ }
+ }
+
+ private void StartCopyBlob(ICloudBlob srcICloudBlob, ICloudBlob destICloudBlob)
+ {
+ StartCopyInTransferManager(srcICloudBlob, destICloudBlob.Container, destICloudBlob.Name);
+ }
+
+ private void StartCopyBlob(ICloudBlob srcICloudBlob, string destContainer, string destBlobName)
+ {
+ CloudBlobContainer container = destChannel.GetContainerReference(destContainer);
+ StartCopyInTransferManager(srcICloudBlob, container, destBlobName);
+ }
+
+ private void StartCopyBlob(string srcUri, string destContainer, string destBlobName)
+ {
+ CloudBlobContainer container = destChannel.GetContainerReference(destContainer);
+ StartCopyInTransferManager(new Uri(srcUri), container, destBlobName);
+ }
+
+ private void StartCopyBlob(string srcContainerName, string srcBlobName, string destContainerName, string destBlobName)
+ {
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ CloudBlobContainer container = Channel.GetContainerReference(srcContainerName);
+ ICloudBlob blob = Channel.GetBlobReferenceFromServer(container, srcBlobName, accessCondition, options, OperationContext);
+
+ if (blob == null)
+ {
+ throw new ResourceNotFoundException(String.Format(Resources.BlobNotFound, srcBlobName, srcContainerName));
+ }
+
+ CloudBlobContainer destContainer = destChannel.GetContainerReference(destContainerName);
+ StartCopyInTransferManager(blob, destContainer, destBlobName);
+ }
+
+ /// <summary>
+ /// Amount of concurrent async tasks to run per available core.
+ /// </summary>
+ [Alias("Concurrent")]
+ [Parameter(HelpMessage = "Amount of concurrent async tasks to run per available core.")]
+ public int ConcurrentCount
+ {
+ get { return AsyncTasksPerCodeMultiplier; }
+ set { AsyncTasksPerCodeMultiplier = value; }
+ }
+ private int AsyncTasksPerCodeMultiplier = 8;
+
+ /// <summary>
+ /// whether the download progress finished
+ /// </summary>
+ private bool finished = false;
+
+ /// <summary>
+ /// exception thrown during downloading
+ /// </summary>
+ private Exception copyException = null;
+
+ /// <summary>
+ /// on uploading finish
+ /// </summary>
+ /// <param name="progress">progress information</param>
+ /// <param name="e">run time exception</param>
+ [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
+ internal virtual void OnFinish(object data, Exception e)
+ {
+ finished = true;
+ copyException = e;
+ }
+
+ private void StartCopyInTransferManager(ICloudBlob blob, CloudBlobContainer destContainer, string destBlobName)
+ {
+ if (string.IsNullOrEmpty(destBlobName))
+ {
+ destBlobName = blob.Name;
+ }
+
+ Action<BlobTransferManager> taskAction = (transferManager) => transferManager.QueueBlobStartCopy(blob, destContainer, destBlobName, null, OnFinish, null);
+ StartCopyInTransferManager(taskAction, destContainer, destBlobName);
+ }
+
+ private void StartCopyInTransferManager(Uri uri, CloudBlobContainer destContainer, string destBlobName)
+ {
+ Action<BlobTransferManager> taskAction = (transferManager) => transferManager.QueueBlobStartCopy(uri, destContainer, destBlobName, null, OnFinish, null);
+ StartCopyInTransferManager(taskAction, destContainer, destBlobName);
+ }
+
+ private void StartCopyInTransferManager(Action<BlobTransferManager> taskAction, CloudBlobContainer destContainer, string destBlobName)
+ {
+ finished = false;
+
+ //status update interval
+ int interval = 1 * 1000; //in millisecond
+
+ BlobTransferOptions opts = new BlobTransferOptions();
+ opts.Concurrency = Environment.ProcessorCount * AsyncTasksPerCodeMultiplier;
+
+ using (BlobTransferManager transferManager = new BlobTransferManager(opts))
+ {
+ taskAction(transferManager);
+
+ while (!finished)
+ {
+ Thread.Sleep(interval);
+
+ if (ShouldForceQuit)
+ {
+ //can't output verbose log for this operation since the Output stream is already stopped.
+ transferManager.CancelWork();
+ break;
+ }
+ }
+
+ transferManager.WaitForCompletion();
+
+ if (copyException != null)
+ {
+ throw copyException;
+ }
+ else
+ {
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ ICloudBlob blob = destChannel.GetBlobReferenceFromServer(destContainer, destBlobName, accessCondition, options, OperationContext);
+ WriteICloudBlobWithProperties(blob, destChannel);
+ }
+ }
+ }
+ }
+}
View
167 WindowsAzurePowershell/src/Management.Storage/Blob/Cmdlet/StopCopyAzureStorageBlob.cs
@@ -0,0 +1,167 @@
+using Microsoft.WindowsAzure.Management.Storage.Common;
+using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.ResourceModel;
+using Microsoft.WindowsAzure.Storage;
+using Microsoft.WindowsAzure.Storage.Blob;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Management.Automation;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.WindowsAzure.Management.Storage.Blob.Cmdlet
+{
+ [Cmdlet(VerbsLifecycle.Stop, StorageNouns.CopyBlob, DefaultParameterSetName = NameParameterSet),
+ OutputType(typeof(AzureStorageBlob))]
+ public class StopCopyAzureStorageBlob : StorageCloudBlobCmdletBase
+ {
+ /// <summary>
+ /// Blob Pipeline parameter set name
+ /// </summary>
+ private const string BlobPipelineParameterSet = "BlobPipeline";
+
+ /// <summary>
+ /// container pipeline paremeter set name
+ /// </summary>
+ private const string ContainerPipelineParmeterSet = "ContainerPipeline";
+
+ /// <summary>
+ /// blob name and container name parameter set
+ /// </summary>
+ private const string NameParameterSet = "NamePipeline";
+
+ [Parameter(HelpMessage = "ICloudBlob Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = BlobPipelineParameterSet)]
+ public ICloudBlob ICloudBlob { get; set; }
+
+ [Parameter(HelpMessage = "CloudBlobContainer Object", Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = ContainerPipelineParmeterSet)]
+ public CloudBlobContainer CloudBlobContainer { get; set; }
+
+ [Parameter(ParameterSetName = ContainerPipelineParmeterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ [Parameter(ParameterSetName = NameParameterSet, Mandatory = true, Position = 0, HelpMessage = "Blob name")]
+ public string Blob
+ {
+ get { return BlobName; }
+ set { BlobName = value; }
+ }
+ private string BlobName = String.Empty;
+
+ [Parameter(HelpMessage = "Container name", Mandatory = true, Position = 1,
+ ParameterSetName = NameParameterSet)]
+ [ValidateNotNullOrEmpty]
+ public string Container
+ {
+ get { return ContainerName; }
+ set { ContainerName = value; }
+ }
+ private string ContainerName = String.Empty;
+
+ [Parameter(HelpMessage = "Force to remove the blob and its snapshot without confirm")]
+ public SwitchParameter Force
+ {
+ get { return force; }
+ set { force = value; }
+ }
+ private bool force = false;
+
+ [Parameter(HelpMessage = "Copy Id", Mandatory = true)]
+ [ValidateNotNullOrEmpty]
+ public string CopyId
+ {
+ get { return copyId; }
+ set { copyId = value; }
+ }
+ private string copyId;
+
+ public override void ExecuteCmdlet()
+ {
+ string blobName = string.Empty;
+ string containerName = string.Empty;
+ switch (ParameterSetName)
+ {
+ case NameParameterSet:
+ StopCopyBlob(ContainerName, BlobName, copyId);
+ blobName = BlobName;
+ containerName = ContainerName;
+ break;
+ case ContainerPipelineParmeterSet:
+ StopCopyBlob(CloudBlobContainer, BlobName, copyId);
+ blobName = BlobName;
+ containerName = CloudBlobContainer.Name;
+ break;
+ case BlobPipelineParameterSet:
+ StopCopyBlob(ICloudBlob, copyId);
+ blobName = ICloudBlob.Name;
+ containerName = ICloudBlob.Container.Name;
+ break;
+ }
+
+ string message = String.Format(Resources.StopCopyBlobSuccessfully, blobName, containerName);
+ WriteObject(message);
+ }
+
+ private void StopCopyBlob(string containerName, string blobName, string copyId)
+ {
+ CloudBlobContainer container = Channel.GetContainerReference(containerName);
+ StopCopyBlob(container, blobName, copyId);
+ }
+
+ private void StopCopyBlob(CloudBlobContainer container, string blobName, string copyId)
+ {
+ if (!NameUtil.IsValidBlobName(blobName))
+ {
+ throw new ArgumentException(String.Format(Resources.InvalidBlobName, blobName));
+ }
+
+ if (!NameUtil.IsValidBlobName(container.Name))
+ {
+ throw new ArgumentException(String.Format(Resources.InvalidContainerName, container.Name));
+ }
+
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ Console.WriteLine("Get blob from server");
+ ICloudBlob blob = Channel.GetBlobReferenceFromServer(container, blobName, accessCondition, options, OperationContext);
+ Console.WriteLine("End blob from server");
+
+ if (blob == null)
+ {
+ throw new ResourceNotFoundException(String.Format(Resources.BlobNotFound, blobName, container.Name));
+ }
+
+ StopCopyBlob(blob, copyId);
+ }
+
+ private void StopCopyBlob(ICloudBlob blob, string copyId)
+ {
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+
+ if (null == blob)
+ {
+ throw new ArgumentException(String.Format(Resources.ObjectCannotBeNull, typeof(ICloudBlob).Name));
+ }
+
+ if (Force)
+ {
+ Channel.FetchBlobAttributes(blob, accessCondition, options, OperationContext);
+
+ if (!String.IsNullOrEmpty(blob.CopyState.CopyId))
+ {
+ copyId = blob.CopyState.CopyId;
+ }
+ }
+
+ if (String.IsNullOrEmpty(copyId))
+ {
+ throw new ArgumentException(Resources.CopyIdCannotBeEmpty);
+ }
+
+ //TODO handle 400 copy id is invalid
+ //TODO handle 409 conflict Trying to abort a copy that has completed or failed results in 409 Conflict. Trying to abort a copy operation using an incorrect copy ID also results in 409 Conflict.
+ Channel.AbortCopy(blob, copyId, accessCondition, options, OperationContext);
+ }
+ }
+}
View
20 WindowsAzurePowershell/src/Management.Storage/Blob/StorageCloudBlobCmdletBase.cs
@@ -15,6 +15,7 @@
namespace Microsoft.WindowsAzure.Management.Storage.Common
{
using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.Contract;
+ using Microsoft.WindowsAzure.ServiceManagement.Storage.Blob.ResourceModel;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
@@ -116,6 +117,11 @@ protected override IStorageBlobManagement CreateChannel()
return Channel;
}
+ protected IStorageBlobManagement CreateChannel(CloudStorageAccount account)
+ {
+ return new StorageBlobManagement(account.CreateCloudBlobClient());
+ }
+
/// <summary>
/// whether the specified blob is a snapshot
/// </summary>
@@ -125,5 +131,19 @@ internal bool IsSnapshot(ICloudBlob blob)
{
return !string.IsNullOrEmpty(blob.Name) && blob.SnapshotTime != null;
}
+
+ internal void WriteICloudBlobWithProperties(ICloudBlob blob, IStorageBlobManagement channel = null)
+ {
+ if (channel == null)
+ {
+ channel = Channel;
+ }
+
+ AccessCondition accessCondition = null;
+ BlobRequestOptions options = null;
+ channel.FetchBlobAttributes(blob, accessCondition, options, OperationContext);
+ AzureStorageBlob azureBlob = new AzureStorageBlob(blob);
+ WriteObjectWithStorageContext(azureBlob);
+ }
}
}
View
2  WindowsAzurePowershell/src/Management.Storage/Common/StorageCloudCmdletBase.cs
@@ -239,7 +239,7 @@ protected override void WriteExceptionError(Exception e)
}
/// <summary>
- /// get the error category for specificed exception
+ /// Get the error category for specificed exception
/// </summary>
/// <param name="e">exception object</param>
/// <returns>error category</returns>
View
10 WindowsAzurePowershell/src/Management.Storage/Common/StorageNouns.cs
@@ -88,5 +88,15 @@ public static class StorageNouns
/// Table cmdlet name
/// </summary>
public const string Table = "AzureStorageTable";
+
+ /// <summary>
+ /// Copy azure storage blob
+ /// </summary>
+ public const string CopyBlob = "CopyAzureStorageBlob";
+
+ /// <summary>
+ /// Copy status for azure storage blob
+ /// </summary>
+ public const string CopyBlobStatus = "AzureStorageBlobCopyState";
}
}
View
4 WindowsAzurePowershell/src/Management.Storage/Management.Storage.csproj
@@ -76,6 +76,7 @@
<ItemGroup>
<Compile Include="Blob\Cmdlet\GetAzureStorageBlob.cs" />
<Compile Include="Blob\Cmdlet\GetAzureStorageBlobContent.cs" />
+ <Compile Include="Blob\Cmdlet\GetAzureStorageBlobCopyState.cs" />
<Compile Include="Blob\Cmdlet\GetAzureStorageContainer.cs" />
<Compile Include="Blob\Cmdlet\NewAzureStorageContainer.cs" />
<Compile Include="Blob\Cmdlet\RemoveAzureStorageBlob.cs" />
@@ -83,6 +84,8 @@
<Compile Include="Blob\Cmdlet\SetAzureStorageBlobContent.cs" />
<Compile Include="Blob\Cmdlet\SetAzureStorageContainerAcl.cs" />
<Compile Include="Common\CmdletOperationContext.cs" />
+ <Compile Include="Blob\Cmdlet\StartCopyAzureStorageBlob.cs" />
+ <Compile Include="Blob\Cmdlet\StopCopyAzureStorageBlob.cs" />
<Compile Include="Common\CommunicationExceptionUtil.cs" />
<Compile Include="Common\NameUtil.cs" />
<Compile Include="Common\Cmdlet\NewAzureStorageContext.cs" />
@@ -133,6 +136,7 @@
<Generator>ResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
View
90 WindowsAzurePowershell/src/Management.Storage/Resources.Designer.cs
@@ -214,6 +214,87 @@ internal class Resources {
}
/// <summary>
+ /// Looks up a localized string similar to Copy Blob..
+ /// </summary>
+ internal static string CopyBlobActivity {
+ get {
+ return ResourceManager.GetString("CopyBlobActivity", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Percent:{0}%. BytesCopied: {1}Bytes. TotalBytes: {2}Bytes..
+ /// </summary>
+ internal static string CopyBlobPendingStatus {
+ get {
+ return ResourceManager.GetString("CopyBlobPendingStatus", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; copy to blob &apos;{1}&apos; in container &apos;{2}&apos; from &apos;{3}&apos;..
+ /// </summary>
+ internal static string CopyBlobStatus {
+ get {
+ return ResourceManager.GetString("CopyBlobStatus", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Copy Blob Status Summary..
+ /// </summary>
+ internal static string CopyBlobSummaryActivity {
+ get {
+ return ResourceManager.GetString("CopyBlobSummaryActivity", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Total: {0}. Finished: {1}. Active:{2}. Failed: {3}..
+ /// </summary>
+ internal static string CopyBlobSummaryCount {
+ get {
+ return ResourceManager.GetString("CopyBlobSummaryCount", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Successfully start copy blob &apos;{0}&apos; in container &apos;{1}&apos; to blob &apos;{2}&apos; in container &apos;{3}&apos;..
+ /// </summary>
+ internal static string CopyBlobToBlobSuccessfully {
+ get {
+ return ResourceManager.GetString("CopyBlobToBlobSuccessfully", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to CopyId can not be empty..
+ /// </summary>
+ internal static string CopyIdCannotBeEmpty {
+ get {
+ return ResourceManager.GetString("CopyIdCannotBeEmpty", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Can not find copy task on specified blob &apos;{0}&apos; in container &apos;{1}&apos;..
+ /// </summary>
+ internal static string CopyTaskNotFound {
+ get {
+ return ResourceManager.GetString("CopyTaskNotFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Successfully start copy &apos;{0}&apos; to blob &apos;{1}&apos; in container &apos;{2}&apos;..
+ /// </summary>
+ internal static string CopyUriToBlobSuccessfully {
+ get {
+ return ResourceManager.GetString("CopyUriToBlobSuccessfully", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Current Storage Account not found in subscription &apos;{0}&apos;. Please set it use &quot;Set-AzureSubscription&quot;..
/// </summary>
internal static string CurrentStorageAccountNameNotFound {
@@ -799,6 +880,15 @@ internal class Resources {
}
/// <summary>
+ /// Looks up a localized string similar to Stop the copy task on blob &apos;{0}&apos; in container &apos;{1}&apos; successfully..
+ /// </summary>
+ internal static string StopCopyBlobSuccessfully {
+ get {
+ return ResourceManager.GetString("StopCopyBlobSuccessfully", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to {0} stop processing, Use {1} remote calls. Elapsed time {2:0.00} ms. Client operation id: {3}..
/// </summary>
internal static string StopProcessingLog {
View
37 WindowsAzurePowershell/src/Management.Storage/Resources.resx
@@ -427,4 +427,41 @@
<value>https://{0}.table.core.windows.net/</value>
<comment>0 for storage account name</comment>
</data>
+ <data name="CopyIdCannotBeEmpty" xml:space="preserve">
+ <value>CopyId can not be empty.</value>
+ </data>
+ <data name="StopCopyBlobSuccessfully" xml:space="preserve">
+ <value>Stop the copy task on blob '{0}' in container '{1}' successfully.</value>
+ <comment>0 for blob name, 1 for container name</comment>
+ </data>
+ <data name="CopyBlobPendingStatus" xml:space="preserve">
+ <value>Percent:{0}%. BytesCopied: {1}Bytes. TotalBytes: {2}Bytes.</value>
+ <comment>0 for copied percent, 1 for bytes copied, 2 for total bytes.</comment>
+ </data>
+ <data name="CopyBlobStatus" xml:space="preserve">
+ <value>'{0}' copy to blob '{1}' in container '{2}' from '{3}'.</value>
+ <comment>0 for copy status, 1 for destination blob name, 2 for destionation container name, 3 for source uri.</comment>
+ </data>
+ <data name="CopyBlobToBlobSuccessfully" xml:space="preserve">
+ <value>Successfully start copy blob '{0}' in container '{1}' to blob '{2}' in container '{3}'.</value>
+ <comment>0 for source blob name, 1 for source container name, 2 for destination blob name, 3 for destination container name.</comment>
+ </data>
+ <data name="CopyUriToBlobSuccessfully" xml:space="preserve">
+ <value>Successfully start copy '{0}' to blob '{1}' in container '{2}'.</value>
+ <comment>0 for source uri, 1 for destination blob name, 2 for destination container name. </comment>
+ </data>
+ <data name="CopyBlobActivity" xml:space="preserve">
+ <value>Copy Blob.</value>
+ </data>
+ <data name="CopyBlobSummaryActivity" xml:space="preserve">
+ <value>Copy Blob Status Summary.</value>
+ </data>
+ <data name="CopyBlobSummaryCount" xml:space="preserve">
+ <value>Total: {0}. Finished: {1}. Active:{2}. Failed: {3}.</value>
+ <comment>0,1,2,3 for related task coun</comment>
+ </data>
+ <data name="CopyTaskNotFound" xml:space="preserve">
+ <value>Can not find copy task on specified blob '{0}' in container '{1}'.</value>
+ <comment>0 for blob name, 1 for container name.</comment>
+ </data>
</root>
View
2  WindowsAzurePowershell/src/ServiceManagement/Storage/Blob/Contract/IStorageBlobManagement.cs
@@ -164,5 +164,7 @@ public interface IStorageBlobManagement
/// <param name="options">blob request options</param>
/// <param name="operationContext">An object that represents the context for the current operation.</param>
void SetBlobMetadata(ICloudBlob blob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext);
+
+ void AbortCopy(ICloudBlob blob, string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext);
}
}
View
8 WindowsAzurePowershell/src/ServiceManagement/Storage/Blob/Contract/StorageBlobManagement.cs
@@ -124,7 +124,7 @@ public ICloudBlob GetBlobReferenceFromServer(CloudBlobContainer container, strin
{
try
{
- ICloudBlob blob = container.GetBlobReferenceFromServer(blobName, accessCondition, options, operationContext);
+ ICloudBlob blob = container.GetBlobReferenceFromServer(blobName, null, null, null);
return blob;
}
catch(StorageException e)
@@ -251,5 +251,11 @@ public void SetBlobMetadata(ICloudBlob blob, AccessCondition accessCondition, Bl
{
blob.SetMetadata(accessCondition, options, operationContext);
}
+
+
+ public void AbortCopy(ICloudBlob blob, string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
+ {
+ blob.AbortCopy(copyId, accessCondition, options, operationContext);
+ }
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.