def open(self):
        """
        Open the Receiver using the supplied conneciton.
        If the handler has previously been redirected, the redirect
        context will be used to create a new handler before opening it.

        :param connection: The underlying client shared connection.
        :type: connection: ~uamqp.connection.Connection
        """
        # pylint: disable=protected-access
        self.running = True
        if self.redirected:
            self.source = self.redirected.address
            source = Source(self.source)
            if self.offset is not None:
                source.set_filter(self.offset.selector())
            alt_creds = {
                "username": self.client._auth_config.get("iot_username"),
                "password":self.client._auth_config.get("iot_password")}
            self._handler = ReceiveClient(
                source,
                auth=self.client.get_auth(**alt_creds),
                debug=self.client.debug,
                prefetch=self.prefetch,
                link_properties=self.properties,
                timeout=self.timeout,
                error_policy=self.retry_policy,
                keep_alive_interval=self.keep_alive,
                client_name=self.name,
                properties=self.client.create_properties())
        self._handler.open()
        while not self._handler.client_ready():
            time.sleep(0.05)
    def _create_handler(self):
        source = Source(self._source)
        if self._offset is not None:
            source.set_filter(self._offset._selector())  # pylint:disable=protected-access

        if StrictVersion(uamqp.__version__) < StrictVersion("1.2.3"):  # backward compatible until uamqp 1.2.3 released
            desired_capabilities = {}
        elif self._track_last_enqueued_event_properties:
            symbol_array = [types.AMQPSymbol(self._receiver_runtime_metric_symbol)]
            desired_capabilities = {"desired_capabilities": utils.data_factory(types.AMQPArray(symbol_array))}
        else:
            desired_capabilities = {"desired_capabilities": None}

        self._handler = ReceiveClientAsync(
            source,
            auth=self._client._create_auth(),  # pylint:disable=protected-access
            debug=self._client._config.network_tracing,  # pylint:disable=protected-access
            prefetch=self._prefetch,
            link_properties=self._link_properties,
            timeout=self._timeout,
            error_policy=self._retry_policy,
            keep_alive_interval=self._keep_alive,
            client_name=self._name,
            receive_settle_mode=uamqp.constants.ReceiverSettleMode.ReceiveAndDelete,
            auto_complete=False,
            properties=self._client._create_properties(  # pylint:disable=protected-access
                self._client._config.user_agent),  # pylint:disable=protected-access
            **desired_capabilities,  # pylint:disable=protected-access
            loop=self._loop)
        self._messages_iter = None
예제 #3
0
    def _create_handler(self, auth: "JWTTokenAsync") -> None:
        source = Source(self._source)
        if self._offset is not None:
            source.set_filter(
                event_position_selector(self._offset, self._offset_inclusive))
        desired_capabilities = None
        if self._track_last_enqueued_event_properties:
            symbol_array = [types.AMQPSymbol(RECEIVER_RUNTIME_METRIC_SYMBOL)]
            desired_capabilities = utils.data_factory(
                types.AMQPArray(symbol_array))

        properties = create_properties(self._client._config.user_agent  # pylint:disable=protected-access
                                       )
        self._handler = ReceiveClientAsync(
            source,
            auth=auth,
            debug=self._client._config.network_tracing,  # pylint:disable=protected-access
            prefetch=self._prefetch,
            link_properties=self._link_properties,
            timeout=self._timeout,
            idle_timeout=self._idle_timeout,
            error_policy=self._retry_policy,
            keep_alive_interval=self._keep_alive,
            client_name=self._name,
            receive_settle_mode=uamqp.constants.ReceiverSettleMode.
            ReceiveAndDelete,
            auto_complete=False,
            properties=properties,
            desired_capabilities=desired_capabilities,
            loop=self._loop,
        )

        self._handler._streaming_receive = True  # pylint:disable=protected-access
        self._handler._message_received_callback = (  # pylint:disable=protected-access
            self._message_received)
