/// <summary> /// The <see cref="RenewInternal"/> 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="httpAccessConditions"> /// Optional <see cref="HttpAccessConditions"/> to add /// conditions on renewing 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="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <Lease> > RenewInternal( HttpAccessConditions?httpAccessConditions, bool async, CancellationToken cancellationToken) { using (this.Pipeline.BeginLoggingScope(nameof(LeaseClient))) { this.Pipeline.LogMethodEnter( nameof(LeaseClient), message: $"{nameof(this.Uri)}: {this.Uri}\n" + $"{nameof(this.LeaseId)}: {this.LeaseId}\n" + $"{nameof(httpAccessConditions)}: {httpAccessConditions}"); try { if (this.BlobClient != null) { return(await BlobRestClient.Blob.RenewLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, ifMatch : httpAccessConditions?.IfMatch, ifNoneMatch : httpAccessConditions?.IfNoneMatch, async : async, operationName : Constants.Blob.Lease.RenewOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false)); } else { if (httpAccessConditions?.IfMatch != default || httpAccessConditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(HttpAccessConditions.IfMatch), nameof(HttpAccessConditions.IfNoneMatch)); } return(await BlobRestClient.Container.RenewLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, async : async, cancellationToken : cancellationToken) .ConfigureAwait(false)); } } catch (Exception ex) { this.Pipeline.LogException(ex); throw; } finally { this.Pipeline.LogMethodExit(nameof(LeaseClient)); } } }
/// <summary> /// Ensure either the Blob or Container is present. /// </summary> private void EnsureClient() { if (BlobClient == null && BlobContainerClient == null) { // This can only happen if someone's not being careful while mocking throw BlobErrors.BlobOrContainerMissing(nameof(BlobLeaseClient), nameof(BlobBaseClient), nameof(BlobContainerClient)); } }
/// <summary> /// The <see cref="CreateInternal"/> operation creates a new 0-length /// append blob. The content of any existing blob is overwritten with /// the newly initialized append blob. To add content to the append /// blob, call the <see cref="AppendBlockAsync"/> operation. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob" />. /// </summary> /// <param name="httpHeaders"> /// Optional standard HTTP header properties that can be set for the /// new append blob. /// </param> /// <param name="metadata"> /// Optional custom metadata to set for this append blob. /// </param> /// <param name="accessConditions"> /// Optional <see cref="AppendBlobAccessConditions"/> to add /// conditions on the creation of this new append blob. /// </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{BlobContentInfo}"/> describing the /// newly created append blob. /// </returns> /// <remarks> /// A <see cref="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <BlobContentInfo> > CreateInternal( BlobHttpHeaders?httpHeaders, Metadata metadata, AppendBlobAccessConditions?accessConditions, bool async, CancellationToken cancellationToken) { using (Pipeline.BeginLoggingScope(nameof(AppendBlobClient))) { Pipeline.LogMethodEnter( nameof(AppendBlobClient), message: $"{nameof(Uri)}: {Uri}\n" + $"{nameof(httpHeaders)}: {httpHeaders}\n" + $"{nameof(accessConditions)}: {accessConditions}"); try { BlobErrors.VerifyHttpsCustomerProvidedKey(Uri, CustomerProvidedKey); return(await BlobRestClient.AppendBlob.CreateAsync( Pipeline, Uri, contentLength : default,
/// <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="breakPeriodInSeconds"/> 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="breakPeriodInSeconds"> /// 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="accessConditions"> /// Optional <see cref="HttpAccessConditions"/> 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="Task{Response{Lease}}"/> describing the broken lease. /// </returns> /// <remarks> /// A <see cref="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <Lease> > BreakAsync( int?breakPeriodInSeconds, HttpAccessConditions?httpAccessConditions, bool async, CancellationToken cancellationToken) { this.EnsureClient(); using (this.Pipeline.BeginLoggingScope(nameof(LeaseClient))) { this.Pipeline.LogMethodEnter( nameof(LeaseClient), message: $"{nameof(this.Uri)}: {this.Uri}\n" + $"{nameof(breakPeriodInSeconds)}: {breakPeriodInSeconds}\n" + $"{nameof(httpAccessConditions)}: {httpAccessConditions}"); try { if (this.BlobClient != null) { return((await BlobRestClient.Blob.BreakLeaseAsync( this.Pipeline, this.Uri, breakPeriod: breakPeriodInSeconds, ifModifiedSince: httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince: httpAccessConditions?.IfUnmodifiedSince, ifMatch: httpAccessConditions?.IfMatch, ifNoneMatch: httpAccessConditions?.IfNoneMatch, async: async, cancellationToken: cancellationToken) .ConfigureAwait(false)) .ToLease()); } else { if (httpAccessConditions?.IfMatch != default || httpAccessConditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(HttpAccessConditions.IfMatch), nameof(HttpAccessConditions.IfNoneMatch)); } return((await BlobRestClient.Container.BreakLeaseAsync( this.Pipeline, this.Uri, breakPeriod: breakPeriodInSeconds, ifModifiedSince: httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince: httpAccessConditions?.IfUnmodifiedSince, async: async, cancellationToken: cancellationToken) .ConfigureAwait(false)) .ToLease()); } } catch (Exception ex) { this.Pipeline.LogException(ex); throw; } finally { this.Pipeline.LogMethodExit(nameof(LeaseClient)); } } }
/// <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="accessConditions"> /// Optional <see cref="HttpAccessConditions"/> 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="Task{Response{ReleasedObjectInfo}}"/> describing the /// updated blob or container. /// </returns> /// <remarks> /// A <see cref="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync( HttpAccessConditions?httpAccessConditions, bool async, CancellationToken cancellationToken) { this.EnsureClient(); using (this.Pipeline.BeginLoggingScope(nameof(LeaseClient))) { this.Pipeline.LogMethodEnter( nameof(LeaseClient), message: $"{nameof(this.Uri)}: {this.Uri}\n" + $"{nameof(this.LeaseId)}: {this.LeaseId}\n" + $"{nameof(httpAccessConditions)}: {httpAccessConditions}"); try { if (this.BlobClient != null) { var response = await BlobRestClient.Blob.ReleaseLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, ifMatch : httpAccessConditions?.IfMatch, ifNoneMatch : httpAccessConditions?.IfNoneMatch, async : async, cancellationToken : cancellationToken) .ConfigureAwait(false); return(new Response <ReleasedObjectInfo>( response.GetRawResponse(), new ReleasedObjectInfo(response.Value))); } else { if (httpAccessConditions?.IfMatch != default || httpAccessConditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(HttpAccessConditions.IfMatch), nameof(HttpAccessConditions.IfNoneMatch)); } var response = await BlobRestClient.Container.ReleaseLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, async : async, cancellationToken : cancellationToken) .ConfigureAwait(false); return(new Response <ReleasedObjectInfo>( response.GetRawResponse(), new ReleasedObjectInfo(response.Value))); } } catch (Exception ex) { this.Pipeline.LogException(ex); throw; } finally { this.Pipeline.LogMethodExit(nameof(LeaseClient)); } } }
/// <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 -1 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="accessConditions"> /// Optional <see cref="HttpAccessConditions"/> 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="Task{Response{Lease}}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <Lease> > AcquireAsync( int duration, HttpAccessConditions?httpAccessConditions, bool async, CancellationToken cancellationToken) { this.EnsureClient(); using (this.Pipeline.BeginLoggingScope(nameof(LeaseClient))) { this.Pipeline.LogMethodEnter( nameof(LeaseClient), message: $"{nameof(this.Uri)}: {this.Uri}\n" + $"{nameof(this.LeaseId)}: {this.LeaseId}\n" + $"{nameof(duration)}: {duration}"); try { if (this.BlobClient != null) { return(await BlobRestClient.Blob.AcquireLeaseAsync( this.Pipeline, this.Uri, duration : duration, proposedLeaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, ifMatch : httpAccessConditions?.IfMatch, ifNoneMatch : httpAccessConditions?.IfNoneMatch, async : async, cancellationToken : cancellationToken) .ConfigureAwait(false)); } else { if (httpAccessConditions?.IfMatch != default || httpAccessConditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(HttpAccessConditions.IfMatch), nameof(HttpAccessConditions.IfNoneMatch)); } return(await BlobRestClient.Container.AcquireLeaseAsync( this.Pipeline, this.Uri, duration : duration, proposedLeaseId : this.LeaseId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, async : async, cancellationToken : cancellationToken) .ConfigureAwait(false)); } } catch (Exception ex) { this.Pipeline.LogException(ex); throw; } finally { this.Pipeline.LogMethodExit(nameof(LeaseClient)); } } }
/// <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)); } } }
/// <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)); } } }
/// <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)); } } }
/// <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)); } } }
/// <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="StorageRequestFailedException"/> will be thrown if the /// proposed lease ID is not in the correct format. /// </param> /// <param name="httpAccessConditions"> /// Optional <see cref="HttpAccessConditions"/> 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="StorageRequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <Lease> > ChangeInternal( string proposedId, HttpAccessConditions?httpAccessConditions, bool async, CancellationToken cancellationToken) { this.EnsureClient(); using (this.Pipeline.BeginLoggingScope(nameof(LeaseClient))) { this.Pipeline.LogMethodEnter( nameof(LeaseClient), message: $"{nameof(this.Uri)}: {this.Uri}\n" + $"{nameof(this.LeaseId)}: {this.LeaseId}\n" + $"{nameof(proposedId)}: {proposedId}\n" + $"{nameof(httpAccessConditions)}: {httpAccessConditions}"); try { if (this.BlobClient != null) { return(await BlobRestClient.Blob.ChangeLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, proposedLeaseId : proposedId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, ifMatch : httpAccessConditions?.IfMatch, ifNoneMatch : httpAccessConditions?.IfNoneMatch, async : async, operationName : "Azure.Storage.Blobs.Specialized.LeaseClient.Change", cancellationToken : cancellationToken) .ConfigureAwait(false)); } else { if (httpAccessConditions?.IfMatch != default || httpAccessConditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(HttpAccessConditions.IfMatch), nameof(HttpAccessConditions.IfNoneMatch)); } return(await BlobRestClient.Container.ChangeLeaseAsync( this.Pipeline, this.Uri, leaseId : this.LeaseId, proposedLeaseId : proposedId, ifModifiedSince : httpAccessConditions?.IfModifiedSince, ifUnmodifiedSince : httpAccessConditions?.IfUnmodifiedSince, async : async, operationName : "Azure.Storage.Blobs.Specialized.LeaseClient.Change", cancellationToken : cancellationToken) .ConfigureAwait(false)); } } catch (Exception ex) { this.Pipeline.LogException(ex); throw; } finally { this.Pipeline.LogMethodExit(nameof(LeaseClient)); } } }