Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
 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!"
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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]
Ejemplo n.º 5
0
 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!"
Ejemplo n.º 6
0
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()