예제 #4
0
    def __init__(  # pylint: disable=super-init-not-called
            self,
            client,
            source,
            offset=None,
            prefetch=300,
            epoch=None,
            keep_alive=None,
            auto_reconnect=True,
            loop=None):
        """
        Instantiate an async receiver.

        :param client: The parent EventHubClientAsync.
        :type client: ~azure.eventhub.async_ops.EventHubClientAsync
        :param source: The source EventHub from which to receive events.
        :type source: ~uamqp.address.Source
        :param prefetch: The number of events to prefetch from the service
         for processing. Default is 300.
        :type prefetch: int
        :param epoch: An optional epoch value.
        :type epoch: int
        :param loop: An event loop.
        """
        self.loop = loop or asyncio.get_event_loop()
        self.running = False
        self.client = client
        self.source = source
        self.offset = offset
        self.prefetch = prefetch
        self.epoch = epoch
        self.keep_alive = keep_alive
        self.auto_reconnect = auto_reconnect
        self.retry_policy = errors.ErrorPolicy(max_retries=3,
                                               on_error=_error_handler)
        self.reconnect_backoff = 1
        self.redirected = None
        self.error = None
        self.properties = None
        partition = self.source.split('/')[-1]
        self.name = "EHReceiver-{}-partition{}".format(uuid.uuid4(), partition)
        source = Source(self.source)
        if self.offset is not None:
            source.set_filter(self.offset.selector())
        if epoch:
            self.properties = {
                types.AMQPSymbol(self._epoch): types.AMQPLong(int(epoch))
            }
        self._handler = ReceiveClientAsync(
            source,
            auth=self.client.get_auth(),
            debug=self.client.debug,
            prefetch=self.prefetch,
            link_properties=self.properties,
            timeout=self.timeout,
            error_policy=self.retry_policy,
            keep_alive_interval=self.keep_alive,
            client_name=self.name,
            properties=self.client.create_properties(),
            loop=self.loop)
 async def _reconnect_async(self):  # pylint: disable=too-many-statements
     # pylint: disable=protected-access
     alt_creds = {
         "username": self.client._auth_config.get("iot_username"),
         "password":self.client._auth_config.get("iot_password")}
     await self._handler.close_async()
     source = Source(self.source)
     if self.offset is not None:
         source.set_filter(self.offset.selector())
     self._handler = ReceiveClientAsync(
         source,
         auth=self.client.get_auth(**alt_creds),
         debug=self.client.debug,
         prefetch=self.prefetch,
         link_properties=self.properties,
         timeout=self.timeout,
         error_policy=self.retry_policy,
         keep_alive_interval=self.keep_alive,
         client_name=self.name,
         properties=self.client.create_properties(),
         loop=self.loop)
     try:
         await self._handler.open_async()
         while not await self._handler.client_ready_async():
             await asyncio.sleep(0.05)
         return True
     except errors.TokenExpired as shutdown:
         log.info("AsyncReceiver disconnected due to token expiry. Shutting down.")
         error = EventHubError(str(shutdown), shutdown)
         await self.close_async(exception=error)
         raise error
     except (errors.LinkDetach, errors.ConnectionClose) as shutdown:
         if shutdown.action.retry and self.auto_reconnect:
             log.info("AsyncReceiver detached. Attempting reconnect.")
             return False
         log.info("AsyncReceiver detached. Shutting down.")
         error = EventHubError(str(shutdown), shutdown)
         await self.close_async(exception=error)
         raise error
     except errors.MessageHandlerError as shutdown:
         if self.auto_reconnect:
             log.info("AsyncReceiver detached. Attempting reconnect.")
             return False
         log.info("AsyncReceiver detached. Shutting down.")
         error = EventHubError(str(shutdown), shutdown)
         await self.close_async(exception=error)
         raise error
     except errors.AMQPConnectionError as shutdown:
         if str(shutdown).startswith("Unable to open authentication session") and self.auto_reconnect:
             log.info("AsyncReceiver couldn't authenticate. Attempting reconnect.")
             return False
         log.info("AsyncReceiver connection error (%r). Shutting down.", shutdown)
         error = EventHubError(str(shutdown))
         await self.close_async(exception=error)
         raise error
     except Exception as e:
         log.info("Unexpected error occurred (%r). Shutting down.", e)
         error = EventHubError("Receiver reconnect failed: {}".format(e))
         await self.close_async(exception=error)
         raise error
