Example #1
0
    def execute(self):
        """
        Get message from channel API and post it to message API.
        Retry in case of failure
        """
        job = self.channel_notification_repo.get_job()
        if not job:
            return
        super().execute()
        queue_message_id, job_payload = job
        attempt = job_payload[self.ATTEMPT]

        try:
            self.process(job_payload)
        except ChannelApiFailure as e:
            increase_counter(
                "usecase.ProcessChannelNotificationUseCase.failure")
            logger.info("%s: processing channel notification failure",
                        queue_message_id)
            logger.exception(e)
            if attempt < self.MAX_ATTEMPTS:
                attempt += 1
                EnqueueChannelNotificationUseCase(
                    self.channel_notification_repo).retry(
                        job_payload, attempt)
                self.channel_notification_repo.delete(queue_message_id)
                return
            raise
        else:
            self.channel_notification_repo.delete(queue_message_id)
Example #2
0
    def process(self, job_payload):
        logger.debug("Processing job: %r", job_payload)
        channel_id = job_payload[self.CHANNEL_ID]
        channel = get_channel_by_id(channel_id, self.routing_table)
        if not channel:
            raise ChannelNotFound("Channel not found, id: %s" % channel_id)

        notification_payload = job_payload[self.NOTIFICATION_PAYLOAD]
        message = self._get_message(channel, notification_payload['id'])
        self.enqueue_message_use_case.execute(message)
        increase_counter("usecase.ProcessChannelNotificationUseCase.processed")
Example #3
0
def channel_message_receive(channel_id):
    """
    Handles the pings
    """
    body = request.get_json(silent=True)
    increase_counter("message_rx.message.received")
    repo = ChannelNotificationRepo(Config.CHANNEL_NOTIFICATION_REPO_CONF)
    use_case = EnqueueChannelNotificationUseCase(
        channel_notification_repo=repo)
    channel = get_channel_by_id(channel_id, Config.ROUTING_TABLE)
    use_case.execute(channel, body)
    return Response()
Example #4
0
 def run(self):
     for channel in get_channels_to_subscribe_as(env.ROUTING_TABLE,
                                                 env.JURISDICTION):
         if self.should_update_subscription():
             increase_counter("subscription.attempt")
             logger.info("Subscribing to channel %s", channel["Name"])
             try:
                 self.subscribe(channel)
             except Exception as e:
                 increase_counter("subscription.error")
                 logger.error("Unable to subscribe to channel %s - %s",
                              channel, str(e))
Example #5
0
 def subscribe(self, channel):
     channel_url = self.get_channel_subscribe_endpoint_url(channel)
     now = datetime.datetime.utcnow()
     try:
         callback_url = self.get_callback_url(channel)
         logger.info('Sending subscription request to %s', channel_url)
         RequestChannelAPIUseCase(channel).subscribe_by_jurisdiction(
             callback_url, env.JURISDICTION)
     except (SubscriptionFailure, InvalidSubscriptionParameters) as e:
         logger.error(e)
     else:
         self.last_subscribed_at = now
         increase_counter("subscription.success")
         logger.info('Successfully subscribed at %s' %
                     self.last_subscribed_at)
Example #6
0
def channel_message_confirm(channel_id):
    """
    Handles subscription verification requests
    https://www.w3.org/TR/websub/#hub-verifies-intent
    hub.mode=subscribe&hub.topic=jurisdiction.AU&
    hub.challenge=e35ad43c-7149-45cb-a8eb-3a5a76a368de&
    hub.lease_seconds=432000
    """
    # TODO: validate topic and mode
    # TODO: validate signature header
    channel = get_channel_by_id(channel_id, Config.ROUTING_TABLE)
    if not channel:
        logger.warning(
            "Trying to confirm subscription for a wrong channel %s (%s)",
            channel_id, Config.ROUTING_TABLE)
        return Response("Bad channel_id", status=400)
    increase_counter("message_rx.channel.confirmed")
    return Response(request.args.get('hub.challenge'))
Example #7
0
 def execute(self, *args, **kwargs):
     increase_counter(f"usecase.{self.__class__.__name__}.execute_called",
                      1)
Example #8
0
        try:
            callback_url = self.get_callback_url(channel)
            logger.info('Sending subscription request to %s', channel_url)
            RequestChannelAPIUseCase(channel).subscribe_by_jurisdiction(
                callback_url, env.JURISDICTION)
        except (SubscriptionFailure, InvalidSubscriptionParameters) as e:
            logger.error(e)
        else:
            self.last_subscribed_at = now
            increase_counter("subscription.success")
            logger.info('Successfully subscribed at %s' %
                        self.last_subscribed_at)

    @staticmethod
    def get_callback_url(channel):
        return urljoin(env.MESSAGE_RX_API_URL,
                       'channel-message/{Id}'.format(**channel))

    def get_channel_subscribe_endpoint_url(self, channel):
        return urljoin(channel['ChannelUrl'],
                       self.CHANNEL_API_SUBSCRIBE_ENDPOINT)


if __name__ == '__main__':
    processor = SubscriptionHandler()
    sleep_period = 30
    increase_counter("subscription.start-process")
    while True:
        processor.run()
        sleep(sleep_period)