Example #1
0
class Sender(object):

    __slots__ = ('__conn', '__session')
    __exchange = 'amq.topic'

    def __init__(self, host='localhost', port=5672, timeout=5):

        self.__conn = None
        qpid.util.socket.setdefaulttimeout(timeout)
        
        if __debug__:
            print 'Connecting to %s:%d' % (host, port)

        sock = qpid.util.connect(host, port)
        self.__conn = Connection(sock=sock)
        self.__conn.start()
        self.__session = self.__conn.session(str(uuid4()))

    def __del__(self):
        if self.__conn: self.__conn.close()

    def send(self, routing_key, msg_text):

        propDelivery = self.__session.delivery_properties(
                       routing_key = routing_key.__str__(),
                       exchange = self.__exchange )
        contentType = 'application/x-protobuf'
        propMessage = self.__session.message_properties(
                          content_type = contentType)

        self.__session.message_transfer(destination = self.__exchange,
                  message = Message(propDelivery, propMessage, msg_text))
Example #2
0
def get_qpid_connection(broker_addr):
    try:
        socket = connect(broker_addr, 5672)
        connection = Connection (sock=socket)
        connection.start()
        return connection
    except:
        sys.stderr.write("mhsAckNotify: connect to %s: %s\n" % (broker_addr, sys.exc_info()[1],))
        return None
Example #3
0
    def run(self):
        # Create connection and session
        socket = connect( self.host, self.port)
        
        connection = Connection(sock=socket, username=self.username, password=self.password)
        
        print("consumer "+self.queueName+": starting connection...")
        connection.start()
        print("consumer "+self.queueName+": ...connection started")

        print("consumer "+self.queueName+": getting session...")
        session = connection.session(str(uuid4()))
        print("consumer "+self.queueName+": ...session got")

        # Define local queue
        local_queue_name = 'my_local_queue_' +self.queueName

        # Create local queue
        print("consumer "+self.queueName+": getting queue...")
        queue = session.incoming(local_queue_name)
        print("consumer "+self.queueName+": ...queue got")

        # Route messages from message_queue to my_local_queue
        print("consumer "+self.queueName+": subscribing...")
        session.message_subscribe(queue = self.queueName, destination=local_queue_name)
        print("consumer "+self.queueName+": ...subscribed")

        print("consumer "+self.queueName+": starting queue...")
        queue.start()
        print("consumer "+self.queueName+": ...queue started")

        content = ''
        index = 0
        
        while (self.running):
            try:
                # Get message from the local queue, timeout 5 seconds
                message = queue.get(timeout=5)
            except:
                break # exit this thread, consumer

            # Get body of the message
            content = message.body

            #message_properties = message.get("message_properties")

            # Accept message (removes it from the queue)
            session.message_accept(RangedSet(message.id))

            if (content != ""):
                try:
                    self.readGPB(content)

                except Exception, e: 
                    print( "Unexpected error: %s\n" % str(e) )
Example #4
0
class IngestViaQPID:
    def __init__(self, host='localhost', port=5672, ssl=None):
        '''
        Connect to QPID and make bindings to route message to external.dropbox queue
        @param host: string hostname of computer running EDEX and QPID (default localhost)
        @param port: integer port used to connect to QPID (default 5672)
        @param ssl: boolean to determine whether ssl is used, default value of None will use ssl only if a client certificate is found.
        '''
        
        try:
            #
            socket = connect(host, port)
            if "QPID_SSL_CERT_DB" in os.environ:
                certdb = os.environ["QPID_SSL_CERT_DB"]
            else:
                certdb = os.path.expanduser("~/.qpid/")
            if "QPID_SSL_CERT_NAME" in os.environ:
                certname = os.environ["QPID_SSL_CERT_NAME"]
            else:
                certname = QPID_USERNAME
            certfile = os.path.join(certdb, certname + ".crt")
            if ssl or (ssl is None and os.path.exists(certfile)):
                keyfile = os.path.join(certdb, certname + ".key")
                trustfile = os.path.join(certdb, "root.crt")
                socket = qpid.util.ssl(socket, keyfile=keyfile, certfile=certfile, ca_certs=trustfile)
            self.connection = Connection (sock=socket, username=QPID_USERNAME, password=QPID_PASSWORD)
            self.connection.start()
            self.session = self.connection.session(str(uuid4()))
            self.session.exchange_bind(exchange='amq.direct', queue='external.dropbox', binding_key='external.dropbox')
            print 'Connected to Qpid'
        except:
            print 'Unable to connect to Qpid'
               
    def sendmessage(self, filepath, header):
        '''
        This function sends a message to the external.dropbox queue providing the path
        to the file to be ingested and a header to determine the plugin to be used to
        decode the file.
        @param filepath: string full path to file to be ingested
        @param header: string header used to determine plugin decoder to use
        '''
        props = self.session.delivery_properties(routing_key='external.dropbox')
        head = self.session.message_properties(application_headers={'header':header},
                                               user_id=QPID_USERNAME) # For issue QPID-5569.  Fixed in Qpid 0.27
        self.session.message_transfer(destination='amq.direct', message=Message(props, head, filepath))
           
    def close(self):
        '''
        After all messages are sent call this function to close connection and make sure
        there are no threads left open
        '''
        self.session.close(timeout=10)
        print 'Connection to Qpid closed'
Example #5
0
class Receiver(object):
    __slots__ = ('__conn', '__session', '__queue')
    __exchange = 'amq.topic'

    def __init__(self, host='localhost', port=5672, timeout=5):

        self.__conn = self.__session = None

        if __debug__:
            print 'Connecting to %s:%d' % (host, port)
            
        qpid.util.socket.setdefaulttimeout(timeout)
        sock = qpid.util.connect(host, port)
        self.__conn = Connection(sock=sock)
        self.__conn.start()
        self.__session = self.__conn.session(str(uuid4()))

    def __del__(self):
        if self.__session: self.__session.close()
        if self.__conn: self.__conn.close()

    def setup(self, binding_keys, queue_name = 'queue_%d' % os.getpid()):

        # Setup queue
        self.__session.queue_declare(queue = queue_name, auto_delete = True,
                                     exclusive = False)

        for k in binding_keys:
            if __debug__:
                print 'Binding', k

            self.__session.exchange_bind(exchange = self.__exchange,
                queue = queue_name, binding_key = k)

        localQueueName = 'local_queue_%d' % os.getpid()
        self.__queue = self.__session.incoming(localQueueName)

        # Route messages from message_queue to my_local_queue
        self.__session.message_subscribe(queue = queue_name,
                                        destination = localQueueName)
        if __debug__:
            print 'Queue info:', self.__session.queue_query(queue_name)

        self.__queue.start()
        return self

    def fetch(self, timeout=None):
        message = self.__queue.get(timeout=timeout)
        self.__session.message_accept(RangedSet(message.id))

        return message
Example #6
0
def get_qpid_connection(broker_host):
    try:
        socket = connect(broker_host, 5672)
        connection = Connection(sock=socket,
                                username=QPID_USERNAME,
                                password=QPID_PASSWORD)
        connection.start()
        return connection
    except:
        sys.stderr.write("mhsAckNotify: connect to %s: %s\n" % (
            broker_host,
            sys.exc_info()[1],
        ))
        return None
