Refine rename functions in datalake (#1493)
* Refine rename functions in datalake * Changed default mode to Legacy * remove mode. * Make rename return clients. * Remove continuation token * Resolve merge issue.
This commit is contained in:
parent
ec9d35ae8c
commit
d99f3ab8e6
@ -34,6 +34,9 @@
|
||||
- Changed all previous `LeaseDuration` members to a new type named `LeaseDurationType`.
|
||||
- `startsOn` parameter for `GetUserDelegationKey` was changed to optional.
|
||||
- Removed `PreviousContinuationToken` from `ListFileSystemsSinglePageResult`.
|
||||
- Removed `Rename` from `DataLakeDirectoryClient` and `DataLakeFileClient`. Instead, added `RenameFile` and `RenameSubdirectory` to `DataLakeDirectoryClient` and added `RenameFile` and `RenameDirectory` to `DataLakeFileSystemClient`.
|
||||
- Rename APIs now return the client of the resource it is renaming to.
|
||||
- Removed `Mode` for rename operations' options, that originally controls the rename mode. Now it is fixed to legacy mode.
|
||||
- Changed `SetAccessControlRecursive` to `SetAccessControlRecursiveListSinglePage`, to mark that it is a single page operation, and removed the `mode` parameter, separated the modify/delete functionality to two new APIs.
|
||||
- Moved `SetAccessControlRecursiveListSinglePage` to `DataLakePathClient`.
|
||||
- Changed `MaxRecord` to `MaxEntries`, `ForceFlag` to `ContinueOnFailure` to be more accurate names.
|
||||
|
||||
@ -116,20 +116,34 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Renames a directory. By default, the destination is overwritten and
|
||||
* @brief Renames a file. By default, the destination is overwritten and
|
||||
* if the destination already exists and has a lease the lease is broken.
|
||||
* @param destinationDirectoryPath The destinationPath this current directory is renaming to.
|
||||
* @param options Optional parameters to rename a resource to the resource the destination
|
||||
* directory points to.
|
||||
* @return Azure::Core::Response<Models::RenameDataLakeDirectoryResult> containing the
|
||||
* information returned when renaming the directory.
|
||||
* @remark This operation will not change the URL this directory client points too, to use the
|
||||
* new name, customer needs to initialize a new directory client with the new name/path.
|
||||
* @param fileName The file that gets renamed.
|
||||
* @param destinationFilePath The path of the file the source file is renaming to.
|
||||
* @param options Optional parameters to rename a file.
|
||||
* @return Azure::Core::Response<DataLakeFileClient> The client targets the renamed file.
|
||||
* @remark This request is sent to dfs endpoint.
|
||||
*/
|
||||
Azure::Core::Response<Models::RenameDataLakeDirectoryResult> Rename(
|
||||
Azure::Core::Response<DataLakeFileClient> RenameFile(
|
||||
const std::string& fileName,
|
||||
const std::string& destinationFilePath,
|
||||
const RenameDataLakeFileOptions& options = RenameDataLakeFileOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Renames a directory. By default, the destination is overwritten and
|
||||
* if the destination already exists and has a lease the lease is broken.
|
||||
* @param subdirectoryName The subdirectory that gets renamed.
|
||||
* @param destinationDirectoryPath The destinationPath the source subdirectory is renaming to.
|
||||
* @param options Optional parameters to rename a directory.
|
||||
* @return Azure::Core::Response<DataLakeDirectoryClient> The client targets the renamed
|
||||
* directory.
|
||||
* @remark This request is sent to dfs endpoint.
|
||||
*/
|
||||
Azure::Core::Response<DataLakeDirectoryClient> RenameSubdirectory(
|
||||
const std::string& subdirectoryName,
|
||||
const std::string& destinationDirectoryPath,
|
||||
const RenameDataLakeDirectoryOptions& options = RenameDataLakeDirectoryOptions()) const;
|
||||
const RenameDataLakeSubdirectoryOptions& options
|
||||
= RenameDataLakeSubdirectoryOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Deletes the directory.
|
||||
|
||||
@ -142,22 +142,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
return DataLakePathClient::CreateIfNotExists(Models::PathResourceType::File, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Renames a file. By default, the destination is overwritten and
|
||||
* if the destination already exists and has a lease the lease is broken.
|
||||
* @param destinationFilePath The path of the file this file is renaming to.
|
||||
* @param options Optional parameters to rename a resource to the resource the destination path
|
||||
* points to.
|
||||
* @return Azure::Core::Response<Models::RenameDataLakeDataLakeFileResult> containing the
|
||||
* information returned when renaming the file.
|
||||
* @remark This operation will not change the URL this file client points too, to use the
|
||||
* new name, customer needs to initialize a new file client with the new name/path.
|
||||
* @remark This request is sent to dfs endpoint.
|
||||
*/
|
||||
Azure::Core::Response<Models::RenameDataLakeFileResult> Rename(
|
||||
const std::string& destinationFilePath,
|
||||
const RenameDataLakeFileOptions& options = RenameDataLakeFileOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Deletes the file.
|
||||
* @param options Optional parameters to delete the file the path points to.
|
||||
|
||||
@ -201,6 +201,35 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
const SetDataLakeFileSystemAccessPolicyOptions& options
|
||||
= SetDataLakeFileSystemAccessPolicyOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Renames a file. By default, the destination is overwritten and
|
||||
* if the destination already exists and has a lease the lease is broken.
|
||||
* @param fileName The file that gets renamed.
|
||||
* @param destinationFilePath The path of the file the source file is renaming to.
|
||||
* @param options Optional parameters to rename a file
|
||||
* @return Azure::Core::Response<DataLakeFileClient> The client targets the renamed file.
|
||||
* @remark This request is sent to dfs endpoint.
|
||||
*/
|
||||
Azure::Core::Response<DataLakeFileClient> RenameFile(
|
||||
const std::string& fileName,
|
||||
const std::string& destinationFilePath,
|
||||
const RenameDataLakeFileOptions& options = RenameDataLakeFileOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Renames a directory. By default, the destination is overwritten and
|
||||
* if the destination already exists and has a lease the lease is broken.
|
||||
* @param directoryName The directory that gets renamed.
|
||||
* @param destinationDirectoryPath The destinationPath the source directory is renaming to.
|
||||
* @param options Optional parameters to rename a directory.
|
||||
* @return Azure::Core::Response<DataLakeDirectoryClient> The client targets the renamed
|
||||
* directory.
|
||||
* @remark This request is sent to dfs endpoint.
|
||||
*/
|
||||
Azure::Core::Response<DataLakeDirectoryClient> RenameDirectory(
|
||||
const std::string& directoryName,
|
||||
const std::string& destinationDirectoryPath,
|
||||
const RenameDataLakeDirectoryOptions& options = RenameDataLakeDirectoryOptions()) const;
|
||||
|
||||
private:
|
||||
Azure::Core::Http::Url m_dfsUrl;
|
||||
Blobs::BlobContainerClient m_blobContainerClient;
|
||||
|
||||
@ -258,6 +258,36 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
FileSystemAccessConditions AccessConditions;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for DataLakeFileSystemClient::RenameDirectory
|
||||
* @remark Some optional parameter is mandatory in certain combination.
|
||||
* More details:
|
||||
* https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create
|
||||
*/
|
||||
struct RenameDataLakeDirectoryOptions
|
||||
{
|
||||
/**
|
||||
* @brief Context for cancelling long running operations.
|
||||
*/
|
||||
Azure::Core::Context Context;
|
||||
|
||||
/**
|
||||
* @brief If not specified, the source's file system is used. Otherwise, rename to destination
|
||||
* file system.
|
||||
*/
|
||||
Azure::Core::Nullable<std::string> DestinationFileSystem;
|
||||
|
||||
/**
|
||||
* @brief Specify the access condition for the path.
|
||||
*/
|
||||
PathAccessConditions AccessConditions;
|
||||
|
||||
/**
|
||||
* @brief The access condition for source path.
|
||||
*/
|
||||
PathAccessConditions SourceAccessConditions;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for PathClient::Append
|
||||
*/
|
||||
@ -585,13 +615,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
*/
|
||||
Azure::Core::Context Context;
|
||||
|
||||
/**
|
||||
* @brief This parameter determines the behavior of the rename operation. The value must be
|
||||
* PathRenameMode::Legacy or PathRenameMode::Posix, and the default value will be
|
||||
* PathRenameMode::Posix.
|
||||
*/
|
||||
Models::PathRenameMode Mode = Models::PathRenameMode::Posix;
|
||||
|
||||
/**
|
||||
* @brief If not specified, the source's file system is used. Otherwise, rename to destination
|
||||
* file system.
|
||||
@ -625,51 +648,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
PathAccessConditions AccessConditions;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for PathClient::Create
|
||||
* @remark Some optional parameter is mandatory in certain combination.
|
||||
* More details:
|
||||
* https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create
|
||||
*/
|
||||
struct RenameDataLakeDirectoryOptions
|
||||
{
|
||||
/**
|
||||
* @brief Context for cancelling long running operations.
|
||||
*/
|
||||
Azure::Core::Context Context;
|
||||
|
||||
/**
|
||||
* @brief When renaming a directory, the number of paths that are renamed with each
|
||||
* invocation is limited. If the number of paths to be renamed exceeds this limit,
|
||||
* a continuation token is returned in this response header. When a continuation token
|
||||
* is returned in the response, it must be specified in a subsequent invocation of the
|
||||
* rename operation to continue renaming the directory.
|
||||
*/
|
||||
Azure::Core::Nullable<std::string> ContinuationToken;
|
||||
|
||||
/**
|
||||
* @brief This parameter determines the behavior of the rename operation. The value must be
|
||||
* PathRenameMode::Legacy or PathRenameMode::Posix, and the default value will be
|
||||
* PathRenameMode::Posix.
|
||||
*/
|
||||
Models::PathRenameMode Mode = Models::PathRenameMode::Posix;
|
||||
|
||||
/**
|
||||
* @brief If not specified, the source's file system is used. Otherwise, rename to destination
|
||||
* file system.
|
||||
*/
|
||||
Azure::Core::Nullable<std::string> DestinationFileSystem;
|
||||
|
||||
/**
|
||||
* @brief Specify the access condition for the path.
|
||||
*/
|
||||
PathAccessConditions AccessConditions;
|
||||
|
||||
/**
|
||||
* @brief The access condition for source path.
|
||||
*/
|
||||
PathAccessConditions SourceAccessConditions;
|
||||
};
|
||||
using RenameDataLakeSubdirectoryOptions = RenameDataLakeDirectoryOptions;
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for DirectoryClient::Delete
|
||||
|
||||
@ -227,11 +227,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam
|
||||
std::string RequestId;
|
||||
};
|
||||
|
||||
struct RenameDataLakeFileResult
|
||||
{
|
||||
std::string RequestId;
|
||||
};
|
||||
|
||||
struct DeleteDataLakeFileResult
|
||||
{
|
||||
bool Deleted = true;
|
||||
|
||||
@ -333,7 +333,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
Azure::Core::Nullable<std::string> ETag;
|
||||
Azure::Core::Nullable<Core::DateTime> LastModified;
|
||||
std::string RequestId;
|
||||
Azure::Core::Nullable<std::string> ContinuationToken;
|
||||
Azure::Core::Nullable<int64_t> ContentLength;
|
||||
};
|
||||
|
||||
@ -1183,11 +1182,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
Core::DateTime::DateFormat::Rfc1123);
|
||||
}
|
||||
result.RequestId = response.GetHeaders().at(Details::HeaderRequestId);
|
||||
if (response.GetHeaders().find(Details::HeaderContinuationToken)
|
||||
!= response.GetHeaders().end())
|
||||
{
|
||||
result.ContinuationToken = response.GetHeaders().at(Details::HeaderContinuationToken);
|
||||
}
|
||||
if (response.GetHeaders().find(Details::HeaderContentLength)
|
||||
!= response.GetHeaders().end())
|
||||
{
|
||||
|
||||
@ -147,9 +147,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
return DataLakeDirectoryClient(std::move(builder), std::move(blobClient), m_pipeline);
|
||||
}
|
||||
|
||||
Azure::Core::Response<Models::RenameDataLakeDirectoryResult> DataLakeDirectoryClient::Rename(
|
||||
const std::string& destinationPath,
|
||||
const RenameDataLakeDirectoryOptions& options) const
|
||||
Azure::Core::Response<DataLakeFileClient> DataLakeDirectoryClient::RenameFile(
|
||||
const std::string& fileName,
|
||||
const std::string& destinationFilePath,
|
||||
const RenameDataLakeFileOptions& options) const
|
||||
{
|
||||
Azure::Core::Nullable<std::string> destinationFileSystem = options.DestinationFileSystem;
|
||||
if (!destinationFileSystem.HasValue() || destinationFileSystem.GetValue().empty())
|
||||
@ -159,11 +160,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
destinationFileSystem = Details::GetSubstringTillDelimiter('/', currentPath, cur);
|
||||
}
|
||||
auto destinationDfsUri = m_dfsUrl;
|
||||
destinationDfsUri.SetPath(destinationFileSystem.GetValue() + '/' + destinationPath);
|
||||
destinationDfsUri.SetPath(
|
||||
destinationFileSystem.GetValue() + '/'
|
||||
+ Storage::Details::UrlEncodePath(destinationFilePath));
|
||||
|
||||
Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.ContinuationToken = options.ContinuationToken;
|
||||
protocolLayerOptions.Mode = options.Mode;
|
||||
protocolLayerOptions.Mode = Models::PathRenameMode::Legacy;
|
||||
protocolLayerOptions.SourceLeaseId = options.SourceAccessConditions.LeaseId;
|
||||
protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId;
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
@ -174,15 +176,65 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.RenameSource = "/" + m_dfsUrl.GetPath();
|
||||
protocolLayerOptions.RenameSource
|
||||
= "/" + m_dfsUrl.GetPath() + Storage::Details::UrlEncodePath(fileName);
|
||||
auto result = Details::DataLakeRestClient::Path::Create(
|
||||
destinationDfsUri, *m_pipeline, options.Context, protocolLayerOptions);
|
||||
// At this point, there is not more exception thrown, meaning the rename is successful.
|
||||
Models::RenameDataLakeDirectoryResult ret;
|
||||
ret.ContinuationToken = std::move(result->ContinuationToken);
|
||||
ret.RequestId = std::move(result->RequestId);
|
||||
return Azure::Core::Response<Models::RenameDataLakeDirectoryResult>(
|
||||
std::move(ret), result.ExtractRawResponse());
|
||||
// Initialize the file client.
|
||||
auto blobClient = m_blobClient;
|
||||
blobClient.m_blobUrl.SetPath(destinationDfsUri.GetPath());
|
||||
auto blockBlobClient = blobClient.AsBlockBlobClient();
|
||||
auto renamedFileClient = DataLakeFileClient(
|
||||
std::move(destinationDfsUri),
|
||||
std::move(blobClient),
|
||||
std::move(blockBlobClient),
|
||||
m_pipeline);
|
||||
return Azure::Core::Response<DataLakeFileClient>(
|
||||
std::move(renamedFileClient), result.ExtractRawResponse());
|
||||
}
|
||||
|
||||
Azure::Core::Response<DataLakeDirectoryClient> DataLakeDirectoryClient::RenameSubdirectory(
|
||||
const std::string& subdirectoryName,
|
||||
const std::string& destinationDirectoryPath,
|
||||
const RenameDataLakeSubdirectoryOptions& options) const
|
||||
{
|
||||
Azure::Core::Nullable<std::string> destinationFileSystem = options.DestinationFileSystem;
|
||||
if (!destinationFileSystem.HasValue() || destinationFileSystem.GetValue().empty())
|
||||
{
|
||||
const auto& currentPath = m_dfsUrl.GetPath();
|
||||
std::string::const_iterator cur = currentPath.begin();
|
||||
destinationFileSystem = Details::GetSubstringTillDelimiter('/', currentPath, cur);
|
||||
}
|
||||
auto destinationDfsUri = m_dfsUrl;
|
||||
destinationDfsUri.SetPath(
|
||||
destinationFileSystem.GetValue() + '/'
|
||||
+ Storage::Details::UrlEncodePath(destinationDirectoryPath));
|
||||
|
||||
Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Mode = Models::PathRenameMode::Legacy;
|
||||
protocolLayerOptions.SourceLeaseId = options.SourceAccessConditions.LeaseId;
|
||||
protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId;
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.SourceIfMatch = options.SourceAccessConditions.IfMatch;
|
||||
protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.RenameSource
|
||||
= "/" + m_dfsUrl.GetPath() + Storage::Details::UrlEncodePath(subdirectoryName);
|
||||
auto result = Details::DataLakeRestClient::Path::Create(
|
||||
destinationDfsUri, *m_pipeline, options.Context, protocolLayerOptions);
|
||||
// At this point, there is not more exception thrown, meaning the rename is successful.
|
||||
// Initialize the directory client.
|
||||
auto blobClient = m_blobClient;
|
||||
blobClient.m_blobUrl.SetPath(destinationDfsUri.GetPath());
|
||||
auto renamedDirectoryClient
|
||||
= DataLakeDirectoryClient(std::move(destinationDfsUri), std::move(blobClient), m_pipeline);
|
||||
return Azure::Core::Response<DataLakeDirectoryClient>(
|
||||
std::move(renamedDirectoryClient), result.ExtractRawResponse());
|
||||
}
|
||||
|
||||
Azure::Core::Response<Models::DeleteDataLakeDirectoryResult> DataLakeDirectoryClient::Delete(
|
||||
|
||||
@ -250,42 +250,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
m_dfsUrl, *m_pipeline, options.Context, protocolLayerOptions);
|
||||
}
|
||||
|
||||
Azure::Core::Response<Models::RenameDataLakeFileResult> DataLakeFileClient::Rename(
|
||||
const std::string& destinationPath,
|
||||
const RenameDataLakeFileOptions& options) const
|
||||
{
|
||||
Azure::Core::Nullable<std::string> destinationFileSystem = options.DestinationFileSystem;
|
||||
if (!destinationFileSystem.HasValue() || destinationFileSystem.GetValue().empty())
|
||||
{
|
||||
const auto& currentPath = m_dfsUrl.GetPath();
|
||||
std::string::const_iterator cur = currentPath.begin();
|
||||
destinationFileSystem = Details::GetSubstringTillDelimiter('/', currentPath, cur);
|
||||
}
|
||||
auto destinationDfsUri = m_dfsUrl;
|
||||
destinationDfsUri.SetPath(destinationFileSystem.GetValue() + '/' + destinationPath);
|
||||
|
||||
Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Mode = options.Mode;
|
||||
protocolLayerOptions.SourceLeaseId = options.SourceAccessConditions.LeaseId;
|
||||
protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId;
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.SourceIfMatch = options.SourceAccessConditions.IfMatch;
|
||||
protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.RenameSource = "/" + m_dfsUrl.GetPath();
|
||||
auto result = Details::DataLakeRestClient::Path::Create(
|
||||
destinationDfsUri, *m_pipeline, options.Context, protocolLayerOptions);
|
||||
// At this point, there is not more exception thrown, meaning the rename is successful.
|
||||
Models::RenameDataLakeFileResult ret;
|
||||
ret.RequestId = std::move(result->RequestId);
|
||||
return Azure::Core::Response<Models::RenameDataLakeFileResult>(
|
||||
std::move(ret), result.ExtractRawResponse());
|
||||
}
|
||||
|
||||
Azure::Core::Response<Models::DeleteDataLakeFileResult> DataLakeFileClient::Delete(
|
||||
const DeleteDataLakeFileOptions& options) const
|
||||
{
|
||||
|
||||
@ -395,4 +395,21 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
|
||||
std::move(ret), result.ExtractRawResponse());
|
||||
}
|
||||
|
||||
Azure::Core::Response<DataLakeFileClient> DataLakeFileSystemClient::RenameFile(
|
||||
const std::string& fileName,
|
||||
const std::string& destinationFilePath,
|
||||
const RenameDataLakeFileOptions& options) const
|
||||
{
|
||||
return this->GetDirectoryClient("").RenameFile(fileName, destinationFilePath, options);
|
||||
}
|
||||
|
||||
Azure::Core::Response<DataLakeDirectoryClient> DataLakeFileSystemClient::RenameDirectory(
|
||||
const std::string& directoryName,
|
||||
const std::string& destinationDirectoryPath,
|
||||
const RenameDataLakeDirectoryOptions& options) const
|
||||
{
|
||||
return this->GetDirectoryClient("").RenameSubdirectory(
|
||||
directoryName, destinationDirectoryPath, options);
|
||||
}
|
||||
|
||||
}}}} // namespace Azure::Storage::Files::DataLake
|
||||
|
||||
@ -140,20 +140,20 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
EXPECT_NO_THROW(client.Create());
|
||||
directoryClients.emplace_back(std::move(client));
|
||||
}
|
||||
std::vector<std::string> newPaths;
|
||||
std::vector<Files::DataLake::DataLakeDirectoryClient> newDirectoryClients;
|
||||
for (auto& client : directoryClients)
|
||||
{
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath));
|
||||
newPaths.push_back(newPath);
|
||||
EXPECT_NO_THROW(newDirectoryClients.emplace_back(
|
||||
client.RenameSubdirectory("", newPath).ExtractValue()));
|
||||
}
|
||||
for (const auto& client : directoryClients)
|
||||
{
|
||||
EXPECT_THROW(client.Delete(false), StorageException);
|
||||
}
|
||||
for (const auto& newPath : newPaths)
|
||||
for (const auto& client : newDirectoryClients)
|
||||
{
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
EXPECT_NO_THROW(client.Delete(false));
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -171,12 +171,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
Files::DataLake::RenameDataLakeDirectoryOptions options1;
|
||||
options1.SourceAccessConditions.IfModifiedSince = response->LastModified;
|
||||
EXPECT_TRUE(IsValidTime(response->LastModified));
|
||||
EXPECT_THROW(client.Rename(RandomString(), options1), StorageException);
|
||||
EXPECT_THROW(client.RenameSubdirectory("", RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeDirectoryOptions options2;
|
||||
options2.SourceAccessConditions.IfUnmodifiedSince = response->LastModified;
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options2));
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
EXPECT_NO_THROW(
|
||||
client.RenameSubdirectory("", newPath, options2).ExtractValue().Delete(false));
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -193,12 +193,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
auto response = client.GetProperties();
|
||||
Files::DataLake::RenameDataLakeDirectoryOptions options1;
|
||||
options1.SourceAccessConditions.IfNoneMatch = response->ETag;
|
||||
EXPECT_THROW(client.Rename(RandomString(), options1), StorageException);
|
||||
EXPECT_THROW(client.RenameSubdirectory("", RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeDirectoryOptions options2;
|
||||
options2.SourceAccessConditions.IfMatch = response->ETag;
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options2));
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
EXPECT_NO_THROW(
|
||||
client.RenameSubdirectory("", newPath, options2).ExtractValue().Delete(false));
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -216,7 +216,7 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
options.DestinationFileSystem = LowercaseRandomString();
|
||||
for (auto& client : directoryClient)
|
||||
{
|
||||
EXPECT_THROW(client.Rename(RandomString(), options), StorageException);
|
||||
EXPECT_THROW(client.RenameSubdirectory("", RandomString(), options), StorageException);
|
||||
EXPECT_NO_THROW(client.GetProperties());
|
||||
}
|
||||
}
|
||||
@ -232,8 +232,8 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
for (auto& client : directoryClient)
|
||||
{
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options));
|
||||
EXPECT_NO_THROW(newfileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
EXPECT_NO_THROW(
|
||||
client.RenameSubdirectory("", newPath, options).ExtractValue().Delete(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,91 +132,66 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
{
|
||||
{
|
||||
// Normal create/rename/delete.
|
||||
std::vector<Files::DataLake::DataLakeFileClient> fileClients;
|
||||
for (int32_t i = 0; i < 5; ++i)
|
||||
{
|
||||
auto client = m_fileSystemClient->GetFileClient(RandomString());
|
||||
EXPECT_NO_THROW(client.Create());
|
||||
fileClients.emplace_back(std::move(client));
|
||||
}
|
||||
std::vector<std::string> newPaths;
|
||||
for (auto& client : fileClients)
|
||||
{
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath));
|
||||
newPaths.push_back(newPath);
|
||||
}
|
||||
for (const auto& client : fileClients)
|
||||
{
|
||||
EXPECT_THROW(client.Delete(), StorageException);
|
||||
}
|
||||
for (const auto& newPath : newPaths)
|
||||
{
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
}
|
||||
auto fileName = RandomString();
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetFileClient(fileName).Create());
|
||||
std::shared_ptr<Files::DataLake::DataLakeFileClient> ret;
|
||||
EXPECT_NO_THROW(
|
||||
ret = std::make_shared<Files::DataLake::DataLakeFileClient>(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString()).ExtractValue()));
|
||||
EXPECT_THROW(m_fileSystemClient->GetFileClient(fileName).Delete(), StorageException);
|
||||
EXPECT_NO_THROW(ret->Delete());
|
||||
}
|
||||
{
|
||||
// Normal rename with last modified access condition.
|
||||
std::vector<Files::DataLake::DataLakeFileClient> fileClient;
|
||||
for (int32_t i = 0; i < 2; ++i)
|
||||
{
|
||||
auto client = m_fileSystemClient->GetFileClient(RandomString());
|
||||
EXPECT_NO_THROW(client.Create());
|
||||
fileClient.emplace_back(std::move(client));
|
||||
}
|
||||
for (auto& client : fileClient)
|
||||
{
|
||||
auto response = client.GetProperties();
|
||||
Files::DataLake::RenameDataLakeFileOptions options1;
|
||||
options1.SourceAccessConditions.IfModifiedSince = response->LastModified;
|
||||
EXPECT_THROW(client.Rename(RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeFileOptions options2;
|
||||
options2.SourceAccessConditions.IfUnmodifiedSince = response->LastModified;
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options2));
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
}
|
||||
auto fileName = RandomString();
|
||||
auto fileClient = m_fileSystemClient->GetFileClient(fileName);
|
||||
EXPECT_NO_THROW(fileClient.Create());
|
||||
auto response = fileClient.GetProperties();
|
||||
Files::DataLake::RenameDataLakeFileOptions options1;
|
||||
options1.SourceAccessConditions.IfModifiedSince = response->LastModified;
|
||||
EXPECT_THROW(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeFileOptions options2;
|
||||
options2.SourceAccessConditions.IfUnmodifiedSince = response->LastModified;
|
||||
std::shared_ptr<Files::DataLake::DataLakeFileClient> ret;
|
||||
EXPECT_NO_THROW(
|
||||
ret = std::make_shared<Files::DataLake::DataLakeFileClient>(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options2).ExtractValue()));
|
||||
EXPECT_THROW(m_fileSystemClient->GetFileClient(fileName).Delete(), StorageException);
|
||||
EXPECT_NO_THROW(ret->Delete());
|
||||
}
|
||||
{
|
||||
// Normal rename with if match access condition.
|
||||
std::vector<Files::DataLake::DataLakeFileClient> fileClient;
|
||||
for (int32_t i = 0; i < 2; ++i)
|
||||
{
|
||||
auto client = m_fileSystemClient->GetFileClient(RandomString());
|
||||
EXPECT_NO_THROW(client.Create());
|
||||
fileClient.emplace_back(std::move(client));
|
||||
}
|
||||
for (auto& client : fileClient)
|
||||
{
|
||||
auto response = client.GetProperties();
|
||||
Files::DataLake::RenameDataLakeFileOptions options1;
|
||||
options1.SourceAccessConditions.IfNoneMatch = response->ETag;
|
||||
EXPECT_THROW(client.Rename(RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeFileOptions options2;
|
||||
options2.SourceAccessConditions.IfMatch = response->ETag;
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options2));
|
||||
EXPECT_NO_THROW(m_fileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
}
|
||||
auto fileName = RandomString();
|
||||
auto fileClient = m_fileSystemClient->GetFileClient(fileName);
|
||||
EXPECT_NO_THROW(fileClient.Create());
|
||||
auto response = fileClient.GetProperties();
|
||||
Files::DataLake::RenameDataLakeFileOptions options1;
|
||||
options1.SourceAccessConditions.IfNoneMatch = response->ETag;
|
||||
EXPECT_THROW(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options1), StorageException);
|
||||
Files::DataLake::RenameDataLakeFileOptions options2;
|
||||
options2.SourceAccessConditions.IfMatch = response->ETag;
|
||||
std::shared_ptr<Files::DataLake::DataLakeFileClient> ret;
|
||||
EXPECT_NO_THROW(
|
||||
ret = std::make_shared<Files::DataLake::DataLakeFileClient>(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options2).ExtractValue()));
|
||||
EXPECT_THROW(m_fileSystemClient->GetFileClient(fileName).Delete(), StorageException);
|
||||
EXPECT_THROW(fileClient.GetProperties(), StorageException);
|
||||
EXPECT_NO_THROW(ret->Delete());
|
||||
}
|
||||
{
|
||||
// Rename to a destination file system.
|
||||
std::vector<Files::DataLake::DataLakeFileClient> fileClient;
|
||||
for (int32_t i = 0; i < 2; ++i)
|
||||
{
|
||||
auto client = m_fileSystemClient->GetFileClient(RandomString());
|
||||
EXPECT_NO_THROW(client.Create());
|
||||
fileClient.emplace_back(std::move(client));
|
||||
}
|
||||
auto fileName = RandomString();
|
||||
auto fileClient = m_fileSystemClient->GetFileClient(fileName);
|
||||
EXPECT_NO_THROW(fileClient.Create());
|
||||
{
|
||||
// Rename to a non-existing file system will fail but will not change URI.
|
||||
Files::DataLake::RenameDataLakeFileOptions options;
|
||||
options.DestinationFileSystem = LowercaseRandomString();
|
||||
for (auto& client : fileClient)
|
||||
{
|
||||
EXPECT_THROW(client.Rename(RandomString(), options), StorageException);
|
||||
EXPECT_NO_THROW(client.GetProperties());
|
||||
}
|
||||
EXPECT_THROW(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options), StorageException);
|
||||
EXPECT_NO_THROW(fileClient.GetProperties());
|
||||
}
|
||||
{
|
||||
// Rename to an existing file system will succeed and changes URI.
|
||||
@ -227,12 +202,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
newfileSystemClient->Create();
|
||||
Files::DataLake::RenameDataLakeFileOptions options;
|
||||
options.DestinationFileSystem = newfileSystemName;
|
||||
for (auto& client : fileClient)
|
||||
{
|
||||
auto newPath = RandomString();
|
||||
EXPECT_NO_THROW(client.Rename(newPath, options));
|
||||
EXPECT_NO_THROW(newfileSystemClient->GetDirectoryClient(newPath).Delete(false));
|
||||
}
|
||||
std::shared_ptr<Files::DataLake::DataLakeFileClient> ret;
|
||||
EXPECT_NO_THROW(
|
||||
ret = std::make_shared<Files::DataLake::DataLakeFileClient>(
|
||||
m_fileSystemClient->RenameFile(fileName, RandomString(), options).ExtractValue()));
|
||||
EXPECT_THROW(fileClient.GetProperties(), StorageException);
|
||||
EXPECT_NO_THROW(ret->Delete());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -570,7 +545,8 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
TEST_F(DataLakeFileClientTest, ConstructorsWorks)
|
||||
{
|
||||
{
|
||||
// Create from connection string validates static creator function and shared key constructor.
|
||||
// Create from connection string validates static creator function and shared key
|
||||
// constructor.
|
||||
auto fileName = RandomString(10);
|
||||
auto connectionStringClient
|
||||
= Azure::Storage::Files::DataLake::DataLakeFileClient::CreateFromConnectionString(
|
||||
|
||||
@ -123,9 +123,10 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
std::string newFilename = RandomString();
|
||||
auto newFileClient0 = directory2Client0.GetFileClient(newFilename);
|
||||
newFileClient0.Create();
|
||||
auto fileClient = Files::DataLake::DataLakeFileClient(
|
||||
Files::DataLake::Details::GetDfsUrlFromUrl(newFileClient0.GetUrl()) + sas);
|
||||
EXPECT_NO_THROW(fileClient.Rename(directory1Name + "/" + directory2Name + "/" + fileName));
|
||||
auto directoryClient = Files::DataLake::DataLakeDirectoryClient(
|
||||
Files::DataLake::Details::GetDfsUrlFromUrl(directory2Client0.GetUrl()) + sas);
|
||||
EXPECT_NO_THROW(directoryClient.RenameFile(
|
||||
newFilename, directory1Name + "/" + directory2Name + "/" + fileName));
|
||||
};
|
||||
|
||||
auto verify_file_execute = [&](const std::string& sas) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user