예제 #1
0
        /// <summary>
        /// The <see cref="Acquire"/> operation acquires a lease on
        /// the path or file system.  The lease <paramref name="duration"/> must
        /// be between 15 to 60 seconds, or infinite (-1).
        ///
        /// If the file system does not have an active lease, the Data Lake service
        /// creates a lease on the path or file system and returns it.  If the
        /// file system has an active lease, you can only request a new lease
        /// using the active lease ID as <see cref="LeaseId"/>, but you can
        /// specify a new <paramref name="duration"/>.
        ///
        /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
        /// </summary>
        /// <param name="duration">
        /// Specifies the duration of the lease, in seconds, or specify
        /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires.
        /// A non-infinite lease can be between 15 and 60 seconds.
        /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>.
        /// </param>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on acquiring a lease.
        /// </param>
        /// <param name="cancellationToken">
        /// Optional <see cref="CancellationToken"/> to propagate
        /// notifications that the operation should be cancelled.
        /// </param>
        /// <returns>
        /// A <see cref="Response{Lease}"/> describing the lease.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual Response <DataLakeLease> Acquire(
            TimeSpan duration,
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(Azure)}.{nameof(Storage)}.{nameof(Files)}.{nameof(DataLake)}.{nameof(DataLakeLeaseClient)}.{nameof(Acquire)}");

            try
            {
                scope.Start();

                Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Acquire(
                    duration,
                    conditions,
                    cancellationToken);

                return(Response.FromValue(
                           response.Value.ToDataLakeLease(),
                           response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
        /// <summary>
        /// The <see cref="ReleaseAsync"/> operation releases the
        /// file system or path's previously-acquired lease.
        ///
        /// The lease may be released if the <see cref="LeaseId"/>
        /// matches that associated with the file system or path.  Releasing the
        /// lease allows another client to immediately acquire the lease for the
        /// file system or path as soon as the release is complete.
        ///
        /// For more information, see
        /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container">
        /// Lease Container</see>.
        /// </summary>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on acquiring a lease.
        /// </param>
        /// <param name="cancellationToken">
        /// Optional <see cref="CancellationToken"/> to propagate
        /// notifications that the operation should be cancelled.
        /// </param>
        /// <returns>
        /// A <see cref="Response{ReleasedObjectInfo}"/> describing the
        /// updated path or file system.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync(
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Release)}");

            try
            {
                scope.Start();

                Response <Blobs.Models.ReleasedObjectInfo> response = await _blobLeaseClient.ReleaseAsync(
                    conditions,
                    cancellationToken)
                                                                      .ConfigureAwait(false);

                return(Response.FromValue(
                           new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified),
                           response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
        /// <summary>
        /// The <see cref="Change"/> operation changes the lease
        /// of an active lease.  A change must include the current
        /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
        ///
        /// For more information, see
        /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container">
        /// Lease Container</see>.
        /// </summary>
        /// <param name="proposedId">
        /// An optional proposed lease ID, in a GUID string format. A
        /// <see cref="RequestFailedException"/> will be thrown if the
        /// proposed lease ID is not in the correct format.
        /// </param>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on acquiring a lease.
        /// </param>
        /// <param name="cancellationToken">
        /// Optional <see cref="CancellationToken"/> to propagate
        /// notifications that the operation should be cancelled.
        /// </param>
        /// <returns>
        /// A <see cref="Response{Lease}"/> describing the lease.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual Response <DataLakeLease> Change(
            string proposedId,
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Change)}");

            try
            {
                scope.Start();

                Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Change(
                    proposedId,
                    conditions,
                    cancellationToken);

                return(Response.FromValue(
                           response.Value.ToDataLakeLease(),
                           response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
        /// <summary>
        /// The <see cref="BreakAsync"/> operation breaks the path or
        /// file system's previously-acquired lease (if it exists).
        ///
        /// Once a lease is broken, it cannot be renewed.  Any authorized
        /// request can break the lease; the request is not required to
        /// specify a matching lease ID.  When a lease is broken, the lease
        /// break <paramref name="breakPeriod"/> is allowed to elapse,
        /// during which time no lease operation except
        /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be
        /// performed on the path or file system.  When a lease is successfully
        /// broken, the response indicates the interval in seconds until a new
        /// lease can be acquired.
        ///
        /// A lease that has been broken can also be released.  A client can
        /// immediately acquire a path or file system lease that has been
        /// released.
        ///
        /// For more information, see
        /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container">
        /// Lease Container</see>.
        /// </summary>
        /// <param name="breakPeriod">
        /// Specifies the proposed duration the lease should continue before
        /// it is broken, in seconds, between 0 and 60.  This break period is
        /// only used if it is shorter than the time remaining on the lease.
        /// If longer, the time remaining on the lease is used.  A new lease
        /// will not be available before the break period has expired, but the
        /// lease may be held for longer than the break period.  If this value
        /// is not provided, a fixed-duration lease breaks after the remaining
        /// lease period elapses, and an infinite lease breaks immediately.
        /// </param>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on acquiring a lease.
        /// </param>
        /// <param name="cancellationToken">
        /// Optional <see cref="CancellationToken"/> to propagate
        /// notifications that the operation should be cancelled.
        /// </param>
        /// <returns>
        /// A <see cref="Response{Lease}"/> describing the broken lease.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual async Task <Response <DataLakeLease> > BreakAsync(
            TimeSpan?breakPeriod                = default,
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Break)}");

            try
            {
                scope.Start();

                Response <Blobs.Models.BlobLease> response = await _blobLeaseClient.BreakAsync(
                    breakPeriod,
                    conditions,
                    cancellationToken).ConfigureAwait(false);

                return(Response.FromValue(
                           response.Value.ToDataLakeLease(),
                           response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
예제 #5
0
 /// <summary>
 /// The <see cref="Release"/> operation releases the
 /// container or blob's previously-acquired lease.
 ///
 /// The lease may be released if the <see cref="LeaseId"/>
 /// matches that associated with the container or blob.  Releasing the
 /// lease allows another client to immediately acquire the lease for the
 /// container or blob as soon as the release is complete.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on releasing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{ReleaseObjectLeaseInfo}"/> describing the
 /// updated blob or container.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual Response <ReleasedObjectInfo> Release(
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 ReleaseInternal(
     conditions,
     false,     // async
     cancellationToken)
 .EnsureCompleted();
예제 #6
0
 /// <summary>
 /// The <see cref="ReleaseAsync"/> operation releases the
 /// container or blob's previously-acquired lease.
 ///
 /// The lease may be released if the <see cref="LeaseId"/>
 /// matches that associated with the container or blob.  Releasing the
 /// lease allows another client to immediately acquire the lease for the
 /// container or blob as soon as the release is complete.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on releasing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{ReleasedObjectInfo}"/> describing the
 /// updated blob or container.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync(
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 await ReleaseInternal(
     conditions,
     true,     // async
     cancellationToken)
 .ConfigureAwait(false);
예제 #7
0
 /// <summary>
 /// The <see cref="RenewAsync"/> operation renews the blob or
 /// container's previously-acquired lease.
 ///
 /// The lease can be renewed if the leaseId
 /// matches that associated with the blob or container.  Note that the]
 /// lease may be renewed even if it has expired as long as the blob or
 /// container has not been leased again since the expiration of that
 /// lease.  When you renew a lease, the lease duration clock resets.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on renewing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual async Task <Response <BlobLease> > RenewAsync(
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 await RenewInternal(
     conditions,
     true,     // async
     cancellationToken)
 .ConfigureAwait(false);
예제 #8
0
 /// <summary>
 /// The <see cref="Renew"/> operation renews the blob or
 /// container's previously-acquired lease.
 ///
 /// The lease can be renewed if the leaseId
 /// matches that associated with the blob or container.  Note that the]
 /// lease may be renewed even if it has expired as long as the blob or
 /// container has not been leased again since the expiration of that
 /// lease.  When you renew a lease, the lease duration clock resets.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on renewing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual Response <BlobLease> Renew(
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 RenewInternal(
     conditions,
     false,     // async
     cancellationToken)
 .EnsureCompleted();
예제 #9
0
 /// <summary>
 /// Convert a base RequestConditions to BlobRequestConditions.
 /// </summary>
 /// <param name="conditions">The <see cref="RequestConditions"/>.</param>
 /// <returns>The <see cref="BlobRequestConditions"/>.</returns>
 public static BlobRequestConditions ToBlobRequestConditions(this RequestConditions conditions) =>
 conditions == null ?
 null :
 new BlobRequestConditions
 {
     IfMatch           = conditions.IfMatch,
     IfNoneMatch       = conditions.IfNoneMatch,
     IfModifiedSince   = conditions.IfModifiedSince,
     IfUnmodifiedSince = conditions.IfUnmodifiedSince
 };
예제 #10
0
 /// <summary>
 /// The <see cref="ChangeAsync"/> operation changes the lease
 /// of an active lease.  A change must include the current
 /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="proposedId">
 /// An optional proposed lease ID, in a GUID string format. A
 /// <see cref="RequestFailedException"/> will be thrown if the
 /// proposed lease ID is not in the correct format.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on changing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual async Task <Response <BlobLease> > ChangeAsync(
     string proposedId,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 await ChangeInternal(
     proposedId,
     conditions,
     true,     // async
     cancellationToken)
 .ConfigureAwait(false);
예제 #11
0
 /// <summary>
 /// The <see cref="Break"/> operation breaks the blob or
 /// container's previously-acquired lease (if it exists).
 ///
 /// Once a lease is broken, it cannot be renewed.  Any authorized
 /// request can break the lease; the request is not required to
 /// specify a matching lease ID.  When a lease is broken, the lease
 /// break <paramref name="breakPeriod"/> is allowed to elapse,
 /// during which time no lease operation except
 /// <see cref="Break"/> and <see cref="Release"/> can be
 /// performed on the blob or container.  When a lease is successfully
 /// broken, the response indicates the interval in seconds until a new
 /// lease can be acquired.
 ///
 /// A lease that has been broken can also be released.  A client can
 /// immediately acquire a blob or container lease that has been
 /// released.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="breakPeriod">
 /// Specifies the proposed duration the lease should continue before
 /// it is broken, in seconds, between 0 and 60.  This break period is
 /// only used if it is shorter than the time remaining on the lease.
 /// If longer, the time remaining on the lease is used.  A new lease
 /// will not be available before the break period has expired, but the
 /// lease may be held for longer than the break period.  If this value
 /// is not provided, a fixed-duration lease breaks after the remaining
 /// lease period elapses, and an infinite lease breaks immediately.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on breaking a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the broken lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual Response <BlobLease> Break(
     TimeSpan?breakPeriod                = default,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 BreakInternal(
     breakPeriod,
     conditions,
     false,     // async
     cancellationToken)
 .EnsureCompleted();
예제 #12
0
 /// <summary>
 /// The <see cref="BreakAsync"/> operation breaks the blob or
 /// container's previously-acquired lease (if it exists).
 ///
 /// Once a lease is broken, it cannot be renewed.  Any authorized
 /// request can break the lease; the request is not required to
 /// specify a matching lease ID.  When a lease is broken, the lease
 /// break <paramref name="breakPeriod"/> is allowed to elapse,
 /// during which time no lease operation except
 /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be
 /// performed on the blob or container.  When a lease is successfully
 /// broken, the response indicates the interval in seconds until a new
 /// lease can be acquired.
 ///
 /// A lease that has been broken can also be released.  A client can
 /// immediately acquire a blob or container lease that has been
 /// released.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="breakPeriod">
 /// Specifies the proposed duration the lease should continue before
 /// it is broken, in seconds, between 0 and 60.  This break period is
 /// only used if it is shorter than the time remaining on the lease.
 /// If longer, the time remaining on the lease is used.  A new lease
 /// will not be available before the break period has expired, but the
 /// lease may be held for longer than the break period.  If this value
 /// is not provided, a fixed-duration lease breaks after the remaining
 /// lease period elapses, and an infinite lease breaks immediately.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on breaking a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the broken lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual async Task <Response <BlobLease> > BreakAsync(
     TimeSpan?breakPeriod                = default,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 await BreakInternal(
     breakPeriod,
     conditions,
     true,     // async
     cancellationToken)
 .ConfigureAwait(false);
예제 #13
0
 /// <summary>
 /// The <see cref="AcquireAsync"/> operation acquires a lease on
 /// the blob or container.  The lease <paramref name="duration"/> must
 /// be between 15 to 60 seconds, or infinite (-1).
 ///
 /// If the container does not have an active lease, the Blob service
 /// creates a lease on the blob or container and returns it.  If the
 /// container has an active lease, you can only request a new lease
 /// using the active lease ID as <see cref="LeaseId"/>, but you can
 /// specify a new <paramref name="duration"/>.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="duration">
 /// Specifies the duration of the lease, in seconds, or specify
 /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires.
 /// A non-infinite lease can be between 15 and 60 seconds.
 /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on acquiring a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual async Task <Response <BlobLease> > AcquireAsync(
     TimeSpan duration,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 await AcquireInternal(
     duration,
     conditions,
     true,     // async
     cancellationToken)
 .ConfigureAwait(false);
예제 #14
0
 /// <summary>
 /// The <see cref="Acquire"/> operation acquires a lease on
 /// the blob or container.  The lease <paramref name="duration"/> must
 /// be between 15 to 60 seconds, or infinite (-1).
 ///
 /// If the container does not have an active lease, the Blob service
 /// creates a lease on the blob or container and returns it.  If the
 /// container has an active lease, you can only request a new lease
 /// using the active lease ID as <see cref="LeaseId"/>, but you can
 /// specify a new <paramref name="duration"/>.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="duration">
 /// Specifies the duration of the lease, in seconds, or specify
 /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires.
 /// A non-infinite lease can be between 15 and 60 seconds.
 /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on acquiring a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual Response <BlobLease> Acquire(
     TimeSpan duration,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 AcquireInternal(
     duration,
     conditions,
     false,     // async
     cancellationToken)
 .EnsureCompleted();
예제 #15
0
 /// <summary>
 /// The <see cref="Change"/> operation changes the lease
 /// of an active lease.  A change must include the current
 /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="proposedId">
 /// An optional proposed lease ID, in a GUID string format. A
 /// <see cref="RequestFailedException"/> will be thrown if the
 /// proposed lease ID is not in the correct format.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on changing a lease.
 /// </param>
 /// <param name="cancellationToken">
 /// Optional <see cref="CancellationToken"/> to propagate
 /// notifications that the operation should be cancelled.
 /// </param>
 /// <returns>
 /// A <see cref="Response{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 public virtual Response <BlobLease> Change(
     string proposedId,
     RequestConditions conditions        = default,
     CancellationToken cancellationToken = default) =>
 ChangeInternal(
     proposedId,
     conditions,
     false,     // async
     cancellationToken)
 .EnsureCompleted();
        public virtual Response <DataLakeLease> Renew(
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Renew(
                conditions,
                cancellationToken);

            return(Response.FromValue(
                       response.Value.ToDataLakeLease(),
                       response.GetRawResponse()));
        }
        public virtual Response <ReleasedObjectInfo> Release(
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.ReleasedObjectInfo> response = _blobLeaseClient.Release(
                conditions,
                cancellationToken);

            return(Response.FromValue(
                       new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified),
                       response.GetRawResponse()));
        }
        public virtual async Task <Response <DataLakeLease> > RenewAsync(
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.BlobLease> response = await _blobLeaseClient.RenewAsync(
                conditions,
                cancellationToken)
                                                         .ConfigureAwait(false);

            return(Response.FromValue(
                       response.Value.ToDataLakeLease(),
                       response.GetRawResponse()));
        }
        public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync(
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.ReleasedObjectInfo> response = await _blobLeaseClient.ReleaseAsync(
                conditions,
                cancellationToken)
                                                                  .ConfigureAwait(false);

            return(Response.FromValue(
                       new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified),
                       response.GetRawResponse()));
        }
        public virtual Response <DataLakeLease> Change(
            string proposedId,
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Change(
                proposedId,
                conditions,
                cancellationToken);

            return(Response.FromValue(
                       response.Value.ToDataLakeLease(),
                       response.GetRawResponse()));
        }
        public virtual Response <DataLakeLease> Break(
            TimeSpan?breakPeriod                = default,
            RequestConditions conditions        = default,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Break(
                breakPeriod,
                conditions,
                cancellationToken);

            return(Response.FromValue(
                       response.Value.ToDataLakeLease(),
                       response.GetRawResponse()));
        }
예제 #22
0
        /// <summary>
        ///     Renew the lease, getting more time to get a work done.
        /// </summary>
        /// <param name="renewInterval">required time</param>
        /// <returns></returns>
        public async Task <bool> RenewLease(TimeSpan renewInterval)
        {
            var renewRequestOptions = new RequestConditions();

            var lease = _currentLease;

            if (lease == null)
            {
                return(false);
            }

            try
            {
                await lease.Blob.GetBlobLeaseClient(lease.Token).RenewAsync(renewRequestOptions).ConfigureAwait(false);
            }
            catch (RequestFailedException)
            {
                return(false);
            }

            return(true);
        }
예제 #23
0
        /// <summary>
        /// The <see cref="BreakInternal"/> operation breaks the blob or
        /// container's previously-acquired lease (if it exists).
        ///
        /// Once a lease is broken, it cannot be renewed.  Any authorized
        /// request can break the lease; the request is not required to
        /// specify a matching lease ID.  When a lease is broken, the lease
        /// break <paramref name="breakPeriod"/> is allowed to elapse,
        /// during which time no lease operation except
        /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be
        /// performed on the blob or container.  When a lease is successfully
        /// broken, the response indicates the interval in seconds until a new
        /// lease can be acquired.
        ///
        /// A lease that has been broken can also be released.  A client can
        /// immediately acquire a blob or container lease that has been
        /// released.
        ///
        /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
        /// </summary>
        /// <param name="breakPeriod">
        /// Specifies the proposed duration the lease should continue before
        /// it is broken, in seconds, between 0 and 60.  This break period is
        /// only used if it is shorter than the time remaining on the lease.
        /// If longer, the time remaining on the lease is used.  A new lease
        /// will not be available before the break period has expired, but the
        /// lease may be held for longer than the break period.  If this value
        /// is not provided, a fixed-duration lease breaks after the remaining
        /// lease period elapses, and an infinite lease breaks immediately.
        /// </param>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on breaking a lease.
        /// </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{Lease}"/> describing the broken lease.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        private async Task <Response <BlobLease> > BreakInternal(
            TimeSpan?breakPeriod,
            RequestConditions conditions,
            bool async,
            CancellationToken cancellationToken)
        {
            EnsureClient();
            long?serviceBreakPeriod = breakPeriod != null?Convert.ToInt64(breakPeriod.Value.TotalSeconds) : (long?)null;

            using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient)))
            {
                Pipeline.LogMethodEnter(
                    nameof(BlobLeaseClient),
                    message:
                    $"{nameof(Uri)}: {Uri}\n" +
                    $"{nameof(breakPeriod)}: {breakPeriod}\n" +
                    $"{nameof(conditions)}: {conditions}");
                try
                {
                    if (BlobClient != null)
                    {
                        return((await BlobRestClient.Blob.BreakLeaseAsync(
                                    ClientDiagnostics,
                                    Pipeline,
                                    Uri,
                                    breakPeriod: serviceBreakPeriod,
                                    ifModifiedSince: conditions?.IfModifiedSince,
                                    ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
                                    ifMatch: conditions?.IfMatch,
                                    ifNoneMatch: conditions?.IfNoneMatch,
                                    async: async,
                                    operationName: Constants.Blob.Lease.BreakOperationName,
                                    cancellationToken: cancellationToken)
                                .ConfigureAwait(false))
                               .ToLease());
                    }
                    else
                    {
                        if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default)
                        {
                            throw BlobErrors.BlobConditionsMustBeDefault(
                                      nameof(conditions.IfMatch),
                                      nameof(conditions.IfNoneMatch));
                        }
                        return((await BlobRestClient.Container.BreakLeaseAsync(
                                    ClientDiagnostics,
                                    Pipeline,
                                    Uri,
                                    breakPeriod: serviceBreakPeriod,
                                    ifModifiedSince: conditions?.IfModifiedSince,
                                    ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
                                    async: async,
                                    operationName: Constants.Blob.Lease.BreakOperationName,
                                    cancellationToken: cancellationToken)
                                .ConfigureAwait(false))
                               .ToLease());
                    }
                }
                catch (Exception ex)
                {
                    Pipeline.LogException(ex);
                    throw;
                }
                finally
                {
                    Pipeline.LogMethodExit(nameof(BlobLeaseClient));
                }
            }
        }