Example #7
0
class IngestViaQPID:
    def __init__(self, host='localhost', port=5672):
        '''
        Connect to QPID and make bindings to route message to external.dropbox queue
        @param host: string hostname of computer running EDEX and QPID (default localhost)
        @param port: integer port used to connect to QPID (default 5672)
        '''

        try:
            #
            self.socket = connect(host, port)
            self.connection = Connection(sock=self.socket,
                                         username=QPID_USERNAME,
                                         password=QPID_PASSWORD)
            self.connection.start()
            self.session = self.connection.session(str(uuid4()))
            self.session.exchange_bind(exchange='amq.direct',
                                       queue='external.dropbox',
                                       binding_key='external.dropbox')
            print('Connected to Qpid')
        except:
            print('Unable to connect to Qpid')

    def sendmessage(self, filepath, header):
        '''
        This function sends a message to the external.dropbox queue providing the path
        to the file to be ingested and a header to determine the plugin to be used to
        decode the file.
        @param filepath: string full path to file to be ingested
        @param header: string header used to determine plugin decoder to use
        '''
        props = self.session.delivery_properties(
            routing_key='external.dropbox')
        head = self.session.message_properties(
            application_headers={'header': header},
            user_id=QPID_USERNAME)  # For issue QPID-5569.  Fixed in Qpid 0.27
        self.session.message_transfer(destination='amq.direct',
                                      message=Message(props, head, filepath))

    def close(self):
        '''
        After all messages are sent call this function to close connection and make sure
        there are no threads left open
        '''
        self.session.close(timeout=10)
        print('Connection to Qpid closed')
Example #8
0
    def start(self):
        """
        Enable AMQP queueing. This method puts up the event processor and
        sets it to "active".
        """
        self.log.debug("enabling AMQP queueing")

        # Evaluate username
        user = self.config.get("amqp.id", default=None)
        if not user:
            user = self.env.uuid
        password = self.config.get("amqp.key")

        # Create initial broker connection
        url = "%s:%s" % (self.url['host'], self.url['port'])
        self._conn = Connection.establish(url, reconnect=self.reconnect,
            username=user,
            password=password,
            transport=self.url['transport'],
            reconnect_interval=self.reconnect_interval,
            reconnect_limit=self.reconnect_limit)

        # Do automatic broker failover if requested
        if self.config.get('amqp.failover', False):
            auto_fetch_reconnect_urls(self._conn)

        # Create event exchange
        socket = connect(self.url['host'], self.url['port'])
        if self.url['scheme'][-1] == 's':
            socket = ssl(socket)
        user = self.config.get("amqp.id", default=None)
        if not user:
            user = self.env.uuid
        connection = DirectConnection(sock=socket,
                username=user,
                password=self.config.get("amqp.key"))
        connection.start()
        session = connection.session(str(uuid4()))
        # pylint: disable=E1103
        session.exchange_declare(exchange=self.env.domain, type="xml")
        connection.close()

        # Create event provider
        self._eventProvider = EventProvider(self.env, self.getConnection())
Example #9
0
class IngestViaQPID:
    def __init__(self, host='localhost', port=5672):
        '''
        Connect to QPID and make bindings to route message to external.dropbox queue
        @param host: string hostname of computer running EDEX and QPID (default localhost)
        @param port: integer port used to connect to QPID (default 5672)
        '''

        try:
            #
            self.socket = connect(host, port)
            self.connection = Connection (sock=self.socket, username=QPID_USERNAME, password=QPID_PASSWORD)
            self.connection.start()
            self.session = self.connection.session(str(uuid4()))
            self.session.exchange_bind(exchange='amq.direct', queue='external.dropbox', binding_key='external.dropbox')
            print('Connected to Qpid')
        except:
            print('Unable to connect to Qpid')

    def sendmessage(self, filepath, header):
        '''
        This function sends a message to the external.dropbox queue providing the path
        to the file to be ingested and a header to determine the plugin to be used to
        decode the file.
        @param filepath: string full path to file to be ingested
        @param header: string header used to determine plugin decoder to use
        '''
        props = self.session.delivery_properties(routing_key='external.dropbox')
        head = self.session.message_properties(application_headers={'header':header},
                                               user_id=QPID_USERNAME) # For issue QPID-5569.  Fixed in Qpid 0.27
        self.session.message_transfer(destination='amq.direct', message=Message(props, head, filepath))

    def close(self):
        '''
        After all messages are sent call this function to close connection and make sure
        there are no threads left open
        '''
        self.session.close(timeout=10)
        print('Connection to Qpid closed')
Example #10
0
class BasilConnection(object):
    def __init__(self, model, host, port):
        self.model = model
        self.host = host
        self.port = port
        self.broker_id = "%s:%i" % (self.host, self.port)

        self.conn = Connection(connect(host, port), self.model.spec)

        self.mclient = managementClient(
            self.model.spec, None, self.model.on_props, self.model.on_stats, self.model.on_callback
        )
        self.mclient.schemaListener(self.model.on_schema)

        self.chan = None

        self.model.connections[self.broker_id] = self

    def open(self):
        self.conn.start()
        self.chan = self.mclient.addChannel(self.conn.session(str(uuid4())), self)

    def close(self):
        self.mclient.removeChannel(self.chan)
Example #11
0
class QpidAMQPHubExtension(BaseAMQPHubExtension):
    """
     Initialize the Moksha Hub.

    `broker`
        [amqps://][<user>[/<password>]@]<host>[:<port>]

    """

    def __init__(self, hub, config):
        self.config = config
        self.set_broker(self.config.get('amqp_broker'))
        self.socket = connect(self.host, self.port)
        if self.url.scheme == URL.AMQPS:
            self.socket = ssl(self.socket)
        self.connection = Connection(sock=self.socket,
                                     username=self.user,
                                     password=self.password)
        self.connection.start()
        log.info("Connected to AMQP Broker %s" % self.host)
        self.session = self.connection.session(str(uuid4()))
        self.local_queues = []
        super(QpidAMQPHubExtension, self).__init__()

    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 send_message(self, topic, message, **headers):
        headers['routing_key'] = headers.get('routing_key', topic)
        props = self.session.delivery_properties(**headers)
        msg = Message(props, message)
        self.session.message_transfer(
            destination=headers.get('exchange', 'amq.topic'),
            message=msg)
        super(QpidAMQPHubExtension, self).send_message(
            topic, message, **headers)

    def subscribe_queue(self, server_queue_name, local_queue_name):
        queue = self.session.incoming(local_queue_name)
        self.session.message_subscribe(queue=server_queue_name,
                                       destination=local_queue_name)
        queue.start()
        return queue

    def queue_declare(self, queue, durable=True, exclusive=False,
                      auto_delete=False, **kw):
        self.session.queue_declare(queue=queue, exclusive=exclusive,
                                   auto_delete=auto_delete,
                                   arguments={'qpid.max_count': 0,
                                              'qpid.max_size': 0}, **kw)

    def exchange_bind(self, queue, exchange='amq.topic', binding_key=None):
        self.session.exchange_bind(exchange=exchange, queue=queue,
                                   binding_key=binding_key)

    def message_subscribe(self, queue, destination):
        return self.session.message_subscribe(queue=queue,
                                              destination=destination)

    def message_accept(self, message):
        try:
            self.session.message_accept(RangedSet(message.id))
        except SessionClosed:
            log.debug("Accepted message on closed session: %s" % message.id)
            pass

    def subscribe(self, topic, callback):
        queue_name = '_'.join([
            "moksha_consumer", self.session.name, str(uuid4()),
        ])
        server_queue_name = local_queue_name = queue_name

        self.queue_declare(queue=server_queue_name, exclusive=True,
                           auto_delete=True)
        self.exchange_bind(server_queue_name, binding_key=topic)

        self.local_queues.append(self.session.incoming(local_queue_name))

        self.message_subscribe(queue=server_queue_name,
                               destination=local_queue_name)

        self.local_queues[-1].start()
        self.local_queues[-1].listen(callback)

        super(QpidAMQPHubExtension, self).subscribe(topic, callback)

    def close(self):
        self.session.close(timeout=2)
        self.connection.close(timeout=2)
        self.socket.close()
Example #12
0
parser.add_option("-d", "--debug", dest="debug", action="store_true",
                  help="debug what messages are being sent")
options, args = parser.parse_args()

options.targets = [t.strip() for t in options.targets.split(',')]