예제 #6
0
 def add_receiver(self,
                  consumer_group,
                  partition,
                  offset=None,
                  prefetch=300):
     """
     Add a receiver to the client for a particular consumer group and partition.
     :param consumer_group: The name of the consumer group.
     :type consumer_group: str
     :param partition: The ID of the partition.
     :type partition: str
     :param offset: The offset from which to start receiving.
     :type offset: ~azure.eventhub.Offset
     :param prefetch: The message prefetch count of the receiver. Default is 300.
     :type prefetch: int
     :returns: ~azure.eventhub.Receiver
     """
     source_url = "amqps://{}{}/ConsumerGroups/{}/Partitions/{}".format(
         self.address.hostname, self.address.path, consumer_group,
         partition)
     source = Source(source_url)
     if offset is not None:
         source.set_filter(offset.selector())
     handler = Receiver(self, source, prefetch=prefetch)
     self.clients.append(handler._handler)  # pylint: disable=protected-access
     return handler
예제 #7
0
 async def reconnect_async(self):
     """If the Receiver was disconnected from the service with
     a retryable error - attempt to reconnect."""
     # pylint: disable=protected-access
     alt_creds = {
         "username": self.client._auth_config.get("iot_username"),
         "password": self.client._auth_config.get("iot_password")
     }
     await self._handler.close_async()
     source = Source(self.source)
     if self.offset is not None:
         source.set_filter(self.offset.selector())
     self._handler = ReceiveClientAsync(
         source,
         auth=self.client.get_auth(**alt_creds),
         debug=self.client.debug,
         prefetch=self.prefetch,
         link_properties=self.properties,
         timeout=self.timeout,
         error_policy=self.retry_policy,
         keep_alive_interval=self.keep_alive,
         client_name=self.name,
         properties=self.client.create_properties(),
         loop=self.loop)
     await self._handler.open_async()
     while not await self.has_started():
         await self._handler._connection.work_async()
예제 #8
0
    def _create_handler(self):
        alt_creds = {
            "username":
            self._client._auth_config.get("iot_username")
            if self._redirected else None,  # pylint:disable=protected-access
            "password":
            self._client._auth_config.get("iot_password")
            if self._redirected else None  # pylint:disable=protected-access
        }

        source = Source(self._source)
        if self._offset is not None:
            source.set_filter(self._offset._selector())  # pylint:disable=protected-access
        self._handler = ReceiveClient(
            source,
            auth=self._client._get_auth(**alt_creds),  # pylint:disable=protected-access
            debug=self._client._config.network_tracing,  # pylint:disable=protected-access
            prefetch=self._prefetch,
            link_properties=self._link_properties,
            timeout=self._timeout,
            error_policy=self._retry_policy,
            keep_alive_interval=self._keep_alive,
            client_name=self._name,
            properties=self._client._create_properties(  # pylint:disable=protected-access
                self._client._config.user_agent))  # pylint:disable=protected-access
        self._messages_iter = None
예제 #9
0
    def _open(self):
        """
        Open the EventHubConsumer using the supplied connection.
        If the handler has previously been redirected, the redirect
        context will be used to create a new handler before opening it.

        """
        # pylint: disable=protected-access
        self._check_closed()
        if self.redirected:
            self.client._process_redirect_uri(self.redirected)
            self.source = self.redirected.address
            source = Source(self.source)
            if self.offset is not None:
                source.set_filter(self.offset._selector())

            alt_creds = {
                "username": self.client._auth_config.get("iot_username"),
                "password": self.client._auth_config.get("iot_password")
            }
            self._handler = ReceiveClient(
                source,
                auth=self.client.get_auth(**alt_creds),
                debug=self.client.config.network_tracing,
                prefetch=self.prefetch,
                link_properties=self.properties,
                timeout=self.timeout,
                error_policy=self.retry_policy,
                keep_alive_interval=self.keep_alive,
                client_name=self.name,
                properties=self.client._create_properties(
                    self.client.config.user_agent))  # pylint: disable=protected-access
        if not self.running:
            self._connect()
            self.running = True