예제 #24
0
        /// <summary>
        /// The <see cref="AcquireInternal"/> operation acquires a lease on
        /// the blob or container.  The lease <paramref name="duration"/> must
        /// be between 15 to 60 seconds, or infinite (-1).
        ///
        /// If the container does not have an active lease, the Blob service
        /// creates a lease on the blob or container and returns it.  If the
        /// container has an active lease, you can only request a new lease
        /// using the active lease ID as <see cref="LeaseId"/>, but you can
        /// specify a new <paramref name="duration"/>.
        ///
        /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
        /// </summary>
        /// <param name="duration">
        /// Specifies the duration of the lease, in seconds, or specify
        /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires.
        /// A non-infinite lease can be between 15 and 60 seconds.
        /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>.
        /// </param>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on acquiring a lease.
        /// </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{Lease}"/> describing the lease.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        private async Task <Response <BlobLease> > AcquireInternal(
            TimeSpan duration,
            RequestConditions conditions,
            bool async,
            CancellationToken cancellationToken)
        {
            EnsureClient();
            // Int64 is an overflow safe cast relative to TimeSpan.MaxValue
            var serviceDuration = duration < TimeSpan.Zero ? Constants.Blob.Lease.InfiniteLeaseDuration : Convert.ToInt64(duration.TotalSeconds);

            using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient)))
            {
                Pipeline.LogMethodEnter(
                    nameof(BlobLeaseClient),
                    message:
                    $"{nameof(Uri)}: {Uri}\n" +
                    $"{nameof(LeaseId)}: {LeaseId}\n" +
                    $"{nameof(duration)}: {duration}");
                try
                {
                    if (BlobClient != null)
                    {
                        return(await BlobRestClient.Blob.AcquireLeaseAsync(
                                   ClientDiagnostics,
                                   Pipeline,
                                   Uri,
                                   duration : serviceDuration,
                                   proposedLeaseId : LeaseId,
                                   ifModifiedSince : conditions?.IfModifiedSince,
                                   ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                                   ifMatch : conditions?.IfMatch,
                                   ifNoneMatch : conditions?.IfNoneMatch,
                                   async : async,
                                   operationName : Constants.Blob.Lease.AcquireOperationName,
                                   cancellationToken : cancellationToken)
                               .ConfigureAwait(false));
                    }
                    else
                    {
                        if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default)
                        {
                            throw BlobErrors.BlobConditionsMustBeDefault(
                                      nameof(conditions.IfMatch),
                                      nameof(conditions.IfNoneMatch));
                        }
                        return(await BlobRestClient.Container.AcquireLeaseAsync(
                                   ClientDiagnostics,
                                   Pipeline,
                                   Uri,
                                   duration : serviceDuration,
                                   proposedLeaseId : LeaseId,
                                   ifModifiedSince : conditions?.IfModifiedSince,
                                   ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                                   async : async,
                                   operationName : Constants.Blob.Lease.AcquireOperationName,
                                   cancellationToken : cancellationToken)
                               .ConfigureAwait(false));
                    }
                }
                catch (Exception ex)
                {
                    Pipeline.LogException(ex);
                    throw;
                }
                finally
                {
                    Pipeline.LogMethodExit(nameof(BlobLeaseClient));
                }
            }
        }
