[rhmessaging-commits] rhmessaging commits: r1742 - in mgmt/basil: python/basil and 1 other directory.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Sat Mar 1 00:09:23 EST 2008


Author: justi9
Date: 2008-03-01 00:09:23 -0500 (Sat, 01 Mar 2008)
New Revision: 1742

Removed:
   mgmt/basil/python/basil/__init__.strings
Modified:
   mgmt/basil/bin/basil
   mgmt/basil/python/basil/__init__.py
Log:
A big change to the way basil works.

Since python makes it possible, don't generate static python code but
rather dynamically create python classes, methods, etc.

Implement the schema, config, and instrumentation methods.

Turn the basil command line tool into a simple interpreter with the
basil environment set up, so you can navigate objects.



Modified: mgmt/basil/bin/basil
===================================================================
--- mgmt/basil/bin/basil	2008-02-29 15:51:44 UTC (rev 1741)
+++ mgmt/basil/bin/basil	2008-03-01 05:09:23 UTC (rev 1742)
@@ -1,21 +1,43 @@
 #!/usr/bin/env python
 
-import sys
+import sys, os
+from code import InteractiveConsole
 
 from basil import *
 
 def usage():
-    print "Usage: basil SCHEMA-XML"
+    print "Usage: basil [BROKER-ADDRESS]"
+    print "Example: basil localhost:5672"
     sys.exit(1)
 
+def do_main(spec, host, port):
+    model = BasilModel(spec)
+
+    conn = BasilConnection(model, host, port)
+    conn.open()
+
+    console = InteractiveConsole(locals())
+
+    try:
+        console.interact()
+    finally:
+        conn.close()
+
 def main():
-    if len(sys.argv) != 2:
-        usage()
+    try:
+        addr = sys.argv[1]
+    except IndexError:
+        addr = "localhost:5672"
 
-    xml = sys.argv[1]
-    maker = ClassMaker(xml)
+    host, port = addr.split(":")
 
-    print maker.make()
+    spec = os.environ.get("AMQP_SPEC", "/usr/share/amqp/amqp.0-10-preview.xml")
 
+    try:
+        do_main(spec, host, int(port))
+    except KeyboardInterrupt:
+        pass
+
 if __name__ == "__main__":
     main()
+    

Modified: mgmt/basil/python/basil/__init__.py
===================================================================
--- mgmt/basil/python/basil/__init__.py	2008-02-29 15:51:44 UTC (rev 1741)
+++ mgmt/basil/python/basil/__init__.py	2008-03-01 05:09:23 UTC (rev 1742)
@@ -1,74 +1,194 @@
-import mllib
+import mllib, qpid
 from string import Template
+from qpid.management import managementChannel, managementClient
+from threading import Lock
 
 from util import *
 
-strings = StringCatalog(__file__)
+class BasilModel(object):
+    def __init__(self, spec_path):
+        self.spec = qpid.spec.load(spec_path)
 
-class ClassMaker(object):
-    def __init__(self, schema_xml):
-        self.schema_xml = schema_xml
-        self.main_tmpl = Template(strings.get("main"))
-        self.class_tmpl = Template(strings.get("class"))
-        self.constructor_tmpl = Template(strings.get("constructor"))
-        self.attribute_tmpl = Template(strings.get("attribute"))
-        self.method_tmpl = Template(strings.get("method"))
+        self.packages = list()
 
-    def make(self):
-        schema = mllib.xml_parse(self.schema_xml)
+        # For later use by BasilObject.method
+        #self.method_sequence = 1
+        #self.outstanding_calls = dict()
 
