1# -------------------------------------------------------------------------
2# Copyright (c) Microsoft Corporation. All rights reserved.
3# Licensed under the MIT License. See License.txt in the project root for
4# license information.
5# --------------------------------------------------------------------------
6
7from typing import (  # pylint: disable=unused-import
8    Union, Optional, Any,
9    TypeVar, TYPE_CHECKING
10)
11from azure.multiapi.storagev2.blob.v2019_07_07.aio import BlobLeaseClient
12from .._data_lake_lease import DataLakeLeaseClient as DataLakeLeaseClientBase
13
14
15if TYPE_CHECKING:
16    FileSystemClient = TypeVar("FileSystemClient")
17    DataLakeDirectoryClient = TypeVar("DataLakeDirectoryClient")
18    DataLakeFileClient = TypeVar("DataLakeFileClient")
19
20
21class DataLakeLeaseClient(DataLakeLeaseClientBase):
22    """Creates a new DataLakeLeaseClient.
23
24    This client provides lease operations on a FileSystemClient, DataLakeDirectoryClient or DataLakeFileClient.
25
26    :ivar str id:
27        The ID of the lease currently being maintained. This will be `None` if no
28        lease has yet been acquired.
29    :ivar str etag:
30        The ETag of the lease currently being maintained. This will be `None` if no
31        lease has yet been acquired or modified.
32    :ivar ~datetime.datetime last_modified:
33        The last modified timestamp of the lease currently being maintained.
34        This will be `None` if no lease has yet been acquired or modified.
35
36    :param client:
37        The client of the file system, directory, or file to lease.
38    :type client: ~azure.storage.filedatalake.aio.FileSystemClient or
39        ~azure.storage.filedatalake.aio.DataLakeDirectoryClient or ~azure.storage.filedatalake.aio.DataLakeFileClient
40    :param str lease_id:
41        A string representing the lease ID of an existing lease. This value does not
42        need to be specified in order to acquire a new lease, or break one.
43    """
44    def __init__(
45            self, client, lease_id=None
46    ):  # pylint: disable=missing-client-constructor-parameter-credential,missing-client-constructor-parameter-kwargs
47        # type: (Union[FileSystemClient, DataLakeDirectoryClient, DataLakeFileClient], Optional[str]) -> None
48        super(DataLakeLeaseClient, self).__init__(client, lease_id)
49
50        if hasattr(client, '_blob_client'):
51            _client = client._blob_client  # type: ignore # pylint: disable=protected-access
52        elif hasattr(client, '_container_client'):
53            _client = client._container_client  # type: ignore # pylint: disable=protected-access
54        else:
55            raise TypeError("Lease must use any of FileSystemClient DataLakeDirectoryClient, or DataLakeFileClient.")
56
57        self._blob_lease_client = BlobLeaseClient(_client, lease_id=lease_id)
58
59    def __enter__(self):
60        raise TypeError("Async lease must use 'async with'.")
61
62    def __exit__(self, *args):
63        self.release()
64
65    async def __aenter__(self):
66        return self
67
68    async def __aexit__(self, *args):
69        await self.release()
70
71    async def acquire(self, lease_duration=-1, **kwargs):
72        # type: (int, Optional[int], **Any) -> None
73        """Requests a new lease.
74
75        If the file/file system does not have an active lease, the DataLake service creates a
76        lease on the file/file system and returns a new lease ID.
77
78        :param int lease_duration:
79            Specifies the duration of the lease, in seconds, or negative one
80            (-1) for a lease that never expires. A non-infinite lease can be
81            between 15 and 60 seconds. A lease duration cannot be changed
82            using renew or change. Default is -1 (infinite lease).
83        :keyword ~datetime.datetime if_modified_since:
84            A DateTime value. Azure expects the date value passed in to be UTC.
85            If timezone is included, any non-UTC datetimes will be converted to UTC.
86            If a date is passed in without timezone info, it is assumed to be UTC.
87            Specify this header to perform the operation only
88            if the resource has been modified since the specified time.
89        :keyword ~datetime.datetime if_unmodified_since:
90            A DateTime value. Azure expects the date value passed in to be UTC.
91            If timezone is included, any non-UTC datetimes will be converted to UTC.
92            If a date is passed in without timezone info, it is assumed to be UTC.
93            Specify this header to perform the operation only if
94            the resource has not been modified since the specified date/time.
95        :keyword str etag:
96            An ETag value, or the wildcard character (*). Used to check if the resource has changed,
97            and act according to the condition specified by the `match_condition` parameter.
98        :keyword ~azure.core.MatchConditions match_condition:
99            The match condition to use upon the etag.
100        :keyword int timeout:
101            The timeout parameter is expressed in seconds.
102        :rtype: None
103        """
104        await self._blob_lease_client.acquire(lease_duration=lease_duration, **kwargs)
105        self._update_lease_client_attributes()
106
107    async def renew(self, **kwargs):
108        # type: (Any) -> None
109        """Renews the lease.
110
111        The lease can be renewed if the lease ID specified in the
112        lease client matches that associated with the file system or file. Note that
113        the lease may be renewed even if it has expired as long as the file system
114        or file has not been leased again since the expiration of that lease. When you
115        renew a lease, the lease duration clock resets.
116
117        :keyword ~datetime.datetime if_modified_since:
118            A DateTime value. Azure expects the date value passed in to be UTC.
119            If timezone is included, any non-UTC datetimes will be converted to UTC.
120            If a date is passed in without timezone info, it is assumed to be UTC.
121            Specify this header to perform the operation only
122            if the resource has been modified since the specified time.
123        :keyword ~datetime.datetime if_unmodified_since:
124            A DateTime value. Azure expects the date value passed in to be UTC.
125            If timezone is included, any non-UTC datetimes will be converted to UTC.
126            If a date is passed in without timezone info, it is assumed to be UTC.
127            Specify this header to perform the operation only if
128            the resource has not been modified since the specified date/time.
129        :keyword str etag:
130            An ETag value, or the wildcard character (*). Used to check if the resource has changed,
131            and act according to the condition specified by the `match_condition` parameter.
132        :keyword ~azure.core.MatchConditions match_condition:
133            The match condition to use upon the etag.
134        :keyword int timeout:
135            The timeout parameter is expressed in seconds.
136        :return: None
137        """
138        await self._blob_lease_client.renew(**kwargs)
139        self._update_lease_client_attributes()
140
141    async def release(self, **kwargs):
142        # type: (Any) -> None
143        """Release the lease.
144
145        The lease may be released if the client lease id specified matches
146        that associated with the file system or file. Releasing the lease allows another client
147        to immediately acquire the lease for the file system or file as soon as the release is complete.
148
149        :keyword ~datetime.datetime if_modified_since:
150            A DateTime value. Azure expects the date value passed in to be UTC.
151            If timezone is included, any non-UTC datetimes will be converted to UTC.
152            If a date is passed in without timezone info, it is assumed to be UTC.
153            Specify this header to perform the operation only
154            if the resource has been modified since the specified time.
155        :keyword ~datetime.datetime if_unmodified_since:
156            A DateTime value. Azure expects the date value passed in to be UTC.
157            If timezone is included, any non-UTC datetimes will be converted to UTC.
158            If a date is passed in without timezone info, it is assumed to be UTC.
159            Specify this header to perform the operation only if
160            the resource has not been modified since the specified date/time.
161        :keyword str etag:
162            An ETag value, or the wildcard character (*). Used to check if the resource has changed,
163            and act according to the condition specified by the `match_condition` parameter.
164        :keyword ~azure.core.MatchConditions match_condition:
165            The match condition to use upon the etag.
166        :keyword int timeout:
167            The timeout parameter is expressed in seconds.
168        :return: None
169        """
170        await self._blob_lease_client.release(**kwargs)
171        self._update_lease_client_attributes()
172
173    async def change(self, proposed_lease_id, **kwargs):
174        # type: (str, Any) -> None
175        """Change the lease ID of an active lease.
176
177        :param str proposed_lease_id:
178            Proposed lease ID, in a GUID string format. The DataLake service returns 400
179            (Invalid request) if the proposed lease ID is not in the correct format.
180        :keyword ~datetime.datetime if_modified_since:
181            A DateTime value. Azure expects the date value passed in to be UTC.
182            If timezone is included, any non-UTC datetimes will be converted to UTC.
183            If a date is passed in without timezone info, it is assumed to be UTC.
184            Specify this header to perform the operation only
185            if the resource has been modified since the specified time.
186        :keyword ~datetime.datetime if_unmodified_since:
187            A DateTime value. Azure expects the date value passed in to be UTC.
188            If timezone is included, any non-UTC datetimes will be converted to UTC.
189            If a date is passed in without timezone info, it is assumed to be UTC.
190            Specify this header to perform the operation only if
191            the resource has not been modified since the specified date/time.
192        :keyword str etag:
193            An ETag value, or the wildcard character (*). Used to check if the resource has changed,
194            and act according to the condition specified by the `match_condition` parameter.
195        :keyword ~azure.core.MatchConditions match_condition:
196            The match condition to use upon the etag.
197        :keyword int timeout:
198            The timeout parameter is expressed in seconds.
199        :return: None
200        """
201        await self._blob_lease_client.change(proposed_lease_id=proposed_lease_id, **kwargs)
202        self._update_lease_client_attributes()
203
204    async def break_lease(self, lease_break_period=None, **kwargs):
205        # type: (Optional[int], Any) -> int
206        """Break the lease, if the file system or file has an active lease.
207
208        Once a lease is broken, it cannot be renewed. Any authorized request can break the lease;
209        the request is not required to specify a matching lease ID. When a lease
210        is broken, the lease break period is allowed to elapse, during which time
211        no lease operation except break and release can be performed on the file system or file.
212        When a lease is successfully broken, the response indicates the interval
213        in seconds until a new lease can be acquired.
214
215        :param int lease_break_period:
216            This is the proposed duration of seconds that the lease
217            should continue before it is broken, between 0 and 60 seconds. This
218            break period is only used if it is shorter than the time remaining
219            on the lease. If longer, the time remaining on the lease is used.
220            A new lease will not be available before the break period has
221            expired, but the lease may be held for longer than the break
222            period. If this header does not appear with a break
223            operation, a fixed-duration lease breaks after the remaining lease
224            period elapses, and an infinite lease breaks immediately.
225        :keyword ~datetime.datetime if_modified_since:
226            A DateTime value. Azure expects the date value passed in to be UTC.
227            If timezone is included, any non-UTC datetimes will be converted to UTC.
228            If a date is passed in without timezone info, it is assumed to be UTC.
229            Specify this header to perform the operation only
230            if the resource has been modified since the specified time.
231        :keyword ~datetime.datetime if_unmodified_since:
232            A DateTime value. Azure expects the date value passed in to be UTC.
233            If timezone is included, any non-UTC datetimes will be converted to UTC.
234            If a date is passed in without timezone info, it is assumed to be UTC.
235            Specify this header to perform the operation only if
236            the resource has not been modified since the specified date/time.
237        :keyword int timeout:
238            The timeout parameter is expressed in seconds.
239        :return: Approximate time remaining in the lease period, in seconds.
240        :rtype: int
241        """
242        await self._blob_lease_client.break_lease(lease_break_period=lease_break_period, **kwargs)
243