Example #1
0
    def handle(self, bundle: TransactionBundle):
        """
        Perform leasequery if requested.

        :param bundle: The transaction bundle
        """
        if not isinstance(bundle.request, LeasequeryMessage):
            # Not a leasequery, not our business
            return

        # Extract the query
        queries = bundle.get_unhandled_options(LQQueryOption)
        if not queries:
            # No unhandled queries
            return

        query = queries[0]

        # Get the leases from the store
        lease_count, leases = self.store.find_leases(query)

        # A count of -1 means unsupported query, so we stop handling
        if lease_count < 0:
            return

        # Otherwise mark this query as handled
        bundle.mark_handled(query)

        # What we do now depends on the protocol
        if bundle.received_over_tcp:
            try:
                if lease_count > 0:
                    # We're doing bulk leasequery, return all the records in separate messages
                    leases_iterator = iter(leases)
                    first_link_address, first_data_option = next(leases_iterator)
                    first_message = bundle.response
                    first_message.options.append(first_data_option)

                    bundle.responses = MessagesList(first_message,
                                                    self.generate_data_messages(first_message.transaction_id,
                                                                                leases_iterator))
                else:
                    # If the server does not find any bindings satisfying a query, it
                    # SHOULD send a LEASEQUERY-REPLY without an OPTION_STATUS_CODE option
                    # and without any OPTION_CLIENT_DATA option.
                    pass
            except:
                # Something went wrong (database changes while reading?), abort
                logger.exception("Error while building bulk leasequery response")
                raise ReplyWithLeasequeryError(STATUS_QUERY_TERMINATED,
                                               "Error constructing your reply, please try again")
        else:
            try:
                if lease_count == 1:
                    # One entry found, return it
                    leases_iterator = iter(leases)
                    first_link_address, first_data_option = next(leases_iterator)
                    bundle.response.options.append(first_data_option)
                elif lease_count > 1:
                    # The Client Link option is used only in a LEASEQUERY-REPLY message and
                    # identifies the links on which the client has one or more bindings.
                    # It is used in reply to a query when no link-address was specified and
                    # the client is found to be on more than one link.
                    link_addresses = set([link_address for link_address, data_option in leases])
                    bundle.response.options.append(LQClientLink(link_addresses))
            except:
                # Something went wrong (database changes while reading?), abort
                logger.exception("Error while building leasequery response")
                raise ReplyWithLeasequeryError(STATUS_UNSPEC_FAIL,
                                               "Error constructing your reply, please try again")
Example #2
0
    def handle(self, bundle: TransactionBundle):
        """
        Perform leasequery if requested.

        :param bundle: The transaction bundle
        """
        if not isinstance(bundle.request, LeasequeryMessage):
            # Not a leasequery, not our business
            return

        # Extract the query
        queries = bundle.get_unhandled_options(LQQueryOption)
        if not queries:
            # No unhandled queries
            return

        query = queries[0]

        # Get the leases from the store
        lease_count, leases = self.store.find_leases(query)

        # A count of -1 means unsupported query, so we stop handling
        if lease_count < 0:
            return

        # Otherwise mark this query as handled
        bundle.mark_handled(query)

        # What we do now depends on the protocol
        if bundle.received_over_tcp:
            try:
                if lease_count > 0:
                    # We're doing bulk leasequery, return all the records in separate messages
                    leases_iterator = iter(leases)
                    first_link_address, first_data_option = next(
                        leases_iterator)
                    first_message = bundle.response
                    first_message.options.append(first_data_option)

                    bundle.responses = MessagesList(
                        first_message,
                        self.generate_data_messages(
                            first_message.transaction_id, leases_iterator))
                else:
                    # If the server does not find any bindings satisfying a query, it
                    # SHOULD send a LEASEQUERY-REPLY without an OPTION_STATUS_CODE option
                    # and without any OPTION_CLIENT_DATA option.
                    pass
            except:
                # Something went wrong (database changes while reading?), abort
                logger.exception(
                    "Error while building bulk leasequery response")
                raise ReplyWithLeasequeryError(
                    STATUS_QUERY_TERMINATED,
                    "Error constructing your reply, please try again")
        else:
            try:
                if lease_count == 1:
                    # One entry found, return it
                    leases_iterator = iter(leases)
                    first_link_address, first_data_option = next(
                        leases_iterator)
                    bundle.response.options.append(first_data_option)
                elif lease_count > 1:
                    # The Client Link option is used only in a LEASEQUERY-REPLY message and
                    # identifies the links on which the client has one or more bindings.
                    # It is used in reply to a query when no link-address was specified and
                    # the client is found to be on more than one link.
                    link_addresses = set(
                        [link_address for link_address, data_option in leases])
                    bundle.response.options.append(
                        LQClientLink(link_addresses))
            except:
                # Something went wrong (database changes while reading?), abort
                logger.exception("Error while building leasequery response")
                raise ReplyWithLeasequeryError(
                    STATUS_UNSPEC_FAIL,
                    "Error constructing your reply, please try again")