class BaseAMQPConnection(BaseConnection): """ An object which does an actual job of (re-)connecting to the the AMQP broker. Concrete subclasses implement either listening or publishing features. """ def __init__(self, conn_params, item_name, properties=None): super(BaseAMQPConnection, self).__init__() self.conn_params = conn_params self.item_name = item_name self.properties = properties self.conn = None self.channel = None self.reconnect_exceptions = (TypeError, EnvironmentError) def _start(self): self.conn = SelectConnection(self.conn_params, self._on_connected) self.conn.ioloop.start() def _close(self): """ Actually close the connection. """ if self.conn: try: self.conn.close() except socket.error, e: if e.errno != errno.EBADF: # EBADF meant we actually had a connection but it was unusable (like the credentials were incorrect) raise
def connect(self, forever=False): name = self.name while True: try: connection = SelectConnection( self.parameters, self.on_connected) log.debug('%s connected', name) except Exception: if not forever: raise log.warning('%s cannot connect', name, exc_info=True) time.sleep(10) continue try: connection.ioloop.start() finally: try: connection.close() connection.ioloop.start() # allow connection to close except Exception: pass if not forever: break
def testnb(): node = NodeNB() #ch = node.channel(('amq.direct', 'foo'), TestServer) ch = node.channel(TestServer) #ch = node.channel(TestClient) conn_parameters = ConnectionParameters() connection = SelectConnection(conn_parameters , node.on_connection_open) # Loop until CTRL-C try: # Start our blocking loop connection.ioloop.start() except KeyboardInterrupt: # Close the connection connection.close() # Loop until the connection is closed connection.ioloop.start()
def simple_server(ca_certs, keyfile, certfile, host_name, use_ssl): host = host_name if use_ssl: ssl_opts = {'ca_certs': ca_certs, 'keyfile': keyfile, 'certfile': certfile, 'cert_reqs': ssl.CERT_REQUIRED} port = 5671 else: ssl_opts = None port = 5672 parameters = ConnectionParameters(host, port, ssl=use_ssl, ssl_options=ssl_opts) connection = SelectConnection(parameters, on_connected) # Loop until CTRL-C try: # Start our blocking loop connection.ioloop.start() except KeyboardInterrupt: # Close the connection connection.close() # Loop until the connection is closed connection.ioloop.start()
routing_key="krqueue", body=jsonmsg, properties=properties) print "demo_send:" + jsonmsg # Close our connection print "Closing client" connection.close() if __name__ == '__main__': pika.log.setup(level=pika.log.INFO) # Connect to RabbitMQ host = (len(sys.argv) > 1) and sys.argv[1] or '127.0.0.1' connection = SelectConnection(ConnectionParameters(host), on_connected) # Loop until CTRL-C try: # Start our blocking loop connection.ioloop.start() except KeyboardInterrupt: # Close the connection connection.close() # Loop until the connection is closed connection.ioloop.stop()
routing_key="test", body=message, properties=properties) print "demo_send: Sent %s" % message # Close our connection print "demo_send: Closing" connection.close() if __name__ == '__main__': pika.log.setup(level=pika.log.INFO) # Connect to RabbitMQ host = (len(sys.argv) > 1) and sys.argv[1] or '127.0.0.1' connection = SelectConnection(ConnectionParameters(host), on_connected) # Loop until CTRL-C try: # Start our blocking loop connection.ioloop.start() except KeyboardInterrupt: # Close the connection connection.close() # Loop until the connection is closed connection.ioloop.start()
class RouterServer(object): """Validates and routes notifications. This acts as a separate server used only for production systems. In a development environment, the post office performs the validation itself, however this does not allow it to scale in situations where a large spike of requests come in (as the requests take longer to complete when validation is performed). Thus in production the post office simply dumps messages into queue which are then consumed, validated, and then routed to their destination. """ def __init__(self, config): self.delivery_conn = None self.delivery_channel = None self.notifs_conn = None self.notifs_channel = None # Extract configuration self.broker_username = config['broker.username'] self.broker_password = config['broker.password'] self.broker_host = config['broker.host'] self.broker_amqp_port = config['broker.amqp_port'] self.broker_http_port = config['broker.http_port'] self.broker_vhost = config['broker.vhost'] self.incoming_exchange_name = config['broker.incoming_exchange_name'] self.notifs_queue_name = config['broker.notifications_queue_name'] # Create connection parameters object for easy reuse self.conn_params = pika.ConnectionParameters( credentials=pika.PlainCredentials( self.broker_username, self.broker_password, ), host=self.broker_host, port=self.broker_amqp_port, virtual_host=self.broker_vhost, ) self.notifs_conn = SelectConnection( self.conn_params, self.on_notifs_connected, ) @wsgify def __call__(self, request): """Allows router to be called directly by POST Office to perform validation. Intended to simplify development -- SHOULD NOT be used in a production system. """ try: self.process_notification(request.body) except KeyError as kerr: raise HTTPBadRequest() except Exception as ex: raise HTTPInternalServerError() return HTTPAccepted() # XXX: Ugh...why must Pika be so difficult with multiple connections? def start(self, blocking=True): #Thread(target=self.delivery_conn.ioloop.start).start() if blocking: self.notifs_conn.ioloop.start() else: Thread(target=self.notifs_conn.ioloop.start).start() def shutdown(self): self.delivery_channel.close() self.notifs_channel.close() self.delivery_conn.close() self.notifs_conn.close() # Loop until everything shuts down self.notifs_conn.ioloop.start() def on_delivery_connected(self, connection): connection.channel(self.on_delivery_channel_open) def on_delivery_channel_open(self, channel): self.delivery_channel = channel def on_notifs_connected(self, connection): connection.channel(self.on_notifications_channel_open) # TODO: Figure out how to get 2 connections working in Pika. # This is a hack for now, since we know we only have one broker. self.on_delivery_connected(connection) def on_notifications_channel_open(self, channel): self.notifs_channel = channel channel.queue_declare( queue=self.notifs_queue_name, durable=False, exclusive=False, auto_delete=False, callback=self.on_notifications_queue_declared, ) def on_notifications_queue_declared(self, frame): self.notifs_channel.basic_consume( self.handle_notification, queue=self.notifs_queue_name, no_ack=True, ) def handle_notification(self, channel, method, properties, body): print "Received notification" try: self.process_notification(body) print "Processed notification" except Exception as ex: print "Error processing notification: %r" % ex def process_notification(self, message): """Processes a message consumed from the incoming queue.""" print " [x] %s" % message # Make sure JSON is valid notif = json.loads(message) if 'token' not in notif: raise KeyError('Notification key "token" not found.') if 'type' not in notif: # No type specified; use default notif['type'] = "text" if 'timestamp' not in notif: # No timestamp specified; create one notif['timestamp'] = int(time.time()) if 'ttl' not in notif: # No TTL specified; create one (30 days) notif['ttl'] = 30*24*60*60 if 'payload' not in notif: raise KeyError('Notification key "payload" not found.') if 'ciphertext' not in notif['payload']: raise KeyError('Notification key "payload.ciphertext" not found.') try: # Assert exchange is declared self.delivery_channel.exchange_declare( exchange=self.incoming_exchange_name, durable=True, type='fanout' ) # Python's JSON parser assumes everything is Unicode, and Pika # uses the "+" operator when it shouldn't. token = notif['token'].encode('ascii') self.delivery_channel.basic_publish( exchange=self.incoming_exchange_name, routing_key=token, body=message ) print "Notification routed to user exchange" except Exception as ex: # TODO: Either put the message back in the incoming queue, or send # a NACK to the broker if we're going to do ACK/NACK crap raise ex
class Amqp(object): def __init__(self, conf): # RabbitMQ general options self.cacertfile = conf['cacertfile'] self.certfile = conf['certfile'] self.exchange = conf['exchange'] self.status_exchange = conf['status_exchange'] self.fail_if_no_peer_cert = conf['fail_if_no_peer_cert'] self.heartbeat = conf['heartbeat'] self.host = conf['host'] self.keyfile = conf['keyfile'] self.password = conf['password'] self.port = conf['port'] self.ssl_port = conf['ssl_port'] self.queue = conf['uuid'] self.retry_timeout = conf['retry_timeout'] self.ssl_auth = conf['ssl_auth'] self.use_ssl = conf['use_ssl'] self.username = conf['username'] self.vhost = conf['vhost'] # Connection and channel initialization self.connection = None self.channel = None # Plain credentials credentials = PlainCredentials(self.username, self.password) pika_options = {'host': self.host, 'port': self.port, 'virtual_host': self.vhost, 'credentials': credentials} # SSL options if self.use_ssl: pika_options['ssl'] = True pika_options['port'] = self.ssl_port if self.ssl_auth: pika_options['credentials'] = ExternalCredentials() pika_options['ssl_options'] = { 'ca_certs': self.cacertfile, 'certfile': self.certfile, 'keyfile': self.keyfile, 'cert_reqs': CERT_REQUIRED } if self.heartbeat: pika_options['heartbeat'] = self.heartbeat self.parameters = None try: self.parameters = pika.ConnectionParameters(**pika_options) except TypeError as err: self.logger.debug(err) # Let's be compatible with original pika version (no integer for # heartbeats and no ssl. self.logger.warning("Wrong pika lib version, won't use ssl.") pika_options['heartbeat'] = True if self.use_ssl: self.use_ssl = False pika_options['port'] = self.port del pika_options['ssl'] if self.ssl_auth: self.ssl_auth = False del pika_options['ssl_options'] self.parameters = pika.ConnectionParameters(**pika_options) def connect(self): SelectPoller.TIMEOUT = .1 self.connection = SelectConnection(self.parameters, self.on_connected) self.connection.ioloop.start() def close(self, amqperror=False): if (self.connection and not self.connection.closing and not self.connection.closed): self.logger.debug("Closing connection") self.connection.close() #self.connection.ioloop.start() def on_remote_close(self, code, text): self.logger.debug("Remote channel close, code %d" % code) time.sleep(2) if code != 200: self.close() raise AmqpError(text) def on_connection_closed(self, frame): self.connection.ioloop.stop() def on_connected(self, connection): self.connection = connection self.connection.add_on_close_callback(self.on_connection_closed) self.connection.channel(self.on_channel_open)
class NewsFeedMaggot(Thread): def __init__(self): super(NewsFeedMaggot, self).__init__() self.feeds = [] self.update_track_dict() self.processfeed = ProcessFeed() self.channel = None self.connection = None self.alive = False self.stop_flag = False self.r = None self.r_last_touched = datetime.now() def update_track_dict(self): global DB_CONN try: LOGGER.info("Obtaining track from postgre") if DB_CONN is None: connect_pg() # Get all ids from "feedjack_track" track_ids = [] cursor = DB_CONN.cursor(cursor_factory=psycopg2.extras.DictCursor) cursor.execute("SELECT id FROM feedjack_track") results = cursor.fetchall() for result in results: track_ids.append(result['id']) # Get "trackedphrase" for each "track" for track_id in track_ids: TRACK_DICT[track_id] = [] cursor.execute("SELECT id, name, mode " \ "FROM feedjack_trackedphrase " \ "WHERE track_id=%s", (track_id,)) results = cursor.fetchall() for result in results: TRACK_DICT[track_id].append({ 'trackedphrase_id': result['id'], 'name': result['name'], 'mode': result['mode'] }) LOGGER.info("Obtaining trackedphrase completed") #pprint(TRACK_DICT) except: DB_CONN.rollback() LOGGER.info(sys.exc_info()) def post_init(self): #初始化 新建RabbitMQ 队列和exchange并绑定(2个) LOGGER.info('Initializing a FeedProcessor') #self.feedprocessor.post_init() LOGGER.info('Initializing a FeedProcessor completed') try: LOGGER.info('Opening a connection') #self.dispatcher = Dispatcher(self.options) self.connection = SelectConnection( parameters=settings.pika_parameters, on_open_callback=self.on_connection_open) try: LOGGER.info('Starting ioloop') self.connection.ioloop.start() except KeyboardInterrupt: # Gracefully close the connection self.connection.close() # Loop until we're fully closed, will stop on its own self.connection.ioloop.start() except: (etype, eobj, etb) = sys.exc_info() print traceback.format_exception(etype, eobj, etb) def on_connection_open(self, unused_connection): LOGGER.info('Opening a connection completed') self.open_channel() def open_channel(self): LOGGER.info('Opening a channel') self.connection.channel(on_open_callback=self.on_channel_open) def on_channel_open(self, new_channel): LOGGER.info('Opening a channel completed') self.channel = new_channel self.declare_exchange() self.declare_exchange2() def declare_exchange(self): LOGGER.info('Declaring an exchange') self.channel.exchange_declare( exchange=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_NAME, exchange_type=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_TYPE, passive=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_PASSIVE, durable=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_DURABLE, auto_delete=settings. RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_AUTO_DELETE, internal=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_INTERNAL, nowait=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_NOWAIT, arguments=None, # Custom key/value pair arguments for the exchange callback=self.on_exchange_declared ) # Call this method on Exchange.DeclareOk def on_exchange_declared(self, unused_frame): LOGGER.info('Declaring an exchange completed') self.declare_queue() def declare_queue(self): LOGGER.info('Declaring a queue') self.channel.queue_declare( self.on_queue_declared, settings.RABBITMQ_NEWSFEED_RAW_FEED_QUEUE_NAME) def on_queue_declared(self, method_frame): LOGGER.info('Declaring a queue completed') self.bind_queue() def bind_queue(self): LOGGER.info('Binding a queue') self.channel.queue_bind( callback=self.on_queue_binded, queue=settings.RABBITMQ_NEWSFEED_RAW_FEED_QUEUE_NAME, exchange=settings.RABBITMQ_NEWSFEED_RAW_FEED_EXCHANGE_NAME, routing_key=settings.RABBITMQ_NEWSFEED_RAW_FEED_ROUTING_KEY) def on_queue_binded(self, frame): LOGGER.info('Binding a queue completed') # Start the thread's activity self.start() ############################### def declare_exchange2(self): LOGGER.info('Declaring an exchange2') self.channel.exchange_declare( exchange=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME, exchange_type=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_TYPE, passive=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_PASSIVE, durable=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_DURABLE, auto_delete=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_AUTO_DELETE, internal=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_INTERNAL, nowait=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NOWAIT, arguments=None, # Custom key/value pair arguments for the exchange callback=self.on_exchange_declared2 ) # Call this method on Exchange.DeclareOk def on_exchange_declared2(self, frame): LOGGER.info('Declaring an exchange2 completed') self.declare_queue2() def declare_queue2(self): LOGGER.info('Declaring a queue2') self.channel.queue_declare( callback=self.on_queue_declared2, queue=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NAME, passive=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_PASSIVE, durable=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_DURABLE, exclusive=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_EXCLUSIVE, auto_delete=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_AUTO_DELETE, nowait=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NOWAIT, arguments=None) def on_queue_declared2(self, method_frame): LOGGER.info('Declaring a queue2 completed') self.bind_queue2() def bind_queue2(self): LOGGER.info('Binding a queue2') self.channel.queue_bind( callback=self.on_queue_binded2, queue=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NAME, exchange=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME, routing_key=settings.RABBITMQ_NEWSFEED_ENTRY_ROUTING_KEY) def on_queue_binded2(self, frame): LOGGER.info('Binding a queue completed on 2') def on_message(self, channel, basic_deliver, properties, body): """Invoked by pika when a message is delivered from RabbitMQ. The channel is passed for your convenience. The basic_deliver object that is passed in carries the exchange, routing key, delivery tag and a redelivered flag for the message. The properties passed in is an instance of BasicProperties with the message properties and the body is the message that was sent 收到消息message,processfeed 类处理成单个postlist并发送给websocket :param pika.channel.Channel channel: The channel object :param pika.Spec.Basic.Deliver: basic_deliver method :param pika.Spec.BasicProperties: properties :param str|unicode body: The message body """ LOGGER.info('Received message # %s from %s', basic_deliver.delivery_tag, properties.app_id) self.ack_message(basic_deliver.delivery_tag) try: data = JSON_DECODER.decode(body) #pprint(data) (entries_status, post_list) = self.processfeed.process(data) for post in post_list: LOGGER.info('Publishing data (post id: %d) to %s', post['post_id'], settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME) json_data = JSON_ENCODER.encode(post) self.channel.basic_publish( exchange=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME, routing_key=settings.RABBITMQ_NEWSFEED_ENTRY_ROUTING_KEY, body=json_data) LOGGER.info('Publishing data completed') except simplejson.JSONDecodeError: LOGGER.info(sys.exc_info()) #except simplejson.JSONEncodeError: # LOGGER.info(sys.exc_info()) def ack_message(self, delivery_tag): """Acknowledge the message delivery from RabbitMQ by sending a Basic.Ack RPC method for the delivery tag. :param int delivery_tag: The delivery tag from the Basic.Deliver frame """ LOGGER.info('Acknowledging message %s', delivery_tag) self.channel.basic_ack(delivery_tag) def run(self): #设置channel.basic_consume MQ消息接收 LOGGER.info('Start to consume message from queue') self.channel.basic_consume( consumer_callback=self.on_message, queue=settings.RABBITMQ_NEWSFEED_RAW_FEED_QUEUE_NAME, no_ack= False, # Set to True means tell the broker to not expect a response exclusive= False, # Set to True means don't allow other consumers on the queue consumer_tag=None) # Specify your own consumer tag
class NewsFeedOpinion(Thread): def __init__(self): super(NewsFeedOpinion, self).__init__() self.feeds = [] self.update_sentimentwords() self.channel = None self.connection = None self.processopinion = ProcessOpinion() self.alive = False self.stop_flag = False self.r = None self.r_last_touched = datetime.now() def update_sentimentwords(self): global NEG_WORDS global DB_CONN try: LOGGER.info("Obtaining sentiment word list from postgre") if DB_CONN is None: connect_pg() cursor = DB_CONN.cursor() cursor.execute( "SELECT name FROM sentidict_sentimentword WHERE mode='2'") results = cursor.fetchall() for result in results: NEG_WORDS.append(str(result[0])) LOGGER.info("Obtaining sentiment word list from postgre completed") except: DB_CONN.rollback() logger(sys.exc_info()) def post_init(self): try: LOGGER.info('Opening a connection') self.connection = SelectConnection( parameters=settings.pika_parameters, on_open_callback=self.on_connection_open) try: LOGGER.info('Starting ioloop') self.connection.ioloop.start() except KeyboardInterrupt: # Gracefully close the connection self.connection.close() # Loop until we're fully closed, will stop on its own self.connection.ioloop.start() except: (etype, eobj, etb) = sys.exc_info() print traceback.format_exception(etype, eobj, etb) def on_connection_open(self, unused_connection): LOGGER.info('Opening a connection completed') self.open_channel() def open_channel(self): LOGGER.info('Opening a channel') self.connection.channel(on_open_callback=self.on_channel_open) def on_channel_open(self, new_channel): LOGGER.info('Opening a channel completed') self.channel = new_channel self.declare_exchange() def declare_exchange(self): LOGGER.info('Declaring an exchange') self.channel.exchange_declare( exchange=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME, exchange_type=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_TYPE, passive=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_PASSIVE, durable=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_DURABLE, auto_delete=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_AUTO_DELETE, internal=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_INTERNAL, nowait=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NOWAIT, arguments=None, # Custom key/value pair arguments for the exchange callback=self.on_exchange_declared ) # Call this method on Exchange.DeclareOk def on_exchange_declared(self, unused_frame): LOGGER.info('Declaring an exchange completed') self.declare_queue() def declare_queue(self): LOGGER.info('Declaring a queue') self.channel.queue_declare( callback=self.on_queue_declared, queue=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NAME, passive=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_PASSIVE, durable=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_DURABLE, exclusive=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_EXCLUSIVE, auto_delete=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_AUTO_DELETE, nowait=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NOWAIT, arguments=None) def on_queue_declared(self, method_frame): LOGGER.info('Declaring a queue completed') self.bind_queue() def bind_queue(self): LOGGER.info('Binding a queue') self.channel.queue_bind( callback=self.on_queue_binded, queue=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NAME, exchange=settings.RABBITMQ_NEWSFEED_ENTRY_EXCHANGE_NAME, routing_key=settings.RABBITMQ_NEWSFEED_ENTRY_ROUTING_KEY) def on_queue_binded(self, frame): LOGGER.info('Binding a queue completed') # Start the thread's activity self.start() def on_message(self, channel, basic_deliver, properties, body): """Invoked by pika when a message is delivered from RabbitMQ. The channel is passed for your convenience. The basic_deliver object that is passed in carries the exchange, routing key, delivery tag and a redelivered flag for the message. The properties passed in is an instance of BasicProperties with the message properties and the body is the message that was sent. :param pika.channel.Channel channel: The channel object :param pika.Spec.Basic.Deliver: basic_deliver method :param pika.Spec.BasicProperties: properties :param str|unicode body: The message body """ LOGGER.info('Received message # %s from %s', basic_deliver.delivery_tag, properties.app_id) self.ack_message(basic_deliver.delivery_tag) try: data = JSON_DECODER.decode(body) #pprint(data) self.processopinion.process(data) except simplejson.JSONDecodeError: LOGGER.info(sys.exc_info()) def ack_message(self, delivery_tag): """Acknowledge the message delivery from RabbitMQ by sending a Basic.Ack RPC method for the delivery tag. :param int delivery_tag: The delivery tag from the Basic.Deliver frame """ LOGGER.info('Acknowledging message %s', delivery_tag) self.channel.basic_ack(delivery_tag) def run(self): LOGGER.info('Start to consume message from queue') self.channel.basic_consume( consumer_callback=self.on_message, queue=settings.RABBITMQ_NEWSFEED_ENTRY_QUEUE_NAME, no_ack= False, # Set to True means tell the broker to not expect a response exclusive= False, # Set to True means don't allow other consumers on the queue consumer_tag=None) # Specify your own consumer tag
class Amqp(object): def __init__(self, conf): # RabbitMQ general options self.cacertfile = conf['cacertfile'] self.certfile = conf['certfile'] self.exchange = conf['exchange'] self.status_exchange = conf['status_exchange'] self.fail_if_no_peer_cert = conf['fail_if_no_peer_cert'] self.heartbeat = conf['heartbeat'] self.host = conf['host'] self.keyfile = conf['keyfile'] self.password = conf['password'] self.port = conf['port'] self.ssl_port = conf['ssl_port'] self.queue = conf['uuid'] self.retry_timeout = conf['retry_timeout'] self.ssl_auth = conf['ssl_auth'] self.use_ssl = conf['use_ssl'] self.username = conf['username'] self.vhost = conf['vhost'] # Connection and channel initialization self.connection = None self.channel = None # Plain credentials credentials = PlainCredentials(self.username, self.password) pika_options = { 'host': self.host, 'port': self.port, 'virtual_host': self.vhost, 'credentials': credentials } # SSL options if self.use_ssl: pika_options['ssl'] = True pika_options['port'] = self.ssl_port if self.ssl_auth: pika_options['credentials'] = ExternalCredentials() pika_options['ssl_options'] = { 'ca_certs': self.cacertfile, 'certfile': self.certfile, 'keyfile': self.keyfile, 'cert_reqs': CERT_REQUIRED } if self.heartbeat: pika_options['heartbeat'] = self.heartbeat self.parameters = None try: self.parameters = pika.ConnectionParameters(**pika_options) except TypeError as err: self.logger.debug(err) # Let's be compatible with original pika version (no integer for # heartbeats and no ssl. self.logger.warning("Wrong pika lib version, won't use ssl.") pika_options['heartbeat'] = True if self.use_ssl: self.use_ssl = False pika_options['port'] = self.port del pika_options['ssl'] if self.ssl_auth: self.ssl_auth = False del pika_options['ssl_options'] self.parameters = pika.ConnectionParameters(**pika_options) def connect(self): SelectPoller.TIMEOUT = .1 self.connection = SelectConnection(self.parameters, self.on_connected) self.connection.ioloop.start() def close(self, amqperror=False): if (self.connection and not self.connection.closing and not self.connection.closed): self.logger.debug("Closing connection") self.connection.close() #self.connection.ioloop.start() def on_remote_close(self, code, text): self.logger.debug("Remote channel close, code %d" % code) time.sleep(2) if code != 200: self.close() raise AmqpError(text) def on_connection_closed(self, frame): self.connection.ioloop.stop() def on_connected(self, connection): self.connection = connection self.connection.add_on_close_callback(self.on_connection_closed) self.connection.channel(self.on_channel_open)