diff options
| author | Kenneth Anthony Giusti <kgiusti@apache.org> | 2010-05-20 21:42:40 +0000 |
|---|---|---|
| committer | Kenneth Anthony Giusti <kgiusti@apache.org> | 2010-05-20 21:42:40 +0000 |
| commit | b806ee99fb0224069ba628bc0c506e02bb227de2 (patch) | |
| tree | 96660eb0b40d818911a7c51bfe7bd8c95d616aa9 | |
| parent | f50e4c2871bbebc89fa2796ff850911f082778c3 (diff) | |
| download | qpid-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.cpp | 46 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/management/ManagementAgent.h | 2 | ||||
| -rw-r--r-- | qpid/extras/qmf/src/py/qmf/console.py | 83 |
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.#") |