-        args = dict()
+        self.lock = Lock()
+
+    def call_method(self, obj, name, args, callback):
+        pass
+        # For later use by BasilObject.method
+        #method_sequence += 1
+        #self.outstanding_calls[self.method_sequence] = callback
+
+        #self.broker.method(id, obj.mgmt_id, obj.mgmt_name, name, args=args,
+        #                   packageName=obj.mgmt_package)
+
+    def on_schema(self, broker_id, object_info,
+                  configs, metrics, methods, events):
+        self.lock.acquire()
+        try:
+            package = self.get_package(object_info)
+            package.on_schema(broker_id, object_info,
+                              configs, metrics, methods, events)
+        finally:
+            self.lock.release()
+
+    def on_config(self, broker_id, object_info, values, timestamps):
+        self.lock.acquire()
+        try:
+            package = self.get_package(object_info)
+            package.on_config(broker_id, object_info, values, timestamps)
+        finally:
+            self.lock.release()
+
+    def on_metric(self, broker_id, object_info, values, timestamps):
+        self.lock.acquire()
+        try:
+            package = self.get_package(object_info)
+            package.on_metric(broker_id, object_info, values, timestamps)
+        finally:
+            self.lock.release()
+
+    def get_package(self, object_info):
+        name = object_info[0].replace(".", "_")
+
+        try:
+            package = getattr(self, name)
+        except AttributeError:
+            package = BasilPackage(self, name)
+            self.packages.append(package)
+            setattr(self, name, package)
+
+        return package
+
+class BasilPackage(object):
+    def __init__(self, model, name):
+        self.model = model
+        self.name = name
+
+        self.classes = list()
+
+    def on_schema(self, broker_id, object_info,
+                  configs, metrics, methods, events):
+        cls = self.get_class(object_info)
+        cls.on_schema(broker_id, object_info,
+                      configs, metrics, methods, events)
+
+    def on_config(self, broker_id, object_info, values, timestamps):
+        cls = self.get_class(object_info)
+        cls.on_config(broker_id, object_info, values, timestamps)
+
+    def on_metric(self, broker_id, object_info, values, timestamps):
+        pass
+
+    def get_class(self, object_info):
+        name = object_info[1]
         
-        l = list()
-        for cls in schema.query["schema/class"]:
-          l.append(self.make_class(cls))
-        args["classes"] = "\n\n".join(l)
+        try:
+            cls = getattr(self, name)
+        except AttributeError:
+            cls = BasilClass(self, name)
+            self.classes.append(cls)
+            setattr(self, name, cls)
 
-        return self.main_tmpl.substitute(args)
+        return cls
 
-    def make_class(self, node):
-        args = dict()
-        args["name"] = node["@name"].capitalize()
-        args["constructor"] = self.make_constructor(node)
+    def __repr__(self):
+        return self.name
 
-        l = list()
-        for meth in node.query["method"]:
-            l.append(self.make_method(meth))
-        args["methods"] = "\n\n".join(l)
+class BasilClass(object):
+    def __init__(self, package, name):
+        self.package = package
+        self.name = name
 
-        return self.class_tmpl.substitute(args)
+        self.objects = list()
+        self.objects_by_id = dict()
 
-    def make_constructor(self, node):
-        args = dict()
-        args["mgmt_name"] = node["@name"]
+        attrs = dict()
+        attrs["basil_model"] = self.package.model
+        attrs["basil_package"] = self.package
+        attrs["basil_class"] = self
+        self.python_class = type(name, (BasilObject,), attrs)
 
-        l = list()
-        for attr in node.query["configElement"]:
-            l.append(self.make_attribute(attr))
-        for attr in node.query["instElement"]:
-            l.append(self.make_attribute(attr))
-        args["attributes"] = "\n".join(l)
+    def on_schema(self, broker_id, object_info,
+                  configs, metrics, methods, events):
+        for spec in configs:
+            setattr(self.python_class, spec[0], None)
 
-        return self.constructor_tmpl.substitute(args)
+        for spec in metrics:
+            setattr(self.python_class, spec[0], None)
 
-    def make_attribute(self, node):
-        args = dict()
-        args["name"] = node["@name"]
+        for name in methods:
+            setattr(self.python_class, name, self.python_class.method)
 
-        return self.attribute_tmpl.substitute(args)
+        for spec in events:
+            pass
 
-    def make_method(self, node):
-        args = dict()
-        args["name"] = node["@name"]
+    def on_config(self, broker_id, object_info, values, timestamps):
+        object = self.get_object(object_info)
 