예제 #10
0
    def __init__(self,
                 client,
                 source,
                 event_position=None,
                 prefetch=300,
                 owner_level=None,
                 keep_alive=None,
                 auto_reconnect=True):
        """
        Instantiate a consumer. EventHubConsumer should be instantiated by calling the `create_consumer` method
         in EventHubClient.

        :param client: The parent EventHubClient.
        :type client: ~azure.eventhub.client.EventHubClient
        :param source: The source EventHub from which to receive events.
        :type source: str
        :param prefetch: The number of events to prefetch from the service
         for processing. Default is 300.
        :type prefetch: int
        :param owner_level: The priority of the exclusive consumer. It will an exclusive
         consumer if owner_level is set.
        :type owner_level: int
        """
        self.running = False
        self.client = client
        self.source = source
        self.offset = event_position
        self.messages_iter = None
        self.prefetch = prefetch
        self.owner_level = owner_level
        self.keep_alive = keep_alive
        self.auto_reconnect = auto_reconnect
        self.retry_policy = errors.ErrorPolicy(
            max_retries=self.client.config.max_retries,
            on_error=_error_handler)
        self.reconnect_backoff = 1
        self.properties = None
        self.redirected = None
        self.error = None
        partition = self.source.split('/')[-1]
        self.name = "EHReceiver-{}-partition{}".format(uuid.uuid4(), partition)
        source = Source(self.source)
        if self.offset is not None:
            source.set_filter(self.offset._selector())  # pylint: disable=protected-access
        if owner_level:
            self.properties = {
                types.AMQPSymbol(self._epoch): types.AMQPLong(int(owner_level))
            }
        self._handler = ReceiveClient(
            source,
            auth=self.client.get_auth(),
            debug=self.client.config.network_tracing,
            prefetch=self.prefetch,
            link_properties=self.properties,
            timeout=self.timeout,
            error_policy=self.retry_policy,
            keep_alive_interval=self.keep_alive,
            client_name=self.name,
            properties=self.client._create_properties(
                self.client.config.user_agent))  # pylint: disable=protected-access
예제 #11
0
    def add_receiver(self,
                     consumer_group,
                     partition,
                     offset=None,
                     prefetch=300,
                     operation=None):
        """
        Add a receiver to the client for a particular consumer group and partition.

        :param consumer_group: The name of the consumer group.
        :type consumer_group: str
        :param partition: The ID of the partition.
        :type partition: str
        :param offset: The offset from which to start receiving.
        :type offset: ~azure.eventhub.common.Offset
        :param prefetch: The message prefetch count of the receiver. Default is 300.
        :type prefetch: int
        :operation: An optional operation to be appended to the hostname in the source URL.
         The value must start with `/` character.
        :type operation: str
        :rtype: ~azure.eventhub.receiver.Receiver
        """
        path = self.address.path + operation if operation else self.address.path
        source_url = "amqps://{}{}/ConsumerGroups/{}/Partitions/{}".format(
            self.address.hostname, path, consumer_group, partition)
        source = Source(source_url)
        if offset is not None:
            source.set_filter(offset.selector())
        handler = Receiver(self, source, prefetch=prefetch)
        self.clients.append(handler)
        return handler
