< Summary

Class:Azure.Storage.Files.Shares.Specialized.SpecializedFileExtensions
Assembly:Azure.Storage.Files.Shares
File(s):C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.Shares\src\ShareLeaseClient.cs
Covered lines:1
Uncovered lines:0
Coverable lines:1
Total lines:607
Line coverage:100% (1 of 1)
Covered branches:0
Total branches:0

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
GetShareLeaseClient(...)-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.Shares\src\ShareLeaseClient.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using Azure.Core.Pipeline;
 8using Azure.Storage.Files.Shares.Models;
 9
 10#pragma warning disable SA1402  // File may only contain a single type
 11
 12namespace Azure.Storage.Files.Shares.Specialized
 13{
 14    /// <summary>
 15    /// The <see cref="ShareLeaseClient"/> allows you to manipulate Azure
 16    /// Storage leases on files.
 17    /// </summary>
 18    public class ShareLeaseClient
 19    {
 20        /// <summary>
 21        /// The <see cref="ShareFileClient"/> to manage leases for.
 22        /// </summary>
 23        private readonly ShareFileClient _file;
 24
 25        /// <summary>
 26        /// The <see cref="ShareFileClient"/> to manage leases for.
 27        /// </summary>
 28        protected virtual ShareFileClient FileClient => _file;
 29
 30        /// <summary>
 31        /// Gets the URI of the object being leased.
 32        /// </summary>
 33        public Uri Uri => FileClient?.Uri;
 34
 35        /// <summary>
 36        /// Gets the Lease ID for this lease.
 37        /// </summary>
 38        public virtual string LeaseId { get; private set; }
 39
 40        /// <summary>
 41        /// The <see cref="HttpPipeline"/> transport pipeline used to send
 42        /// every request.
 43        /// </summary>
 44        private HttpPipeline Pipeline => FileClient?.Pipeline;
 45
 46        /// <summary>
 47        /// The version of the service to use when sending requests.
 48        /// </summary>
 49        internal virtual ShareClientOptions.ServiceVersion Version => FileClient.Version;
 50
 51        /// <summary>
 52        /// The <see cref="ClientDiagnostics"/> instance used to create diagnostic scopes
 53        /// every request.
 54        /// </summary>
 55        internal virtual ClientDiagnostics ClientDiagnostics => FileClient?.ClientDiagnostics;
 56
 57        /// <summary>
 58        /// Initializes a new instance of the <see cref="ShareLeaseClient"/> class
 59        /// for mocking.
 60        /// </summary>
 61        protected ShareLeaseClient()
 62        {
 63            _file = null;
 64        }
 65
 66        /// <summary>
 67        /// Initializes a new instance of the <see cref="ShareLeaseClient"/> class.
 68        /// </summary>
 69        /// <param name="client">
 70        /// A <see cref="ShareFileClient"/> representing the file being leased.
 71        /// </param>
 72        /// <param name="leaseId">
 73        /// An optional lease ID.  If no lease ID is provided, a random lease
 74        /// ID will be created.
 75        /// </param>
 76        public ShareLeaseClient(ShareFileClient client, string leaseId = null)
 77        {
 78            _file = client ?? throw Errors.ArgumentNull(nameof(client));
 79            LeaseId = leaseId ?? CreateUniqueLeaseId();
 80        }
 81
 82        /// <summary>
 83        /// Gets a unique lease ID.
 84        /// </summary>
 85        /// <returns>A unique lease ID.</returns>
 86        private static string CreateUniqueLeaseId() => Guid.NewGuid().ToString();
 87
 88        #region Acquire
 89        /// <summary>
 90        /// The <see cref="Acquire"/> operation acquires a lease on
 91        /// the file.
 92        ///
 93        /// If the file does not have an active lease, the File service
 94        /// creates a lease on the file and returns it.  If the
 95        /// file has an active lease, you can only request a new lease
 96        /// using the active lease ID as <see cref="LeaseId"/>
 97        ///
 98        /// </summary>
 99        /// <param name="cancellationToken">
 100        /// Optional <see cref="CancellationToken"/> to propagate
 101        /// notifications that the operation should be cancelled.
 102        /// </param>
 103        /// <returns>
 104        /// A <see cref="Response{Lease}"/> describing the lease.
 105        /// </returns>
 106        /// <remarks>
 107        /// A <see cref="RequestFailedException"/> will be thrown if
 108        /// a failure occurs.
 109        /// </remarks>
 110        public virtual Response<ShareFileLease> Acquire(
 111            CancellationToken cancellationToken = default) =>
 112            AcquireInternal(
 113                false, // async
 114                cancellationToken)
 115                .EnsureCompleted();
 116
 117        /// <summary>
 118        /// The <see cref="AcquireAsync"/> operation acquires a lease on
 119        /// the file.
 120        ///
 121        /// If the file does not have an active lease, the File service
 122        /// creates a lease on the file and returns it.  If the
 123        /// file has an active lease, you can only request a new lease
 124        /// using the active lease ID as <see cref="LeaseId"/>.
 125        ///
 126        /// </summary>
 127        /// <param name="cancellationToken">
 128        /// Optional <see cref="CancellationToken"/> to propagate
 129        /// notifications that the operation should be cancelled.
 130        /// </param>
 131        /// <returns>
 132        /// A <see cref="Response{Lease}"/> describing the lease.
 133        /// </returns>
 134        /// <remarks>
 135        /// A <see cref="RequestFailedException"/> will be thrown if
 136        /// a failure occurs.
 137        /// </remarks>
 138        public virtual async Task<Response<ShareFileLease>> AcquireAsync(
 139            CancellationToken cancellationToken = default) =>
 140            await AcquireInternal(
 141                true, // async
 142                cancellationToken)
 143                .ConfigureAwait(false);
 144
 145        /// <summary>
 146        /// The <see cref="AcquireInternal"/> operation acquires a lease on
 147        /// the file.
 148        ///
 149        /// If the file does not have an active lease, the File service
 150        /// creates a lease on the file and returns it.  If the
 151        /// file has an active lease, you can only request a new lease
 152        /// using the active lease ID as <see cref="LeaseId"/>.
 153        ///
 154        /// </summary>
 155        /// <param name="async">
 156        /// Whether to invoke the operation asynchronously.
 157        /// </param>
 158        /// <param name="cancellationToken">
 159        /// Optional <see cref="CancellationToken"/> to propagate
 160        /// notifications that the operation should be cancelled.
 161        /// </param>
 162        /// <returns>
 163        /// A <see cref="Response{Lease}"/> describing the lease.
 164        /// </returns>
 165        /// <remarks>
 166        /// A <see cref="RequestFailedException"/> will be thrown if
 167        /// a failure occurs.
 168        /// </remarks>
 169        private async Task<Response<ShareFileLease>> AcquireInternal(
 170            bool async,
 171            CancellationToken cancellationToken)
 172        {
 173            using (Pipeline.BeginLoggingScope(nameof(ShareLeaseClient)))
 174            {
 175                Pipeline.LogMethodEnter(
 176                    nameof(ShareLeaseClient),
 177                    message:
 178                    $"{nameof(Uri)}: {Uri}\n" +
 179                    $"{nameof(LeaseId)}: {LeaseId}\n");
 180                try
 181                {
 182                    return await FileRestClient.File.AcquireLeaseAsync(
 183                        ClientDiagnostics,
 184                        Pipeline,
 185                        Uri,
 186                        Version.ToVersionString(),
 187                        duration: Constants.File.Lease.InfiniteLeaseDuration,
 188                        proposedLeaseId: LeaseId,
 189                        async: async,
 190                        operationName: $"{nameof(ShareLeaseClient)}.{nameof(Acquire)}",
 191                        cancellationToken: cancellationToken)
 192                        .ConfigureAwait(false);
 193                }
 194                catch (Exception ex)
 195                {
 196                    Pipeline.LogException(ex);
 197                    throw;
 198                }
 199                finally
 200                {
 201                    Pipeline.LogMethodExit(nameof(ShareLeaseClient));
 202                }
 203            }
 204        }
 205        #endregion Acquire
 206
 207        #region Release
 208        /// <summary>
 209        /// The <see cref="Release"/> operation releases the
 210        /// files's previously-acquired lease.
 211        ///
 212        /// The lease may be released if the <see cref="LeaseId"/>
 213        /// matches that associated with the file.  Releasing the
 214        /// lease allows another client to immediately acquire the lease for the
 215        /// file as soon as the release is complete.
 216        ///
 217        /// </summary>
 218        /// <param name="cancellationToken">
 219        /// Optional <see cref="CancellationToken"/> to propagate
 220        /// notifications that the operation should be cancelled.
 221        /// </param>
 222        /// <returns>
 223        /// A <see cref="Response{FileLeaseReleaseInfo}"/> describing the
 224        /// updated blob or container.
 225        /// </returns>
 226        /// <remarks>
 227        /// A <see cref="RequestFailedException"/> will be thrown if
 228        /// a failure occurs.
 229        /// </remarks>
 230        public virtual Response<FileLeaseReleaseInfo> Release(
 231            CancellationToken cancellationToken = default) =>
 232            ReleaseInternal(
 233                false, // async
 234                cancellationToken)
 235                .EnsureCompleted();
 236
 237        /// <summary>
 238        /// The <see cref="ReleaseAsync"/> operation releases the
 239        /// files's previously-acquired lease.
 240        ///
 241        /// The lease may be released if the <see cref="LeaseId"/>
 242        /// matches that associated with the file.  Releasing the
 243        /// lease allows another client to immediately acquire the lease for the
 244        /// file as soon as the release is complete.
 245        ///
 246        /// </summary>
 247        /// <param name="cancellationToken">
 248        /// Optional <see cref="CancellationToken"/> to propagate
 249        /// notifications that the operation should be cancelled.
 250        /// </param>
 251        /// <returns>
 252        /// A <see cref="Response{FileLeaseReleaseInfo}"/> describing the
 253        /// updated file.
 254        /// </returns>
 255        /// <remarks>
 256        /// A <see cref="RequestFailedException"/> will be thrown if
 257        /// a failure occurs.
 258        /// </remarks>
 259        public virtual async Task<Response<FileLeaseReleaseInfo>> ReleaseAsync(
 260            CancellationToken cancellationToken = default) =>
 261            await ReleaseInternal(
 262                true, // async
 263                cancellationToken)
 264                .ConfigureAwait(false);
 265
 266        /// <summary>
 267        /// The <see cref="ReleaseInternal"/> operation releases the
 268        /// files's previously-acquired lease.
 269        ///
 270        /// The lease may be released if the <see cref="LeaseId"/>
 271        /// matches that associated with the file.  Releasing the
 272        /// lease allows another client to immediately acquire the lease for the
 273        /// file as soon as the release is complete.
 274        ///
 275        /// </summary>
 276        /// <param name="async">
 277        /// Whether to invoke the operation asynchronously.
 278        /// </param>
 279        /// <param name="cancellationToken">
 280        /// Optional <see cref="CancellationToken"/> to propagate
 281        /// notifications that the operation should be cancelled.
 282        /// </param>
 283        /// <returns>
 284        /// A <see cref="Response{FileLeaseReleaseInfo}"/> describing the
 285        /// updated file.
 286        /// </returns>
 287        /// <remarks>
 288        /// A <see cref="RequestFailedException"/> will be thrown if
 289        /// a failure occurs.
 290        /// </remarks>
 291        internal virtual async Task<Response<FileLeaseReleaseInfo>> ReleaseInternal(
 292            bool async,
 293            CancellationToken cancellationToken)
 294        {
 295            using (Pipeline.BeginLoggingScope(nameof(ShareLeaseClient)))
 296            {
 297                Pipeline.LogMethodEnter(
 298                    nameof(ShareLeaseClient),
 299                    message:
 300                    $"{nameof(Uri)}: {Uri}\n" +
 301                    $"{nameof(LeaseId)}: {LeaseId}");
 302                try
 303                {
 304                    return await FileRestClient.File.ReleaseLeaseAsync(
 305                        ClientDiagnostics,
 306                        Pipeline,
 307                        Uri,
 308                        leaseId: LeaseId,
 309                        Version.ToVersionString(),
 310                        async: async,
 311                        operationName: $"{nameof(ShareLeaseClient)}.{nameof(Release)}",
 312                        cancellationToken: cancellationToken)
 313                        .ConfigureAwait(false);
 314                }
 315                catch (Exception ex)
 316                {
 317                    Pipeline.LogException(ex);
 318                    throw;
 319                }
 320                finally
 321                {
 322                    Pipeline.LogMethodExit(nameof(ShareLeaseClient));
 323                }
 324            }
 325        }
 326        #endregion Release
 327
 328        #region Change
 329        /// <summary>
 330        /// The <see cref="Change"/> operation changes the lease
 331        /// of an active lease.  A change must include the current
 332        /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 333        ///
 334        /// </summary>
 335        /// <param name="proposedId">
 336        /// An optional proposed lease ID, in a GUID string format. A
 337        /// <see cref="RequestFailedException"/> will be thrown if the
 338        /// proposed lease ID is not in the correct format.
 339        /// </param>
 340        /// <param name="cancellationToken">
 341        /// Optional <see cref="CancellationToken"/> to propagate
 342        /// notifications that the operation should be cancelled.
 343        /// </param>
 344        /// <returns>
 345        /// A <see cref="Response{FileLease}"/> describing the lease.
 346        /// </returns>
 347        /// <remarks>
 348        /// A <see cref="RequestFailedException"/> will be thrown if
 349        /// a failure occurs.
 350        /// </remarks>
 351        public virtual Response<ShareFileLease> Change(
 352            string proposedId,
 353            CancellationToken cancellationToken = default) =>
 354            ChangeInternal(
 355                proposedId,
 356                false, // async
 357                cancellationToken)
 358                .EnsureCompleted();
 359
 360        /// <summary>
 361        /// The <see cref="ChangeAsync"/> operation changes the lease
 362        /// of an active lease.  A change must include the current
 363        /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 364        ///
 365        /// </summary>
 366        /// <param name="proposedId">
 367        /// An optional proposed lease ID, in a GUID string format. A
 368        /// <see cref="RequestFailedException"/> will be thrown if the
 369        /// proposed lease ID is not in the correct format.
 370        /// </param>
 371        /// <param name="cancellationToken">
 372        /// Optional <see cref="CancellationToken"/> to propagate
 373        /// notifications that the operation should be cancelled.
 374        /// </param>
 375        /// <returns>
 376        /// A <see cref="Response{Lease}"/> describing the lease.
 377        /// </returns>
 378        /// <remarks>
 379        /// A <see cref="RequestFailedException"/> will be thrown if
 380        /// a failure occurs.
 381        /// </remarks>
 382        public virtual async Task<Response<ShareFileLease>> ChangeAsync(
 383            string proposedId,
 384            CancellationToken cancellationToken = default) =>
 385            await ChangeInternal(
 386                proposedId,
 387                true, // async
 388                cancellationToken)
 389                .ConfigureAwait(false);
 390
 391        /// <summary>
 392        /// The <see cref="ChangeInternal"/> operation changes the lease
 393        /// of an active lease.  A change must include the current
 394        /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>.
 395        ///
 396        /// </summary>
 397        /// <param name="proposedId">
 398        /// An optional proposed lease ID, in a GUID string format. A
 399        /// <see cref="RequestFailedException"/> will be thrown if the
 400        /// proposed lease ID is not in the correct format.
 401        /// </param>
 402        /// <param name="async">
 403        /// Whether to invoke the operation asynchronously.
 404        /// </param>
 405        /// <param name="cancellationToken">
 406        /// Optional <see cref="CancellationToken"/> to propagate
 407        /// notifications that the operation should be cancelled.
 408        /// </param>
 409        /// <returns>
 410        /// A <see cref="Response{FileLease}"/> describing the lease.
 411        /// </returns>
 412        /// <remarks>
 413        /// A <see cref="RequestFailedException"/> will be thrown if
 414        /// a failure occurs.
 415        /// </remarks>
 416        private async Task<Response<ShareFileLease>> ChangeInternal(
 417            string proposedId,
 418            bool async,
 419            CancellationToken cancellationToken)
 420        {
 421            using (Pipeline.BeginLoggingScope(nameof(ShareLeaseClient)))
 422            {
 423                Pipeline.LogMethodEnter(
 424                    nameof(ShareLeaseClient),
 425                    message:
 426                    $"{nameof(Uri)}: {Uri}\n" +
 427                    $"{nameof(LeaseId)}: {LeaseId}\n" +
 428                    $"{nameof(proposedId)}: {proposedId}");
 429                try
 430                {
 431                    return await FileRestClient.File.ChangeLeaseAsync(
 432                        ClientDiagnostics,
 433                        Pipeline,
 434                        Uri,
 435                        leaseId: LeaseId,
 436                        Version.ToVersionString(),
 437                        proposedLeaseId: proposedId,
 438                        async: async,
 439                        operationName: $"{nameof(ShareLeaseClient)}.{nameof(Change)}",
 440                        cancellationToken: cancellationToken)
 441                        .ConfigureAwait(false);
 442                }
 443                catch (Exception ex)
 444                {
 445                    Pipeline.LogException(ex);
 446                    throw;
 447                }
 448                finally
 449                {
 450                    Pipeline.LogMethodExit(nameof(ShareLeaseClient));
 451                }
 452            }
 453        }
 454        #endregion Change
 455
 456        #region Break
 457        /// <summary>
 458        /// The <see cref="Break"/> operation breaks the files's
 459        /// previously-acquired lease (if it exists).
 460        ///
 461        /// Once a lease is broken, it cannot be renewed.  Any authorized
 462        /// request can break the lease; the request is not required to
 463        /// specify a matching lease ID.
 464        ///
 465        /// A lease that has been broken can also be released.  A client can
 466        /// immediately acquire a file lease that has been
 467        /// released.
 468        ///
 469        /// </summary>
 470        /// <param name="cancellationToken">
 471        /// Optional <see cref="CancellationToken"/> to propagate
 472        /// notifications that the operation should be cancelled.
 473        /// </param>
 474        /// <returns>
 475        /// A <see cref="Response{FileLease}"/> describing the broken lease.
 476        /// </returns>
 477        /// <remarks>
 478        /// A <see cref="RequestFailedException"/> will be thrown if
 479        /// a failure occurs.
 480        /// </remarks>
 481        public virtual Response<ShareFileLease> Break(
 482            CancellationToken cancellationToken = default) =>
 483            BreakInternal(
 484                false, // async
 485                cancellationToken)
 486                .EnsureCompleted();
 487
 488        /// <summary>
 489        /// The <see cref="BreakAsync"/> operation breaks the files's
 490        /// previously-acquired lease (if it exists).
 491        ///
 492        /// Once a lease is broken, it cannot be renewed.  Any authorized
 493        /// request can break the lease; the request is not required to
 494        /// specify a matching lease ID.
 495        ///
 496        /// A lease that has been broken can also be released.  A client can
 497        /// immediately acquire a file lease that has been
 498        /// released.
 499        ///
 500        /// </summary>
 501        /// <param name="cancellationToken">
 502        /// Optional <see cref="CancellationToken"/> to propagate
 503        /// notifications that the operation should be cancelled.
 504        /// </param>
 505        /// <returns>
 506        /// A <see cref="Response{FileLease}"/> describing the broken lease.
 507        /// </returns>
 508        /// <remarks>
 509        /// A <see cref="RequestFailedException"/> will be thrown if
 510        /// a failure occurs.
 511        /// </remarks>
 512        public virtual async Task<Response<ShareFileLease>> BreakAsync(
 513            CancellationToken cancellationToken = default) =>
 514            await BreakInternal(
 515                true, // async
 516                cancellationToken)
 517                .ConfigureAwait(false);
 518
 519        /// <summary>
 520        /// The <see cref="BreakInternal"/> operation breaks the files's
 521        /// previously-acquired lease (if it exists).
 522        ///
 523        /// Once a lease is broken, it cannot be renewed.  Any authorized
 524        /// request can break the lease; the request is not required to
 525        /// specify a matching lease ID.
 526        ///
 527        /// A lease that has been broken can also be released.  A client can
 528        /// immediately acquire a file lease that has been
 529        /// released.
 530        ///
 531        /// </summary>
 532        /// <param name="async">
 533        /// Whether to invoke the operation asynchronously.
 534        /// </param>
 535        /// <param name="cancellationToken">
 536        /// Optional <see cref="CancellationToken"/> to propagate
 537        /// notifications that the operation should be cancelled.
 538        /// </param>
 539        /// <returns>
 540        /// A <see cref="Response{FileLease}"/> describing the broken lease.
 541        /// </returns>
 542        /// <remarks>
 543        /// A <see cref="RequestFailedException"/> will be thrown if
 544        /// a failure occurs.
 545        /// </remarks>
 546        private async Task<Response<ShareFileLease>> BreakInternal(
 547            bool async,
 548            CancellationToken cancellationToken)
 549        {
 550            using (Pipeline.BeginLoggingScope(nameof(ShareLeaseClient)))
 551            {
 552                Pipeline.LogMethodEnter(
 553                    nameof(ShareLeaseClient),
 554                    message:
 555                    $"{nameof(Uri)}: {Uri}\n" +
 556                    $"{nameof(LeaseId)}: {LeaseId}");
 557                try
 558                {
 559                    return (await FileRestClient.File.BreakLeaseAsync(
 560                        ClientDiagnostics,
 561                        Pipeline,
 562                        Uri,
 563                        Version.ToVersionString(),
 564                        leaseId: LeaseId,
 565                        async: async,
 566                        operationName: $"{nameof(ShareLeaseClient)}.{nameof(Break)}",
 567                        cancellationToken: cancellationToken)
 568                        .ConfigureAwait(false))
 569                        .ToLease();
 570                }
 571                catch (Exception ex)
 572                {
 573                    Pipeline.LogException(ex);
 574                    throw;
 575                }
 576                finally
 577                {
 578                    Pipeline.LogMethodExit(nameof(ShareLeaseClient));
 579                }
 580            }
 581        }
 582        #endregion Break
 583    }
 584
 585    /// <summary>
 586    /// Add easy to discover methods to <see cref="ShareFileClient"/> for
 587    /// easily creating <see cref="ShareLeaseClient"/>
 588    /// instances.
 589    /// </summary>
 590    public static partial class SpecializedFileExtensions
 591    {
 592        /// <summary>
 593        /// Initializes a new instance of the <see cref="ShareLeaseClient"/> class.
 594        /// </summary>
 595        /// <param name="client">
 596        /// A <see cref="ShareFileClient"/> representing the file being leased.
 597        /// </param>
 598        /// <param name="leaseId">
 599        /// An optional lease ID.  If no lease ID is provided, a random lease
 600        /// ID will be created.
 601        /// </param>
 602        public static ShareLeaseClient GetShareLeaseClient(
 603            this ShareFileClient client,
 604            string leaseId = null) =>
 48605            new ShareLeaseClient(client, leaseId);
 606    }
 607}

Methods/Properties

GetShareLeaseClient(...)