# Create connection and session
session_dicts = []
for target in options.targets:
    print "Attempting to setup connection with", target
    try:
        socket = connect(target, 5672)
        connection = Connection(
            socket, username='******', password='******',
        )
        connection.start(timeout=10000)
        session = connection.session(str(uuid4()))

        # Setup routing properties
        properties = session.delivery_properties(routing_key='httpdlight_http_rawlogs')
        session_dicts.append({
            'target' : target,
            'socket' : socket,
            'connection' : connection,
            'session' : session,
            'properties' : properties,
        })
        print "    Created target", target
    except Exception as e:
        print "    Failed to create target", target
        print str(e)
Example #13
0
class QpidAMQPHubExtension(BaseAMQPHubExtension):
    """
     Initialize the Moksha Hub.

    `broker`
        [amqps://][<user>[/<password>]@]<host>[:<port>]

    """
    def __init__(self, hub, config):
        self.config = config
        self.set_broker(self.config.get('amqp_broker'))
        self.socket = connect(self.host, self.port)
        if self.url.scheme == URL.AMQPS:
            self.socket = ssl(self.socket)
        self.connection = Connection(sock=self.socket,
                                     username=self.user,
                                     password=self.password)
        self.connection.start()
        log.info("Connected to AMQP Broker %s" % self.host)
        self.session = self.connection.session(str(uuid4()))
        self.local_queues = []
        super(QpidAMQPHubExtension, self).__init__()

    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 send_message(self, topic, message, **headers):
        headers['routing_key'] = headers.get('routing_key', topic)
        props = self.session.delivery_properties(**headers)
        msg = Message(props, message)
        self.session.message_transfer(destination=headers.get(
            'exchange', 'amq.topic'),
                                      message=msg)
        super(QpidAMQPHubExtension, self).send_message(topic, message,
                                                       **headers)

    def subscribe_queue(self, server_queue_name, local_queue_name):
        queue = self.session.incoming(local_queue_name)
        self.session.message_subscribe(queue=server_queue_name,
                                       destination=local_queue_name)
        queue.start()
        return queue

    def queue_declare(self,
                      queue,
                      durable=True,
                      exclusive=False,
                      auto_delete=False,
                      **kw):
        self.session.queue_declare(queue=queue,
                                   exclusive=exclusive,
                                   auto_delete=auto_delete,
                                   arguments={
                                       'qpid.max_count': 0,
                                       'qpid.max_size': 0
                                   },
                                   **kw)

    def exchange_bind(self, queue, exchange='amq.topic', binding_key=None):
        self.session.exchange_bind(exchange=exchange,
                                   queue=queue,
                                   binding_key=binding_key)

    def message_subscribe(self, queue, destination):
        return self.session.message_subscribe(queue=queue,
                                              destination=destination)

    def message_accept(self, message):
        try:
            self.session.message_accept(RangedSet(message.id))
        except SessionClosed:
            log.debug("Accepted message on closed session: %s" % message.id)
            pass

    def subscribe(self, topic, callback):
        queue_name = '_'.join([
            "moksha_consumer",
            self.session.name,
            str(uuid4()),
        ])
        server_queue_name = local_queue_name = queue_name

        self.queue_declare(queue=server_queue_name,
                           exclusive=True,
                           auto_delete=True)
        self.exchange_bind(server_queue_name, binding_key=topic)

        self.local_queues.append(self.session.incoming(local_queue_name))

        self.message_subscribe(queue=server_queue_name,
                               destination=local_queue_name)

        self.local_queues[-1].start()
        self.local_queues[-1].listen(callback)

        super(QpidAMQPHubExtension, self).subscribe(topic, callback)

    def close(self):
        self.session.close(timeout=2)
        self.connection.close(timeout=2)
        self.socket.close()
Example #14
0
options, args = parser.parse_args()

options.targets = [t.strip() for t in options.targets.split(',')]

# Create connection and session
session_dicts = []
for target in options.targets:
    print "Attempting to setup connection with", target
    try:
        socket = connect(target, 5672)
        connection = Connection(
            socket,
            username='******',
            password='******',
        )
        connection.start(timeout=10000)
        session = connection.session(str(uuid4()))

        # Setup routing properties
        print "Talking to %s on topic %s" % (target, options.topic)
        properties = session.delivery_properties(routing_key=options.topic)
        session_dicts.append({
            'target': target,
            'socket': socket,
            'connection': connection,
            'session': session,
            'properties': properties,
        })
        print "    Created target", target
    except Exception as e:
        print "    Failed to create target", target