예제 #12
0
 def _get_source(self):
     # pylint: disable=protected-access
     if self._session:
         source = Source(self._entity_uri)
         session_filter = None if self._session_id == NEXT_AVAILABLE_SESSION else self._session_id
         source.set_filter(session_filter,
                           name=SESSION_FILTER,
                           descriptor=None)
         return source
     return self._entity_uri
 async def reconnect_async(self):
     """If the Receiver was disconnected from the service with
     a retryable error - attempt to reconnect."""
     # pylint: disable=protected-access
     alt_creds = {
         "username": self.client._auth_config.get("iot_username"),
         "password": self.client._auth_config.get("iot_password")
     }
     await self._handler.close_async()
     source = Source(self.source)
     if self.offset is not None:
         source.set_filter(self.offset.selector())
     self._handler = ReceiveClientAsync(
         source,
         auth=self.client.get_auth(**alt_creds),
         debug=self.client.debug,
         prefetch=self.prefetch,
         link_properties=self.properties,
         timeout=self.timeout,
         error_policy=self.retry_policy,
         keep_alive_interval=self.keep_alive,
         client_name=self.name,
         properties=self.client.create_properties(),
         loop=self.loop)
     try:
         await self._handler.open_async()
         while not await self.has_started():
             await self._handler._connection.work_async()
     except (errors.LinkDetach, errors.ConnectionClose) as shutdown:
         if shutdown.action.retry and self.auto_reconnect:
             log.info("AsyncReceiver detached. Attempting reconnect.")
             await self.reconnect_async()
         else:
             log.info("AsyncReceiver detached. Shutting down.")
             error = EventHubError(str(shutdown), shutdown)
             await self.close_async(exception=error)
             raise error
     except errors.MessageHandlerError as shutdown:
         if self.auto_reconnect:
             log.info("AsyncReceiver detached. Attempting reconnect.")
             await self.reconnect_async()
         else:
             log.info("AsyncReceiver detached. Shutting down.")
             error = EventHubError(str(shutdown), shutdown)
             await self.close_async(exception=error)
             raise error
     except Exception as e:
         log.info("Unexpected error occurred (%r). Shutting down.", e)
         error = EventHubError("Receiver reconnect failed: {}".format(e))
         await self.close_async(exception=error)
         raise error
예제 #14
0
    def __init__(  # pylint: disable=super-init-not-called
            self, client, source, offset=None, prefetch=300, epoch=None,
            keep_alive=None, auto_reconnect=True, loop=None):
        """
        Instantiate an async receiver.

        :param client: The parent EventHubClientAsync.
        :type client: ~azure.eventhub.async_ops.EventHubClientAsync
        :param source: The source EventHub from which to receive events.
        :type source: ~uamqp.address.Source
        :param prefetch: The number of events to prefetch from the service
         for processing. Default is 300.
        :type prefetch: int
        :param epoch: An optional epoch value.
        :type epoch: int
        :param loop: An event loop.
        """
        self.loop = loop or asyncio.get_event_loop()
        self.running = False
        self.client = client
        self.source = source
        self.offset = offset
        self.prefetch = prefetch
        self.epoch = epoch
        self.keep_alive = keep_alive
        self.auto_reconnect = auto_reconnect
        self.retry_policy = errors.ErrorPolicy(max_retries=3, on_error=_error_handler)
        self.reconnect_backoff = 1
        self.redirected = None
        self.error = None
        self.properties = None
        partition = self.source.split('/')[-1]
        self.name = "EHReceiver-{}-partition{}".format(uuid.uuid4(), partition)
        source = Source(self.source)
        if self.offset is not None:
            source.set_filter(self.offset.selector())
        if epoch:
            self.properties = {types.AMQPSymbol(self._epoch): types.AMQPLong(int(epoch))}
        self._handler = ReceiveClientAsync(
            source,
            auth=self.client.get_auth(),
            debug=self.client.debug,
            prefetch=self.prefetch,
            link_properties=self.properties,
            timeout=self.timeout,
            error_policy=self.retry_policy,
            keep_alive_interval=self.keep_alive,
            client_name=self.name,
            properties=self.client.create_properties(),
            loop=self.loop)
