in sdk/storage/Azure.Storage.Files.DataLake/src/DataLakePathClient.cs [1247:1897]
properties: BuildMetadataString(metadata),
permissions: permissions,
umask: umask,
ifMatch: conditions?.IfMatch?.ToString(),
ifNoneMatch: conditions?.IfNoneMatch?.ToString(),
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
encryptionKey: ClientConfiguration.CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: ClientConfiguration.CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: ClientConfiguration.CustomerProvidedKey?.EncryptionAlgorithm == null ? null : EncryptionAlgorithmTypeInternal.AES256,
owner: owner,
group: group,
acl: PathAccessControlExtensions.ToAccessControlListString(accessControlList),
proposedLeaseId: leaseId,
leaseDuration: serviceLeaseDuration,
expiryOptions: pathExpiryOptions,
expiresOn: expiresOnString,
encryptionContext: encryptionContext,
cancellationToken: cancellationToken);
}
return Response.FromValue(
response.ToPathInfo(),
response.GetRawResponse());
}
catch (Exception ex)
{
ClientConfiguration.Pipeline.LogException(ex);
scope.Failed(ex);
throw;
}
finally
{
ClientConfiguration.Pipeline.LogMethodExit(nameof(DataLakePathClient));
scope.Dispose();
}
}
}
#endregion Create
#region Create If Not Exists
/// <summary>
/// The <see cref="CreateIfNotExists(PathResourceType, PathHttpHeaders, Metadata, string, string, CancellationToken)"/>
/// operation creates a file or directory. If the file or directory already exists, it is not changed.
///
/// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create.
/// </summary>
/// <param name="resourceType">
/// Resource type of this path - file or directory.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{PathInfo}"/> describing the
/// newly created path.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
public virtual Response<PathInfo> CreateIfNotExists(
PathResourceType resourceType,
DataLakePathCreateOptions options = default,
CancellationToken cancellationToken = default)
=> CreateIfNotExistsInternal(
resourceType: resourceType,
httpHeaders: options?.HttpHeaders,
metadata: options?.Metadata,
permissions: options?.AccessOptions?.Permissions,
umask: options?.AccessOptions?.Umask,
owner: options?.AccessOptions?.Owner,
group: options?.AccessOptions?.Group,
accessControlList: options?.AccessOptions?.AccessControlList,
leaseId: options?.LeaseId,
leaseDuration: options?.LeaseDuration,
timeToExpire: options?.ScheduleDeletionOptions?.TimeToExpire,
expiresOn: options?.ScheduleDeletionOptions?.ExpiresOn,
encryptionContext: options?.EncryptionContext,
async: false,
cancellationToken: cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="CreateIfNotExistsAsync(PathResourceType, PathHttpHeaders, Metadata, string, string, CancellationToken)"/>
/// operation creates a file or directory. If the file or directory already exists, it is not changed.
///
/// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create.
/// </summary>
/// <param name="resourceType">
/// Resource type of this path - file or directory.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{PathInfo}"/> describing the
/// newly created path.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
public virtual async Task<Response<PathInfo>> CreateIfNotExistsAsync(
PathResourceType resourceType,
DataLakePathCreateOptions options = default,
CancellationToken cancellationToken = default)
=> await CreateIfNotExistsInternal(
resourceType: resourceType,
httpHeaders: options?.HttpHeaders,
metadata: options?.Metadata,
permissions: options?.AccessOptions?.Permissions,
umask: options?.AccessOptions?.Umask,
owner: options?.AccessOptions?.Owner,
group: options?.AccessOptions?.Group,
accessControlList: options?.AccessOptions?.AccessControlList,
leaseId: options?.LeaseId,
leaseDuration: options?.LeaseDuration,
timeToExpire: options?.ScheduleDeletionOptions?.TimeToExpire,
expiresOn: options?.ScheduleDeletionOptions?.ExpiresOn,
encryptionContext: options?.EncryptionContext,
async: true,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="CreateIfNotExists(PathResourceType, PathHttpHeaders, Metadata, string, string, CancellationToken)"/>
/// operation creates a file or directory. If the file or directory already exists, it is not changed.
///
/// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create.
/// </summary>
/// <param name="resourceType">
/// Resource type of this path - file or directory.
/// </param>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new file or directory..
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this file or directory..
/// </param>
/// <param name="permissions">
/// Optional and only valid if Hierarchical Namespace is enabled for the account. Sets POSIX access
/// permissions for the file owner, the file owning group, and others. Each class may be granted read,
/// write, or execute permission. The sticky bit is also supported. Both symbolic (rwxrw-rw-) and 4-digit
/// octal notation (e.g. 0766) are supported.
/// </param>
/// <param name="umask">
/// Optional and only valid if Hierarchical Namespace is enabled for the account.
/// When creating a file or directory and the parent folder does not have a default ACL,
/// the umask restricts the permissions of the file or directory to be created. The resulting
/// permission is given by p bitwise-and ^u, where p is the permission and u is the umask. For example,
/// if p is 0777 and u is 0057, then the resulting permission is 0720. The default permission is
/// 0777 for a directory and 0666 for a file. The default umask is 0027. The umask must be specified
/// in 4-digit octal notation (e.g. 0766).
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{PathInfo}"/> describing the
/// newly created path.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual Response<PathInfo> CreateIfNotExists(
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
PathResourceType resourceType,
PathHttpHeaders httpHeaders,
Metadata metadata,
string permissions,
string umask,
CancellationToken cancellationToken)
=> CreateIfNotExistsInternal(
resourceType: resourceType,
httpHeaders: httpHeaders,
metadata: metadata,
permissions: permissions,
umask: umask,
owner: null,
group: null,
accessControlList: null,
leaseId: null,
leaseDuration: null,
timeToExpire: null,
expiresOn: null,
encryptionContext: null,
async: false,
cancellationToken: cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="CreateIfNotExistsAsync(PathResourceType, PathHttpHeaders, Metadata, string, string, CancellationToken)"/>
/// operation creates a file or directory. If the file or directory already exists, it is not changed.
///
/// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create.
/// </summary>
/// <param name="resourceType">
/// Resource type of this path - file or directory.
/// </param>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new file or directory.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this file or directory..
/// </param>
/// <param name="permissions">
/// Optional and only valid if Hierarchical Namespace is enabled for the account. Sets POSIX access
/// permissions for the file owner, the file owning group, and others. Each class may be granted read,
/// write, or execute permission. The sticky bit is also supported. Both symbolic (rwxrw-rw-) and 4-digit
/// octal notation (e.g. 0766) are supported.
/// </param>
/// <param name="umask">
/// Optional and only valid if Hierarchical Namespace is enabled for the account.
/// When creating a file or directory and the parent folder does not have a default ACL,
/// the umask restricts the permissions of the file or directory to be created. The resulting
/// permission is given by p bitwise-and ^u, where p is the permission and u is the umask. For example,
/// if p is 0777 and u is 0057, then the resulting permission is 0720. The default permission is
/// 0777 for a directory and 0666 for a file. The default umask is 0027. The umask must be specified
/// in 4-digit octal notation (e.g. 0766).
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{PathInfo}"/> describing the
/// newly created path.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual async Task<Response<PathInfo>> CreateIfNotExistsAsync(
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
PathResourceType resourceType,
PathHttpHeaders httpHeaders,
Metadata metadata,
string permissions,
string umask,
CancellationToken cancellationToken)
=> await CreateIfNotExistsInternal(
resourceType: resourceType,
httpHeaders: httpHeaders,
metadata: metadata,
permissions: permissions,
umask: umask,
owner: null,
group: null,
accessControlList: null,
leaseId: null,
leaseDuration: null,
timeToExpire: null,
expiresOn: null,
encryptionContext: null,
async: true,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="CreateIfNotExistsInternal(PathResourceType, PathHttpHeaders, Metadata, string, string, string, string, IList{PathAccessControlItem}, string, TimeSpan?, TimeSpan?, DateTimeOffset?, string, bool, CancellationToken)"/>
/// operation creates a file or directory. If the file or directory already exists, it is not changed.
///
/// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create.
/// </summary>
/// <param name="resourceType">
/// Resource type of this path - file or directory.
/// </param>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// new file or directory.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this file or directory.
/// </param>
/// <param name="permissions">
/// Optional and only valid if Hierarchical Namespace is enabled for the account. Sets POSIX access
/// permissions for the file owner, the file owning group, and others. Each class may be granted read,
/// write, or execute permission. The sticky bit is also supported. Both symbolic (rwxrw-rw-) and 4-digit
/// octal notation (e.g. 0766) are supported.
/// </param>
/// <param name="umask">
/// Optional and only valid if Hierarchical Namespace is enabled for the account.
/// When creating a file or directory and the parent folder does not have a default ACL,
/// the umask restricts the permissions of the file or directory to be created. The resulting
/// permission is given by p bitwise-and ^u, where p is the permission and u is the umask. For example,
/// if p is 0777 and u is 0057, then the resulting permission is 0720. The default permission is
/// 0777 for a directory and 0666 for a file. The default umask is 0027. The umask must be specified
/// in 4-digit octal notation (e.g. 0766).
/// </param>
/// <param name="owner">
/// The owner of the file or directory.
/// </param>
/// <param name="group">
/// Optional. The owning group of the file or directory.
/// </param>
/// <param name="accessControlList">
/// The POSIX access control list for the file or directory.
/// </param>
/// <param name="leaseId">
/// Proposed LeaseId.
/// </param>
/// <param name="leaseDuration">
/// Specifies the duration of the lease.
/// </param>
/// <param name="timeToExpire">
/// Duration before file should be deleted.
/// </param>
/// <param name="expiresOn">
/// The <see cref="DateTimeOffset"/> to set for when
/// the file will be deleted. If null, the existing
/// ExpiresOn time on the file will be removed, if it exists.
/// </param>
/// <param name="encryptionContext">
/// Encryption context.
/// </param>
/// <param name="async">
/// Whether to invoke the operation asynchronously.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{PathInfo}"/> describing the
/// newly created path.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
private async Task<Response<PathInfo>> CreateIfNotExistsInternal(
PathResourceType resourceType,
PathHttpHeaders httpHeaders,
Metadata metadata,
string permissions,
string umask,
string owner,
string group,
IList<PathAccessControlItem> accessControlList,
string leaseId,
TimeSpan? leaseDuration,
TimeSpan? timeToExpire,
DateTimeOffset? expiresOn,
string encryptionContext,
bool async,
CancellationToken cancellationToken)
{
Response<PathInfo> response;
try
{
DataLakeRequestConditions conditions = new DataLakeRequestConditions { IfNoneMatch = new ETag(Constants.Wildcard) };
response = await CreateInternal(
resourceType: resourceType,
httpHeaders: httpHeaders,
metadata: metadata,
permissions: permissions,
umask: umask,
owner: owner,
group: group,
accessControlList: accessControlList,
leaseId: leaseId,
leaseDuration: leaseDuration,
timeToExpire: timeToExpire,
expiresOn: expiresOn,
encryptionContext: encryptionContext,
conditions: conditions,
async: async,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
catch (RequestFailedException storageRequestFailedException)
when (storageRequestFailedException.ErrorCode == Constants.DataLake.PathAlreadyExists)
{
response = default;
}
return response;
}
#endregion Create If Not Exists
#region Exists
/// <summary>
/// The <see cref="Exists"/> operation can be called on a
/// <see cref="DataLakePathClient"/> to see if the associated
/// file or director exists in the file system.
/// </summary>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// Returns true if the file or directory exists.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance. If you want to create the file system if
/// it doesn't exist, use
/// <see cref="CreateIfNotExists(PathResourceType, DataLakePathCreateOptions, CancellationToken)"/>
/// instead.
/// </remarks>
/// <remarks>
/// Note that if you call FileClient.Exists on a path that does not
/// represent a file, Exists will return true. Similarly, if you
/// call DirectoryClient.Exists on a path that is not a directory,
/// Exists will return true.
/// </remarks>
public virtual Response<bool> Exists(
CancellationToken cancellationToken = default)
{
DiagnosticScope scope = ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(DataLakePathClient)}.{nameof(Exists)}");
try
{
scope.Start();
return _blockBlobClient.Exists(cancellationToken);
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
finally
{
scope.Dispose();
}
}
/// <summary>
/// The <see cref="ExistsAsync"/> operation can be called on a
/// <see cref="DataLakePathClient"/> to see if the associated
/// file or directory exists in the file system.
/// </summary>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// Returns true if the file or directory exists.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance. If you want to create the file system if
/// it doesn't exist, use
/// <see cref="CreateIfNotExistsAsync(PathResourceType, DataLakePathCreateOptions, CancellationToken)"/>
/// instead.
/// </remarks>
/// <remarks>
/// Note that if you call FileClient.Exists on a path that does not
/// represent a file, Exists will return true. Similarly, if you
/// call DirectoryClient.Exists on a path that is not a directory,
/// Exists will return true.
/// </remarks>
public virtual async Task<Response<bool>> ExistsAsync(
CancellationToken cancellationToken = default)
{
DiagnosticScope scope = ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(DataLakePathClient)}.{nameof(Exists)}");
try
{
scope.Start();
return await _blockBlobClient.ExistsAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
finally
{
scope.Dispose();
}
}
#endregion Exists
#region Delete
/// <summary>
/// The <see cref="Delete"/> operation marks the specified path
/// deletion.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/delete">
/// Delete Path</see>.
/// </summary>
/// <param name="recursive">
/// Required and valid only when the resource is a directory. If "true", all paths beneath the directory will be deleted.
/// If "false" and the directory is non-empty, an error occurs.
/// </param>
/// <param name="conditions">
/// Optional <see cref="DataLakeRequestConditions"/> to add conditions on
/// deleting this path.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully marking for deletion.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
public virtual Response Delete(
bool? recursive = default,
DataLakeRequestConditions conditions = default,
CancellationToken cancellationToken = default)
{
return DeleteInternal(
recursive,
conditions,
false, // async
cancellationToken)
.EnsureCompleted();
}
/// <summary>
/// The <see cref="DeleteAsync"/> operation marks the specified path
/// deletion.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/delete">
/// Delete Path</see>.
/// </summary>
/// <param name="recursive">
/// Required and valid only when the resource is a directory. If "true", all paths beneath the directory will be deleted.
/// If "false" and the directory is non-empty, an error occurs.
/// </param>
/// <param name="conditions">
/// Optional <see cref="DataLakeRequestConditions"/> to add conditions on
/// deleting this path.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully marking for deletion.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
public virtual async Task<Response> DeleteAsync(
bool? recursive = default,
DataLakeRequestConditions conditions = default,
CancellationToken cancellationToken = default)
{
return await DeleteInternal(
recursive,
conditions,
true, // async
cancellationToken)
.ConfigureAwait(false);
}
/// <summary>
/// The <see cref="DeleteInternal"/> operation marks the specified path
/// deletion.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/delete">
/// Delete Path</see>.
/// </summary>
/// <param name="recursive">
/// Required and valid only when the resource is a directory. If "true", all paths beneath the directory will be deleted.
/// If "false" and the directory is non-empty, an error occurs.
/// </param>
/// <param name="conditions">
/// Optional <see cref="DataLakeRequestConditions"/> to add conditions on
/// deleting this path.
/// </param>
/// <param name="async">
/// Whether to invoke the operation asynchronously.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> on successfully marking for deletion.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
private async Task<Response> DeleteInternal(
bool? recursive,
DataLakeRequestConditions conditions,
bool async,
CancellationToken cancellationToken)
{
using (ClientConfiguration.Pipeline.BeginLoggingScope(nameof(DataLakePathClient)))
{
ClientConfiguration.Pipeline.LogMethodEnter(
nameof(DataLakePathClient),
message:
$"{nameof(Uri)}: {Uri}\n" +
$"{nameof(recursive)}: {recursive}\n" +
$"{nameof(conditions)}: {conditions}");
DiagnosticScope scope = ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(DataLakePathClient)}.{nameof(Delete)}");
try
{
scope.Start();
ResponseWithHeaders<PathDeleteHeaders> response = null;
// Pagination only applies to service version 2023-08-03 and later, when using OAuth.
bool? paginated = null;
if (_clientConfiguration.ClientOptions.Version >= DataLakeClientOptions.ServiceVersion.V2023_08_03
&& recursive.GetValueOrDefault()
&& _clientConfiguration.TokenCredential != null)
{