def _publish(pool, exchange, routing_key, body, properties, mandatory, stopwatch): """Execute pika publish method using connection from connection pool Also this message catches all pika related exceptions and raise oslo.messaging specific exceptions :param pool: Pool, pika connection pool for connection choosing :param exchange: String, RabbitMQ exchange name for message sending :param routing_key: String, RabbitMQ routing key for message routing :param body: Bytes, RabbitMQ message payload :param properties: Properties, RabbitMQ message properties :param mandatory: Boolean, RabbitMQ publish mandatory flag (raise exception if it is not possible to deliver message to any queue) :param stopwatch: StopWatch, stopwatch object for calculating allowed timeouts """ if stopwatch.expired(): raise exceptions.MessagingTimeout( "Timeout for current operation was expired.") try: timeout = stopwatch.leftover(return_none=True) with pool.acquire(timeout=timeout) as conn: if timeout is not None: properties.expiration = str(int(timeout * 1000)) conn.channel.publish(exchange=exchange, routing_key=routing_key, body=body, properties=properties, mandatory=mandatory) except pika_exceptions.NackError as e: raise pika_drv_exc.MessageRejectedException( "Can not send message: [body: {}], properties: {}] to " "target [exchange: {}, routing_key: {}]. {}".format( body, properties, exchange, routing_key, str(e))) except pika_exceptions.UnroutableError as e: raise pika_drv_exc.RoutingException( "Can not deliver message:[body:{}, properties: {}] to any " "queue using target: [exchange:{}, " "routing_key:{}]. {}".format(body, properties, exchange, routing_key, str(e))) except pika_pool.Timeout as e: raise exceptions.MessagingTimeout( "Timeout for current operation was expired. {}".format(str(e))) except pika_pool.Connection.connectivity_errors as e: if (isinstance(e, pika_exceptions.ChannelClosed) and e.args and e.args[0] == 404): raise pika_drv_exc.ExchangeNotFoundException( "Attempt to send message to not existing exchange " "detected, message: [body:{}, properties: {}], target: " "[exchange:{}, routing_key:{}]. {}".format( body, properties, exchange, routing_key, str(e))) raise pika_drv_exc.ConnectionException( "Connectivity problem detected during sending the message: " "[body:{}, properties: {}] to target: [exchange:{}, " "routing_key:{}]. {}".format(body, properties, exchange, routing_key, str(e))) except socket.timeout: raise pika_drv_exc.TimeoutConnectionException( "Socket timeout exceeded.")
def reconnect(self): """Safe version of _reconnect. Performs reconnection to the broker.""" with self._lock: self._cleanup() try: self._reconnect() except Exception as exc: self._cleanup() if isinstance(exc, pika_pool.Connection.connectivity_errors): raise pika_drv_exc.ConnectionException( "Connectivity problem detected during establishing " "poller's connection. " + str(exc)) else: raise exc
def declare_exchange_by_channel(self, channel, exchange, exchange_type, durable): """Declare exchange using already created channel, if they don't exist :param channel: Channel for communication with RabbitMQ :param exchange: String, RabbitMQ exchange name :param exchange_type: String ('direct', 'topic' or 'fanout') exchange type for exchange to be declared :param durable: Boolean, creates durable exchange if true """ try: channel.exchange_declare(exchange, exchange_type, auto_delete=True, durable=durable) except pika_drv_cmns.PIKA_CONNECTIVITY_ERRORS as e: raise pika_drv_exc.ConnectionException( "Connectivity problem detected during declaring exchange: " "exchange:{}, exchange_type: {}, durable: {}. {}".format( exchange, exchange_type, durable, str(e)))
def start(self): """Starts poller. Should be called before polling to allow message consuming """ with self._lock: if self._started: return self._started = True self._cleanup() try: self._reconnect() except Exception as exc: self._cleanup() if isinstance(exc, pika_pool.Connection.connectivity_errors): raise pika_drv_exc.ConnectionException( "Connectivity problem detected during establishing " "poller's connection. " + str(exc)) else: raise exc
def stop(self): """Stops poller. Should be called when polling is not needed anymore to stop new message consuming. After that it is necessary to poll already prefetched messages """ with self._lock: if not self._started: return if self._queues_to_consume and self._channel: try: self._stop_consuming() except Exception as exc: self._cleanup() if isinstance(exc, pika_pool.Connection.connectivity_errors): raise pika_drv_exc.ConnectionException( "Connectivity problem detected during " "consumer canceling. " + str(exc)) else: raise exc self._started = False
def declare_queue_binding_by_channel(self, channel, exchange, queue, routing_key, exchange_type, queue_expiration, durable): """Declare exchange, queue and bind them using already created channel, if they don't exist :param channel: Channel for communication with RabbitMQ :param exchange: String, RabbitMQ exchange name :param queue: Sting, RabbitMQ queue name :param routing_key: Sting, RabbitMQ routing key for queue binding :param exchange_type: String ('direct', 'topic' or 'fanout') exchange type for exchange to be declared :param queue_expiration: Integer, time in seconds which queue will remain existing in RabbitMQ when there no consumers connected :param durable: Boolean, creates durable exchange and queue if true """ try: channel.exchange_declare( exchange, exchange_type, auto_delete=True, durable=durable ) arguments = {} if queue_expiration > 0: arguments['x-expires'] = queue_expiration * 1000 channel.queue_declare(queue, durable=durable, arguments=arguments) channel.queue_bind(queue, exchange, routing_key) except pika_drv_cmns.PIKA_CONNECTIVITY_ERRORS as e: raise pika_drv_exc.ConnectionException( "Connectivity problem detected during declaring queue " "binding: exchange:{}, queue: {}, routing_key: {}, " "exchange_type: {}, queue_expiration: {}, " "durable: {}. {}".format( exchange, queue, routing_key, exchange_type, queue_expiration, durable, str(e) ) )