예제 #25
0
 /// <summary>
 /// The <see cref="ChangeInternal"/> operation changes the lease
 /// of an active lease.  A change must include the current
 /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 ///
 /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
 /// </summary>
 /// <param name="proposedId">
 /// An optional proposed lease ID, in a GUID string format. A
 /// <see cref="RequestFailedException"/> will be thrown if the
 /// proposed lease ID is not in the correct format.
 /// </param>
 /// <param name="conditions">
 /// Optional <see cref="RequestConditions"/> to add
 /// conditions on changing a lease.
 /// </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{Lease}"/> describing the lease.
 /// </returns>
 /// <remarks>
 /// A <see cref="RequestFailedException"/> will be thrown if
 /// a failure occurs.
 /// </remarks>
 private async Task <Response <BlobLease> > ChangeInternal(
     string proposedId,
     RequestConditions conditions,
     bool async,
     CancellationToken cancellationToken)
 {
     EnsureClient();
     using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient)))
     {
         Pipeline.LogMethodEnter(
             nameof(BlobLeaseClient),
             message:
             $"{nameof(Uri)}: {Uri}\n" +
             $"{nameof(LeaseId)}: {LeaseId}\n" +
             $"{nameof(proposedId)}: {proposedId}\n" +
             $"{nameof(conditions)}: {conditions}");
         try
         {
             if (BlobClient != null)
             {
                 return(await BlobRestClient.Blob.ChangeLeaseAsync(
                            ClientDiagnostics,
                            Pipeline,
                            Uri,
                            leaseId : LeaseId,
                            proposedLeaseId : proposedId,
                            ifModifiedSince : conditions?.IfModifiedSince,
                            ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                            ifMatch : conditions?.IfMatch,
                            ifNoneMatch : conditions?.IfNoneMatch,
                            async : async,
                            operationName : Constants.Blob.Lease.ChangeOperationName,
                            cancellationToken : cancellationToken)
                        .ConfigureAwait(false));
             }
             else
             {
                 if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default)
                 {
                     throw BlobErrors.BlobConditionsMustBeDefault(
                               nameof(conditions.IfMatch),
                               nameof(conditions.IfNoneMatch));
                 }
                 return(await BlobRestClient.Container.ChangeLeaseAsync(
                            ClientDiagnostics,
                            Pipeline,
                            Uri,
                            leaseId : LeaseId,
                            proposedLeaseId : proposedId,
                            ifModifiedSince : conditions?.IfModifiedSince,
                            ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                            async : async,
                            operationName : Constants.Blob.Lease.ChangeOperationName,
                            cancellationToken : cancellationToken)
                        .ConfigureAwait(false));
             }
         }
         catch (Exception ex)
         {
             Pipeline.LogException(ex);
             throw;
         }
         finally
         {
             Pipeline.LogMethodExit(nameof(BlobLeaseClient));
         }
     }
 }
