You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2010/01/13 12:57:20 UTC

svn commit: r898727 - in /qpid/trunk/qpid/cpp: bindings/qmf/ bindings/qmf/python/ bindings/qmf/ruby/ bindings/qmf/tests/ include/qmf/engine/ src/ src/qmf/engine/

Author: tross
Date: Wed Jan 13 11:57:19 2010
New Revision: 898727

URL: http://svn.apache.org/viewvc?rev=898727&view=rev
Log:
Added raise_event support to the Ruby and Python wrapped agent APIs.

Added:
    qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.cpp
    qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.h
Modified:
    qpid/trunk/qpid/cpp/bindings/qmf/python/qmf.py
    qpid/trunk/qpid/cpp/bindings/qmf/qmfengine.i
    qpid/trunk/qpid/cpp/bindings/qmf/ruby/qmf.rb
    qpid/trunk/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
    qpid/trunk/qpid/cpp/bindings/qmf/tests/python_agent.py
    qpid/trunk/qpid/cpp/bindings/qmf/tests/python_console.py
    qpid/trunk/qpid/cpp/include/qmf/engine/Event.h
    qpid/trunk/qpid/cpp/include/qmf/engine/Schema.h
    qpid/trunk/qpid/cpp/include/qmf/engine/Value.h
    qpid/trunk/qpid/cpp/src/qmf.mk
    qpid/trunk/qpid/cpp/src/qmf/engine/Agent.cpp
    qpid/trunk/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
    qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.cpp
    qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.h

Modified: qpid/trunk/qpid/cpp/bindings/qmf/python/qmf.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/python/qmf.py?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/python/qmf.py (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/python/qmf.py Wed Jan 13 11:57:19 2010
@@ -34,6 +34,8 @@
                        TYPE_UINT8, TYPE_UUID)
 from qmfengine import (O_EQ, O_NE, O_LT, O_LE, O_GT, O_GE, O_RE_MATCH, O_RE_NOMATCH,
                        E_NOT, E_AND, E_OR, E_XOR)
+from qmfengine import (SEV_EMERG, SEV_ALERT, SEV_CRIT, SEV_ERROR, SEV_WARN, SEV_NOTICE,
+                       SEV_INFORM, SEV_DEBUG)
 
 
 def qmf_to_native(val):
@@ -351,9 +353,103 @@
 
 
   ##==============================================================================
-  ## OBJECTS
+  ## OBJECTS and EVENTS
   ##==============================================================================
 
+class QmfEvent(object):
+    # attr_reader :impl, :event_class
+    def __init__(self, cls, kwargs={}):
+        self._allow_sets = True
+        if kwargs.has_key("broker"):
+            self._broker = kwargs["broker"]
+        else:
+            self._broker = None
+        if cls:
+            self.event_class = cls
+            self.impl = qmfengine.Event(self.event_class.impl)
+        elif kwargs.has_key("impl"):
+            self.impl = qmfengine.Event(kwargs["impl"])
+            self.event_class = SchemaEventClass(None, None, 0,
+                                                {"impl":self.impl.getClass()})
+        else:
+            raise Exception("Argument error: required parameter ('impl') not supplied")
+    
+    
+    def arguments(self):
+        list = []
+        for arg in self.event_class.arguments:
+            list.append([arg, self.get_attr(arg.name())])
+        return list
+
+
+    def get_attr(self, name):
+        val = self._value(name)
+        return qmf_to_native(val)
+    
+    
+    def set_attr(self, name, v):
+        val = self._value(name)
+        native_to_qmf(val, v)
+    
+    
+    def __getitem__(self, name):
+        return self.get_attr(name)
+    
+    
+    def __setitem__(self, name, value):
+        self.set_attr(name, value)
+    
+    
+    def __setattr__(self, name, value):
+        #
+        # Ignore the internal attributes, set them normally...
+        #
+        if (name[0] == '_' or
+            name == 'impl' or
+            name == 'event_class'):
+            return super.__setattr__(self, name, value)
+
+        if not self._allow_sets:
+            raise Exception("'Set' operations not permitted on this object")
+
+        #
+        # If the name matches an argument name, set the value of the argument.
+        #
+        # print "set name=%s" % str(name)
+        for arg in self.event_class.arguments:
+            if arg.name() == name:
+                return self.set_attr(name, value)
+
+        # unrecognized name?  should I raise an exception?
+        super.__setattr__(self, name, value)
+
+
+    def __getattr__(self, name, *args):
+        #
+        # If the name matches an argument name, return the value of the argument.
+        #
+        for arg in self.event_class.arguments:
+            if arg.name() == name:
+                return self.get_attr(name)
+
+        #
+        # This name means nothing to us, pass it up the line to the parent
+        # class's handler.
+        #
+        # print "__getattr__=%s" % str(name)
+        super.__getattr__(self, name)
+
+
+    def _value(self, name):
+        val = self.impl.getValue(name)
+        if not val:
+            raise Exception("Argument error: attribute named '%s' not defined for package %s, class %s" % 
+                            (name,
+                             self.event_class.impl.getClassKey().getPackageName(),
+                             self.event_class.impl.getClassKey().getClassName()))
+        return val
+
+
 class QmfObject(object):
     # attr_reader :impl, :object_class
     def __init__(self, cls, kwargs={}):
