Skip to content

Commit 7ad9435

Browse files
authored
Fixed bug where DataLakeFileClient.Rename(), DataLakePathClient.Rename(), and DataLakeDirectoryClient.Rename() couldn't handle source paths with special characters (#15106)
1 parent 0eb862d commit 7ad9435

File tree

37 files changed

+6168
-2
lines changed

37 files changed

+6168
-2
lines changed

sdk/storage/Azure.Storage.Files.DataLake/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Fixed bug where DataLakeFileClient.Upload() could not upload read-only files.
66
- Fixed bug where DataLakeBlobAccessPolicy.StartsOn and .ExpiresOn would cause the process to crash.
77
- Added Close and RetainUncommitedData to DataLakeFileUploadOptions.
8+
- Fixed bug where DataLakeDirectoryClient.Rename(), DataLakeFileClient.Rename(), and DataLakeFileClient.Rename() couldn't handle source paths with special characters.
89

910
## 12.4.0 (2020-08-31)
1011
- Fixed bug where DataLakeFileClient.Upload() would deadlock if the content stream's position was not 0.

sdk/storage/Azure.Storage.Files.DataLake/src/DataLakeFileSystemClient.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Metadata = System.Collections.Generic.IDictionary<string, string>;
1414
using System.Text.Json;
1515
using System.Collections.Generic;
16+
using Azure.Storage.Shared;
1617

