diff --git a/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 b/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 index 3e2369a4aff6..c68d94969026 100644 --- a/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 +++ b/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 @@ -56,6 +56,7 @@ function Test-File $file = Get-AzStorageFile -ShareName $shareName -Context $storageContext Assert-AreEqual $file.Count 1 Assert-AreEqual $file[0].Name $objectName1 + Assert-NotNull $file[0].ListFileProperties.Properties.ETag if ($Env:OS -eq "Windows_NT") { @@ -65,16 +66,17 @@ function Test-File { Set-AzStorageFileContent -source $localSrcFile -ShareName $shareName -Path $objectName1 -Force -Context $storageContext } - $file = Get-AzStorageFile -ShareName $shareName -Context $storageContext + $file = Get-AzStorageFile -ShareName $shareName -Context $storageContext Assert-AreEqual $file.Count 1 Assert-AreEqual $file[0].Name $objectName1 + Assert-NotNull $file[0].ListFileProperties.Properties.ETag if ($Env:OS -eq "Windows_NT") { $file[0].CloudFile.FetchAttributes() $localFileProperties = Get-ItemProperty $localSrcFile - Assert-AreEqual $localFileProperties.CreationTime.ToUniversalTime().Ticks $file[0].CloudFile.Properties.CreationTime.ToUniversalTime().Ticks - Assert-AreEqual $localFileProperties.LastWriteTime.ToUniversalTime().Ticks $file[0].CloudFile.Properties.LastWriteTime.ToUniversalTime().Ticks - Assert-AreEqual $localFileProperties.Attributes.ToString() $file[0].CloudFile.Properties.NtfsAttributes.ToString() + Assert-AreEqual $localFileProperties.CreationTime.ToUniversalTime().Ticks $file[0].ListFileProperties.Properties.CreatedOn.ToUniversalTime().Ticks + Assert-AreEqual $localFileProperties.LastWriteTime.ToUniversalTime().Ticks $file[0].ListFileProperties.Properties.LastWrittenOn.ToUniversalTime().Ticks + Assert-AreEqual $localFileProperties.Attributes.ToString() $file[0].ListFileProperties.FileAttributes.ToString() } Start-AzStorageFileCopy -SrcShareName $shareName -SrcFilePath $objectName1 -DestShareName $shareName -DestFilePath $objectName2 -Force -Context $storageContext -DestContext $storageContext @@ -103,9 +105,9 @@ function Test-File { $file = Get-AzStorageFile -ShareName $shareName -Path $objectName1 -Context $storageContext $localFileProperties = Get-ItemProperty $localSrcFile - Assert-AreEqual $localFileProperties.CreationTime.ToUniversalTime().Ticks $file[0].CloudFile.Properties.CreationTime.ToUniversalTime().Ticks - Assert-AreEqual $localFileProperties.LastWriteTime.ToUniversalTime().Ticks $file[0].CloudFile.Properties.LastWriteTime.ToUniversalTime().Ticks - Assert-AreEqual $localFileProperties.Attributes.ToString() $file[0].CloudFile.Properties.NtfsAttributes.ToString() + Assert-AreEqual $localFileProperties.CreationTime.ToUniversalTime().Ticks $file[0].FileProperties.SmbProperties.FileCreatedOn.ToUniversalTime().Ticks + Assert-AreEqual $localFileProperties.LastWriteTime.ToUniversalTime().Ticks $file[0].FileProperties.SmbProperties.FileLastWrittenOn.ToUniversalTime().Ticks + Assert-AreEqual $localFileProperties.Attributes.ToString() $file[0].FileProperties.SmbProperties.FileAttributes.ToString() } Remove-AzStorageFile -ShareName $shareName -Path $objectName1 -Context $storageContext @@ -115,12 +117,14 @@ function Test-File $dirName = "filetestdir" New-AzStorageDirectory -ShareName $shareName -Path $dirName -Context $storageContext - $file = Get-AzStorageFile -ShareName $shareName -Context $storageContext + $file = Get-AzStorageShare -Name $shareName -Context $storageContext | Get-AzStorageFile -ExcludeExtendedInfo Assert-AreEqual $file.Count 2 - Assert-AreEqual $file[0].Name $objectName2 - Assert-AreEqual $file[0].GetType().Name "AzureStorageFile" - Assert-AreEqual $file[1].Name $dirName - Assert-AreEqual $file[1].GetType().Name "AzureStorageFileDirectory" + Assert-AreEqual $file[0].Name $dirName + Assert-AreEqual $file[0].GetType().Name "AzureStorageFileDirectory" + Assert-Null $file[0].ListFileProperties.Properties.ETag + Assert-AreEqual $file[1].Name $objectName2 + Assert-AreEqual $file[1].GetType().Name "AzureStorageFile" + Assert-Null $file[1].ListFileProperties.Properties.ETag Get-AzStorageFile -ShareName $shareName -Path $dirName -Context $storageContext | Remove-AzStorageDirectory $file = Get-AzStorageFile -ShareName $shareName -Context $storageContext Assert-AreEqual $file.Count 1 diff --git a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj index 233191c0a2da..e487d11b89d4 100644 --- a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj +++ b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/src/Storage/Storage.Management/ChangeLog.md b/src/Storage/Storage.Management/ChangeLog.md index 6cd4ab3ce0f3..0b14a762243c 100644 --- a/src/Storage/Storage.Management/ChangeLog.md +++ b/src/Storage/Storage.Management/ChangeLog.md @@ -20,6 +20,8 @@ ## Upcoming Release * Show OAuth token in debug log in debug build only - `New-AzStorageContext` +* Supported return more file properties when list Azure file + - `Get-AzStorageFile` ## Version 4.5.0 * Supported DaysAfterLastTierChangeGreaterThan in Management Policy diff --git a/src/Storage/Storage.Management/help/Get-AzStorageFile.md b/src/Storage/Storage.Management/help/Get-AzStorageFile.md index 8c12fdd66c27..afb9b67cecce 100644 --- a/src/Storage/Storage.Management/help/Get-AzStorageFile.md +++ b/src/Storage/Storage.Management/help/Get-AzStorageFile.md @@ -15,23 +15,23 @@ Lists directories and files for a path. ### ShareName (Default) ``` -Get-AzStorageFile [-ShareName] [[-Path] ] [-Context ] +Get-AzStorageFile [-ShareName] [[-Path] ] [-ExcludeExtendedInfo] [-Context ] [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] [-DefaultProfile ] [-ConcurrentTaskCount ] [] ``` ### Share ``` -Get-AzStorageFile [-Share] [[-Path] ] [-ServerTimeoutPerRequest ] - [-ClientTimeoutPerRequest ] [-DefaultProfile ] [-ConcurrentTaskCount ] - [] +Get-AzStorageFile [-Share] [[-Path] ] [-ExcludeExtendedInfo] + [-Context ] [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [] ``` ### Directory ``` -Get-AzStorageFile [-Directory] [[-Path] ] [-ServerTimeoutPerRequest ] - [-ClientTimeoutPerRequest ] [-DefaultProfile ] [-ConcurrentTaskCount ] - [] +Get-AzStorageFile [-Directory] [[-Path] ] [-ExcludeExtendedInfo] + [-Context ] [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [] ``` ## DESCRIPTION @@ -102,7 +102,7 @@ To obtain a Storage context, use the New-AzStorageContext cmdlet. ```yaml Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext -Parameter Sets: ShareName +Parameter Sets: (All) Aliases: Required: False @@ -145,6 +145,21 @@ Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` +### -ExcludeExtendedInfo +Not include extended file info like timestamps, ETag, attributes, permissionKey in list file and Directory. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Path Specifies the path of a folder. If you omit the *Path* parameter, **Get-AzStorageFile** lists the directories and files in the specified file share or directory. @@ -214,7 +229,7 @@ Accept wildcard characters: False ``` ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS diff --git a/src/Storage/Storage/Common/AzureStorageFile.cs b/src/Storage/Storage/Common/AzureStorageFile.cs index 1b54ffdb050a..d5beeec07a94 100644 --- a/src/Storage/Storage/Common/AzureStorageFile.cs +++ b/src/Storage/Storage/Common/AzureStorageFile.cs @@ -22,6 +22,8 @@ namespace Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel using global::Azure.Storage.Files.Shares; using global::Azure.Storage; using Microsoft.WindowsAzure.Commands.Storage.Common; + using global::Azure.Storage.Files.Shares.Models; + using Microsoft.Azure.Storage.Auth; /// /// Azure storage file object @@ -29,14 +31,14 @@ namespace Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel public class AzureStorageFile : AzureStorageBase { /// - /// CloudBlob object + /// File object /// [Ps1Xml(Label = "Share Uri", Target = ViewControl.Table, GroupByThis = true, ScriptBlock = "$_.CloudFile.Share.Uri")] [Ps1Xml(Label = "Name", Target = ViewControl.Table, ScriptBlock = "$_.Name", Position = 0, TableColumnWidth = 20)] public CloudFile CloudFile { get; private set; } /// - /// Blob length + /// File length /// [Ps1Xml(Label = "Length", Target = ViewControl.Table, Position = 1, TableColumnWidth = 15)] public long Length { get; private set; } @@ -56,7 +58,7 @@ public ShareFileClient ShareFileClient { if (privateFileClient == null) { - privateFileClient = GetTrack2FileClient(this.CloudFile, (AzureStorageContext)this.Context); + privateFileClient = GetTrack2FileClient(this.CloudFile, this.shareClientOptions); } return privateFileClient; } @@ -80,20 +82,85 @@ public ShareFileClient ShareFileClient private global::Azure.Storage.Files.Shares.Models.ShareFileProperties privateFileProperties = null; /// - /// Azure storage file constructor + /// XSCL Track2 File List properties + /// + public global::Azure.Storage.Files.Shares.Models.ShareFileItem ListFileProperties { get; private set; } + + + private ShareClientOptions shareClientOptions { get; set; } + + /// + /// Azure storage file constructor from track1 file object /// /// Cloud file object - public AzureStorageFile(CloudFile file, AzureStorageContext storageContext) + public AzureStorageFile(CloudFile file, AzureStorageContext storageContext, ShareClientOptions clientOptions = null) { Name = file.Name; CloudFile = file; Length = file.Properties.Length; LastModified = file.Properties.LastModified; Context = storageContext; + shareClientOptions = clientOptions; + } + + /// + /// Azure storage file constructor from Track2 list file item + /// + /// Cloud file object + public AzureStorageFile(ShareFileClient shareFileClient, AzureStorageContext storageContext, ShareFileItem shareFileItem, ShareClientOptions clientOptions = null) + { + Name = shareFileClient.Name; + this.privateFileClient = shareFileClient; + CloudFile = GetTrack1FileClient(shareFileClient, storageContext.StorageAccount.Credentials); + if (shareFileItem != null) + { + ListFileProperties = shareFileItem; + if (shareFileItem.FileSize != null) + { + Length = shareFileItem.FileSize.Value; + } + if (shareFileItem.Properties != null) + { + LastModified = shareFileItem.Properties.LastModified; + } + } + Context = storageContext; + shareClientOptions = clientOptions; + } + + /// + /// Azure storage file constructor from Track2 get file properties output + /// + /// Cloud file object + public AzureStorageFile(ShareFileClient shareFileClient, AzureStorageContext storageContext, ShareFileProperties shareFileProperties = null, ShareClientOptions clientOptions = null) + { + Name = shareFileClient.Name; + this.privateFileClient = shareFileClient; + CloudFile = GetTrack1FileClient(shareFileClient, storageContext.StorageAccount.Credentials); + if (shareFileProperties != null) + { + privateFileProperties = shareFileProperties; + Length = shareFileProperties.ContentLength; + LastModified = shareFileProperties.LastModified; + } + Context = storageContext; + shareClientOptions = clientOptions; + } + + // Convert Track2 File object to Track 1 file object + public static CloudFile GetTrack1FileClient(ShareFileClient shareFileClient, StorageCredentials credentials) + { + if (credentials.IsSAS) // the Uri already contains credentail. + { + credentials = null; + } + CloudFile track1CloudFile; + track1CloudFile = new CloudFile(shareFileClient.Uri, credentials); + return track1CloudFile; } // Convert Track1 File object to Track 2 file Client - public static ShareFileClient GetTrack2FileClient(CloudFile cloudFile, AzureStorageContext context) + public static ShareFileClient GetTrack2FileClient(CloudFile cloudFile, ShareClientOptions clientOptions = null) { ShareFileClient fileClient; if (cloudFile.ServiceClient.Credentials.IsSAS) //SAS @@ -109,16 +176,16 @@ public static ShareFileClient GetTrack2FileClient(CloudFile cloudFile, AzureStor { fullUri = fullUri + "?" + sas; } - fileClient = new ShareFileClient(new Uri(fullUri)); + fileClient = new ShareFileClient(new Uri(fullUri), clientOptions); } else if (cloudFile.ServiceClient.Credentials.IsSharedKey) //Shared Key { fileClient = new ShareFileClient(cloudFile.SnapshotQualifiedUri, - new StorageSharedKeyCredential(context.StorageAccountName, cloudFile.ServiceClient.Credentials.ExportBase64EncodedKey())); + new StorageSharedKeyCredential(cloudFile.ServiceClient.Credentials.AccountName, cloudFile.ServiceClient.Credentials.ExportBase64EncodedKey()), clientOptions); } else //Anonymous { - fileClient = new ShareFileClient(cloudFile.SnapshotQualifiedUri); + fileClient = new ShareFileClient(cloudFile.SnapshotQualifiedUri, clientOptions); } return fileClient; diff --git a/src/Storage/Storage/Common/AzureStorageFileDirectory.cs b/src/Storage/Storage/Common/AzureStorageFileDirectory.cs index 1a38ac901888..301f4cb85c30 100644 --- a/src/Storage/Storage/Common/AzureStorageFileDirectory.cs +++ b/src/Storage/Storage/Common/AzureStorageFileDirectory.cs @@ -22,6 +22,8 @@ namespace Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel using global::Azure.Storage.Files.Shares; using global::Azure.Storage; using Microsoft.WindowsAzure.Commands.Storage.Common; + using global::Azure.Storage.Files.Shares.Models; + using Microsoft.Azure.Storage.Auth; /// /// Azure storage file object @@ -50,7 +52,7 @@ public ShareDirectoryClient ShareDirectoryClient { if (privateFileDirClient == null) { - privateFileDirClient = GetTrack2FileDirClient(this.CloudFileDirectory, (AzureStorageContext)this.Context); + privateFileDirClient = GetTrack2FileDirClient(this.CloudFileDirectory, shareClientOptions); } return privateFileDirClient; } @@ -73,21 +75,79 @@ public ShareDirectoryClient ShareDirectoryClient } private global::Azure.Storage.Files.Shares.Models.ShareDirectoryProperties privateFileDirProperties = null; + /// + /// XSCL Track2 File List properties + /// + public global::Azure.Storage.Files.Shares.Models.ShareFileItem ListFileProperties { get; private set; } + + private ShareClientOptions shareClientOptions { get; set; } /// /// Azure storage file constructor /// /// Cloud file Directory object - public AzureStorageFileDirectory(CloudFileDirectory dir, AzureStorageContext storageContext) + public AzureStorageFileDirectory(CloudFileDirectory dir, AzureStorageContext storageContext, ShareClientOptions clientOptions = null) { Name = dir.Name; CloudFileDirectory = dir; LastModified = dir.Properties.LastModified; Context = storageContext; + shareClientOptions = clientOptions; + } + + /// + /// Azure storage file constructor from Track2 list file item + /// + /// Cloud file object + public AzureStorageFileDirectory(ShareDirectoryClient shareDirectoryClient, AzureStorageContext storageContext, ShareFileItem shareFileItem, ShareClientOptions clientOptions = null) + { + Name = shareDirectoryClient.Name; + this.privateFileDirClient = shareDirectoryClient; + CloudFileDirectory = GetTrack1FileDirClient(shareDirectoryClient, storageContext.StorageAccount.Credentials); + if (shareFileItem != null) + { + ListFileProperties = shareFileItem; + if (shareFileItem.Properties != null) + { + LastModified = shareFileItem.Properties.LastModified; + } + } + Context = storageContext; + shareClientOptions = clientOptions; + } + + /// + /// Azure storage file constructor from Track2 get file properties output + /// + /// Cloud file object + public AzureStorageFileDirectory(ShareDirectoryClient shareDirectoryClient, AzureStorageContext storageContext, ShareDirectoryProperties shareDirectoryProperties = null, ShareClientOptions clientOptions = null) + { + Name = shareDirectoryClient.Name; + this.privateFileDirClient = shareDirectoryClient; + CloudFileDirectory = GetTrack1FileDirClient(shareDirectoryClient, storageContext.StorageAccount.Credentials); + if (shareDirectoryProperties != null) + { + privateFileDirProperties = shareDirectoryProperties; + LastModified = shareDirectoryProperties.LastModified; + } + Context = storageContext; + shareClientOptions = clientOptions; + } + + // Convert Track2 File Dir object to Track 1 file Dir object + public static CloudFileDirectory GetTrack1FileDirClient(ShareDirectoryClient shareFileDirClient, StorageCredentials credentials) + { + if (credentials.IsSAS) // the Uri already contains credentail. + { + credentials = null; + } + CloudFileDirectory track1CloudFileDir; + track1CloudFileDir = new CloudFileDirectory(shareFileDirClient.Uri, credentials); + return track1CloudFileDir; } // Convert Track1 File Dir object to Track 2 file Dir Client - protected static ShareDirectoryClient GetTrack2FileDirClient(CloudFileDirectory cloudFileDir, AzureStorageContext context) + public static ShareDirectoryClient GetTrack2FileDirClient(CloudFileDirectory cloudFileDir, ShareClientOptions clientOptions = null) { ShareDirectoryClient fileDirClient; if (cloudFileDir.ServiceClient.Credentials.IsSAS) //SAS @@ -103,16 +163,16 @@ protected static ShareDirectoryClient GetTrack2FileDirClient(CloudFileDirectory { fullUri = fullUri + "?" + sas; } - fileDirClient = new ShareDirectoryClient(new Uri(fullUri)); + fileDirClient = new ShareDirectoryClient(new Uri(fullUri), clientOptions); } else if (cloudFileDir.ServiceClient.Credentials.IsSharedKey) //Shared Key { fileDirClient = new ShareDirectoryClient(cloudFileDir.SnapshotQualifiedUri, - new StorageSharedKeyCredential(context.StorageAccountName, cloudFileDir.ServiceClient.Credentials.ExportBase64EncodedKey())); + new StorageSharedKeyCredential(cloudFileDir.ServiceClient.Credentials.AccountName, cloudFileDir.ServiceClient.Credentials.ExportBase64EncodedKey()), clientOptions); } else //Anonymous { - fileDirClient = new ShareDirectoryClient(cloudFileDir.SnapshotQualifiedUri); + fileDirClient = new ShareDirectoryClient(cloudFileDir.SnapshotQualifiedUri, clientOptions); } return fileDirClient; diff --git a/src/Storage/Storage/Common/StorageCloudCmdletBase.cs b/src/Storage/Storage/Common/StorageCloudCmdletBase.cs index 6823d50dc053..1dad80d3515a 100644 --- a/src/Storage/Storage/Common/StorageCloudCmdletBase.cs +++ b/src/Storage/Storage/Common/StorageCloudCmdletBase.cs @@ -268,15 +268,16 @@ public XTable.TableRequestOptions GetTableRequestOptions() /// /// Get cloud storage account /// + /// If fail, set true will output error message, set false will throw exception. /// Storage account - internal AzureStorageContext GetCmdletStorageContext() + internal AzureStorageContext GetCmdletStorageContext(bool outputErrorMessage = true) { - var context = GetCmdletStorageContext(Context); + var context = GetCmdletStorageContext(Context, outputErrorMessage); Context = context; return context; } - internal AzureStorageContext GetCmdletStorageContext(IStorageContext inContext) + internal AzureStorageContext GetCmdletStorageContext(IStorageContext inContext, bool outputErrorMessage = true) { var context = inContext as AzureStorageContext; if (context == null && inContext != null) @@ -308,8 +309,15 @@ internal AzureStorageContext GetCmdletStorageContext(IStorageContext inContext) } catch (Exception e) { - //stop the pipeline if storage account is missed. - WriteTerminatingError(e); + if (outputErrorMessage) + { + //stop the pipeline if storage account is missed. + WriteTerminatingError(e); + } + else + { + throw; + } } //Set the storage context and use it in pipeline diff --git a/src/Storage/Storage/File/AzureStorageFileCmdletBase.cs b/src/Storage/Storage/File/AzureStorageFileCmdletBase.cs index 8a5db8cbe96d..913036166ffa 100644 --- a/src/Storage/Storage/File/AzureStorageFileCmdletBase.cs +++ b/src/Storage/Storage/File/AzureStorageFileCmdletBase.cs @@ -23,16 +23,16 @@ namespace Microsoft.WindowsAzure.Commands.Storage.File using System.Collections.Generic; using System.Management.Automation; using Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel; + using global::Azure.Storage.Files.Shares; + using Microsoft.WindowsAzure.Commands.Common; + using global::Azure.Core; + using global::Azure; + using global::Azure.Storage.Files.Shares.Models; + using System.Linq; + using Microsoft.Azure.Cosmos.Table; public abstract class AzureStorageFileCmdletBase : StorageCloudCmdletBase { - [Parameter( - ValueFromPipeline = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = Constants.ShareNameParameterSetName, - HelpMessage = "Azure Storage Context Object")] - public override IStorageContext Context { get; set; } - protected FileRequestOptions RequestOptions { get @@ -45,14 +45,18 @@ protected override IStorageFileManagement CreateChannel() { if (this.Channel == null || !this.ShareChannel) { - this.Channel = new StorageFileManagement( - this.ParameterSetName == Constants.ShareNameParameterSetName || - this.ParameterSetName.StartsWith("ShareName") || - this.ParameterSetName == Constants.MatchingPrefixParameterSetName || - this.ParameterSetName == Constants.SpecificParameterSetName ? - this.GetCmdletStorageContext() : + try + { + this.Channel = new StorageFileManagement( + this.GetCmdletStorageContext(outputErrorMessage: false) + ); + } + catch (InvalidOperationException) + { + this.Channel = new StorageFileManagement( AzureStorageContext.EmptyContextInstance - ); + ); + } } return this.Channel; @@ -131,6 +135,37 @@ internal void WriteListFileItemObject(long taskId, IStorageFileManagement channe { WriteCloudFileDirectoryeObject(taskId, channel, item as CloudFileDirectory); } - } + } + + public ShareClientOptions ClientOptions + { + get + { + if (clientOptions == null) + { + clientOptions = new ShareClientOptions(); + clientOptions.AddPolicy(new UserAgentPolicy(ApiConstants.UserAgentHeaderValue), HttpPipelinePosition.PerCall); + return clientOptions; + } + else + { + return clientOptions; + } + } + } + private ShareClientOptions clientOptions = null; + + public static AzureStorageContext GetStorageContextFromTrack1FileServiceClient(CloudFileClient fileServiceClient, IAzureContext DefaultContext = null) + { + Microsoft.Azure.Storage.CloudStorageAccount account = new Microsoft.Azure.Storage.CloudStorageAccount( + fileServiceClient.Credentials, + null, //blob Uri + null, //queue Uri + null, //talbe Uri + fileServiceClient.BaseUri); //file Uri + return new AzureStorageContext(account, + fileServiceClient.Credentials.AccountName, + DefaultContext); + } } } diff --git a/src/Storage/Storage/File/Cmdlet/GetAzureStorageFile.cs b/src/Storage/Storage/File/Cmdlet/GetAzureStorageFile.cs index 537efb63f4d9..4c3b26fb81c7 100644 --- a/src/Storage/Storage/File/Cmdlet/GetAzureStorageFile.cs +++ b/src/Storage/Storage/File/Cmdlet/GetAzureStorageFile.cs @@ -14,17 +14,15 @@ namespace Microsoft.WindowsAzure.Commands.Storage.File.Cmdlet { - using Microsoft.Azure.Storage; + using global::Azure; + using global::Azure.Storage.Files.Shares; + using global::Azure.Storage.Files.Shares.Models; using Microsoft.Azure.Storage.File; - using Microsoft.WindowsAzure.Commands.Common.CustomAttributes; using Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel; + using System.Collections.Generic; using System.Globalization; using System.Management.Automation; - using System.Net; - [GenericBreakingChange("The cmdlet might run slower in a furture release since more file properties will be returned. Add parameter '-ExcludeExtendedInfo' to get same performance as before. " + - "The returned file properties will be moved from CloudFile to FileProperties (with '-Path'), ListFileProperties (without '-Path'). " + - "The returned Directory properties will be moved from CloudFileDirectory to ShareDirectoryProperties (with '-Path'), ListFileProperties (without '-Path').")] [Cmdlet("Get", Azure.Commands.ResourceManager.Common.AzureRMConstants.AzurePrefix + "StorageFile", DefaultParameterSetName = Constants.ShareNameParameterSetName)] [OutputType(typeof(AzureStorageFile))] public class GetAzureStorageFile : AzureStorageFileCmdletBase @@ -64,6 +62,10 @@ public class GetAzureStorageFile : AzureStorageFileCmdletBase HelpMessage = "Path to an existing file/directory.")] public string Path { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Not include extended file info like timestamps, ETag, attributes, permissionKey in list file and Directory.")] + public SwitchParameter ExcludeExtendedInfo { get; set; } + public override void ExecuteCmdlet() { CloudFileDirectory baseDirectory; @@ -85,64 +87,71 @@ public override void ExecuteCmdlet() throw new PSArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid parameter set name: {0}", this.ParameterSetName)); } - if (string.IsNullOrEmpty(this.Path)) + // when only track1 object input, will miss storage context, so need to build storage context for prepare the output object. + if (this.Context == null) { - this.RunTask(async (taskId) => - { - await this.Channel.EnumerateFilesAndDirectoriesAsync( - baseDirectory, - item => this.WriteListFileItemObject(taskId, this.Channel, item), - this.RequestOptions, - this.OperationContext, - this.CmdletCancellationToken).ConfigureAwait(false); - }); + this.Context = GetStorageContextFromTrack1FileServiceClient(baseDirectory.ServiceClient, DefaultContext); } - else + + ShareDirectoryClient baseDirClient = AzureStorageFileDirectory.GetTrack2FileDirClient(baseDirectory, ClientOptions); + + if (string.IsNullOrEmpty(this.Path)) { - this.RunTask(async (taskId) => + ShareDirectoryGetFilesAndDirectoriesOptions listFileOptions = new ShareDirectoryGetFilesAndDirectoriesOptions(); + if (!this.ExcludeExtendedInfo.IsPresent) { - bool foundAFolder = true; - string[] subfolders = NamingUtil.ValidatePath(this.Path); - CloudFileDirectory targetDir = baseDirectory.GetDirectoryReferenceByPath(subfolders); - - try - { - await this.Channel.FetchDirectoryAttributesAsync( - targetDir, - null, - this.RequestOptions, - this.OperationContext, - this.CmdletCancellationToken).ConfigureAwait(false); - } - catch (StorageException se) + listFileOptions.Traits = ShareFileTraits.All; + listFileOptions.IncludeExtendedInfo = true; + } + Pageable fileItems = baseDirClient.GetFilesAndDirectories(listFileOptions, this.CmdletCancellationToken); + IEnumerable> fileitempages = fileItems.AsPages(); + foreach (var page in fileitempages) + { + foreach (var file in page.Values) { - if (null == se.RequestInformation - || (int)HttpStatusCode.NotFound != se.RequestInformation.HttpStatusCode) + if (!file.IsDirectory) // is file { - throw; + ShareFileClient shareFileClient = baseDirClient.GetFileClient(file.Name); + WriteObject(new AzureStorageFile(shareFileClient, (AzureStorageContext)this.Context, file, ClientOptions)); + } + else // Dir + { + ShareDirectoryClient shareDirClient = baseDirClient.GetSubdirectoryClient(file.Name); + WriteObject(new AzureStorageFileDirectory(shareDirClient, (AzureStorageContext)this.Context, file, ClientOptions)); } - foundAFolder = false; } + } + } + else + { + if (ExcludeExtendedInfo.IsPresent) + { + WriteWarning("'-ExcludeExtendedInfo' will be omit, it only works when list file and directory without '-Path'."); + } + bool foundAFolder = true; + ShareDirectoryClient targetDir = baseDirClient.GetSubdirectoryClient(this.Path); + ShareDirectoryProperties dirProperties = null; - if (foundAFolder) - { - WriteCloudFileDirectoryeObject(taskId, this.Channel, targetDir); - return; - } + try + { + dirProperties = targetDir.GetProperties(this.CmdletCancellationToken).Value; + } + catch (global::Azure.RequestFailedException e) when (e.Status == 404) + { + foundAFolder = false; + } - string[] filePath = NamingUtil.ValidatePath(this.Path, true); - CloudFile targetFile = baseDirectory.GetFileReferenceByPath(filePath); + if (foundAFolder) + { + WriteObject(new AzureStorageFileDirectory(targetDir, (AzureStorageContext)this.Context, dirProperties)); + return; + } - await this.Channel.FetchFileAttributesAsync( - targetFile, - null, - this.RequestOptions, - this.OperationContext, - this.CmdletCancellationToken).ConfigureAwait(false); + ShareFileClient targetFile = baseDirClient.GetFileClient(this.Path); + ShareFileProperties fileProperties = targetFile.GetProperties(this.CmdletCancellationToken).Value; - WriteCloudFileObject(taskId, this.Channel, targetFile); - }); + WriteObject(new AzureStorageFile(targetFile, (AzureStorageContext)this.Context, fileProperties, ClientOptions)); } } } diff --git a/src/Storage/Storage/File/Cmdlet/SetAzureStorageFileContent.cs b/src/Storage/Storage/File/Cmdlet/SetAzureStorageFileContent.cs index 960e1b3db701..d082fdc22ec4 100644 --- a/src/Storage/Storage/File/Cmdlet/SetAzureStorageFileContent.cs +++ b/src/Storage/Storage/File/Cmdlet/SetAzureStorageFileContent.cs @@ -165,7 +165,7 @@ await DataMovementTransferHelper.DoTransfer(() => else // use Track2 SDK { //Create File - ShareFileClient fileClient = AzureStorageFile.GetTrack2FileClient(cloudFileToBeUploaded, Channel.StorageContext); + ShareFileClient fileClient = AzureStorageFile.GetTrack2FileClient(cloudFileToBeUploaded, ClientOptions); // confirm overwrite if file exist if(!this.Force.IsPresent && diff --git a/src/Storage/Storage/Storage.csproj b/src/Storage/Storage/Storage.csproj index f36e42c3eff6..40dcb9c26faa 100644 --- a/src/Storage/Storage/Storage.csproj +++ b/src/Storage/Storage/Storage.csproj @@ -13,10 +13,10 @@ - - - - + + + +