Ejemplo n.º 1
0
    def test_on_message_nack(self):
        # When the callback raises a Nack, the server should be notified.
        self.protocol._message_callback.side_effect = Nack()
        d = self._call_on_message("testing.topic", {}, {"key": "value"})

        def _check(_):
            self.protocol._message_callback.assert_called()
            self.protocol._channel.basic_nack.assert_called_with(
                delivery_tag="delivery_tag", requeue=True)

        d.addCallback(_check)
        return pytest_twisted.blockon(d)
Ejemplo n.º 2
0
def deliver(message):
    """
    Send an email to the given user.

    Args:
        email_address (str): The recipient's email address.
        message (str): The formatted message, ready for dispatching.
    """
    email_address = message.queue.split('.', 1)[1]
    try:
        # TODO handle the mail server being down gracefully
        yield smtp.sendmail(
            config.conf["SMTP_SERVER_HOSTNAME"].encode('utf-8'),
            config.conf["EMAIL_FROM_ADDRESS"].encode('utf-8'),
            [email_address.encode('utf-8')],
            str(message).encode('utf-8'),
            port=config.conf["SMTP_SERVER_PORT"],
            username=config.conf["SMTP_USERNAME"],
            password=config.conf["SMTP_PASSWORD"],
            requireAuthentication=config.conf["SMTP_REQUIRE_AUTHENTICATION"],
            requireTransportSecurity=config.conf["SMTP_REQUIRE_TLS"],
        )
        _log.info("Email successfully delivered to %s", email_address)
    except error.ConnectionRefusedError as e:
        _log.error(
            "Failed to connect to the SMTP server (%s), returning message to queue",
            str(e))
        raise Nack()
    except smtp.SMTPClientError as e:
        _log.info("Failed to email %s: %s", email_address, str(e))
        if e.code == 550:
            # TODO Mark email as invalid in the database
            pass
        else:
            # TODO Raise a try-again-later exception
            raise
Ejemplo n.º 3
0
 def test_message_nack(self):
     self.consumer._consumer_callback.side_effect = Nack()
     self.consumer._on_message(self.channel, self.frame, self.properties,
                               b'"body"')
     self.channel.basic_nack.assert_called_with(delivery_tag="testtag",
                                                requeue=True)
Ejemplo n.º 4
0
    def __call__(self, message):
        """
        Invoked when a message is received by the consumer.

        Args:
            message (fedora_messaging.api.Message): The message from AMQP.
        """
        # fedmsg wraps message bodies in the following dictionary. We need to
        # wrap messages bridged back into ZMQ with it so old consumers don't
        # explode with KeyErrors.
        self._message_counter += 1
        msg_id = message.id
        if msg_id is None:
            _log.error("Message is missing a message id, dropping it")
            return
        if not YEAR_PREFIX_RE.match(msg_id[:5]):
            msg_id = "{}-{}".format(datetime.datetime.utcnow().year, msg_id)
        wrapped_body = {
            "topic": message.topic,
            "msg": message.body,
            "timestamp": int(time.time()),
            "msg_id": msg_id,
            "i": self._message_counter,
            "username": "******",
        }
        message.body = wrapped_body

        if fedmsg_config.conf["sign_messages"]:
            # Find the cert name
            if not fedmsg_config.conf.get("certname"):
                hostname = socket.gethostname().split(".", 1)[0]
                if "cert_prefix" in fedmsg_config.conf:
                    cert_index = "%s.%s" % (fedmsg_config.conf["cert_prefix"], hostname)
                else:
                    cert_index = fedmsg_config.conf["name"]
                    if cert_index == "relay_inbound":
                        cert_index = "shell.%s" % hostname
                fedmsg_config.conf["certname"] = fedmsg_config.conf["certnames"][
                    cert_index
                ]
            # Sign the message
            try:
                message.body = fedmsg.crypto.sign(message.body, **fedmsg_config.conf)
            except ValueError as e:
                _log.error("Unable to sign message with fedmsg: %s", str(e))
                raise HaltConsumer(exit_code=1, reason=e)

        try:
            _log.debug(
                'Publishing message on "%s" to the ZeroMQ PUB socket "%s"',
                message.topic,
                self.publish_endpoint,
            )
            zmq_message = [
                message.topic.encode("utf-8"),
                json.dumps(message.body).encode("utf-8"),
            ]
            self.pub_socket.send_multipart(zmq_message)
        except zmq.ZMQError as e:
            _log.error("Message delivery failed: %r", e)
            raise Nack()