예제 #15
0
 def reconnect(self):
     """If the Receiver was disconnected from the service with
     a retryable error - attempt to reconnect."""
     # pylint: disable=protected-access
     alt_creds = {
         "username": self.client._auth_config.get("iot_username"),
         "password": self.client._auth_config.get("iot_password")
     }
     self._handler.close()
     source = Source(self.source)
     if self.offset is not None:
         source.set_filter(self.offset.selector())
     self._handler = ReceiveClient(
         source,
         auth=self.client.get_auth(**alt_creds),
         debug=self.client.debug,
         prefetch=self.prefetch,
         link_properties=self.properties,
         timeout=self.timeout,
         error_policy=self.retry_policy,
         keep_alive_interval=self.keep_alive,
         client_name=self.name,
         properties=self.client.create_properties())
     try:
         self._handler.open()
         while not self._handler.client_ready():
             time.sleep(0.05)
     except (errors.LinkDetach, errors.ConnectionClose) as shutdown:
         if shutdown.action.retry and self.auto_reconnect:
             self.reconnect()
         else:
             error = EventHubError(str(shutdown), shutdown)
             self.close(exception=error)
             raise error
     except errors.MessageHandlerError as shutdown:
         if self.auto_reconnect:
             self.reconnect()
         else:
             error = EventHubError(str(shutdown), shutdown)
             self.close(exception=error)
             raise error
     except Exception as e:
         error = EventHubError("Receiver reconnect failed: {}".format(e))
         self.close(exception=error)
         raise error
    async def open_async(self):
        """
        Open the Receiver using the supplied conneciton.
        If the handler has previously been redirected, the redirect
        context will be used to create a new handler before opening it.

        :param connection: The underlying client shared connection.
        :type: connection: ~uamqp.async_ops.connection_async.ConnectionAsync

        Example:
            .. literalinclude:: ../examples/async_examples/test_examples_eventhub_async.py
                :start-after: [START eventhub_client_async_receiver_open]
                :end-before: [END eventhub_client_async_receiver_open]
                :language: python
                :dedent: 4
                :caption: Open the Receiver using the supplied conneciton.

        """
        # pylint: disable=protected-access
        self.running = True
        if self.redirected:
            self.source = self.redirected.address
            source = Source(self.source)
            if self.offset is not None:
                source.set_filter(self.offset.selector())
            alt_creds = {
                "username": self.client._auth_config.get("iot_username"),
                "password":self.client._auth_config.get("iot_password")}
            self._handler = ReceiveClientAsync(
                source,
                auth=self.client.get_auth(**alt_creds),
                debug=self.client.debug,
                prefetch=self.prefetch,
                link_properties=self.properties,
                timeout=self.timeout,
                error_policy=self.retry_policy,
                keep_alive_interval=self.keep_alive,
                client_name=self.name,
                properties=self.client.create_properties(),
                loop=self.loop)
        await self._handler.open_async()
        while not await self._handler.client_ready_async():
            await asyncio.sleep(0.05)
예제 #17
0
 def _create_handler(self):
     alt_creds = {
         "username": self.client._auth_config.get("iot_username"),
         "password": self.client._auth_config.get("iot_password")
     }
     source = Source(self.source)
     if self.offset is not None:
         source.set_filter(self.offset._selector())
     self._handler = ReceiveClientAsync(
         source,
         auth=self.client.get_auth(**alt_creds),
         debug=self.client.config.network_tracing,
         prefetch=self.prefetch,
         link_properties=self._link_properties,
         timeout=self.timeout,
         error_policy=self.retry_policy,
         keep_alive_interval=self.keep_alive,
         client_name=self.name,
         properties=self.client._create_properties(
             self.client.config.user_agent),  # pylint: disable=protected-access
         loop=self.loop)
     self.messages_iter = None
예제 #18
0
 def _get_source(self):
     source = Source(self.endpoint)
     session_filter = None if self.session_filter == NEXT_AVAILABLE else self.session_filter
     source.set_filter(session_filter, name=SESSION_FILTER, descriptor=None)
     return source