@@ -922,14 +1018,14 @@
 
 class SchemaEventClass:
     # attr_reader :impl :arguments
-    def __init__(self, package, name, kwargs={}):
+    def __init__(self, package, name, sev, kwargs={}):
       self.arguments = []
       if "impl" in kwargs:
           self.impl = kwargs["impl"]
           for i in range(self.impl.getArgumentCount()):
               self.arguments.append(SchemaArgument(nil, nil, {"impl":self.impl.getArgument(i)}))
       else:
-          self.impl = qmfengine.SchemaEventClass(package, name)
+          self.impl = qmfengine.SchemaEventClass(package, name, sev)
           if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
     
     
@@ -1026,7 +1122,7 @@
                 if kind == CLASS_OBJECT:
                     clist.append(SchemaObjectClass(None, None, {"impl":self.impl.getObjectClass(key)}))
                 elif kind == CLASS_EVENT:
-                    clist.append(SchemaEventClass(None, None, {"impl":self.impl.getEventClass(key)}))
+                    clist.append(SchemaEventClass(None, None, 0, {"impl":self.impl.getEventClass(key)}))
         return clist
     
     
@@ -1436,7 +1532,10 @@
     def alloc_object_id(self, low = 0, high = 0):
         return ObjectId(self.impl.allocObjectId(low, high))
     
-    
+
+    def raise_event(self, event):
+        self.impl.raiseEvent(event.impl)
+
     def query_response(self, context, obj):
         self.impl.queryResponse(context, obj.impl)
     

