diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs index dfa95cd1db82..c8b0b1eda0ba 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.net6.0.cs @@ -1,5 +1,11 @@ namespace Azure.Storage.DataMovement.Files.Shares { + public partial class ShareDirectoryClientTransferOptions + { + public ShareDirectoryClientTransferOptions() { } + public Azure.Storage.DataMovement.Files.Shares.ShareFileStorageResourceOptions ShareDirectoryOptions { get { throw null; } set { } } + public Azure.Storage.DataMovement.DataTransferOptions TransferOptions { get { throw null; } set { } } + } public partial class ShareFilesStorageResourceProvider : Azure.Storage.DataMovement.StorageResourceProvider { public ShareFilesStorageResourceProvider() { } @@ -25,3 +31,11 @@ public partial class ShareFileStorageResourceOptions public ShareFileStorageResourceOptions() { } } } +namespace Azure.Storage.Files.Shares +{ + public static partial class ShareDirectoryClientExtensions + { + public static System.Threading.Tasks.Task StartDownloadToDirectoryAsync(this Azure.Storage.Files.Shares.ShareDirectoryClient client, string localDirectoryPath, Azure.Storage.DataMovement.Files.Shares.ShareDirectoryClientTransferOptions options = null) { throw null; } + public static System.Threading.Tasks.Task StartUploadDirectoryAsync(this Azure.Storage.Files.Shares.ShareDirectoryClient client, string localDirectoryPath, Azure.Storage.DataMovement.Files.Shares.ShareDirectoryClientTransferOptions options = null) { throw null; } + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs index dfa95cd1db82..c8b0b1eda0ba 100644 --- a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/api/Azure.Storage.DataMovement.Files.Shares.netstandard2.0.cs @@ -1,5 +1,11 @@ namespace Azure.Storage.DataMovement.Files.Shares { + public partial class ShareDirectoryClientTransferOptions + { + public ShareDirectoryClientTransferOptions() { } + public Azure.Storage.DataMovement.Files.Shares.ShareFileStorageResourceOptions ShareDirectoryOptions { get { throw null; } set { } } + public Azure.Storage.DataMovement.DataTransferOptions TransferOptions { get { throw null; } set { } } + } public partial class ShareFilesStorageResourceProvider : Azure.Storage.DataMovement.StorageResourceProvider { public ShareFilesStorageResourceProvider() { } @@ -25,3 +31,11 @@ public partial class ShareFileStorageResourceOptions public ShareFileStorageResourceOptions() { } } } +namespace Azure.Storage.Files.Shares +{ + public static partial class ShareDirectoryClientExtensions + { + public static System.Threading.Tasks.Task StartDownloadToDirectoryAsync(this Azure.Storage.Files.Shares.ShareDirectoryClient client, string localDirectoryPath, Azure.Storage.DataMovement.Files.Shares.ShareDirectoryClientTransferOptions options = null) { throw null; } + public static System.Threading.Tasks.Task StartUploadDirectoryAsync(this Azure.Storage.Files.Shares.ShareDirectoryClient client, string localDirectoryPath, Azure.Storage.DataMovement.Files.Shares.ShareDirectoryClientTransferOptions options = null) { throw null; } + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientExtensions.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientExtensions.cs new file mode 100644 index 000000000000..d59047129b16 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientExtensions.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.Storage.DataMovement; +using Azure.Storage.DataMovement.Files.Shares; + +namespace Azure.Storage.Files.Shares +{ + /// + /// Data movement extension methods for the . + /// + public static class ShareDirectoryClientExtensions + { + private static Lazy s_defaultTransferManager = new(() => new TransferManager(default)); + private static Lazy s_localFilesProvider = new(); + private static Lazy s_shareFilesProvider = new(); + + /// + /// Uploads the entire contents of local directory to the share directory. + /// + /// + /// The used for service operations. + /// + /// + /// The full path to the local directory to be uploaded. + /// + /// + /// Options which control the directory upload. + /// + /// + /// A instance which can be used track progress and wait for + /// completion with . + /// + public static async Task StartUploadDirectoryAsync( + this ShareDirectoryClient client, + string localDirectoryPath, + ShareDirectoryClientTransferOptions options = default) + { + StorageResource localDirectory = s_localFilesProvider.Value.FromPath(localDirectoryPath); + StorageResource shareDirectory = s_shareFilesProvider.Value.FromClient(client, options?.ShareDirectoryOptions); + + return await s_defaultTransferManager.Value.StartTransferAsync( + localDirectory, shareDirectory, options?.TransferOptions).ConfigureAwait(false); + } + + /// + /// Downloads the contents of a share directory. + /// + /// The used for service operations. + /// The full path to the local directory where files will be dowloaded. + /// Options which control the container download. + /// + public static async Task StartDownloadToDirectoryAsync( + this ShareDirectoryClient client, + string localDirectoryPath, + ShareDirectoryClientTransferOptions options = default) + { + StorageResource localDirectory = s_localFilesProvider.Value.FromPath(localDirectoryPath); + StorageResource shareDirectory = s_shareFilesProvider.Value.FromClient(client, options?.ShareDirectoryOptions); + + return await s_defaultTransferManager.Value.StartTransferAsync( + shareDirectory, localDirectory, options?.TransferOptions).ConfigureAwait(false); + } + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientTransferOptions.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientTransferOptions.cs new file mode 100644 index 000000000000..79a5f36d19df --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/src/ShareDirectoryClientTransferOptions.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Storage.Files.Shares; + +namespace Azure.Storage.DataMovement.Files.Shares +{ + /// + /// Options applying to data transfer uploads and downloads using the extension methods + /// and + /// . + /// + public class ShareDirectoryClientTransferOptions + { + /// + /// Options pertaining to the share file directory used in the data transfer. + /// + public ShareFileStorageResourceOptions ShareDirectoryOptions { get; set; } + + /// + /// Options pertaining to the data tranfer. + /// + public DataTransferOptions TransferOptions { get; set; } + } +} diff --git a/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareDirectoryClientExtensionsTests.cs b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareDirectoryClientExtensionsTests.cs new file mode 100644 index 000000000000..0b0d0f3cd785 --- /dev/null +++ b/sdk/storage/Azure.Storage.DataMovement.Files.Shares/tests/ShareDirectoryClientExtensionsTests.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Azure.Storage.Files.Shares; +using Moq; +using NUnit.Framework; + +namespace Azure.Storage.DataMovement.Files.Shares.Tests +{ + [NonParallelizable] + public class ShareDirectoryClientExtensionsTests + { + private Mock ExtensionMockTransferManager { get; set; } + + // temporarily stores the static value that was in the extensions class + private Lazy _backupTransferManagerValue; + + [SetUp] + public void Setup() + { + ExtensionMockTransferManager = new(); + ExtensionMockTransferManager.Setup(tm => tm.StartTransferAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())); + + _backupTransferManagerValue = (Lazy)typeof(ShareDirectoryClientExtensions) + .GetField("s_defaultTransferManager", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); + typeof(ShareDirectoryClientExtensions) + .GetField("s_defaultTransferManager", BindingFlags.NonPublic | BindingFlags.Static) + .SetValue(null, new Lazy(() => ExtensionMockTransferManager.Object)); + } + + [TearDown] + public void Teardown() + { + typeof(ShareDirectoryClientExtensions) + .GetField("s_defaultTransferManager", BindingFlags.NonPublic | BindingFlags.Static) + .SetValue(null, _backupTransferManagerValue); + } + + [Test] + public async Task StartUploadDirectory([Values(true, false)] bool useOptions) + { + ShareFileStorageResourceOptions storageResourceOptions = new(); + DataTransferOptions dataTransferOptions = new(); + ShareDirectoryClientTransferOptions transferOptions = new() + { + ShareDirectoryOptions = storageResourceOptions, + TransferOptions = dataTransferOptions, + }; + string localPath = Path.GetTempPath(); + Mock clientMock = new(); + + await clientMock.Object.StartUploadDirectoryAsync(localPath, useOptions ? transferOptions : null); + + ExtensionMockTransferManager.Verify(tm => tm.StartTransferAsync( + It.IsAny(), + It.Is(res => res is ShareDirectoryStorageResourceContainer && + (res as ShareDirectoryStorageResourceContainer).ShareDirectoryClient == clientMock.Object && + (res as ShareDirectoryStorageResourceContainer).ResourceOptions == (useOptions ? storageResourceOptions : null)), + useOptions ? dataTransferOptions : null, + default), Times.Once); + ExtensionMockTransferManager.VerifyNoOtherCalls(); + } + + [Test] + public async Task StartDownloadDirectory([Values(true, false)] bool useOptions) + { + ShareFileStorageResourceOptions storageResourceOptions = new(); + DataTransferOptions dataTransferOptions = new(); + ShareDirectoryClientTransferOptions transferOptions = new() + { + ShareDirectoryOptions = storageResourceOptions, + TransferOptions = dataTransferOptions, + }; + string localPath = Path.GetTempPath(); + Mock clientMock = new(); + + await clientMock.Object.StartDownloadToDirectoryAsync(localPath, useOptions ? transferOptions : null); + + ExtensionMockTransferManager.Verify(tm => tm.StartTransferAsync( + It.Is(res => res is ShareDirectoryStorageResourceContainer && + (res as ShareDirectoryStorageResourceContainer).ShareDirectoryClient == clientMock.Object && + (res as ShareDirectoryStorageResourceContainer).ResourceOptions == (useOptions ? storageResourceOptions : null)), + It.IsAny(), + useOptions ? dataTransferOptions : null, + default), Times.Once); + ExtensionMockTransferManager.VerifyNoOtherCalls(); + } + } +}