Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -480,7 +480,7 @@ public async Task UploadDirectory_EventHandler_SasAsync()
DataTransferOptions transferOptions = new DataTransferOptions();
transferOptions.TransferStatusChanged += (TransferStatusEventArgs args) =>
{
if (args.StorageTransferStatus == DataTransferStatus.Completed)
if (args.TransferStatus.HasCompletedSuccessfully)
{
using (StreamWriter logStream = File.AppendText(logFile))
{
Expand Down Expand Up @@ -672,7 +672,7 @@ public async Task CopySingle_ConnectionStringAsync()
#endregion

Assert.IsTrue(await destinationAppendBlobClient.ExistsAsync());
Assert.AreEqual(dataTransfer.TransferStatus, DataTransferStatus.Completed);
Assert.AreEqual(DataTransferState.Completed, dataTransfer.TransferStatus.State);
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@
<Compile Include="$(AzureStorageDataMovementSharedSources)CheckpointerExtensions.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)Errors.DataMovement.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)DataMovementConstants.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)DataTransferStatusInternal.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)JobPlanExtensions.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)ResponseExtensions.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)LocalTransferCheckpointer.cs" LinkBase="Shared\DataMovement" />
<Compile Include="$(AzureStorageDataMovementSharedSources)TransferCheckpointer.cs" LinkBase="Shared\DataMovement" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(AzureStorageDataMovementSharedSources)\JobPlan\*" LinkBase="Shared\DataMovement\JobPlan" />

</ItemGroup>
<ItemGroup>
<Compile Include="$(AzureStorageBlobsSharedSources)BlobErrors.cs" LinkBase="Shared\Blobs" />
Expand Down
4 changes: 3 additions & 1 deletion sdk/storage/Azure.Storage.DataMovement/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- [BREAKING CHANGE] Renamed `SingleTransferCompletedEventArgs` to `TransferItemCompletedEventArgs`
- [BREAKING CHANGE] Renamed `TransferItemFailedEventArgs` to `TransferItemFailedEventArgs`
- [BREAKING CHANGE] Renamed `TransferItemSkippedEventArgs` to `TransferItemSkippedEventArgs`
- [BREAKING CHANGE] Renamed `TransferStatusEventArgs.StorageTransferStatus` to `TransferStatus`
- [BREAKING CHANGE] Renamed `StorageResourceSingle` to `StorageResourceItem`
- [BREAKING CHANGE] Renamed `StorageResourceItem.WriteFromStreamAsync` to `CopyFromStreamAsync`
- [BREAKING CHANGE] Renamed `StorageResourceContainer.GetChildStorageResource` to `StorageResourceContainer.GetStorageResourceReference`
Expand All @@ -49,8 +50,9 @@
- [BREAKING CHANGE] Renamed `ErrorHandlingBehavior` to `DataTransferErrorMode`
- [BREAKING CHANGE] Renamed `DataTransferErrorMode.StopOnAnyFailures` to `StopOnAnyFailure`
- [BREAKING CHANGE] Renamed `TransferType` to `DataTransferOrder`
- [BREAKING CHANGE] Renamed `DataTransferOrder.Unordered` to `Unordered`
- [BREAKING CHANGE] Renamed `DataTransferOrder.Concurrent` to `Unordered`
- [BREAKING CHANGE] Renamed `StorageTransferStatus` to `DataTransferStatus`
- [BREAKING CHANGE] Changed `DataTransferStatus` from `enum` to a `class`.
- [BREAKING CHANGE] Renamed `StorageResourceCreateMode` to `StorageResourceCreationPreference`.
- [BREAKING CHANGE] Renamed `StorageResourceCreationPreference` values from `Fail` to `FailIfExists`, `Overwrite` to `OverwriteIfExists` and `Skip` to `SkipIfExists`. `None` was removed, use `FailIfExists` instead.
- [BREAKING CHANGE] Renamed `DataTransferOptions.CreateMode` to `CreationPreference`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,25 @@ protected internal DataTransferProperties() { }
public virtual string SourceTypeId { get { throw null; } }
public virtual string TransferId { get { throw null; } }
}
public enum DataTransferStatus
public enum DataTransferState
{
None = 0,
Queued = 1,
InProgress = 2,
Paused = 3,
Completed = 4,
CompletedWithSkippedTransfers = 5,
CompletedWithFailedTransfers = 6,
PauseInProgress = 7,
CancellationInProgress = 8,
Pausing = 3,
Stopping = 4,
Paused = 5,
Completed = 6,
}
public partial class DataTransferStatus : System.IEquatable<Azure.Storage.DataMovement.DataTransferStatus>
{
protected internal DataTransferStatus() { }
protected internal DataTransferStatus(Azure.Storage.DataMovement.DataTransferState state, bool hasFailureItems, bool hasSkippedItems) { }
public bool HasCompletedSuccessfully { get { throw null; } }
public bool HasFailedItems { get { throw null; } }
public bool HasSkippedItems { get { throw null; } }
public Azure.Storage.DataMovement.DataTransferState State { get { throw null; } }
public bool Equals(Azure.Storage.DataMovement.DataTransferStatus other) { throw null; }
}
public partial class LocalFilesStorageResourceProvider : Azure.Storage.DataMovement.StorageResourceProvider
{
Expand Down Expand Up @@ -213,6 +221,6 @@ public TransferManagerOptions() { }
public partial class TransferStatusEventArgs : Azure.Storage.DataMovement.DataTransferEventArgs
{
public TransferStatusEventArgs(string transferId, Azure.Storage.DataMovement.DataTransferStatus transferStatus, bool isRunningSynchronously, System.Threading.CancellationToken cancellationToken) : base (default(string), default(bool), default(System.Threading.CancellationToken)) { }
public Azure.Storage.DataMovement.DataTransferStatus StorageTransferStatus { get { throw null; } }
public Azure.Storage.DataMovement.DataTransferStatus TransferStatus { get { throw null; } }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,25 @@ protected internal DataTransferProperties() { }
public virtual string SourceTypeId { get { throw null; } }
public virtual string TransferId { get { throw null; } }
}
public enum DataTransferStatus
public enum DataTransferState
{
None = 0,
Queued = 1,
InProgress = 2,
Paused = 3,
Completed = 4,
CompletedWithSkippedTransfers = 5,
CompletedWithFailedTransfers = 6,
PauseInProgress = 7,
CancellationInProgress = 8,
Pausing = 3,
Stopping = 4,
Paused = 5,
Completed = 6,
}
public partial class DataTransferStatus : System.IEquatable<Azure.Storage.DataMovement.DataTransferStatus>
{
protected internal DataTransferStatus() { }
protected internal DataTransferStatus(Azure.Storage.DataMovement.DataTransferState state, bool hasFailureItems, bool hasSkippedItems) { }
public bool HasCompletedSuccessfully { get { throw null; } }
public bool HasFailedItems { get { throw null; } }
public bool HasSkippedItems { get { throw null; } }
public Azure.Storage.DataMovement.DataTransferState State { get { throw null; } }
public bool Equals(Azure.Storage.DataMovement.DataTransferStatus other) { throw null; }
}
public partial class LocalFilesStorageResourceProvider : Azure.Storage.DataMovement.StorageResourceProvider
{
Expand Down Expand Up @@ -213,6 +221,6 @@ public TransferManagerOptions() { }
public partial class TransferStatusEventArgs : Azure.Storage.DataMovement.DataTransferEventArgs
{
public TransferStatusEventArgs(string transferId, Azure.Storage.DataMovement.DataTransferStatus transferStatus, bool isRunningSynchronously, System.Threading.CancellationToken cancellationToken) : base (default(string), default(bool), default(System.Threading.CancellationToken)) { }
public Azure.Storage.DataMovement.DataTransferStatus StorageTransferStatus { get { throw null; } }
public Azure.Storage.DataMovement.DataTransferStatus TransferStatus { get { throw null; } }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -13,13 +14,25 @@ internal static async Task<bool> IsResumableAsync(
string transferId,
CancellationToken cancellationToken)
{
DataTransferStatus jobStatus = (DataTransferStatus)await checkpointer.GetByteValue(
DataTransferState transferState = (DataTransferState) await checkpointer.GetByteValue(
transferId,
DataMovementConstants.JobPartPlanFile.AtomicJobStatusIndex,
DataMovementConstants.JobPartPlanFile.AtomicJobStatusStateIndex,
cancellationToken).ConfigureAwait(false);

byte hasFailedItemsByte = await checkpointer.GetByteValue(
transferId,
DataMovementConstants.JobPartPlanFile.AtomicJobStatusHasFailedIndex,
cancellationToken).ConfigureAwait(false);
bool hasFailedItems = Convert.ToBoolean(hasFailedItemsByte);

byte hasSkippedItemsByte = await checkpointer.GetByteValue(
transferId,
DataMovementConstants.JobPartPlanFile.AtomicJobStatusHasSkippedIndex,
cancellationToken).ConfigureAwait(false);
bool hasSkippedItems = Convert.ToBoolean(hasSkippedItemsByte);

// Transfers marked as fully completed are not resumable
return jobStatus != DataTransferStatus.Completed;
return transferState != DataTransferState.Completed || hasFailedItems || hasSkippedItems;
}

internal static async Task<DataTransferProperties> GetDataTransferPropertiesAsync(
Expand Down
57 changes: 57 additions & 0 deletions sdk/storage/Azure.Storage.DataMovement/src/DataTransferState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading;

namespace Azure.Storage.DataMovement
{
/// <summary>
/// Defines the types of the state a transfer can have.
/// </summary>
public enum DataTransferState
{
/// <summary>
/// Default value.
/// </summary>
None = 0,

/// <summary>
/// The transfer has been queued up but has not yet started.
/// </summary>
Queued = 1,

/// <summary>
/// The transfer has started, but has not yet completed.
/// </summary>
InProgress = 2,

/// <summary>
/// The transfer is in progress and is in the process of being paused.
///
/// Transfer can be stopped if <see cref="TransferManager.PauseTransferIfRunningAsync(string, System.Threading.CancellationToken)"/>
/// or <see cref="DataTransfer.PauseAsync(CancellationToken)"/> is called.
/// </summary>
Pausing = 3,

/// <summary>
/// The transfer is in progress and is in the process of being stopped.
///
/// Transfer can be stopped if <see cref="DataTransferErrorMode.StopOnAnyFailure"/> is
/// enabled in the <see cref="TransferManagerOptions.ErrorHandling"/>.
/// </summary>
Stopping = 4,

/// <summary>
/// The transfer has been paused. When transfer is paused
/// (e.g. see <see cref="TransferManager.PauseTransferIfRunningAsync(string, System.Threading.CancellationToken)"/>)
/// during the transfer, this will be the value.
/// </summary>
Paused = 5,

/// <summary>
/// The transfer has come to a completed state. If the transfer has started and
/// has fully stopped will also come to this state.
Comment thread
amnguye marked this conversation as resolved.
/// </summary>
Completed = 6
}
}
118 changes: 91 additions & 27 deletions sdk/storage/Azure.Storage.DataMovement/src/DataTransferStatus.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Runtime.CompilerServices;
using System.Threading;

namespace Azure.Storage.DataMovement
{
/// <summary>
/// Defines the status of the Transfer Job.
/// </summary>
public enum DataTransferStatus
public class DataTransferStatus : IEquatable<DataTransferStatus>
{
private int _hasFailedItemValue;
private int _hasSkippedItemValue;
private int _stateValue;

/// <summary>
/// Default value.
/// Equivalent to <see cref="DataTransferStatus.None"/>.
/// Defines the state of the transfer.
/// </summary>
None = 0,
public DataTransferState State => (DataTransferState)_stateValue;

/// <summary>
/// The Job has been queued up but has not yet begun any transfers.
/// Equivalent to <see cref="DataTransferStatus.Queued"/>.
/// Represents if the transfer has completed successfully without any failure or skipped items.
/// </summary>
Queued = 1,
public bool HasCompletedSuccessfully =>
(State == DataTransferState.Completed) &&
!HasFailedItems &&
!HasSkippedItems;

/// <summary>
/// The Job has started, but has not yet completed.
/// Equivalent to <see cref="DataTransferStatus.InProgress"/>.
/// Represents if transfer has any failure items.
///
/// If set to `true`, the transfer has at least one failure item.
/// If set to `false`, the transfer currently has no failures.
/// </summary>
InProgress = 2,
public bool HasFailedItems => _hasFailedItemValue != 0;

/// <summary>
/// The Job has been paused. When transfer is paused (e.g. see <see cref="TransferManager.PauseTransferIfRunningAsync(string, System.Threading.CancellationToken)"/>) during the transfer,
/// this will be the value.
/// Represents if transfer has any skipped items.
///
/// This status is a resumable state, only
/// transfers that failed will be retried when <see cref="TransferManager.StartTransferAsync(StorageResource, StorageResource, DataTransferOptions, CancellationToken)"/>
/// with the respective transfer ID to resume.
/// If set to `true`, the transfer has at least one item it has skipped.
/// If set to `false`, the transfer currently has no items that has been skipped.
///
/// It's possible to never have any items skipped if
/// <see cref="StorageResourceCreationPreference.SkipIfExists"/> is not enabled in the <see cref="DataTransferOptions.CreationPreference"/>.
/// </summary>
Paused = 3,
public bool HasSkippedItems => _hasSkippedItemValue != 0;

/// <summary>
/// The Job has completed successfully with no failures or skips.
/// Constructor to set the initial state to <see cref="DataTransferState.Queued"/> with no failures or skipped items.
/// </summary>
Completed = 4,
protected internal DataTransferStatus()
{
_stateValue = (int)DataTransferState.Queued;
_hasFailedItemValue = 0; // Initialized to false
_hasSkippedItemValue = 0; // Initialized to false
}

/// <summary>
/// The Job has been completed with at least one skipped transfer.
/// Constructor to have a custom state, failure state, and skipped state.
/// </summary>
CompletedWithSkippedTransfers = 5,
protected internal DataTransferStatus(DataTransferState state, bool hasFailureItems, bool hasSkippedItems)
{
_stateValue = (int)state;
_hasFailedItemValue = hasFailureItems ? 1 : 0;
_hasSkippedItemValue = hasSkippedItems ? 1 : 0;
}

internal bool IsCompletedWithFailedItems => State.Equals(DataTransferState.Completed) && HasFailedItems;
internal bool IsCompletedWithSkippedItems => State.Equals(DataTransferState.Completed) && HasSkippedItems;

/// <summary>
/// The Job has been completed with at least one failed transfer.
/// Accordingly update the <see cref="HasFailedItems"/> to true. If already set to true, nothing will happen.
///
/// This should only be triggered when a failed item has been seen.
/// </summary>
/// <returns>True if <see cref="HasFailedItems"/> was updated. False otherwise.</returns>
internal bool TrySetFailedItem()
{
return Interlocked.Exchange(ref _hasFailedItemValue, 1) != 1;
}

/// <summary>
/// Accordingly update the <see cref="HasSkippedItems"/> to true. If already set to true, nothing will happen.
///
/// This should only be triggered when a skipped item has been seen.
/// </summary>
/// /// <returns>True if <see cref="HasSkippedItems"/> was updated. False otherwise.</returns>
internal bool TrySetSkippedItem()
{
return Interlocked.Exchange(ref _hasSkippedItemValue, 1) != 1;
}

/// <summary>
/// Accordingly update the <see cref="State"/>. If the current State is the same as the parameter,
/// then nothing will happen.
///
/// This should only be triggered when the state updates.
/// </summary>
CompletedWithFailedTransfers = 6,
/// <returns>True if <see cref="State"/> was updated. False otherwise.</returns>
internal bool TrySetTransferStateChange(DataTransferState state)
{
return Interlocked.Exchange(ref _stateValue, (int)state) != (int)state;
}

/// <summary>
/// A pause was called on the transfer job and is in progress.
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
PauseInProgress = 7,
/// <param name="other">An object to compare with this object.</param>
/// <returns>Returns true if the current object is equal to the other parameter; otherwise, false.</returns>
public bool Equals(DataTransferStatus other)
Comment thread
amnguye marked this conversation as resolved.
=> State.Equals(other.State) &&
HasFailedItems.Equals(other.HasFailedItems) &&
HasSkippedItems.Equals(other.HasSkippedItems);

/// <summary>
/// A pause was called on the transfer job and is in progress.
/// Performs a Deep Copy of the <see cref="DataTransferStatus"/>.
/// </summary>
CancellationInProgress = 8,
};
/// <returns>A deep copy of the respective <see cref="DataTransferStatus"/>.</returns>
internal DataTransferStatus DeepCopy()
=> new()
{
_stateValue = _stateValue,
_hasFailedItemValue = _hasFailedItemValue,
_hasSkippedItemValue = _hasSkippedItemValue,
};
}
}
Loading