Example #15
0
class ManagementData:

    #
    # Data Structure:
    #
    # Please note that this data structure holds only the most recent
    # configuration and instrumentation data for each object.  It does
    # not hold the detailed historical data that is sent from the broker.
    # The only historical data it keeps are the high and low watermarks
    # for hi-lo statistics.
    #
    #    tables        :== {class-key}
    #                        {<obj-id>}
    #                          (timestamp, config-record, inst-record)
    #    class-key     :== (<package-name>, <class-name>, <class-hash>)
    #    timestamp     :== (<last-interval-time>, <create-time>, <delete-time>)
    #    config-record :== [element]
    #    inst-record   :== [element]
    #    element       :== (<element-name>, <element-value>)
    #

    def registerObjId(self, objId):
        if not objId.index() in self.idBackMap:
            self.idBackMap[objId.index()] = self.nextId
            self.idMap[self.nextId] = objId
            self.nextId += 1

    def displayObjId(self, objIdIndex):
        if objIdIndex in self.idBackMap:
            return self.idBackMap[objIdIndex]
        else:
            return 0

    def rawObjId(self, displayId):
        if displayId in self.idMap:
            return self.idMap[displayId]
        else:
            return None

    def displayClassName(self, cls):
        (packageName, className, hash) = cls
        rev = self.schema[cls][4]
        if rev == 0:
            suffix = ""
        else:
            suffix = ".%d" % rev
        return packageName + ":" + className + suffix

    def dataHandler(self, context, className, list, timestamps):
        """ Callback for configuration and instrumentation data updates """
        self.lock.acquire()
        try:
            # If this class has not been seen before, create an empty dictionary to
            # hold objects of this class
            if className not in self.tables:
                self.tables[className] = {}

            # Register the ID so a more friendly presentation can be displayed
            objId = list[0][1]
            oidx = objId.index()
            self.registerObjId(objId)

            # If this object hasn't been seen before, create a new object record with
            # the timestamps and empty lists for configuration and instrumentation data.
            if oidx not in self.tables[className]:
                self.tables[className][oidx] = (timestamps, [], [])

            (unused, oldConf, oldInst) = self.tables[className][oidx]

            # For config updates, simply replace old config list with the new one.
            if context == 0:  #config
                self.tables[className][oidx] = (timestamps, list, oldInst)

            # For instrumentation updates, carry the minimum and maximum values for
            # "hi-lo" stats forward.
            elif context == 1:  #inst
                if len(oldInst) == 0:
                    newInst = list
                else:
                    newInst = []
                    for idx in range(len(list)):
                        (key, value) = list[idx]
                        if key.find("High") == len(key) - 4:
                            if oldInst[idx][1] > value:
                                value = oldInst[idx][1]
                        if key.find("Low") == len(key) - 3:
                            if oldInst[idx][1] < value:
                                value = oldInst[idx][1]
                        newInst.append((key, value))
                self.tables[className][oidx] = (timestamps, oldConf, newInst)

        finally:
            self.lock.release()

    def ctrlHandler(self, context, op, data):
        if op == self.mclient.CTRL_BROKER_INFO:
            pass
        elif op == self.mclient.CTRL_HEARTBEAT:
            pass

    def configHandler(self, context, className, list, timestamps):
        self.dataHandler(0, className, list, timestamps)

    def instHandler(self, context, className, list, timestamps):
        self.dataHandler(1, className, list, timestamps)

    def methodReply(self, broker, sequence, status, sText, args):
        """ Callback for method-reply messages """
        self.lock.acquire()
        try:
            line = "Call Result: " + self.methodsPending[sequence] + \
                   "  " + str (status) + " (" + sText + ")"
            print line, args
            del self.methodsPending[sequence]
        finally:
            self.lock.release()

    def closeHandler(self, context, reason):
        if self.operational:
            print "Connection to broker lost:", reason
        self.operational = False
        if self.cli != None:
            self.cli.setPromptMessage("Broker Disconnected")

    def schemaHandler(self, context, classKey, configs, insts, methods,
                      events):
        """ Callback for schema updates """
        if classKey not in self.schema:
            schemaRev = 0
            for key in self.schema:
                if classKey[0] == key[0] and classKey[1] == key[1]:
                    schemaRev += 1
            self.schema[classKey] = (configs, insts, methods, events,
                                     schemaRev)

    def setCli(self, cliobj):
        self.cli = cliobj

    def __init__(self, disp, host, username="******", password="******"):
        self.lock = Lock()
        self.tables = {}
        self.schema = {}
        self.bootSequence = 0
        self.operational = False
        self.disp = disp
        self.cli = None
        self.lastUnit = None
        self.methodSeq = 1
        self.methodsPending = {}
        self.sessionId = "%s.%d" % (platform.uname()[1], os.getpid())

        self.broker = Broker(host)
        sock = connect(self.broker.host, self.broker.port)
        oldTimeout = sock.gettimeout()
        sock.settimeout(10)
        self.conn = Connection(sock,
                               username=self.broker.username,
                               password=self.broker.password)

        def aborted():
            raise Timeout(
                "Waiting for connection to be established with broker")

        oldAborted = self.conn.aborted
        self.conn.aborted = aborted

        self.conn.start()

        sock.settimeout(oldTimeout)
        self.conn.aborted = oldAborted

        self.mclient = managementClient("unused", self.ctrlHandler,
                                        self.configHandler, self.instHandler,
                                        self.methodReply, self.closeHandler)
        self.mclient.schemaListener(self.schemaHandler)
        self.mch = self.mclient.addChannel(self.conn.session(self.sessionId))
        self.operational = True
        self.idMap = {}
        self.idBackMap = {}
        self.nextId = 101

    def close(self):
        pass

    def refName(self, oid):
        if oid == None:
            return "NULL"
        return str(self.displayObjId(oid.index()))

    def valueDisplay(self, classKey, key, value):
        if value == None:
            return "<NULL>"
        for kind in range(2):
            schema = self.schema[classKey][kind]
            for item in schema:
                if item[0] == key:
                    typecode = item[1]
                    unit = item[2]
                    if (typecode >= 1 and typecode <= 5) or typecode == 12 or typecode == 13 or \
                          (typecode >= 16 and typecode <= 19):
                        if unit == None or unit == self.lastUnit:
                            return str(value)
                        else:
                            self.lastUnit = unit
                            suffix = ""
                            if value != 1:
                                suffix = "s"
                            return str(value) + " " + unit + suffix
                    elif typecode == 6 or typecode == 7:  # strings
                        return value
                    elif typecode == 8:
                        if value == 0:
                            return "--"
                        return self.disp.timestamp(value)
                    elif typecode == 9:
                        return str(value)
                    elif typecode == 10:
                        return self.refName(value)
                    elif typecode == 11:
                        if value == 0:
                            return "False"
                        else:
                            return "True"
                    elif typecode == 14:
                        return str(value)
                    elif typecode == 15:
                        return str(value)
        return "*type-error*"

    def getObjIndex(self, classKey, config):
        """ Concatenate the values from index columns to form a unique object name """
        result = ""
        schemaConfig = self.schema[classKey][0]
        for item in schemaConfig:
            if item[5] == 1 and item[0] != "id":
                if result != "":
                    result = result + "."
                for key, val in config:
                    if key == item[0]:
                        result = result + self.valueDisplay(classKey, key, val)
        return result

    def getClassKey(self, className):
        delimPos = className.find(":")
        if delimPos == -1:
            schemaRev = 0
            delim = className.find(".")
            if delim != -1:
                schemaRev = int(className[delim + 1:])
                name = className[0:delim]
            else:
                name = className
            for key in self.schema:
                if key[1] == name and self.schema[key][4] == schemaRev:
                    return key
        else:
            package = className[0:delimPos]
            name = className[delimPos + 1:]
            schemaRev = 0
            delim = name.find(".")
            if delim != -1:
                schemaRev = int(name[delim + 1:])
                name = name[0:delim]
            for key in self.schema:
                if key[0] == package and key[1] == name:
                    if self.schema[key][4] == schemaRev:
                        return key
        return None

    def classCompletions(self, prefix):
        """ Provide a list of candidate class names for command completion """
        self.lock.acquire()
        complist = []
        try:
            for name in self.tables:
                if name.find(prefix) == 0:
                    complist.append(name)
        finally:
            self.lock.release()
        return complist

    def typeName(self, typecode):
        """ Convert type-codes to printable strings """
        if typecode == 1:
            return "uint8"
        elif typecode == 2:
            return "uint16"
        elif typecode == 3:
            return "uint32"
        elif typecode == 4:
            return "uint64"
        elif typecode == 5:
            return "bool"
        elif typecode == 6:
            return "short-string"
        elif typecode == 7:
            return "long-string"
        elif typecode == 8:
            return "abs-time"
        elif typecode == 9:
            return "delta-time"
        elif typecode == 10:
            return "reference"
        elif typecode == 11:
            return "boolean"
        elif typecode == 12:
            return "float"
        elif typecode == 13:
            return "double"
        elif typecode == 14:
            return "uuid"
        elif typecode == 15:
            return "field-table"
        elif typecode == 16:
            return "int8"
        elif typecode == 17:
            return "int16"
        elif typecode == 18:
            return "int32"
        elif typecode == 19:
            return "int64"
        elif typecode == 20:
            return "object"
        elif typecode == 21:
            return "list"
        elif typecode == 22:
            return "array"
        else:
            raise ValueError("Invalid type code: %d" % typecode)

    def accessName(self, code):
        """ Convert element access codes to printable strings """
        if code == 1:
            return "ReadCreate"
        elif code == 2:
            return "ReadWrite"
        elif code == 3:
            return "ReadOnly"
        else:
            raise ValueError("Invalid access code: %d" % code)

    def notNone(self, text):
        if text == None:
            return ""
        else:
            return text

    def isOid(self, id):
        for char in str(id):
            if not char.isdigit() and not char == '-':
                return False
        return True

    def listOfIds(self, classKey, tokens):
        """ Generate a tuple of object ids for a classname based on command tokens. """
        list = []
        if len(tokens) == 0 or tokens[0] == "all":
            for id in self.tables[classKey]:
                list.append(self.displayObjId(id))

        elif tokens[0] == "active":
            for id in self.tables[classKey]:
                if self.tables[classKey][id][0][2] == 0:
                    list.append(self.displayObjId(id))

        else:
            for token in tokens:
                if self.isOid(token):
                    if token.find("-") != -1:
                        ids = token.split("-", 2)
                        for id in range(int(ids[0]), int(ids[1]) + 1):
                            if self.getClassForId(self.rawObjId(
                                    long(id))) == classKey:
                                list.append(id)
                    else:
                        list.append(int(token))

        list.sort()
        result = ()
        for item in list:
            result = result + (item, )
        return result

    def listClasses(self):
        """ Generate a display of the list of classes """
        self.lock.acquire()
        try:
            rows = []
            sorted = self.tables.keys()
            sorted.sort()
            for name in sorted:
                active = 0
                deleted = 0
                for record in self.tables[name]:
                    isdel = False
                    ts = self.tables[name][record][0]
                    if ts[2] > 0:
                        isdel = True
                    if isdel:
                        deleted = deleted + 1
                    else:
                        active = active + 1
                rows.append((self.displayClassName(name), active, deleted))
            if len(rows) != 0:
                self.disp.table("Management Object Types:",
                                ("ObjectType", "Active", "Deleted"), rows)
            else:
                print "Waiting for next periodic update"
        finally:
            self.lock.release()

    def listObjects(self, tokens):
        """ Generate a display of a list of objects in a class """
        if len(tokens) == 0:
            print "Error - No class name provided"
            return

        self.lock.acquire()
        try:
            classKey = self.getClassKey(tokens[0])
            if classKey == None:
                print("Object type %s not known" % tokens[0])
            else:
                rows = []
                if classKey in self.tables:
                    ids = self.listOfIds(classKey, tokens[1:])
                    for objId in ids:
                        (ts, config, inst) = self.tables[classKey][
                            self.rawObjId(objId).index()]
                        createTime = self.disp.timestamp(ts[1])
                        destroyTime = "-"
                        if ts[2] > 0:
                            destroyTime = self.disp.timestamp(ts[2])
                        objIndex = self.getObjIndex(classKey, config)
                        row = (objId, createTime, destroyTime, objIndex)
                        rows.append(row)
                    self.disp.table(
                        "Objects of type %s" % self.displayClassName(classKey),
                        ("ID", "Created", "Destroyed", "Index"), rows)
        finally:
            self.lock.release()

    def showObjects(self, tokens):
        """ Generate a display of object data for a particular class """
        self.lock.acquire()
        try:
            self.lastUnit = None
            if self.isOid(tokens[0]):
                if tokens[0].find("-") != -1:
                    rootId = int(tokens[0][0:tokens[0].find("-")])
                else:
                    rootId = int(tokens[0])

                classKey = self.getClassForId(self.rawObjId(rootId))
                remaining = tokens
                if classKey == None:
                    print "Id not known: %d" % int(tokens[0])
                    raise ValueError()
            else:
                classKey = self.getClassKey(tokens[0])
                remaining = tokens[1:]
                if classKey not in self.tables:
                    print "Class not known: %s" % tokens[0]
                    raise ValueError()

            userIds = self.listOfIds(classKey, remaining)
            if len(userIds) == 0:
                print "No object IDs supplied"
                raise ValueError()

            ids = []
            for id in userIds:
                if self.getClassForId(self.rawObjId(long(id))) == classKey:
                    ids.append(self.rawObjId(long(id)))

            rows = []
            timestamp = None
            config = self.tables[classKey][ids[0].index()][1]
            for eIdx in range(len(config)):
                key = config[eIdx][0]
                if key != "id":
                    row = ("property", key)
                    for id in ids:
                        if timestamp == None or \
                           timestamp < self.tables[classKey][id.index()][0][0]:
                            timestamp = self.tables[classKey][id.index()][0][0]
                        (key,
                         value) = self.tables[classKey][id.index()][1][eIdx]
                        row = row + (self.valueDisplay(classKey, key, value), )
                    rows.append(row)

            inst = self.tables[classKey][ids[0].index()][2]
            for eIdx in range(len(inst)):
                key = inst[eIdx][0]
                if key != "id":
                    row = ("statistic", key)
                    for id in ids:
                        (key,
                         value) = self.tables[classKey][id.index()][2][eIdx]
                        row = row + (self.valueDisplay(classKey, key, value), )
                    rows.append(row)

            titleRow = ("Type", "Element")
            for id in ids:
                titleRow = titleRow + (self.refName(id), )
            caption = "Object of type %s:" % self.displayClassName(classKey)
            if timestamp != None:
                caption = caption + " (last sample time: " + self.disp.timestamp(
                    timestamp) + ")"
            self.disp.table(caption, titleRow, rows)

        except:
            pass
        self.lock.release()

    def schemaSummary(self):
        """ Generate a display of the list of classes in the schema """
        self.lock.acquire()
        try:
            rows = []
            sorted = self.schema.keys()
            sorted.sort()
            for classKey in sorted:
                tuple = self.schema[classKey]
                row = (self.displayClassName(classKey), len(tuple[0]),
                       len(tuple[1]), len(tuple[2]))
                rows.append(row)
            self.disp.table("Classes in Schema:",
                            ("Class", "Properties", "Statistics", "Methods"),
                            rows)
        finally:
            self.lock.release()

    def schemaTable(self, className):
        """ Generate a display of details of the schema of a particular class """
        self.lock.acquire()
        try:
            classKey = self.getClassKey(className)
            if classKey == None:
                print("Class name %s not known" % className)
                raise ValueError()

            rows = []
            schemaRev = self.schema[classKey][4]
            for config in self.schema[classKey][0]:
                name = config[0]
                if name != "id":
                    typename = self.typeName(config[1])
                    unit = self.notNone(config[2])
                    desc = self.notNone(config[3])
                    access = self.accessName(config[4])
                    extra = ""
                    if config[5] == 1:
                        extra += "index "
                    if config[6] != None:
                        extra += "Min: " + str(config[6]) + " "
                    if config[7] != None:
                        extra += "Max: " + str(config[7]) + " "
                    if config[8] != None:
                        extra += "MaxLen: " + str(config[8]) + " "
                    if config[9] == 1:
                        extra += "optional "
                    rows.append((name, typename, unit, access, extra, desc))

            for config in self.schema[classKey][1]:
                name = config[0]
                if name != "id":
                    typename = self.typeName(config[1])
                    unit = self.notNone(config[2])
                    desc = self.notNone(config[3])
                    rows.append((name, typename, unit, "", "", desc))

            titles = ("Element", "Type", "Unit", "Access", "Notes",
                      "Description")
            self.disp.table(
                "Schema for class '%s':" % self.displayClassName(classKey),
                titles, rows)

            for mname in self.schema[classKey][2]:
                (mdesc, args) = self.schema[classKey][2][mname]
                caption = "\nMethod '%s' %s" % (mname, self.notNone(mdesc))
                rows = []
                for arg in args:
                    name = arg[0]
                    typename = self.typeName(arg[1])
                    dir = arg[2]
                    unit = self.notNone(arg[3])
                    desc = self.notNone(arg[4])
                    extra = ""
                    if arg[5] != None:
                        extra = extra + "Min: " + str(arg[5])
                    if arg[6] != None:
                        extra = extra + "Max: " + str(arg[6])
                    if arg[7] != None:
                        extra = extra + "MaxLen: " + str(arg[7])
                    if arg[8] != None:
                        extra = extra + "Default: " + str(arg[8])
                    rows.append((name, typename, dir, unit, extra, desc))
                titles = ("Argument", "Type", "Direction", "Unit", "Notes",
                          "Description")
                self.disp.table(caption, titles, rows)

        except Exception, e:
            pass
        self.lock.release()
