def start(self): specDir = os.sep.join(qpid.__file__.split('/')[:-2])+"/amqp_specs" self.connection = Client(self.host, self.port, spec=qpid.spec.load('file://%s/amqp0-8.xml' % specDir), vhost=self.vhost) self.connection.start({ 'LOGIN': self.config.username, 'PASSWORD': self.config.password}) exchanges = [('domain_control','topic'), ('logging', 'topic'), ('events', 'topic')] self.registeredExchanges = [] self.mqueue = DeferredQueue() self.mqueue.get().addCallback(self._processQueue) self.channel = self.connection.channel(1) self.channel.channel_open() for x,t in exchanges: self.channel.exchange_declare(exchange=x, type=t, auto_delete=False) self.registeredExchanges.append(x)
def init_qpid_connection(self): self.client = Client(self.host, self.port, spec=self.amqp_spec) self.client.start({'LOGIN': self.user, 'PASSWORD': self.password}) self.conn = self.client.channel(1) self.conn.channel_open() print "opened channel!"
class QpidAMQP08Hub(BaseAMQPHub): client = None def __init__(self, broker, username=None, password=None, ssl=False): """ Initialize the Moksha Hub. `broker` [amqps://][<user>[/<password>]@]<host>[:<port>] """ self.set_broker(broker) self.init_qpid_connection() # We need 0.8 for RabbitMQ self.amqp_spec=qpid.spec08.load('/usr/share/amqp/amqp.0-8.xml') def set_broker(self, broker): self.url = URL(broker) self.user = self.url.password or 'guest' self.password = self.url.password or 'guest' self.host = self.url.host if self.url.scheme == URL.AMQPS: self.ssl = True default_port = 5671 else: self.ssl = False default_port = 5672 self.port = self.url.port or default_port def init_qpid_connection(self): self.client = Client(self.host, self.port, spec=self.amqp_spec) self.client.start({'LOGIN': self.user, 'PASSWORD': self.password}) self.conn = self.client.channel(1) self.conn.channel_open() print "opened channel!" def create_queue(self, queue, routing_key, exchange='amq.topic', auto_delete=False, durable=True, **kw): self.conn.queue_declare(queue=queue, auto_delete=auto_delete, durable=durable, **kw) self.conn.queue_bind(queue=queue, exchange=exchange, routing_key=routing_key) print "Created %s queue" % queue def send_message(self, message, exchange='amq.topic', routing_key=''): self.conn.basic_publish(routing_key=routing_key, content=Content(message), exchange=exchange) def get(self, queue): t = self.conn.basic_consume(queue=queue, no_ack=True) print "t.consumer_tag =", t.consumer_tag q = self.client.queue(t.consumer_tag) msg = q.get() print "got message: ", msg return msg.content.body q.close() def close(self): if self.conn: print "Closing connection" self.conn.close()
class AMQPEventBus(PelotonPlugin,AbstractEventBusPlugin): """Uses Python-QPID to hook into the AMQP event bus, most probably provided by RabbitMQ but potentially any provider. The QPID is not Twisted based and provides a blocking handler for receiving messages off the bus. This plugin needs to be superceded by one based on a Twisted AMQP protocol handler for greater efficiency in this environment. As it stands one thread is used per routing_key being listened for and in the event that subscribers do not de-register, threads will be consumed at an un-wholesome rate. @todo - purging of threads with no real listeners behind them? """ def initialise(self): self.vhost = self.kernel.settings.messagingVHost self.host = self.kernel.settings.messagingHost hp = self.host.split(':') if len(hp) == 1: self.port = 5672 else: self.host = hp[0] try: self.port = int(hp[1]) except ValueError: raise ConfigurationError("Invalid port number for AMQP host: %s " % hp[1]) # NB: THIS HANDLER DOES NOT SUPPORT REALM self.realm = self.kernel.settings.messagingRealm self.domain = self.kernel.settings.domain self.node_guid = self.kernel.profile.guid # key is ctag; value is handler object self.handlersByCtag = {} # key is <exchange>.<routing_key>; value is ctag self.ctagByQueue = {} # key is handler, value is (exchange, routing_key, ctag) self.registeredHandlers = {} def start(self): specDir = os.sep.join(qpid.__file__.split('/')[:-2])+"/amqp_specs" self.connection = Client(self.host, self.port, spec=qpid.spec.load('file://%s/amqp0-8.xml' % specDir), vhost=self.vhost) self.connection.start({ 'LOGIN': self.config.username, 'PASSWORD': self.config.password}) exchanges = [('domain_control','topic'), ('logging', 'topic'), ('events', 'topic')] self.registeredExchanges = [] self.mqueue = DeferredQueue() self.mqueue.get().addCallback(self._processQueue) self.channel = self.connection.channel(1) self.channel.channel_open() for x,t in exchanges: self.channel.exchange_declare(exchange=x, type=t, auto_delete=False) self.registeredExchanges.append(x) def stop(self): for _, _, q in self.ctagByQueue.values(): try: q.close() except: pass def register(self, key, handler, exchange='events'): """ Register to receive events from the specified exchange (default 'events') with all messages to be handled by a peloton.events.AbstractEventHandler instance.""" if exchange not in self.registeredExchanges: raise MessagingError("Exchange %s not valid" % exchange) if not isinstance(handler, AbstractEventHandler): raise MessagingError("Subscription to %s.%s attempted with invalid handler: %s" % (exchange, key, str(handler))) key = "%s.%s" % (self.domain, key) queue = "%s.%s" % (exchange,key) if not self.ctagByQueue.has_key(queue): try: qname, _, _ = self.channel.queue_declare(exclusive=True).fields self.channel.queue_bind(queue=qname, exchange=exchange, routing_key=key) ctag = self.channel.basic_consume(queue=qname, no_ack=True).consumer_tag q = self.connection.queue(ctag) self.ctagByQueue[queue] = (ctag, qname, q) self._startListener(ctag, q) except Exception: self.logger.error("Message published to closed exchange: %s/%s " % (exchange, key)) raise MessagingError("Message published to closed exchange: %s/%s " % (exchange, key)) else: ctag, qname, _ = self.ctagByQueue[queue] record = (exchange, key, ctag, qname) try: queues = self.registeredHandlers[handler] if record not in queues: queues.append(record) except KeyError: self.registeredHandlers[handler]=[record] try: handlers = self.handlersByCtag[ctag] if handler not in handlers: handlers.append(handler) except Exception, ex: self.handlersByCtag[ctag] = [handler]