예제 #26
0
        public AzureBlobsLogWriter(BlobContainerClient blobsContainerClient,
                                   string fileName,
                                   bool appendOpen = false)
        {
            fileName = AzureBlobsLogsInterface.PathFixer(fileName);
            _blobsContainerClient = blobsContainerClient;
            _logClient            = _blobsContainerClient.GetAppendBlobClient(fileName);
            ETag currentETag;

            if (_previousOpenAttempts.ContainsKey(fileName) && appendOpen)
            {
                // We've opened this blob before and want to be non-destructive. We don't need to CreateIfNotExists, which could be VERY slow.
                currentETag = _logClient.GetProperties().Value.ETag;
            }
            else
            {
                try
                {
                    // Create the file non-destructively if needed, guaranteeing write continuity on creation by grabbing the etag of the create, if needed
                    if (appendOpen)
                    {
                        var response = _logClient.CreateIfNotExists();
                        if (response != null)
                        {
                            currentETag = response.Value.ETag;
                        }
                        else
                        {
                            currentETag = _logClient.GetProperties().Value.ETag;
                        }
                    }
                    else
                    {
                        currentETag = _logClient.Create().Value.ETag;
                    }
                }
                catch { currentETag = _logClient.GetProperties().Value.ETag; }
            }
            // Try to grab the blob lease
            _leaseClient = _logClient.GetBlobLeaseClient();
            // The blob hasn't be touched since the last time. This is a candidate for breaking the lease.
            if (_previousOpenAttempts.ContainsKey(fileName) && (_previousOpenAttempts[fileName].ToString().Equals(currentETag.ToString())))
            {
                _previousOpenAttempts[fileName] = currentETag;
                // The blob hasn't been updated. Try to break the lease and reacquire
                var requestConditions = new BlobRequestConditions();
                requestConditions         = new BlobRequestConditions();
                requestConditions.IfMatch = currentETag;
                // If the condition fails in the break, it's because someone else managed to touch the file, so give up
                ETag newETag;
                try
                {
                    newETag = _leaseClient.Break(null, requestConditions).Value.ETag;
                }
                catch (Exception e) { newETag = currentETag; }
                var etagCondition = new RequestConditions();
                etagCondition.IfMatch = newETag;
                // If the condition fails, someone snuck in and grabbed the lock before we could. Give up.
                _curLease = _leaseClient.Acquire(TimeSpan.FromSeconds(-1), etagCondition).Value;
            }
            else
            {
                // Not a candidate for breaking the lease. Just try to acquire.
                _previousOpenAttempts[fileName] = currentETag;
                _curLease = _leaseClient.Acquire(TimeSpan.FromSeconds(-1)).Value;
            }

            _leaseCondition         = new AppendBlobRequestConditions();
            _leaseCondition.LeaseId = _curLease.LeaseId;
            // We got the lease! Set up thread to periodically touch the blob to prevent others from breaking the lease.
            _blobMetadata        = _logClient.GetProperties().Value.Metadata;
            _stopRelockThread    = false;
            _relockThreadStopped = false;
            _leaseRenewThread    = new Thread(() =>
            {
                while (!_stopRelockThread)
                {
                    Thread.Sleep(100);
                    var response = _logClient.SetMetadata(_blobMetadata, _leaseCondition);
                }
                _relockThreadStopped = true;
            })
            {
                IsBackground = true
            };
            _leaseRenewThread.Start();
            _bytesToSend = new MemoryStream();
            Debug.Assert(_logClient.Exists());
        }