1718
namespace Azure.Storage.Files.DataLake
1819
{
@@ -1574,7 +1575,7 @@ public virtual async Task<Response<DataLakeDirectoryClient>> CreateDirectoryAsyn
15741575

15751576
DataLakeDirectoryClient directoryClient = GetDirectoryClient(path);
15761577

1577-
Response<PathInfo> response = await GetDirectoryClient(path).CreateAsync(
1578+
Response<PathInfo> response = await directoryClient.CreateAsync(
15781579
httpHeaders,
15791580
metadata,
15801581
permissions,

sdk/storage/Azure.Storage.Files.DataLake/src/DataLakePathClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1604,7 +1604,7 @@ private async Task<Response<DataLakePathClient>> RenameInternal(
16041604
{
16051605
// Build renameSource
16061606
DataLakeUriBuilder sourceUriBuilder = new DataLakeUriBuilder(_dfsUri);
1607-
string renameSource = "/" + sourceUriBuilder.FileSystemName + "/" + sourceUriBuilder.DirectoryOrFilePath;
1607+
string renameSource = "/" + sourceUriBuilder.FileSystemName + "/" + sourceUriBuilder.DirectoryOrFilePath.EscapePath();
16081608

16091609
if (sourceUriBuilder.Sas != null)
16101610
{

sdk/storage/Azure.Storage.Files.DataLake/tests/DirectoryClientTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,53 @@ await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
700700
}
701701
}
702702

703+
[Test]
704+
[TestCase("!'();[]@&%=+$,#äÄöÖüÜß;")]
705+
[TestCase("%21%27%28%29%3B%5B%5D%40%26%25%3D%2B%24%2C%23äÄöÖüÜß%3B")]
706+
[TestCase(" my cool directory ")]
707+
[TestCase("directory")]
708+
public async Task RenameAsync_DestinationSpecialCharacters(string destDirectoryName)
709+
{
710+
await using DisposingFileSystem test = await GetNewFileSystem();
711+
712+
// Arrange
713+
DataLakeDirectoryClient sourceDirectory = await test.FileSystem.CreateDirectoryAsync(GetNewDirectoryName());
714+
Uri expectedDestDirectoryUri = new Uri($"https://{test.FileSystem.AccountName}.dfs.core.windows.net/{test.FileSystem.Name}/{Uri.EscapeDataString(destDirectoryName)}");
715+
716+
// Act
717+
DataLakeDirectoryClient destDirectory = await sourceDirectory.RenameAsync(destinationPath: destDirectoryName);
718+
719+
// Assert
720+
Response<PathProperties> response = await destDirectory.GetPropertiesAsync();
721+
Assert.AreEqual(destDirectoryName, destDirectory.Name);
722+
Assert.AreEqual(destDirectoryName, destDirectory.Path);
723+
Assert.AreEqual(expectedDestDirectoryUri, destDirectory.Uri);
724+
}
725+
726+
[Test]
727+
[TestCase("!'();[]@&%=+$,#äÄöÖüÜß;")]
728+
[TestCase("%21%27%28%29%3B%5B%5D%40%26%25%3D%2B%24%2C%23äÄöÖüÜß%3B")]
729+
[TestCase(" my cool directory ")]
730+
[TestCase("directory")]
731+
public async Task RenameAsync_SourceSpecialCharacters(string sourceDirectoryName)
732+
{
733+
await using DisposingFileSystem test = await GetNewFileSystem();
734+
735+
// Arrange
736+
string destDirectoryName = GetNewDirectoryName();
737+
DataLakeDirectoryClient sourceDirectory = await test.FileSystem.CreateDirectoryAsync(sourceDirectoryName);
738+
Uri expectedDestDirectoryUri = new Uri($"https://{test.FileSystem.AccountName}.dfs.core.windows.net/{test.FileSystem.Name}/{destDirectoryName}");
739+
740+
// Act
741+
DataLakeDirectoryClient destDirectory = await sourceDirectory.RenameAsync(destinationPath: destDirectoryName);
742+
743+
// Assert
744+
Response<PathProperties> response = await destDirectory.GetPropertiesAsync();
745+
Assert.AreEqual(destDirectoryName, destDirectory.Name);
746+
Assert.AreEqual(destDirectoryName, destDirectory.Path);
747+
Assert.AreEqual(expectedDestDirectoryUri, destDirectory.Uri);
748+
}
749+
703750
[Test]
704751
public async Task GetAccessControlAsync()
705752
{

sdk/storage/Azure.Storage.Files.DataLake/tests/FileClientTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,59 @@ await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
681681
}
682682
}
683683

684+
[Test]
685+
[TestCase("!'();[]@&%=+$,#äÄöÖüÜß;")]
686+
[TestCase("%21%27%28%29%3B%5B%5D%40%26%25%3D%2B%24%2C%23äÄöÖüÜß%3B")]
687+
[TestCase(" my cool file ")]
688+
[TestCase("file")]
689+
public async Task RenameAsync_DestinationSpecialCharacters(string destFileName)
690+
{
691+
// Arrange
692+
await using DisposingFileSystem test = await GetNewFileSystem();
693+
string directoryName = GetNewDirectoryName();
694+
DataLakeDirectoryClient directory = InstrumentClient(test.FileSystem.GetDirectoryClient(directoryName));
695+
await directory.CreateAsync();
696+
DataLakeFileClient sourceFile = await test.FileSystem.CreateFileAsync(GetNewFileName());
697+
Uri expectedDestFileUri = new Uri($"https://{test.FileSystem.AccountName}.dfs.core.windows.net/{test.FileSystem.Name}/{directoryName}/{Uri.EscapeDataString(destFileName)}");
698+
string destFilePath = $"{directoryName}/{destFileName}";
699+
700+
// Act
701+
DataLakeFileClient destFile = await sourceFile.RenameAsync(destinationPath: destFilePath);
702+
703+
// Assert
704+
Response<PathProperties> response = await destFile.GetPropertiesAsync();
705+
Assert.AreEqual(destFileName, destFile.Name);
706+
Assert.AreEqual(destFilePath, destFile.Path);
707+
Assert.AreEqual(expectedDestFileUri, destFile.Uri);
708+
}
709+
710+
[Test]
711+
[TestCase("!'();[]@&%=+$,#äÄöÖüÜß;")]
712+
[TestCase("%21%27%28%29%3B%5B%5D%40%26%25%3D%2B%24%2C%23äÄöÖüÜß%3B")]
713+
[TestCase(" my cool file ")]
714+
[TestCase("file")]
715+
public async Task RenameAsync_SourceSpecialCharacters(string sourceFileName)
716+
{
717+
// Arrange
718+
await using DisposingFileSystem test = await GetNewFileSystem();
719+
string directoryName = GetNewDirectoryName();
720+
DataLakeDirectoryClient directory = InstrumentClient(test.FileSystem.GetDirectoryClient(directoryName));
721+
await directory.CreateAsync();
722+
DataLakeFileClient sourceFile = await test.FileSystem.CreateFileAsync(sourceFileName);
723+
string destFileName = GetNewFileName();
724+
Uri expectedDestFileUri = new Uri($"https://{test.FileSystem.AccountName}.dfs.core.windows.net/{test.FileSystem.Name}/{directoryName}/{destFileName}");
725+
string destFilePath = $"{directoryName}/{destFileName}";
726+
727+
// Act
728+
DataLakeFileClient destFile = await sourceFile.RenameAsync(destinationPath: destFilePath);
729+
730+
// Assert
731+
Response<PathProperties> response = await destFile.GetPropertiesAsync();
732+
Assert.AreEqual(destFileName, destFile.Name);
733+
Assert.AreEqual(destFilePath, destFile.Path);
734+
Assert.AreEqual(expectedDestFileUri, destFile.Uri);
735+
}
736+
684737
[Test]
685738
public async Task GetAccessControlAsync()
686739
{

sdk/storage/Azure.Storage.Files.DataLake/tests/SessionRecords/DirectoryClientTests/RenameAsync_DestinationSpecialCharacters(% my cool directory %).json

Lines changed: 174 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)