Modified: qpid/trunk/qpid/cpp/bindings/qmf/qmfengine.i
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/qmfengine.i?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/qmfengine.i (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/qmfengine.i Wed Jan 13 11:57:19 2010
@@ -37,6 +37,7 @@
 %include <qmf/engine/Value.h>
 %include <qmf/engine/ObjectId.h>
 %include <qmf/engine/Object.h>
+%include <qmf/engine/Event.h>
 
 
 %inline {

Modified: qpid/trunk/qpid/cpp/bindings/qmf/ruby/qmf.rb
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/ruby/qmf.rb?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/ruby/qmf.rb (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/ruby/qmf.rb Wed Jan 13 11:57:19 2010
@@ -26,7 +26,8 @@
 
   # Pull all the TYPE_* constants into Qmf namespace.  Maybe there's an easier way?
   Qmfengine.constants.each do |c|
-    if c.index('TYPE_') == 0 or c.index('ACCESS_') == 0 or c.index('DIR_') == 0 or c.index('CLASS_') == 0
+    if c.index('TYPE_') == 0 or c.index('ACCESS_') == 0 or c.index('DIR_') == 0 or
+        c.index('CLASS_') == 0 or c.index('SEV_') == 0
       const_set(c, Qmfengine.const_get(c))
     end
   end
@@ -307,9 +308,90 @@
   end
 
   ##==============================================================================
-  ## OBJECTS
+  ## OBJECTS and EVENTS
   ##==============================================================================
 
+  class QmfEvent
+    attr_reader :impl, :event_class
+    def initialize(cls, kwargs={})
+      @broker = kwargs[:broker] if kwargs.include?(:broker)
+      @allow_sets = :true
+
+      if cls:
+        @event_class = cls
+        @impl = Qmfengine::Event.new(@event_class.impl)
+      elsif kwargs.include?(:impl)
+        @impl = Qmfengine::Event.new(kwargs[:impl])
+        @event_class = SchemaEventClass.new(nil, nil, :impl => @impl.getClass)
+      end
+    end
+
+    def arguments
+      list = []
+      @event_class.arguments.each do |arg|
+        list << [arg, get_attr(arg.name)]
+      end
+      return list
+    end
+
+    def get_attr(name)
+      val = value(name)
+      $util.qmf_to_native(val)
+    end
+
+    def set_attr(name, v)
+      val = value(name)
+      $util.native_to_qmf(val, v)
+    end
+
+    def [](name)
+      get_attr(name)
+    end
+
+    def []=(name, value)
+      set_attr(name, value)
+    end
+
+    def method_missing(name_in, *args)
+      #
+      # Convert the name to a string and determine if it represents an
+      # attribute assignment (i.e. "attr=")
+      #
+      name = name_in.to_s
+      attr_set = (name[name.length - 1] == 61)
+      name = name[0..name.length - 2] if attr_set
+      raise "Sets not permitted on this object" if attr_set && !@allow_sets
+
+      #
+      # If the name matches an argument name, set or return the value of the argument.
+      #
+      @event_class.arguments.each do |arg|
+        if arg.name == name
+          if attr_set
+            return set_attr(name, args[0])
+          else
+            return get_attr(name)
+          end
+        end
+      end
+
+      #
+      # This name means nothing to us, pass it up the line to the parent
+      # class's handler.
+      #
+      super.method_missing(name_in, args)
+    end
+
+    private
+    def value(name)
+      val = @impl.getValue(name.to_s)
+      if val.nil?
+        raise ArgumentError, "Attribute '#{name}' not defined for event #{@event_class.impl.getClassKey.getPackageName}:#{@object_class.impl.getClassKey.getClassName}"
+      end
+      return val
+    end
+  end
+
   class QmfObject
     include MonitorMixin
     attr_reader :impl, :object_class
@@ -845,7 +927,7 @@
 
   class SchemaEventClass
     attr_reader :impl, :arguments
-    def initialize(package, name, kwargs={})
+    def initialize(package, name, sev, kwargs={})
       @arguments = []
       if kwargs.include?(:impl)
         @impl = kwargs[:impl]
@@ -853,7 +935,7 @@
           @arguments << SchemaArgument.new(nil, nil, :impl => @impl.getArgument(i))
         end
       else
-        @impl = Qmfengine::SchemaEventClass.new(package, name)
+        @impl = Qmfengine::SchemaEventClass.new(package, name, sev)
         @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
       end
     end
@@ -1288,6 +1370,10 @@
       ObjectId.new(@impl.allocObjectId(low, high))
     end
 
+    def raise_event(event)
+      @impl.raiseEvent(event.impl)
+    end
+
     def query_response(context, object)
       @impl.queryResponse(context, object.impl)
     end

Modified: qpid/trunk/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/tests/agent_ruby.rb?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/tests/agent_ruby.rb (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/tests/agent_ruby.rb Wed Jan 13 11:57:19 2010
@@ -23,7 +23,7 @@
 require 'socket'
 
 class Model
-  attr_reader :parent_class, :child_class
+  attr_reader :parent_class, :child_class, :event_class
 
   def initialize
     @parent_class = Qmf::SchemaObjectClass.new("org.apache.qpid.qmf", "parent")
@@ -79,11 +79,16 @@
 
     @child_class = Qmf::SchemaObjectClass.new("org.apache.qpid.qmf", "child")
     @child_class.add_property(Qmf::SchemaProperty.new("name", Qmf::TYPE_SSTR, :index => true))
+
+    @event_class = Qmf::SchemaEventClass.new("org.apache.qpid.qmf", "test_event", Qmf::SEV_INFORM)
+    @event_class.add_argument(Qmf::SchemaArgument.new("uint32val", Qmf::TYPE_UINT32))
+    @event_class.add_argument(Qmf::SchemaArgument.new("strval", Qmf::TYPE_LSTR))
   end
 
   def register(agent)
     agent.register_class(@parent_class)
     agent.register_class(@child_class)
+    agent.register_class(@event_class)
   end
 end
 
@@ -139,6 +144,11 @@
                           'sstr' => "Short String",
                           'map'  => {'first' => 'FIRST', 'second' => 'SECOND'}}
 
+        event = Qmf::QmfEvent.new(@model.event_class)
+        event.uint32val = @parent.uint32val
+        event.strval = "Unused"
+        @agent.raise_event(event)
+
       elsif args['test'] == "small"
         @parent.uint64val = 4
         @parent.uint32val = 5
@@ -150,6 +160,11 @@
         @parent.int16val = 10
         @parent.int8val  = 11
 
+        event = Qmf::QmfEvent.new(@model.event_class)
+        event.uint32val = @parent.uint32val
+        event.strval = "Unused"
+        @agent.raise_event(event)
+
       elsif args['test'] == "negative"
         @parent.uint64val = 0
         @parent.uint32val = 0
@@ -161,6 +176,11 @@
         @parent.int16val = -1000
         @parent.int8val  = -100
 
+        event = Qmf::QmfEvent.new(@model.event_class)
+        event.uint32val = @parent.uint32val
+        event.strval = "Unused"
+        @agent.raise_event(event)
+
       else
         retCode = 1
         retText = "Invalid argument value for test"
@@ -169,9 +189,19 @@
     elsif name == "set_short_string"
       @parent.sstrval = args['value']
 
+      event = Qmf::QmfEvent.new(@model.event_class)
+      event.uint32val = 0
+      event.strval = @parent.sstrval
+      @agent.raise_event(event)
+
     elsif name == "set_long_string"
       @parent.lstrval = args['value']
 
+      event = Qmf::QmfEvent.new(@model.event_class)
+      event.uint32val = 0
+      event.strval = @parent.lstrval
+      @agent.raise_event(event)
+
     elsif name == "create_child"
       oid = @agent.alloc_object_id(2)
       args['child_ref'] = oid

Modified: qpid/trunk/qpid/cpp/bindings/qmf/tests/python_agent.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/tests/python_agent.py?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/tests/python_agent.py (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/tests/python_agent.py Wed Jan 13 11:57:19 2010
@@ -82,10 +82,15 @@
         self.child_class = qmf.SchemaObjectClass("org.apache.qpid.qmf", "child")
         self.child_class.add_property(qmf.SchemaProperty("name", qmf.TYPE_SSTR, {"index":True}))
 
+        self.event_class = qmf.SchemaEventClass("org.apache.qpid.qmf", "test_event", qmf.SEV_NOTICE)
+        self.event_class.add_argument(qmf.SchemaArgument("uint32val", qmf.TYPE_UINT32))
+        self.event_class.add_argument(qmf.SchemaArgument("strval", qmf.TYPE_LSTR))
+
 
     def register(self, agent):
         agent.register_class(self.parent_class)
         agent.register_class(self.child_class)
+        agent.register_class(self.event_class)
 
 
 
@@ -151,6 +156,12 @@
                                                  'sstr' : "Short String",
                                                  'map'  : {'first' : 'FIRST', 'second' : 'SECOND'}})
 
+                event = qmf.QmfEvent(self._model.event_class)
+                event.uint32val = self._parent.get_attr("uint32val")
+                event.strval = "Unused"
+
+                self._agent.raise_event(event)
+
                 ## Test the __getattr__ implementation:
                 ## @todo: remove once python_client implements this
                 ## form of property access
@@ -169,6 +180,11 @@
                 self._parent.set_attr("int16val", 10)
                 self._parent.set_attr("int8val",  11)
 
+                event = qmf.QmfEvent(self._model.event_class)
+                event.uint32val = self._parent.uint32val
+                event.strval = "Unused"
+                self._agent.raise_event(event)
+
             elif args['test'] == "negative":
                 self._parent.set_attr("uint64val", 0)
                 self._parent.set_attr("uint32val", 0)
@@ -180,6 +196,11 @@
                 self._parent.set_attr("int16val", -1000)
                 self._parent.set_attr("int8val",  -100)
 
+                event = qmf.QmfEvent(self._model.event_class)
+                event.uint32val = self._parent.uint32val
+                event.strval = "Unused"
+                self._agent.raise_event(event)
+
             else:
                 _retCode = 1
                 _retText = "Invalid argument value for test"
@@ -188,10 +209,20 @@
 
         elif name == "set_short_string":
             self._parent.set_attr('sstrval', args['value'])
+            event = qmf.QmfEvent(self._model.event_class)
+            event.uint32val = 0
+            event.strval = self._parent.sstrval
+            self._agent.raise_event(event)
+
             self._agent.method_response(context, 0, "OK", args)
 
         elif name == "set_long_string":
             self._parent.set_attr('lstrval', args['value'])
+            event = qmf.QmfEvent(self._model.event_class)
+            event.uint32val = 0
+            event.strval = self._parent.lstrval
+            self._agent.raise_event(event)
+
             self._agent.method_response(context, 0, "OK", args)
 
         elif name == "create_child":

Modified: qpid/trunk/qpid/cpp/bindings/qmf/tests/python_console.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/bindings/qmf/tests/python_console.py?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/bindings/qmf/tests/python_console.py (original)
+++ qpid/trunk/qpid/cpp/bindings/qmf/tests/python_console.py Wed Jan 13 11:57:19 2010
@@ -23,6 +23,7 @@
 from qpid.datatypes import Message
 from qpid.queue import Empty
 from time import sleep
+import qmf.console
 
 class QmfInteropTests(TestBase010):
 
@@ -166,6 +167,43 @@
         for binding in bindings:
             self.assertEqual(binding.exchangeRef, mgmt_exchange.getObjectId())
 
+    def test_F_events(self):
+        class Handler(qmf.console.Console):
+            def __init__(self):
+                self.queue = []
+
+            def event(self, broker, event):
+                if event.getClassKey().getClassName() == "test_event":
+                    self.queue.append(event)
+
+        handler = Handler()
+        self.startQmf(handler)
+
+        parents = self.qmf.getObjects(_class="parent")
+        self.assertEqual(len(parents), 1)
+        parent = parents[0]
+
+        parent.set_numerics("big")
+        parent.set_numerics("small")
+        parent.set_numerics("negative")
+        parent.set_short_string("TEST")
+        parent.set_long_string("LONG_TEST")
+        parent.probe_userid()
+
+        queue = handler.queue
+        self.assertEqual(len(queue), 5)
+        self.assertEqual(queue[0].arguments["uint32val"], 0xA5A55A5A)
+        self.assertEqual(queue[0].arguments["strval"], "Unused")
+        self.assertEqual(queue[1].arguments["uint32val"], 5)
+        self.assertEqual(queue[1].arguments["strval"], "Unused")
+        self.assertEqual(queue[2].arguments["uint32val"], 0)
+        self.assertEqual(queue[2].arguments["strval"], "Unused")
+        self.assertEqual(queue[3].arguments["uint32val"], 0)
+        self.assertEqual(queue[3].arguments["strval"], "TEST")
+        self.assertEqual(queue[4].arguments["uint32val"], 0)
+        self.assertEqual(queue[4].arguments["strval"], "LONG_TEST")
+        
+
     def getProperty(self, msg, name):
         for h in msg.headers:
             if hasattr(h, name): return getattr(h, name)

Modified: qpid/trunk/qpid/cpp/include/qmf/engine/Event.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qmf/engine/Event.h?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qmf/engine/Event.h (original)
+++ qpid/trunk/qpid/cpp/include/qmf/engine/Event.h Wed Jan 13 11:57:19 2010
@@ -23,7 +23,24 @@
 namespace qmf {
 namespace engine {
 
+    class SchemaEventClass;
+    class Value;
+    struct EventImpl;
+
     class Event {
+    public:
+        Event(const SchemaEventClass* type);
+        Event(const Event& from);
+        ~Event();
+
+        const SchemaEventClass* getClass() const;
+        Value* getValue(const char* key) const;
+
+    private:
+        friend struct EventImpl;
+        friend struct AgentImpl;
+        Event(EventImpl* impl);
+        EventImpl* impl;
     };
 }
 }

Modified: qpid/trunk/qpid/cpp/include/qmf/engine/Schema.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qmf/engine/Schema.h?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qmf/engine/Schema.h (original)
+++ qpid/trunk/qpid/cpp/include/qmf/engine/Schema.h Wed Jan 13 11:57:19 2010
@@ -29,6 +29,7 @@
     enum Access { ACCESS_READ_CREATE = 1, ACCESS_READ_WRITE = 2, ACCESS_READ_ONLY = 3 };
     enum Direction { DIR_IN = 1, DIR_OUT = 2, DIR_IN_OUT = 3 };
     enum ClassKind { CLASS_OBJECT = 1, CLASS_EVENT = 2 };
+    enum Severity { SEV_EMERG = 0, SEV_ALERT = 1, SEV_CRIT = 2, SEV_ERROR = 3, SEV_WARN = 4, SEV_NOTICE = 5, SEV_INFORM = 6, SEV_DEBUG = 7 };
 
     struct SchemaArgumentImpl;
     struct SchemaMethodImpl;
@@ -186,13 +187,14 @@
      */
     class SchemaEventClass {
     public:
-        SchemaEventClass(const char* package, const char* name);
+        SchemaEventClass(const char* package, const char* name, Severity severity);
         SchemaEventClass(const SchemaEventClass& from);
         ~SchemaEventClass();
         void addArgument(const SchemaArgument* argument);
         void setDesc(const char* desc);
 
         const SchemaClassKey* getClassKey() const;
+        Severity getSeverity() const;
         int getArgumentCount() const;
         const SchemaArgument* getArgument(int idx) const;
 

Modified: qpid/trunk/qpid/cpp/include/qmf/engine/Value.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qmf/engine/Value.h?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qmf/engine/Value.h (original)
+++ qpid/trunk/qpid/cpp/include/qmf/engine/Value.h Wed Jan 13 11:57:19 2010
@@ -110,6 +110,7 @@
         friend struct ValueImpl;
         friend class  BrokerProxyImpl;
         friend struct ObjectImpl;
+        friend struct EventImpl;
         friend class  AgentImpl;
         Value(ValueImpl* impl);
         ValueImpl* impl;

Modified: qpid/trunk/qpid/cpp/src/qmf.mk
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf.mk?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf.mk (original)
+++ qpid/trunk/qpid/cpp/src/qmf.mk Wed Jan 13 11:57:19 2010
@@ -73,6 +73,8 @@
   qmf/engine/ConnectionSettingsImpl.h		\
   qmf/engine/ConsoleImpl.cpp			\
   qmf/engine/ConsoleImpl.h			\
+  qmf/engine/EventImpl.cpp			\
+  qmf/engine/EventImpl.h			\
   qmf/engine/MessageImpl.cpp			\
   qmf/engine/MessageImpl.h			\
   qmf/engine/ObjectIdImpl.cpp			\

Modified: qpid/trunk/qpid/cpp/src/qmf/engine/Agent.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/Agent.cpp?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/Agent.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/Agent.cpp Wed Jan 13 11:57:19 2010
@@ -21,6 +21,7 @@
 #include "qmf/engine/MessageImpl.h"
 #include "qmf/engine/SchemaImpl.h"
 #include "qmf/engine/Typecode.h"
+#include "qmf/engine/EventImpl.h"
 #include "qmf/engine/ObjectImpl.h"
 #include "qmf/engine/ObjectIdImpl.h"
 #include "qmf/engine/QueryImpl.h"
@@ -476,9 +477,19 @@
     return allocObjectId(((uint64_t) persistIdHi) << 32 | (uint64_t) persistIdLo);
 }
 
-void AgentImpl::raiseEvent(Event&)
+void AgentImpl::raiseEvent(Event& event)
 {
     Mutex::ScopedLock _lock(lock);
+    Buffer buffer(outputBuffer, MA_BUFFER_SIZE);
+    Protocol::encodeHeader(buffer, Protocol::OP_EVENT_INDICATION);
+
+    event.impl->encodeSchemaKey(buffer);
+    buffer.putLongLong(uint64_t(Duration(now())));
+    event.impl->encode(buffer);
+    string key(event.impl->getRoutingKey(assignedBrokerBank, assignedAgentBank));
+
+    sendBufferLH(buffer, QMF_EXCHANGE, key);
+    QPID_LOG(trace, "SENT EventIndication");
 }
 
 AgentEventImpl::Ptr AgentImpl::eventDeclareQueue(const string& name)

Added: qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.cpp?rev=898727&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.cpp Wed Jan 13 11:57:19 2010
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <qmf/engine/EventImpl.h>
+#include <qmf/engine/ValueImpl.h>
+
+using namespace std;
+using namespace qmf::engine;
+using qpid::framing::Buffer;
+
+EventImpl::EventImpl(const SchemaEventClass* type) : eventClass(type)
+{
+    int argCount = eventClass->getArgumentCount();
+    int idx;
+
+    for (idx = 0; idx < argCount; idx++) {
+        const SchemaArgument* arg = eventClass->getArgument(idx);
+        arguments[arg->getName()] = ValuePtr(new Value(arg->getType()));
+    }
+}
+
+
+EventImpl::EventImpl(const SchemaEventClass* type, Buffer&) :
+    eventClass(type)
+{
+}
+
+
+Event* EventImpl::factory(const SchemaEventClass* type, Buffer& buffer)
+{
+    EventImpl* impl(new EventImpl(type, buffer));
+    return new Event(impl);
+}
+
+
+Value* EventImpl::getValue(const char* key) const
+{
+    map<string, ValuePtr>::const_iterator iter;
+
+    iter = arguments.find(key);
+    if (iter != arguments.end())
+        return iter->second.get();
+
+    return 0;
+}
+
+
+void EventImpl::encodeSchemaKey(Buffer& buffer) const
+{
+    buffer.putShortString(eventClass->getClassKey()->getPackageName());
+    buffer.putShortString(eventClass->getClassKey()->getClassName());
+    buffer.putBin128(const_cast<uint8_t*>(eventClass->getClassKey()->getHash()));
+}
+
+
+void EventImpl::encode(Buffer& buffer) const
+{
+    buffer.putOctet((uint8_t) eventClass->getSeverity());
+
+    int argCount = eventClass->getArgumentCount();
+    for (int idx = 0; idx < argCount; idx++) {
+        const SchemaArgument* arg = eventClass->getArgument(idx);
+        ValuePtr value = arguments[arg->getName()];
+        value->impl->encode(buffer);
+    }
+}
+
+
+string EventImpl::getRoutingKey(uint32_t brokerBank, uint32_t agentBank) const
+{
+    stringstream key;
+
+    key << "console.event." << brokerBank << "." << agentBank << "." <<
+        eventClass->getClassKey()->getPackageName() << "." <<
+        eventClass->getClassKey()->getClassName();
+    return key.str();
+}
+
+
+//==================================================================
+// Wrappers
+//==================================================================
+
+Event::Event(const SchemaEventClass* type) : impl(new EventImpl(type)) {}
+Event::Event(EventImpl* i) : impl(i) {}
+Event::Event(const Event& from) : impl(new EventImpl(*(from.impl))) {}
+Event::~Event() { delete impl; }
+const SchemaEventClass* Event::getClass() const { return impl->getClass(); }
+Value* Event::getValue(const char* key) const { return impl->getValue(key); }
+

Added: qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.h?rev=898727&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.h (added)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/EventImpl.h Wed Jan 13 11:57:19 2010
@@ -0,0 +1,53 @@
+#ifndef _QmfEngineEventImpl_
+#define _QmfEngineEventImpl_
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <qmf/engine/Event.h>
+#include <qmf/engine/Schema.h>
+#include <qpid/framing/Buffer.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+namespace qmf {
+namespace engine {
+
+    struct EventImpl {
+        typedef boost::shared_ptr<Value> ValuePtr;
+        const SchemaEventClass* eventClass;
+        mutable std::map<std::string, ValuePtr> arguments;
+
+        EventImpl(const SchemaEventClass* type);
+        EventImpl(const SchemaEventClass* type, qpid::framing::Buffer& buffer);
+        static Event* factory(const SchemaEventClass* type, qpid::framing::Buffer& buffer);
+
+        const SchemaEventClass* getClass() const { return eventClass; }
+        Value* getValue(const char* key) const;
+
+        void encodeSchemaKey(qpid::framing::Buffer& buffer) const;
+        void encode(qpid::framing::Buffer& buffer) const;
+        std::string getRoutingKey(uint32_t brokerBank, uint32_t agentBank) const;
+    };
+
+}
+}
+
+#endif
+

Modified: qpid/trunk/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/ResilientConnection.cpp?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/ResilientConnection.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/ResilientConnection.cpp Wed Jan 13 11:57:19 2010
@@ -39,6 +39,8 @@
 #include <set>
 #include <boost/intrusive_ptr.hpp>
 #include <boost/noncopyable.hpp>
+#include <unistd.h>
+#include <fcntl.h>
 
 using namespace std;
 using namespace qmf::engine;
@@ -330,6 +332,10 @@
 void ResilientConnectionImpl::setNotifyFd(int fd)
 {
     notifyFd = fd;
+    if (notifyFd > 0) {
+        int original = fcntl(notifyFd, F_GETFL);
+        fcntl(notifyFd, F_SETFL, O_NONBLOCK | original);
+    }
 }
 
 void ResilientConnectionImpl::run()
@@ -403,13 +409,16 @@
                                            const MessageImpl& message,
                                            const string& errorText)
 {
-    Mutex::ScopedLock _lock(lock);
-    ResilientConnectionEventImpl event(kind, message);
+    {
+        Mutex::ScopedLock _lock(lock);
+        ResilientConnectionEventImpl event(kind, message);
 
-    event.sessionContext = sessionContext;
-    event.errorText      = errorText;
+        event.sessionContext = sessionContext;
+        event.errorText      = errorText;
+
+        eventQueue.push_back(event);
+    }
 
-    eventQueue.push_back(event);
     if (notifyFd != -1)
     {
         int unused_ret;    //Suppress warnings about ignoring return value.

Modified: qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.cpp?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.cpp Wed Jan 13 11:57:19 2010
@@ -459,7 +459,6 @@
     buffer.getShortString(package);
     buffer.getShortString(name);
     hash.decode(buffer);
-    buffer.putOctet(0); // No parent class
 
     uint16_t argCount = buffer.getShort();
 
@@ -598,13 +597,14 @@
 const SchemaStatistic* SchemaObjectClass::getStatistic(int idx) const { return impl->getStatistic(idx); }
 const SchemaMethod* SchemaObjectClass::getMethod(int idx) const { return impl->getMethod(idx); }
 
-SchemaEventClass::SchemaEventClass(const char* package, const char* name) : impl(new SchemaEventClassImpl(package, name)) {}
+SchemaEventClass::SchemaEventClass(const char* package, const char* name, Severity s) : impl(new SchemaEventClassImpl(package, name, s)) {}
 SchemaEventClass::SchemaEventClass(SchemaEventClassImpl* i) : impl(i) {}
 SchemaEventClass::SchemaEventClass(const SchemaEventClass& from) : impl(new SchemaEventClassImpl(*(from.impl))) {}
 SchemaEventClass::~SchemaEventClass() { delete impl; }
 void SchemaEventClass::addArgument(const SchemaArgument* argument) { impl->addArgument(argument); }
 void SchemaEventClass::setDesc(const char* desc) { impl->setDesc(desc); }
 const SchemaClassKey* SchemaEventClass::getClassKey() const { return impl->getClassKey(); }
+Severity SchemaEventClass::getSeverity() const { return impl->getSeverity(); }
 int SchemaEventClass::getArgumentCount() const { return impl->getArgumentCount(); }
 const SchemaArgument* SchemaEventClass::getArgument(int idx) const { return impl->getArgument(idx); }
 

Modified: qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.h?rev=898727&r1=898726&r2=898727&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.h (original)
+++ qpid/trunk/qpid/cpp/src/qmf/engine/SchemaImpl.h Wed Jan 13 11:57:19 2010
@@ -201,10 +201,11 @@
         mutable bool hasHash;
         std::auto_ptr<SchemaClassKey> classKey;
         std::string description;
+        Severity severity;
         std::vector<const SchemaArgument*> arguments;
 
-        SchemaEventClassImpl(const char* p, const char* n) :
-            package(p), name(n), hasHash(false), classKey(SchemaClassKeyImpl::factory(package, name, hash)) {}
+    SchemaEventClassImpl(const char* p, const char* n, Severity sev) :
+        package(p), name(n), hasHash(false), classKey(SchemaClassKeyImpl::factory(package, name, hash)), severity(sev) {}
         SchemaEventClassImpl(qpid::framing::Buffer& buffer);
         static SchemaEventClass* factory(qpid::framing::Buffer& buffer);
 
@@ -213,6 +214,7 @@
         void setDesc(const char* desc) { description = desc; }
 
         const SchemaClassKey* getClassKey() const;
+        Severity getSeverity() const { return severity; }
         int getArgumentCount() const { return arguments.size(); }
         const SchemaArgument* getArgument(int idx) const;
     };



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org