-        pl, al = list(), list()
-        pl.append("self")
-        for arg in node.query["arg"]:
-            name = arg["@name"]
-            pl.append(name)
-            al.append("\"%s\": %s" % (name, name))
-        pl.append("callback")
-        args["parameters"] = ", ".join(pl)
-        args["args"] = ", ".join(al)
+        for name, value in values:
+            if name != "id":
+                setattr(object, name, value)
 
-        return self.method_tmpl.substitute(args)
+    def on_metric(self, broker_id, object_info, values, timestamps):
+        object = self.get_object(object_info)
+
+        for name, value in values:
+            setattr(object, name, value)
+
+    def get_object(self, object_info):
+        id = object_info[2]
+
+        try:
+            object = self.objects_by_id[id]
+        except KeyError:
+            object = self.python_class(id)
+            self.objects.append(object)
+            self.objects_by_id[id] = object
+
+        return object
+
+    def __repr__(self):
+        return self.name
+
+class BasilObject(object):
+    def __init__(self, id):
+        self.id = id
+
+    def method(self, *args, **kwargs):
+        print "method", self, self.basil_model, self.basil_package, self.basil_class, args, kwargs
+        
+    def __repr__(self):
+        return str(self.id)
+
+class BasilConnection(object):
+    def __init__(self, model, host, port):
+        self.model = model
+        self.host = host
+        self.port = port
+
+        self.client = managementClient(self.model.spec,
+                                       None, 
+                                       self.model.on_config,
+                                       self.model.on_metric,
+                                       "%s:%i" % (self.host, self.port))
+        self.client.schemaListener(self.model.on_schema)
+
+        self.chan = None
+
+    def open(self):
+        client = qpid.client.Client(self.host, self.port, self.model.spec)
+        client.start({})
+        chan = client.channel(1)
+
+        self.chan = managementChannel \
+            (chan, self.client.topicCb, self.client.replyCb)
+
+        self.client.addChannel(self.chan)
+
+    def close(self):
+        self.client.removeChannel(self.chan)

Deleted: mgmt/basil/python/basil/__init__.strings
===================================================================
--- mgmt/basil/python/basil/__init__.strings	2008-02-29 15:51:44 UTC (rev 1741)
+++ mgmt/basil/python/basil/__init__.strings	2008-03-01 05:09:23 UTC (rev 1742)
@@ -1,68 +0,0 @@
-[main]
-import sys, os
-
-class Model(object):
-    def __init__(self, broker):
-        self.broker = broker
-        self.broker_id = "%s:%i" % (broker.host, broker.port)
-        self.broker.configListener(self.broker_id, self.__config_callback)
-
-        self.method_sequence = 1
-        self.outstanding_calls = dict()
-
-        self.classes = list()
-        self.classes_by_mgmt_name = dict()
-
-    def call_method(self, obj, name, args, callback):
-        method_sequence += 1
-        self.outstanding_calls[self.method_sequence] = callback
-
-        self.broker.method(id, obj.mgmt_id, obj.mgmt_name, name, args=args,
-                           packageName=obj.mgmt_package)
-
-    def __config_callback(self, broker_id, object_name, values, timestamps):
-        if broker_id != self.broker_id:
-            raise Exception("Unexpected broker")
-
-        print broker_id, object_name, values, timestamps
-
-${classes}
-
-if __name__ == "__main__":
-    from qpid.management import ManagedBroker
-    from time import sleep
-
-    host = "localhost"
-    port = 5672
-    spec = os.environ.get("AMQP_SPEC", "/usr/share/amqp/amqp.0-10-preview.xml")
-
-    broker = ManagedBroker(host, port, spec)
-    model = Model(broker)
-
-    broker.start()
-
-    while True:
-        sleep(5)
-
-[class]
-class ${name}(object):
-${constructor}
-
-${methods}
-
-[constructor]
-    def __init__(self, model, id):
-        self.mgmt_model = model
-        self.mgmt_id = id
-        self.mgmt_name = "${mgmt_name}"
-        self.mgmt_package = "qpid"
-
-${attributes}
-
-[attribute]
-        self.${name} = None
-
-[method]
-    def ${name}(${parameters}):
-        args = {${args}}
-        self.mgmt_model.call_method(self, ${name}, args, callback)




More information about the rhmessaging-commits mailing list