예제 #19
0
 def _get_source(self):
     source = Source(self.endpoint)
     session_filter = None if self.session_filter == NEXT_AVAILABLE else self.session_filter
     source.set_filter(session_filter, name=SESSION_FILTER, descriptor=None)
     return source
예제 #20
0
    def _build_connection(self, is_reconnect=False):
        """

        :param is_reconnect: True - trying to reconnect after fail to connect or a connection is lost.
                             False - the 1st time to connect
        :return: True - connected.  False - not connected
        """
        # pylint: disable=protected-access
        if is_reconnect:
            alt_creds = {
                "username": self.client._auth_config.get("iot_username"),
                "password": self.client._auth_config.get("iot_password")
            }
            self._handler.close()
            source = Source(self.source)
            if self.offset is not None:
                source.set_filter(self.offset._selector())
            self._handler = ReceiveClient(
                source,
                auth=self.client.get_auth(**alt_creds),
                debug=self.client.config.network_tracing,
                prefetch=self.prefetch,
                link_properties=self.properties,
                timeout=self.timeout,
                error_policy=self.retry_policy,
                keep_alive_interval=self.keep_alive,
                client_name=self.name,
                properties=self.client._create_properties(
                    self.client.config.user_agent))  # pylint: disable=protected-access
            self.messages_iter = None
        try:
            self._handler.open()
            while not self._handler.client_ready():
                time.sleep(0.05)
            return True
        except errors.AuthenticationException as shutdown:
            if is_reconnect:
                log.info(
                    "EventHubConsumer couldn't authenticate. Shutting down. (%r)",
                    shutdown)
                error = AuthenticationError(str(shutdown), shutdown)
                self.close(exception=error)
                raise error
            else:
                log.info(
                    "EventHubConsumer couldn't authenticate. Attempting reconnect."
                )
                return False
        except errors.LinkRedirect as redirect:
            self._redirect(redirect)
            return True
        except (errors.LinkDetach, errors.ConnectionClose) as shutdown:
            if shutdown.action.retry:
                log.info("EventHubConsumer detached. Attempting reconnect.")
                return False
            else:
                log.info("EventHubConsumer detached. Shutting down.")
                error = ConnectError(str(shutdown), shutdown)
                self.close(exception=error)
                raise error
        except errors.MessageHandlerError as shutdown:
            if is_reconnect:
                log.info("EventHubConsumer detached. Shutting down.")
                error = ConnectError(str(shutdown), shutdown)
                self.close(exception=error)
                raise error
            else:
                log.info("EventHubConsumer detached. Attempting reconnect.")
                return False
        except errors.AMQPConnectionError as shutdown:
            if is_reconnect:
                log.info(
                    "EventHubConsumer connection error (%r). Shutting down.",
                    shutdown)
                error = AuthenticationError(str(shutdown), shutdown)
                self.close(exception=error)
                raise error
            else:
                log.info(
                    "EventHubConsumer couldn't authenticate. Attempting reconnect."
                )
                return False
        except compat.TimeoutException as shutdown:
            if is_reconnect:
                log.info(
                    "EventHubConsumer authentication timed out. Shutting down."
                )
                error = AuthenticationError(str(shutdown), shutdown)
                self.close(exception=error)
                raise error
            else:
                log.info(
                    "EventHubConsumer authentication timed out. Attempting reconnect."
                )
                return False
        except Exception as e:
            log.error(
                "Unexpected error occurred when building connection (%r). Shutting down.",
                e)
            error = EventHubError(
                "Unexpected error occurred when building connection", e)
            self.close(exception=error)
            raise error
 def _get_source(self):
     source = Source(self._entity_uri)
     session_filter = None if self._session_id == NEXT_AVAILABLE else self._session_id
     source.set_filter(session_filter, name=SESSION_FILTER, descriptor=None)
     return source