Example #16
0
      broker_info['queue'] = broker_info['broker_queue']
   except ConfigError, error:
      print '%s' % error.msg
      print 'Attempting to retrieve config from %s' % conf_file
      try:
         broker_info = read_config_file(conf_file, 'Broker')
      except ConfigError, error:
         print '%s' % error.msg
         print 'Exiting'
         return(FAILURE)

   replyTo = str(uuid4())

   # Create a client and log in to it.
   connection = Connection(sock=connect(str(broker_info['ip']), int(broker_info['port'])))
   connection.start()

   session = connection.session(str(uuid4()))

   session.queue_declare(queue=replyTo, exclusive=True, auto_delete=True)
   session.queue_declare(queue=broker_info['queue'], exclusive=False, durable="true")
   session.exchange_bind(exchange='amq.direct', queue=broker_info['queue'], binding_key='grid')
   session.exchange_bind(exchange='amq.direct', queue=replyTo, binding_key=replyTo)

   # Create the local queue. Use the queue name as destination name
   dest = replyTo 
   recv_queue = session.incoming(dest)
   print 'Messages queue: ' + dest 

   # Subscribe the local queue to the queue on the server
   session.message_subscribe(queue=replyTo, destination=dest, accept_mode=session.accept_mode.explicit)
Example #17
0
def dump_queue(binfo, queue_name, to):
   # Create a client and log in to it.
   child_connection = Connection(sock=connect(str(binfo['ip']), int(binfo['port'])))
   child_connection.start()
   child_session = child_connection.session(str(uuid4()))
   child_session.queue_declare(queue=queue_name, exclusive=True)
   child_session.exchange_bind(exchange='amq.direct', queue=queue_name, binding_key=queue_name)

   print 'Messages queue: ' + queue_name 

   # Create the local queue. Use the queue name as destination name
   dest = queue_name 
   queue = child_session.incoming(dest)

   # Subscribe the local queue to the queue on the server
   child_session.message_subscribe(queue=queue_name, destination=dest, accept_mode=child_session.accept_mode.explicit)
   child_session.message_flow(dest, child_session.credit_unit.message, 0xFFFFFFFFL)
   child_session.message_flow(dest, child_session.credit_unit.byte, 0xFFFFFFFFL)

   # Read responses as they come in and print to the screen.
   message = 0
   count = 0

   while True:
      try:
         message = queue.get(timeout=to)
         count = count + 1
         if count == 1:
            print 'Received first reponse: %s ' % str(time.time())
      except Empty:
         print 'Received %s messages: %s' % (str(count), str(time.time() - to))
         break