예제 #27
0
        /// <summary>
        /// The <see cref="ReleaseInternal"/> operation releases the
        /// container or blob's previously-acquired lease.
        ///
        /// The lease may be released if the <see cref="LeaseId"/>
        /// matches that associated with the container or blob.  Releasing the
        /// lease allows another client to immediately acquire the lease for the
        /// container or blob as soon as the release is complete.
        ///
        /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />.
        /// </summary>
        /// <param name="conditions">
        /// Optional <see cref="RequestConditions"/> to add
        /// conditions on releasing a lease.
        /// </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{ReleasedObjectInfo}"/> describing the
        /// updated blob or container.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual async Task <Response <ReleasedObjectInfo> > ReleaseInternal(
            RequestConditions conditions,
            bool async,
            CancellationToken cancellationToken)
        {
            EnsureClient();
            using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient)))
            {
                Pipeline.LogMethodEnter(
                    nameof(BlobLeaseClient),
                    message:
                    $"{nameof(Uri)}: {Uri}\n" +
                    $"{nameof(LeaseId)}: {LeaseId}\n" +
                    $"{nameof(conditions)}: {conditions}");
                try
                {
                    if (BlobClient != null)
                    {
                        Response <BlobInfo> response =
                            await BlobRestClient.Blob.ReleaseLeaseAsync(
                                ClientDiagnostics,
                                Pipeline,
                                Uri,
                                leaseId : LeaseId,
                                ifModifiedSince : conditions?.IfModifiedSince,
                                ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                                ifMatch : conditions?.IfMatch,
                                ifNoneMatch : conditions?.IfNoneMatch,
                                async : async,
                                operationName : Constants.Blob.Lease.ReleaseOperationName,
                                cancellationToken : cancellationToken)
                            .ConfigureAwait(false);

                        return(Response.FromValue(new ReleasedObjectInfo(response.Value), response.GetRawResponse()));
                    }
                    else
                    {
                        if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default)
                        {
                            throw BlobErrors.BlobConditionsMustBeDefault(
                                      nameof(RequestConditions.IfMatch),
                                      nameof(RequestConditions.IfNoneMatch));
                        }
                        Response <BlobContainerInfo> response =
                            await BlobRestClient.Container.ReleaseLeaseAsync(
                                ClientDiagnostics,
                                Pipeline,
                                Uri,
                                leaseId : LeaseId,
                                ifModifiedSince : conditions?.IfModifiedSince,
                                ifUnmodifiedSince : conditions?.IfUnmodifiedSince,
                                async : async,
                                operationName : Constants.Blob.Lease.ReleaseOperationName,
                                cancellationToken : cancellationToken)
                            .ConfigureAwait(false);

                        return(Response.FromValue(new ReleasedObjectInfo(response.Value), response.GetRawResponse()));
                    }
                }
                catch (Exception ex)
                {
                    Pipeline.LogException(ex);
                    throw;
                }
                finally
                {
                    Pipeline.LogMethodExit(nameof(BlobLeaseClient));
                }
            }
        }