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)
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
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)
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()