#      except qpid.session.Closed:
#         print "Re-establishing"
#         try:
#            child_connection.close()
#         except:
#            pass
#
#         # Give broker time to stablize and accept connections
#         time.sleep(2)
#         child_connection = Connection(sock=connect(str(binfo['ip']), int(binfo['port'])))
#         child_connection.start()
#         child_session = child_connection.session(str(uuid4()))
#         child_session.queue_declare(queue=queue_name, exclusive=True)
#         child_session.exchange_bind(exchange='amq.direct', queue=queue_name, binding_key=queue_name)
#
#         # Create the local queue. Use the queue name as destination name
#         queue = child_session.incoming(dest)
#
#         # Subscribe the local queue to the queue on the server
#         child_session.message_subscribe(queue=queue_name, destination=dest, accept_mode=child_session.accept_mode.explicit)
#         child_session.message_flow(dest, child_session.credit_unit.message, 0xFFFFFFFFL)
#         child_session.message_flow(dest, child_session.credit_unit.byte, 0xFFFFFFFFL)
      except:
         print 'Unexpected exception!'
         break

      if message != 0:
        child_session.message_accept(RangedSet(message.id))

   child_session.close(timeout=10)
   child_connection.close()
   return (0)
Example #18
0
import qpid.delegate
import time
from qpid.datatypes import Message, RangedSet, serial
from qpid.ops import *

logging.basicConfig(level=logging.DEBUG)

address = "amq.topic"

sock = connect("127.0.0.1", "5672")
conn = Connection(sock,
                  username="******",
                  password="******",
                  vhost="/ssw",
                  client_properties={"client_process": "aa"})
conn.start(timeout=10000)
session = conn.session("PYTHON_SESSION")

time.sleep(5)

session.queue_declare(queue="test-queue", exclusive=True, auto_delete=True)
session.exchange_declare("test", "direct")

session.exchange_bind(queue="test-queue", exchange="test", binding_key="key")

session.message_subscribe(queue="test-queue",
                          destination="consumer_tag",
                          accept_mode=session.accept_mode.none,
                          acquire_mode=session.acquire_mode.pre_acquired)
