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