summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Anthony Giusti <kgiusti@apache.org>2010-05-20 21:42:40 +0000
committerKenneth Anthony Giusti <kgiusti@apache.org>2010-05-20 21:42:40 +0000
commitb806ee99fb0224069ba628bc0c506e02bb227de2 (patch)
tree96660eb0b40d818911a7c51bfe7bd8c95d616aa9
parentf50e4c2871bbebc89fa2796ff850911f082778c3 (diff)
downloadqpid-python-b806ee99fb0224069ba628bc0c506e02bb227de2.tar.gz
QMF: provide event filter api for python console
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@946801 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/src/qpid/management/ManagementAgent.cpp46
-rw-r--r--qpid/cpp/src/qpid/management/ManagementAgent.h2
-rw-r--r--qpid/extras/qmf/src/py/qmf/console.py83
3 files changed, 114 insertions, 17 deletions
diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.cpp b/qpid/cpp/src/qpid/management/ManagementAgent.cpp
index 39ac2d11af..7f2dd69b52 100644
--- a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
+++ b/qpid/cpp/src/qpid/management/ManagementAgent.cpp
@@ -52,6 +52,25 @@ using namespace std;
namespace _qmf = qmf::org::apache::qpid::broker;
+namespace {
+ const string defaultVendorName("vendor");
+ const string defaultProductName("product");
+
+ // Create a valid binding key substring by
+ // replacing all '.' chars with '_'
+ const string keyifyNameStr(const string& name)
+ {
+ string n2 = name;
+
+ size_t pos = n2.find('.');
+ while (pos != n2.npos) {
+ n2.replace(pos, 1, "_");
+ pos = n2.find('.', pos);
+ }
+ return n2;
+ }
+}
+
static Variant::Map mapEncodeSchemaId(const string& pname,
const string& cname,
@@ -81,6 +100,7 @@ ManagementAgent::ManagementAgent (const bool qmfV1, const bool qmfV2) :
threadPoolSize(1), interval(10), broker(0), timer(0),
startTime(sys::now()),
suppressed(false), disallowAllV1Methods(false),
+ vendorNameKey(defaultVendorName), productNameKey(defaultProductName),
qmf1Support(qmfV1), qmf2Support(qmfV2)
{
nextObjectId = 1;
@@ -89,6 +109,8 @@ ManagementAgent::ManagementAgent (const bool qmfV1, const bool qmfV2) :
nextRemoteBank = 10;
nextRequestSequence = 1;
clientWasAdded = false;
+ attrMap["_vendor"] = defaultVendorName;
+ attrMap["_product"] = defaultProductName;
}
ManagementAgent::~ManagementAgent ()
@@ -190,6 +212,9 @@ void ManagementAgent::setName(const string& vendor, const string& product, const
name_address = vendor + ":" + product + ":" + inst;
attrMap["_instance"] = inst;
attrMap["_name"] = name_address;
+
+ vendorNameKey = keyifyNameStr(vendor);
+ productNameKey = keyifyNameStr(product);
}
@@ -300,6 +325,10 @@ ObjectId ManagementAgent::addObject(ManagementObject* object,
void ManagementAgent::raiseEvent(const ManagementEvent& event, severity_t severity)
{
+ static const std::string severityStr[] = {
+ "emerg", "alert", "crit", "error", "warn",
+ "note", "info", "debug"
+ };
sys::Mutex::ScopedLock lock (userLock);
uint8_t sev = (severity == SEV_DEFAULT) ? event.getSeverity() : (uint8_t) severity;
@@ -344,7 +373,11 @@ void ManagementAgent::raiseEvent(const ManagementEvent& event, severity_t severi
headers["qmf.agent"] = name_address;
stringstream key;
- key << "agent.ind.event." << sev << "." << name_address << "." << event.getEventName();
+ key << "agent.ind.event." << vendorNameKey
+ << "." << productNameKey
+ << "." << severityStr[sev]
+ << "." << keyifyNameStr(event.getPackageName())
+ << "." << keyifyNameStr(event.getEventName());
string content;
MapCodec::encode(map_, content);
@@ -720,16 +753,7 @@ void ManagementAgent::periodicProcessing (void)
if (qmf2Support) {
std::stringstream addr_key;
- addr_key << "agent.ind.heartbeat";
-
- // append .<vendor>.<product> to address key if present.
- Variant::Map::const_iterator v;
- if ((v = attrMap.find("_vendor")) != attrMap.end()){
- addr_key << "." << v->second.getString();
- if ((v = attrMap.find("_product")) != attrMap.end()) {
- addr_key << "." << v->second.getString();
- }
- }
+ addr_key << "agent.ind.heartbeat." << vendorNameKey << "." << productNameKey;
Variant::Map map;
Variant::Map headers;
diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.h b/qpid/cpp/src/qpid/management/ManagementAgent.h
index a1c6f3ce24..d101ca198e 100644
--- a/qpid/cpp/src/qpid/management/ManagementAgent.h
+++ b/qpid/cpp/src/qpid/management/ManagementAgent.h
@@ -282,6 +282,8 @@ private:
// Agent name and address
qpid::types::Variant::Map attrMap;
std::string name_address;
+ std::string vendorNameKey; // "." --> "_"
+ std::string productNameKey; // "." --> "_"
// supported management protocol
bool qmf1Support;
diff --git a/qpid/extras/qmf/src/py/qmf/console.py b/qpid/extras/qmf/src/py/qmf/console.py
index 907badbcdd..8b7aeaa576 100644
--- a/qpid/extras/qmf/src/py/qmf/console.py
+++ b/qpid/extras/qmf/src/py/qmf/console.py
@@ -801,17 +801,85 @@ class Session:
return request.result
- def setEventFilter(self, **kwargs):
- """ """
- pass
+ def addEventFilter(self, **kwargs):
+ """Filter unsolicited events based on package and event name.
+ QMF v2 also can filter on vendor, product, and severity values.
+
+ By default, a console receives unsolicted events by binding to:
+
+ qpid.management/console.event.# (v1)
+
+ qmf.default.topic/agent.ind.event.# (v2)
+
+ A V1 event filter binding uses the pattern:
+
+ qpid.management/console.event.*.*[.<package>[.<event>]].#
+
+ A V2 event filter binding uses the pattern:
+
+ qmf.default.topic/agent.ind.event.<Vendor|*>.<Product|*>.<severity|*>.<package|*>.<event|*>.#
+ """
+ package = kwargs.get("package", "*")
+ event = kwargs.get("event", "*")
+ vendor = kwargs.get("vendor", "*")
+ product = kwargs.get("product", "*")
+ severity = kwargs.get("severity", "*")
+
+ if package is "*" and event is not "*":
+ raise Exception("'package' parameter required if 'event' parameter"
+ " supplied")
+
+ # V1 key - can only filter on package (and event)
+ if package is not "*":
+ key = "console.event.*.*." + str(package)
+ if event is not "*":
+ key += "." + str(event)
+ key += ".#"
+
+ if key not in self.v1BindingKeyList:
+ self.v1BindingKeyList.append(key)
+ try:
+ # remove default wildcard binding
+ self.v1BindingKeyList.remove("console.event.#")
+ except:
+ pass
+
+ # V2 key - escape any "." in the filter strings
+
+ key = "agent.ind.event." + str(vendor).replace(".", "_") \
+ + "." + str(product).replace(".", "_") \
+ + "." + str(severity).replace(".", "_") \
+ + "." + str(package).replace(".", "_") \
+ + "." + str(event).replace(".", "_") + ".#"
+
+ if key not in self.v2BindingKeyList:
+ self.v2BindingKeyList.append(key)
+ try:
+ # remove default wildcard binding
+ self.v2BindingKeyList.remove("agent.ind.event.#")
+ except:
+ pass
def addAgentFilter(self, vendor, product=None):
+ """Deprecate - use heartbeat filter instead"""
+ self.addHeartbeatFilter(vendor=vendor, product=product)
+
+ def addHeartbeatFilter(self, **kwargs):
""" Listen for heartbeat messages only for those agent(s) that match the
vendor and, optionally, the product strings.
"""
- key = "agent.ind.heartbeat." + vendor
+ vendor = kwargs.get("vendor")
+ product = kwargs.get("product")
+ if vendor is None:
+ raise Exception("vendor parameter required!")
+
+ # V1 heartbeats do not have any agent identifier - we cannot
+ # filter them by agent.
+
+ # build the binding key - escape "."s...
+ key = "agent.ind.heartbeat." + str(vendor).replace(".", "_")
if product is not None:
- key += "." + product
+ key += "." + str(product).replace(".", "_")
key += ".#"
if key not in self.v2BindingKeyList:
@@ -830,7 +898,10 @@ class Session:
pass
def _bindingKeys(self):
- """ The set of default key bindings."""
+ """ Construct the initial set of default key bindings. These keys can be
+ overridden using the add{Event,Heartbeat}Filter() api calls _prior_ to
+ adding a broker with addBroker()
+ """
v1KeyList = []
v2KeyList = []
v1KeyList.append("schema.#")