session.message_flow(destination="consumer_tag",
                     unit=session.credit_unit.message,
Example #19
0
 def get_session(self, user, passwd):
     socket = connect(self.broker.host, self.broker.port)
     connection = Connection (sock=socket, username=user, password=passwd,
                              mechanism="PLAIN")
     connection.start()
     return connection.session(str(uuid4()))
Example #20
0
# Any functions and classes needed for a given example
# go here.

#----- Initialization -----------------------------------

#  Set parameters for login

host = "127.0.0.1"
port = 5672
user = "******"
password = "******"

# Create a connection and a session. The constructor for a session
# requires a UUID to uniquely identify the session.

socket = connect(host, port)
connection = Connection(sock=socket)
connection.start()
session = connection.session(str(uuid4()))

print connection
#----- Main Body of Program --------------------------------

#   Main body of each example goes here

#----- Cleanup ---------------------------------------------

# Close the session before exiting so there are no open threads.
session.close(timeout=10)
Example #21
0
def dump_queue(queue, ses, con, num_msgs, to, dest, broker):

   # Read responses as they come in and print to the screen.
   message = 0
   count = 0
   expected = 2*int(num_msgs)

   while True:
      try:
         message = queue.get(timeout=to)
         content = message.body
         count = count + 1
         job_data = message.get('message_properties').application_headers
         print 'Reply Message ID: ' + str(message.get('message_properties').message_id)
         print 'Correlation ID: ' + str(message.get('message_properties').correlation_id)
         print 'Headers:'
         for header in job_data.keys():
            print header + ': ' + str(job_data[header])
#         print ''
#         print 'Body: '
#         print content
         print ''
      except Empty:
         if count < expected:
            print 'Only received %d messages but expected %d.  TEST FAILED!' % (count, expected)
         else:
            print 'Received %d messages.  TEST PASSED.' % count
         break
      except qpid.session.Closed:
         try:
            con.close()
         except:
            pass

         # Give broker time to stablize and accept connections
         time.sleep(2)
         con = Connection(sock=connect(str(broker['ip']), int(broker['port'])))
         con.start()

         ses = con.session(str(uuid4()))

         ses.queue_declare(queue=dest, exclusive=True)
         ses.queue_declare(queue=broker['queue'], exclusive=False, durable=True)
         ses.exchange_bind(exchange='amq.direct', queue=broker['queue'], binding_key='grid')
         ses.exchange_bind(exchange='amq.direct', queue=dest, binding_key=dest)

         # Create the local queue. Use the queue name as destination name
         queue = ses.incoming(dest)

         # Subscribe the local queue to the queue on the server
         ses.message_subscribe(queue=dest, destination=dest, accept_mode=ses.accept_mode.explicit)
         ses.message_flow(dest, ses.credit_unit.message, 0xFFFFFFFFL)
         ses.message_flow(dest, ses.credit_unit.byte, 0xFFFFFFFFL)
      except:
         print 'Unexpected exception!'
         break

      if message != 0:
        ses.message_accept(RangedSet(message.id))

   return (0)
Example #22
0
class ManagementData:

  #
  # Data Structure:
  #
  # Please note that this data structure holds only the most recent
  # configuration and instrumentation data for each object.  It does
  # not hold the detailed historical data that is sent from the broker.
  # The only historical data it keeps are the high and low watermarks
  # for hi-lo statistics.
  #
  #    tables        :== {class-key}
  #                        {<obj-id>}
  #                          (timestamp, config-record, inst-record)
  #    class-key     :== (<package-name>, <class-name>, <class-hash>)
  #    timestamp     :== (<last-interval-time>, <create-time>, <delete-time>)
  #    config-record :== [element]
  #    inst-record   :== [element]
  #    element       :== (<element-name>, <element-value>)
  #

  def registerObjId (self, objId):
    if not objId.index() in self.idBackMap:
      self.idBackMap[objId.index()] = self.nextId
      self.idMap[self.nextId] = objId
      self.nextId += 1

  def displayObjId (self, objIdIndex):
    if objIdIndex in self.idBackMap:
      return self.idBackMap[objIdIndex]
    else:
      return 0

  def rawObjId (self, displayId):
    if displayId in self.idMap:
      return self.idMap[displayId]
    else:
      return None

  def displayClassName (self, cls):
    (packageName, className, hash) = cls
    rev = self.schema[cls][4]
    if rev == 0:
      suffix = ""
    else:
      suffix = ".%d" % rev
    return packageName + ":" + className + suffix

  def dataHandler (self, context, className, list, timestamps):
    """ Callback for configuration and instrumentation data updates """
    self.lock.acquire ()
    try:
      # If this class has not been seen before, create an empty dictionary to
      # hold objects of this class
      if className not in self.tables:
        self.tables[className] = {}

      # Register the ID so a more friendly presentation can be displayed
      objId = list[0][1]
      oidx  = objId.index()
      self.registerObjId (objId)

      # If this object hasn't been seen before, create a new object record with
      # the timestamps and empty lists for configuration and instrumentation data.
      if oidx not in self.tables[className]:
        self.tables[className][oidx] = (timestamps, [], [])

      (unused, oldConf, oldInst) = self.tables[className][oidx]

      # For config updates, simply replace old config list with the new one.
      if   context == 0: #config
        self.tables[className][oidx] = (timestamps, list, oldInst)

      # For instrumentation updates, carry the minimum and maximum values for
      # "hi-lo" stats forward.
      elif context == 1: #inst
        if len (oldInst) == 0:
          newInst = list
        else:
          newInst = []
          for idx in range (len (list)):
            (key, value) = list[idx]
            if key.find ("High") == len (key) - 4:
              if oldInst[idx][1] > value:
                value = oldInst[idx][1]
            if key.find ("Low") == len (key) - 3:
              if oldInst[idx][1] < value:
                value = oldInst[idx][1]
            newInst.append ((key, value))
        self.tables[className][oidx] = (timestamps, oldConf, newInst)

    finally:
      self.lock.release ()

  def ctrlHandler (self, context, op, data):
    if op == self.mclient.CTRL_BROKER_INFO:
      pass
    elif op == self.mclient.CTRL_HEARTBEAT:
      pass

  def configHandler (self, context, className, list, timestamps):
    self.dataHandler (0, className, list, timestamps);

  def instHandler (self, context, className, list, timestamps):
    self.dataHandler (1, className, list, timestamps);

  def methodReply (self, broker, sequence, status, sText, args):
    """ Callback for method-reply messages """
    self.lock.acquire ()
    try:
      line = "Call Result: " + self.methodsPending[sequence] + \
             "  " + str (status) + " (" + sText + ")"
      print line, args
      del self.methodsPending[sequence]
    finally:
      self.lock.release ()

  def closeHandler (self, context, reason):
    if self.operational:
      print "Connection to broker lost:", reason
    self.operational = False
    if self.cli != None:
      self.cli.setPromptMessage ("Broker Disconnected")

  def schemaHandler (self, context, classKey, configs, insts, methods, events):
    """ Callback for schema updates """
    if classKey not in self.schema:
      schemaRev = 0
      for key in self.schema:
        if classKey[0] == key[0] and classKey[1] == key[1]:
          schemaRev += 1
      self.schema[classKey] = (configs, insts, methods, events, schemaRev)

  def setCli (self, cliobj):
    self.cli = cliobj

  def __init__ (self, disp, host, username="******", password="******"):
    self.lock           = Lock ()
    self.tables         = {}
    self.schema         = {}
    self.bootSequence   = 0
    self.operational    = False
    self.disp           = disp
    self.cli            = None
    self.lastUnit       = None
    self.methodSeq      = 1
    self.methodsPending = {}
    self.sessionId      = "%s.%d" % (platform.uname()[1], os.getpid())

    self.broker = Broker (host)
    sock = connect (self.broker.host, self.broker.port)
    oldTimeout = sock.gettimeout()
    sock.settimeout(10)
    self.conn   = Connection (sock,
                              username=self.broker.username, password=self.broker.password)
    def aborted():
      raise Timeout("Waiting for connection to be established with broker")
    oldAborted = self.conn.aborted
    self.conn.aborted = aborted

    self.conn.start ()

    sock.settimeout(oldTimeout)
    self.conn.aborted = oldAborted

    self.mclient = managementClient ("unused", self.ctrlHandler, self.configHandler,
                                     self.instHandler, self.methodReply, self.closeHandler)
    self.mclient.schemaListener (self.schemaHandler)
    self.mch = self.mclient.addChannel (self.conn.session(self.sessionId))
    self.operational = True
    self.idMap = {}
    self.idBackMap = {}
    self.nextId = 101

  def close (self):
    pass

  def refName (self, oid):
    if oid == None:
      return "NULL"
    return str (self.displayObjId (oid.index()))

  def valueDisplay (self, classKey, key, value):
    if value == None:
      return "<NULL>"
    for kind in range (2):
      schema = self.schema[classKey][kind]
      for item in schema:
        if item[0] == key:
          typecode = item[1]
          unit     = item[2]
          if (typecode >= 1 and typecode <= 5) or typecode == 12 or typecode == 13 or \
                (typecode >= 16 and typecode <= 19):
            if unit == None or unit == self.lastUnit:
              return str (value)
            else:
              self.lastUnit = unit
              suffix = ""
              if value != 1:
                suffix = "s"
              return str (value) + " " + unit + suffix
          elif typecode == 6 or typecode == 7: # strings
            return value
          elif typecode == 8:
            if value == 0:
              return "--"
            return self.disp.timestamp (value)
          elif typecode == 9:
            return str (value)
          elif typecode == 10:
            return self.refName (value)
          elif typecode == 11:
            if value == 0:
              return "False"
            else:
              return "True"
          elif typecode == 14:
            return str (value)
          elif typecode == 15:
            return str (value)
    return "*type-error*"

  def getObjIndex (self, classKey, config):
    """ Concatenate the values from index columns to form a unique object name """
    result = ""
    schemaConfig = self.schema[classKey][0]
    for item in schemaConfig:
      if item[5] == 1 and item[0] != "id":
        if result != "":
          result = result + "."
        for key,val in config:
          if key == item[0]:
            result = result + self.valueDisplay (classKey, key, val)
    return result

  def getClassKey (self, className):
    delimPos = className.find(":")
    if delimPos == -1:
      schemaRev = 0
      delim = className.find(".")
      if delim != -1:
        schemaRev = int(className[delim + 1:])
        name      = className[0:delim]
      else:
        name = className
      for key in self.schema:
        if key[1] == name and self.schema[key][4] == schemaRev:
          return key
    else:
      package   = className[0:delimPos]
      name      = className[delimPos + 1:]
      schemaRev = 0
      delim = name.find(".")
      if delim != -1:
        schemaRev = int(name[delim + 1:])
        name      = name[0:delim]
      for key in self.schema:
        if key[0] == package and key[1] == name:
          if self.schema[key][4] == schemaRev:
            return key
    return None

  def classCompletions (self, prefix):
    """ Provide a list of candidate class names for command completion """
    self.lock.acquire ()
    complist = []
    try:
      for name in self.tables:
        if name.find (prefix) == 0:
          complist.append (name)
    finally:
      self.lock.release ()
    return complist

  def typeName (self, typecode):
    """ Convert type-codes to printable strings """
    if   typecode == 1:
      return "uint8"
    elif typecode == 2:
      return "uint16"
    elif typecode == 3:
      return "uint32"
    elif typecode == 4:
      return "uint64"
    elif typecode == 5:
      return "bool"
    elif typecode == 6:
      return "short-string"
    elif typecode == 7:
      return "long-string"
    elif typecode == 8:
      return "abs-time"
    elif typecode == 9:
      return "delta-time"
    elif typecode == 10:
      return "reference"
    elif typecode == 11:
      return "boolean"
    elif typecode == 12:
      return "float"
    elif typecode == 13:
      return "double"
    elif typecode == 14:
      return "uuid"
    elif typecode == 15:
      return "field-table"
    elif typecode == 16:
      return "int8"
    elif typecode == 17:
      return "int16"
    elif typecode == 18:
      return "int32"
    elif typecode == 19:
      return "int64"
    elif typecode == 20:
      return "object"
    elif typecode == 21:
      return "list"
    elif typecode == 22:
      return "array"      
    else:
      raise ValueError ("Invalid type code: %d" % typecode)

  def accessName (self, code):
    """ Convert element access codes to printable strings """
    if code == 1:
      return "ReadCreate"
    elif code == 2:
      return "ReadWrite"
    elif code == 3:
      return "ReadOnly"
    else:
      raise ValueError ("Invalid access code: %d" %code)

  def notNone (self, text):
    if text == None:
      return ""
    else:
      return text

  def isOid (self, id):
    for char in str (id):
      if not char.isdigit () and not char == '-':
        return False
    return True

  def listOfIds (self, classKey, tokens):
    """ Generate a tuple of object ids for a classname based on command tokens. """
    list = []
    if len(tokens) == 0 or tokens[0] == "all":
      for id in self.tables[classKey]:
        list.append (self.displayObjId (id))

    elif tokens[0] == "active":
      for id in self.tables[classKey]:
        if self.tables[classKey][id][0][2] == 0:
          list.append (self.displayObjId (id))

    else:
      for token in tokens:
        if self.isOid (token):
          if token.find ("-") != -1:
            ids = token.split("-", 2)
            for id in range (int (ids[0]), int (ids[1]) + 1):
              if self.getClassForId (self.rawObjId (long (id))) == classKey:
                list.append (id)
          else:
            list.append (int(token))

    list.sort ()
    result = ()
    for item in list:
      result = result + (item,)
    return result

  def listClasses (self):
    """ Generate a display of the list of classes """
    self.lock.acquire ()
    try:
      rows = []
      sorted = self.tables.keys ()
      sorted.sort ()
      for name in sorted:
        active  = 0
        deleted = 0
        for record in self.tables[name]:
          isdel = False
          ts    = self.tables[name][record][0]
          if ts[2] > 0:
            isdel = True
          if isdel:
            deleted = deleted + 1
          else:
            active = active + 1
        rows.append ((self.displayClassName (name), active, deleted))
      if len (rows) != 0:
        self.disp.table ("Management Object Types:",
                         ("ObjectType", "Active", "Deleted"), rows)
      else:
        print "Waiting for next periodic update"
    finally:
      self.lock.release ()

  def listObjects (self, tokens):
    """ Generate a display of a list of objects in a class """
    if len(tokens) == 0:
      print "Error - No class name provided"
      return

    self.lock.acquire ()
    try:
      classKey = self.getClassKey (tokens[0])
      if classKey == None:
        print ("Object type %s not known" % tokens[0])
      else:
        rows = []
        if classKey in self.tables:
          ids = self.listOfIds(classKey, tokens[1:])
          for objId in ids:
            (ts, config, inst) = self.tables[classKey][self.rawObjId(objId).index()]
            createTime  = self.disp.timestamp (ts[1])
            destroyTime = "-"
            if ts[2] > 0:
              destroyTime = self.disp.timestamp (ts[2])
            objIndex = self.getObjIndex (classKey, config)
            row = (objId, createTime, destroyTime, objIndex)
            rows.append (row)
          self.disp.table ("Objects of type %s" % self.displayClassName(classKey),
                           ("ID", "Created", "Destroyed", "Index"),
                           rows)
    finally:
      self.lock.release ()

  def showObjects (self, tokens):
    """ Generate a display of object data for a particular class """
    self.lock.acquire ()
    try:
      self.lastUnit = None
      if self.isOid (tokens[0]):
        if tokens[0].find ("-") != -1:
          rootId = int (tokens[0][0:tokens[0].find ("-")])
        else:
          rootId = int (tokens[0])

        classKey  = self.getClassForId (self.rawObjId (rootId))
        remaining = tokens
        if classKey == None:
          print "Id not known: %d" % int (tokens[0])
          raise ValueError ()
      else:
        classKey  = self.getClassKey (tokens[0])
        remaining = tokens[1:]
        if classKey not in self.tables:
          print "Class not known: %s" % tokens[0]
          raise ValueError ()

      userIds = self.listOfIds (classKey, remaining)
      if len (userIds) == 0:
        print "No object IDs supplied"
        raise ValueError ()

      ids = []
      for id in userIds:
        if self.getClassForId (self.rawObjId (long (id))) == classKey:
          ids.append (self.rawObjId (long (id)))

      rows = []
      timestamp = None
      config = self.tables[classKey][ids[0].index()][1]
      for eIdx in range (len (config)):
        key = config[eIdx][0]
        if key != "id":
          row   = ("property", key)
          for id in ids:
            if timestamp == None or \
               timestamp < self.tables[classKey][id.index()][0][0]:
              timestamp = self.tables[classKey][id.index()][0][0]
            (key, value) = self.tables[classKey][id.index()][1][eIdx]
            row = row + (self.valueDisplay (classKey, key, value),)
          rows.append (row)

      inst = self.tables[classKey][ids[0].index()][2]
      for eIdx in range (len (inst)):
        key = inst[eIdx][0]
        if key != "id":
          row = ("statistic", key)
          for id in ids:
            (key, value) = self.tables[classKey][id.index()][2][eIdx]
            row = row + (self.valueDisplay (classKey, key, value),)
          rows.append (row)

      titleRow = ("Type", "Element")
      for id in ids:
        titleRow = titleRow + (self.refName(id),)
      caption = "Object of type %s:" % self.displayClassName(classKey)
      if timestamp != None:
        caption = caption + " (last sample time: " + self.disp.timestamp (timestamp) + ")"
      self.disp.table (caption, titleRow, rows)

    except:
      pass
    self.lock.release ()

  def schemaSummary (self):
    """ Generate a display of the list of classes in the schema """
    self.lock.acquire ()
    try:
      rows = []
      sorted = self.schema.keys ()
      sorted.sort ()
      for classKey in sorted:
        tuple = self.schema[classKey]
        row = (self.displayClassName(classKey), len (tuple[0]), len (tuple[1]),
               len (tuple[2]))
        rows.append (row)
      self.disp.table ("Classes in Schema:",
                       ("Class", "Properties", "Statistics", "Methods"),
                       rows)
    finally:
      self.lock.release ()

  def schemaTable (self, className):
    """ Generate a display of details of the schema of a particular class """
    self.lock.acquire ()
    try:
      classKey = self.getClassKey (className)
      if classKey == None:
        print ("Class name %s not known" % className)
        raise ValueError ()

      rows = []
      schemaRev =  self.schema[classKey][4]
      for config in self.schema[classKey][0]:
        name     = config[0]
        if name != "id":
          typename = self.typeName(config[1])
          unit     = self.notNone (config[2])
          desc     = self.notNone (config[3])
          access   = self.accessName (config[4])
          extra    = ""
          if config[5] == 1:
            extra += "index "
          if config[6] != None:
            extra += "Min: " + str(config[6]) + " "
          if config[7] != None:
            extra += "Max: " + str(config[7]) + " "
          if config[8] != None:
            extra += "MaxLen: " + str(config[8]) + " "
          if config[9] == 1:
            extra += "optional "
          rows.append ((name, typename, unit, access, extra, desc))
        
      for config in self.schema[classKey][1]:
        name     = config[0]
        if name != "id":
          typename = self.typeName(config[1])
          unit     = self.notNone (config[2])
          desc     = self.notNone (config[3])
          rows.append ((name, typename, unit, "", "", desc))

      titles = ("Element", "Type", "Unit", "Access", "Notes", "Description")
      self.disp.table ("Schema for class '%s':" % self.displayClassName(classKey), titles, rows)

      for mname in self.schema[classKey][2]:
        (mdesc, args) = self.schema[classKey][2][mname]
        caption = "\nMethod '%s' %s" % (mname, self.notNone (mdesc))
        rows = []
        for arg in args:
          name     = arg[0]
          typename = self.typeName (arg[1])
          dir      = arg[2]
          unit     = self.notNone (arg[3])
          desc     = self.notNone (arg[4])
          extra    = ""
          if arg[5] != None:
            extra = extra + "Min: " + str (arg[5])
          if arg[6] != None:
            extra = extra + "Max: " + str (arg[6])
          if arg[7] != None:
            extra = extra + "MaxLen: " + str (arg[7])
          if arg[8] != None:
            extra = extra + "Default: " + str (arg[8])
          rows.append ((name, typename, dir, unit, extra, desc))
        titles = ("Argument", "Type", "Direction", "Unit", "Notes", "Description")
        self.disp.table (caption, titles, rows)

    except Exception,e:
      pass
    self.lock.release ()