diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/qpid/agent/ManagementAgentImpl.cpp | 2 | ||||
-rw-r--r-- | cpp/src/qpid/cluster/ClusterPlugin.cpp | 9 | ||||
-rw-r--r-- | cpp/src/qpid/management/ManagementAgent.cpp | 438 | ||||
-rw-r--r-- | cpp/src/qpid/management/ManagementAgent.h | 38 | ||||
-rw-r--r-- | cpp/src/qpid/management/ManagementDirectExchange.cpp | 2 | ||||
-rw-r--r-- | cpp/src/qpid/management/ManagementObject.cpp | 3 | ||||
-rw-r--r-- | cpp/src/qpid/management/ManagementTopicExchange.cpp | 2 | ||||
-rw-r--r-- | cpp/src/qpid/types/Variant.cpp | 36 | ||||
-rw-r--r-- | cpp/src/tests/ManagementTest.cpp | 10 |
9 files changed, 297 insertions, 243 deletions
diff --git a/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/cpp/src/qpid/agent/ManagementAgentImpl.cpp index b0207582ee..890ecd2ca2 100644 --- a/cpp/src/qpid/agent/ManagementAgentImpl.cpp +++ b/cpp/src/qpid/agent/ManagementAgentImpl.cpp @@ -653,7 +653,7 @@ void ManagementAgentImpl::handleGetQuery(const string& body, const string& cid, } } - // end empty "non-partial" message to indicate CommandComplete + // Send empty "non-partial" message to indicate CommandComplete list_.clear(); headers.erase("partial"); ListCodec::encode(list_, content); diff --git a/cpp/src/qpid/cluster/ClusterPlugin.cpp b/cpp/src/qpid/cluster/ClusterPlugin.cpp index 6806b3e1dd..3192896956 100644 --- a/cpp/src/qpid/cluster/ClusterPlugin.cpp +++ b/cpp/src/qpid/cluster/ClusterPlugin.cpp @@ -146,16 +146,9 @@ struct ClusterPlugin : public Plugin { } } - void disallow(ManagementAgent* agent, const string& className, const string& methodName) { - string message = "Management method " + className + ":" + methodName + " is not allowed on a clustered broker."; - agent->disallow(className, methodName, message); - } void disallowManagementMethods(ManagementAgent* agent) { if (!agent) return; - disallow(agent, "queue", "purge"); - disallow(agent, "session", "detach"); - disallow(agent, "session", "close"); - disallow(agent, "connection", "close"); + agent->disallowV1Methods(); } void initialize(Plugin::Target& target) { diff --git a/cpp/src/qpid/management/ManagementAgent.cpp b/cpp/src/qpid/management/ManagementAgent.cpp index c4b670ca5f..1a1415a06e 100644 --- a/cpp/src/qpid/management/ManagementAgent.cpp +++ b/cpp/src/qpid/management/ManagementAgent.cpp @@ -54,9 +54,9 @@ namespace _qmf = qmf::org::apache::qpid::broker; -static Variant::Map mapEncodeSchemaId(const std::string& pname, - const std::string& cname, - const std::string& type, +static Variant::Map mapEncodeSchemaId(const string& pname, + const string& cname, + const string& type, const uint8_t *md5Sum) { Variant::Map map_; @@ -81,7 +81,7 @@ ManagementAgent::RemoteAgent::~RemoteAgent () ManagementAgent::ManagementAgent (const bool qmfV1, const bool qmfV2) : threadPoolSize(1), interval(10), broker(0), timer(0), startTime(sys::now()), - suppressed(false), + suppressed(false), disallowAllV1Methods(false), qmf1Support(qmfV1), qmf2Support(qmfV2) { nextObjectId = 1; @@ -287,7 +287,7 @@ ObjectId ManagementAgent::addObject(ManagementObject* object, uint64_t persistId ObjectId ManagementAgent::addObject(ManagementObject* object, - const std::string& key, + const string& key, bool persistent) { uint16_t sequence; @@ -337,7 +337,7 @@ void ManagementAgent::raiseEvent(const ManagementEvent& event, severity_t severi outBuffer.putBin128(event.getMd5Sum()); outBuffer.putLongLong(uint64_t(sys::Duration(sys::EPOCH, sys::now()))); outBuffer.putOctet(sev); - std::string sBuf; + string sBuf; event.encode(sBuf); outBuffer.putRawData(sBuf); outLen = MA_BUFFER_SIZE - outBuffer.available(); @@ -391,7 +391,7 @@ void ManagementAgent::Periodic::fire () agent.periodicProcessing (); } -void ManagementAgent::clientAdded (const std::string& routingKey) +void ManagementAgent::clientAdded (const string& routingKey) { sys::Mutex::ScopedLock lock(userLock); @@ -492,12 +492,12 @@ void ManagementAgent::sendBufferLH(Buffer& buf, // NOTE WELL: assumes userLock is held by caller (LH) -void ManagementAgent::sendBufferLH(const std::string& data, - const std::string& cid, +void ManagementAgent::sendBufferLH(const string& data, + const string& cid, const Variant::Map& headers, - const std::string& content_type, + const string& content_type, qpid::broker::Exchange::shared_ptr exchange, - const std::string& routingKey) + const string& routingKey) { Variant::Map::const_iterator i; @@ -592,7 +592,7 @@ void ManagementAgent::periodicProcessing (void) uint32_t contentSize; string routingKey; list<pair<ObjectId, ManagementObject*> > deleteList; - std::string sBuf; + string sBuf; uint64_t uptime = sys::Duration(startTime, sys::now()); static_cast<_qmf::Broker*>(broker->GetManagementObject())->set_uptime(uptime); @@ -844,7 +844,7 @@ void ManagementAgent::deleteObjectNowLH(const ObjectId& oid) char msgChars[DNOW_BUFSIZE]; uint32_t contentSize; Buffer msgBuffer(msgChars, DNOW_BUFSIZE); - std::string sBuf; + string sBuf; encodeHeader(msgBuffer, 'c'); object->writeProperties(sBuf); @@ -889,8 +889,8 @@ void ManagementAgent::deleteObjectNowLH(const ObjectId& oid) managementObjects.erase(oid); } -void ManagementAgent::sendCommandCompleteLH(string replyToKey, uint32_t sequence, - uint32_t code, string text) +void ManagementAgent::sendCommandCompleteLH(const string& replyToKey, uint32_t sequence, + uint32_t code, const string& text) { Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; @@ -905,14 +905,40 @@ void ManagementAgent::sendCommandCompleteLH(string replyToKey, uint32_t sequence replyToKey << " seq=" << sequence); } +void ManagementAgent::sendExceptionLH(const string& replyToKey, const string& cid, + const string& text, uint32_t code, bool viaLocal) +{ + static const string addr_exchange("qmf.default.direct"); + + Variant::Map map; + Variant::Map headers; + Variant::Map values; + string content; + + headers["method"] = "indication"; + headers["qmf.opcode"] = "_exception"; + headers["qmf.agent"] = viaLocal ? "broker" : name_address; + + values["error_code"] = code; + values["error_text"] = text; + map["_values"] = values; + + MapCodec::encode(map, content); + sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyToKey); + + QPID_LOG(trace, "SENT Exception code=" << code <<" text=" << text); +} + bool ManagementAgent::dispatchCommand (Deliverable& deliverable, const string& routingKey, const FieldTable* /*args*/, - const bool topic) + const bool topic, + int qmfVersion) { sys::Mutex::ScopedLock lock (userLock); Message& msg = ((DeliverableMessage&) deliverable).getMessage (); - if (topic) { + + if (topic && qmfVersion == 1) { // qmf1 is bound only to the topic management exchange. // Parse the routing key. This management broker should act as though it @@ -945,7 +971,7 @@ bool ManagementAgent::dispatchCommand (Deliverable& deliverable, } } - if (qmf2Support) { + if (qmfVersion == 2) { if (topic) { // Intercept messages bound to: @@ -962,7 +988,7 @@ bool ManagementAgent::dispatchCommand (Deliverable& deliverable, // "<name_address>" - the broker agent's proper name // and do not forward them futher if (routingKey == "broker" || routingKey == name_address) { - dispatchAgentCommandLH(msg); + dispatchAgentCommandLH(msg, routingKey == "broker"); return false; } } @@ -971,8 +997,7 @@ bool ManagementAgent::dispatchCommand (Deliverable& deliverable, return true; } -void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string replyToKey, - uint32_t sequence, const ConnectionToken* connToken) +void ManagementAgent::handleMethodRequestLH(Buffer& inBuffer, const string& replyToKey, uint32_t sequence, const ConnectionToken* connToken) { string methodName; string packageName; @@ -981,9 +1006,9 @@ void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string replyToKey Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; AclModule* acl = broker->getAcl(); - std::string inArgs; + string inArgs; - std::string sBuf; + string sBuf; inBuffer.getRawData(sBuf, 16); ObjectId objId; objId.decode(sBuf); @@ -998,7 +1023,17 @@ void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string replyToKey encodeHeader(outBuffer, 'm', sequence); - DisallowedMethods::const_iterator i = disallowed.find(std::make_pair(className, methodName)); + if (disallowAllV1Methods) { + outBuffer.putLong(Manageable::STATUS_FORBIDDEN); + outBuffer.putMediumString("QMFv1 methods forbidden on this broker, use QMFv2"); + outLen = MA_BUFFER_SIZE - outBuffer.available(); + outBuffer.reset(); + sendBufferLH(outBuffer, outLen, dExchange, replyToKey); + QPID_LOG(trace, "SEND MethodResponse status=FORBIDDEN reason='All QMFv1 Methods Forbidden' seq=" << sequence); + return; + } + + DisallowedMethods::const_iterator i = disallowed.find(make_pair(className, methodName)); if (i != disallowed.end()) { outBuffer.putLong(Manageable::STATUS_FORBIDDEN); outBuffer.putMediumString(i->second); @@ -1040,7 +1075,7 @@ void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string replyToKey try { outBuffer.record(); sys::Mutex::ScopedUnlock u(userLock); - std::string outBuf; + string outBuf; iter->second->doMethod(methodName, inArgs, outBuf); outBuffer.putRawData(outBuf); } catch(exception& e) { @@ -1057,39 +1092,34 @@ void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string replyToKey } -void ManagementAgent::handleMethodRequestLH (const std::string& body, string replyTo, - const std::string& cid, const ConnectionToken* connToken) +void ManagementAgent::handleMethodRequestLH (const string& body, const string& replyTo, + const string& cid, const ConnectionToken* connToken, bool viaLocal) { string methodName; Variant::Map inMap; MapCodec::decode(body, inMap); Variant::Map::const_iterator oid, mid; string content; + string error; + uint32_t errorCode(0); Variant::Map outMap; Variant::Map headers; headers["method"] = "response"; headers["qmf.opcode"] = "_method_response"; - headers["qmf.agent"] = name_address; + headers["qmf.agent"] = viaLocal ? "broker" : name_address; if ((oid = inMap.find("_object_id")) == inMap.end() || - (mid = inMap.find("_method_name")) == inMap.end()) - { - Variant::Map _values; - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_PARAMETER_INVALID; - _values["_status_text"] = Manageable::StatusText(Manageable::STATUS_PARAMETER_INVALID); - outMap["_values"] = _values; - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse (invalid param) to=" << replyTo << " seq=" << cid); + (mid = inMap.find("_method_name")) == inMap.end()) { + sendExceptionLH(replyTo, cid, Manageable::StatusText(Manageable::STATUS_PARAMETER_INVALID), + Manageable::STATUS_PARAMETER_INVALID, viaLocal); return; } ObjectId objId; Variant::Map inArgs; + Variant::Map callMap; try { // coversions will throw if input is invalid. @@ -1101,31 +1131,16 @@ void ManagementAgent::handleMethodRequestLH (const std::string& body, string rep inArgs = (mid->second).asMap(); } } catch(exception& e) { - Variant::Map _values; - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_EXCEPTION; - _values["_status_text"] = e.what(); - outMap["_values"] = _values; - - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse (invalid format) to=" << replyTo << " seq=" << cid); + sendExceptionLH(replyTo, cid, e.what(), Manageable::STATUS_EXCEPTION, viaLocal); return; } ManagementObjectMap::iterator iter = managementObjects.find(objId); if (iter == managementObjects.end() || iter->second->isDeleted()) { - Variant::Map _values; - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_UNKNOWN_OBJECT; - _values["_status_text"] = Manageable::StatusText(Manageable::STATUS_UNKNOWN_OBJECT); - outMap["_values"] = _values; - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse (unknown object) to=" << replyTo << " seq=" << cid); + stringstream estr; + estr << "No object found with ID=" << objId; + sendExceptionLH(replyTo, cid, estr.str(), 1, viaLocal); return; } @@ -1133,17 +1148,9 @@ void ManagementAgent::handleMethodRequestLH (const std::string& body, string rep AclModule* acl = broker->getAcl(); DisallowedMethods::const_iterator i; - i = disallowed.find(std::make_pair(iter->second->getClassName(), methodName)); + i = disallowed.find(make_pair(iter->second->getClassName(), methodName)); if (i != disallowed.end()) { - Variant::Map _values; - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_FORBIDDEN; - _values["_status_text"] = i->second; - outMap["_values"] = _values; - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse status=FORBIDDEN text=" << i->second << " seq=" << cid); + sendExceptionLH(replyTo, cid, i->second, Manageable::STATUS_FORBIDDEN, viaLocal); return; } @@ -1154,15 +1161,8 @@ void ManagementAgent::handleMethodRequestLH (const std::string& body, string rep params[acl::PROP_SCHEMACLASS] = iter->second->getClassName(); if (!acl->authorise(userId, acl::ACT_ACCESS, acl::OBJ_METHOD, methodName, ¶ms)) { - Variant::Map _values; - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_FORBIDDEN; - _values["_status_text"] = Manageable::StatusText(Manageable::STATUS_FORBIDDEN); - outMap["_values"] = _values; - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse status=FORBIDDEN" << " seq=" << cid); + sendExceptionLH(replyTo, cid, Manageable::StatusText(Manageable::STATUS_FORBIDDEN), + Manageable::STATUS_FORBIDDEN, viaLocal); return; } } @@ -1171,32 +1171,37 @@ void ManagementAgent::handleMethodRequestLH (const std::string& body, string rep QPID_LOG(trace, "RECV MethodRequest (v2) class=" << iter->second->getPackageName() << ":" << iter->second->getClassName() << " method=" << - methodName << " replyTo=" << replyTo); + methodName << " replyTo=" << replyTo << " objId=" << objId << " inArgs=" << inArgs); try { sys::Mutex::ScopedUnlock u(userLock); - iter->second->doMethod(methodName, inArgs, outMap); + iter->second->doMethod(methodName, inArgs, callMap); + errorCode = callMap["_status_code"].asUint32(); + if (errorCode == 0) { + outMap["_arguments"] = Variant::Map(); + for (Variant::Map::const_iterator iter = callMap.begin(); + iter != callMap.end(); iter++) + if (iter->first != "_status_code" && iter->first != "_status_text") + outMap["_arguments"].asMap()[iter->first] = iter->second; + } else + error = callMap["_status_text"].asString(); } catch(exception& e) { - Variant::Map _values; - outMap.clear(); - headers["qmf.opcode"] = "_exception"; - _values["_status"] = Manageable::STATUS_EXCEPTION; - _values["_status_text"] = e.what(); - outMap["_values"] = _values; - - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse (exception) to=" << replyTo << " seq=" << cid); + sendExceptionLH(replyTo, cid, e.what(), Manageable::STATUS_EXCEPTION, viaLocal); + return; + } + + if (errorCode != 0) { + sendExceptionLH(replyTo, cid, error, errorCode, viaLocal); return; } MapCodec::encode(outMap, content); sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyTo); - QPID_LOG(trace, "SEND MethodResponse (v2) to=" << replyTo << " seq=" << cid); + QPID_LOG(trace, "SEND MethodResponse (v2) to=" << replyTo << " seq=" << cid << " map=" << outMap); } -void ManagementAgent::handleBrokerRequestLH (Buffer&, string replyToKey, uint32_t sequence) +void ManagementAgent::handleBrokerRequestLH (Buffer&, const string& replyToKey, uint32_t sequence) { Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; @@ -1212,7 +1217,7 @@ void ManagementAgent::handleBrokerRequestLH (Buffer&, string replyToKey, uint32_ QPID_LOG(trace, "SEND BrokerResponse to=" << replyToKey); } -void ManagementAgent::handlePackageQueryLH (Buffer&, string replyToKey, uint32_t sequence) +void ManagementAgent::handlePackageQueryLH (Buffer&, const string& replyToKey, uint32_t sequence) { QPID_LOG(trace, "RECV PackageQuery replyTo=" << replyToKey); @@ -1234,7 +1239,7 @@ void ManagementAgent::handlePackageQueryLH (Buffer&, string replyToKey, uint32_t sendCommandCompleteLH(replyToKey, sequence); } -void ManagementAgent::handlePackageIndLH (Buffer& inBuffer, string replyToKey, uint32_t sequence) +void ManagementAgent::handlePackageIndLH (Buffer& inBuffer, const string& replyToKey, uint32_t sequence) { string packageName; @@ -1245,7 +1250,7 @@ void ManagementAgent::handlePackageIndLH (Buffer& inBuffer, string replyToKey, u findOrAddPackageLH(packageName); } -void ManagementAgent::handleClassQueryLH(Buffer& inBuffer, string replyToKey, uint32_t sequence) +void ManagementAgent::handleClassQueryLH(Buffer& inBuffer, const string& replyToKey, uint32_t sequence) { string packageName; @@ -1279,7 +1284,7 @@ void ManagementAgent::handleClassQueryLH(Buffer& inBuffer, string replyToKey, ui sendCommandCompleteLH(replyToKey, sequence); } -void ManagementAgent::handleClassIndLH (Buffer& inBuffer, string replyToKey, uint32_t) +void ManagementAgent::handleClassIndLH (Buffer& inBuffer, const string& replyToKey, uint32_t) { string packageName; SchemaClassKey key; @@ -1323,14 +1328,14 @@ void ManagementAgent::SchemaClass::appendSchema(Buffer& buf) // is from a remote management agent, send the stored schema information. if (writeSchemaCall != 0) { - std::string schema; + string schema; writeSchemaCall(schema); buf.putRawData(schema); } else buf.putRawData(reinterpret_cast<uint8_t*>(&data[0]), data.size()); } -void ManagementAgent::handleSchemaRequestLH(Buffer& inBuffer, string replyToKey, uint32_t sequence) +void ManagementAgent::handleSchemaRequestLH(Buffer& inBuffer, const string& replyToKey, uint32_t sequence) { string packageName; SchemaClassKey key; @@ -1368,7 +1373,7 @@ void ManagementAgent::handleSchemaRequestLH(Buffer& inBuffer, string replyToKey, sendCommandCompleteLH(replyToKey, sequence, 1, "Package not found"); } -void ManagementAgent::handleSchemaResponseLH(Buffer& inBuffer, string /*replyToKey*/, uint32_t sequence) +void ManagementAgent::handleSchemaResponseLH(Buffer& inBuffer, const string& /*replyToKey*/, uint32_t sequence) { string packageName; SchemaClassKey key; @@ -1466,7 +1471,7 @@ void ManagementAgent::deleteOrphanedAgentsLH() deleteList.clear(); } -void ManagementAgent::handleAttachRequestLH (Buffer& inBuffer, string replyToKey, uint32_t sequence, const ConnectionToken* connToken) +void ManagementAgent::handleAttachRequestLH (Buffer& inBuffer, const string& replyToKey, uint32_t sequence, const ConnectionToken* connToken) { string label; uint32_t requestedBrokerBank, requestedAgentBank; @@ -1524,7 +1529,7 @@ void ManagementAgent::handleAttachRequestLH (Buffer& inBuffer, string replyToKey " to=" << replyToKey << " seq=" << sequence); } -void ManagementAgent::handleGetQueryLH (Buffer& inBuffer, string replyToKey, uint32_t sequence) +void ManagementAgent::handleGetQueryLH(Buffer& inBuffer, const string& replyToKey, uint32_t sequence) { FieldTable ft; FieldTable::ValuePtr value; @@ -1552,7 +1557,7 @@ void ManagementAgent::handleGetQueryLH (Buffer& inBuffer, string replyToKey, uin object->setUpdateTime(); if (!object->isDeleted()) { - std::string sBuf; + string sBuf; encodeHeader(outBuffer, 'g', sequence); object->writeProperties(sBuf); outBuffer.putRawData(sBuf); @@ -1583,7 +1588,7 @@ void ManagementAgent::handleGetQueryLH (Buffer& inBuffer, string replyToKey, uin object->setUpdateTime(); if (!object->isDeleted()) { - std::string sBuf; + string sBuf; encodeHeader(outBuffer, 'g', sequence); object->writeProperties(sBuf); outBuffer.putRawData(sBuf); @@ -1602,108 +1607,144 @@ void ManagementAgent::handleGetQueryLH (Buffer& inBuffer, string replyToKey, uin } -void ManagementAgent::handleGetQueryLH(const std::string& body, std::string replyTo, const std::string& cid, const std::string& contentType) +void ManagementAgent::handleGetQueryLH(const string& body, const string& replyTo, const string& cid, bool viaLocal) { - FieldTable ft; - FieldTable::ValuePtr value; - moveNewObjectsLH(); - if (contentType != "_query_v1") { - QPID_LOG(warning, "Support for QMF V2 Query format TBD!!!"); - return; - } - Variant::Map inMap; - MapCodec::decode(body, inMap); Variant::Map::const_iterator i; Variant::Map headers; + MapCodec::decode(body, inMap); QPID_LOG(trace, "RECV GetQuery (v2): map=" << inMap << " seq=" << cid); headers["method"] = "response"; headers["qmf.opcode"] = "_query_response"; headers["qmf.content"] = "_data"; - headers["qmf.agent"] = name_address; - headers["partial"]; + headers["qmf.agent"] = viaLocal ? "broker" : name_address; + headers["partial"] = Variant(); Variant::List list_; Variant::Map map_; Variant::Map values; - string className; + Variant::Map oidMap; string content; - i = inMap.find("_class"); - if (i != inMap.end()) - try { - className = i->second.asString(); - } catch(exception& /*e*/) { - className.clear(); - QPID_LOG(trace, "RCVD GetQuery: invalid format - class target ignored."); - } + /* + * Unpack the _what element of the query. Currently we only support OBJECT queries. + */ + i = inMap.find("_what"); + if (i == inMap.end()) { + sendExceptionLH(replyTo, cid, "_what element missing in Query"); + return; + } - if (className.empty()) { - ObjectId objId; - i = inMap.find("_object_id"); - if (i != inMap.end()) { + if (i->second.getType() != qpid::types::VAR_STRING) { + sendExceptionLH(replyTo, cid, "_what element is not a string"); + return; + } - try { - objId = ObjectId(i->second.asMap()); - } catch (exception & /*e*/) { - objId = ObjectId(); // empty object id - won't find a match (I hope). - QPID_LOG(trace, "RCVD GetQuery (invalid Object Id format) to=" << replyTo << " seq=" << cid); - } + if (i->second.asString() != "OBJECT") { + sendExceptionLH(replyTo, cid, "Query for _what => '" + i->second.asString() + "' not supported"); + return; + } - ManagementObjectMap::iterator iter = managementObjects.find(objId); - if (iter != managementObjects.end()) { - ManagementObject* object = iter->second; + string className; + string packageName; - if (object->getConfigChanged() || object->getInstChanged()) - object->setUpdateTime(); + /* + * Handle the _schema_id element, if supplied. + */ + i = inMap.find("_schema_id"); + if (i != inMap.end() && i->second.getType() == qpid::types::VAR_MAP) { + const Variant::Map& schemaIdMap(i->second.asMap()); - if (!object->isDeleted()) { - object->writeTimestamps(map_); - object->mapEncodeValues(values, true, true); // write both stats and properties - map_["_values"] = values; - list_.push_back(map_); + Variant::Map::const_iterator s_iter = schemaIdMap.find("_class_name"); + if (s_iter != schemaIdMap.end() && s_iter->second.getType() == qpid::types::VAR_STRING) + className = s_iter->second.asString(); - ListCodec::encode(list_, content); - sendBufferLH(content, cid, headers, "amqp/list", v2Direct, replyTo); - } + s_iter = schemaIdMap.find("_package_name"); + if (s_iter != schemaIdMap.end() && s_iter->second.getType() == qpid::types::VAR_STRING) + packageName = s_iter->second.asString(); + } + + + /* + * Unpack the _object_id element of the query if it is present. If it is present, find that one + * object and return it. If it is not present, send a class-based result. + */ + i = inMap.find("_object_id"); + if (i != inMap.end() && i->second.getType() == qpid::types::VAR_MAP) { + ObjectId objId(i->second.asMap()); + + ManagementObjectMap::iterator iter = managementObjects.find(objId); + if (iter != managementObjects.end()) { + ManagementObject* object = iter->second; + + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + + if (!object->isDeleted()) { + object->mapEncodeValues(values, true, true); // write both stats and properties + objId.mapEncode(oidMap); + map_["_values"] = values; + map_["_object_id"] = oidMap; + map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(), + object->getClassName(), + "_data", + object->getMd5Sum()); + list_.push_back(map_); } + + headers.erase("partial"); + ListCodec::encode(list_, content); + sendBufferLH(content, cid, headers, "amqp/list", v2Direct, replyTo); + QPID_LOG(trace, "SENT QueryResponse (query by object_id) to=" << replyTo); + return; } } else { for (ManagementObjectMap::iterator iter = managementObjects.begin(); iter != managementObjects.end(); iter++) { ManagementObject* object = iter->second; - if (object->getClassName () == className) { - - // @todo: support multiple objects per message reply - values.clear(); - list_.clear(); - if (object->getConfigChanged() || object->getInstChanged()) - object->setUpdateTime(); + if (object->getClassName() == className && + (packageName.empty() || object->getPackageName() == packageName)) { + // @todo support multiple object reply per message if (!object->isDeleted()) { + values.clear(); + list_.clear(); + oidMap.clear(); + + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + object->writeTimestamps(map_); object->mapEncodeValues(values, true, true); // write both stats and properties - map_["_values"] = values; - list_.push_back(map_); + iter->first.mapEncode(oidMap); + + map_["_values"] = values; + map_["_object_id"] = oidMap; + map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(), + object->getClassName(), + "_data", + object->getMd5Sum()); + list_.push_back(map_); + } ListCodec::encode(list_, content); sendBufferLH(content, cid, headers, "amqp/list", v2Direct, replyTo); - } + QPID_LOG(trace, "SENT QueryResponse (query by schema_id) to=" << replyTo); } } } - // end empty "non-partial" message to indicate CommandComplete + // Send empty "non-partial" message to indicate CommandComplete list_.clear(); headers.erase("partial"); ListCodec::encode(list_, content); sendBufferLH(content, cid, headers, "amqp/list", v2Direct, replyTo); - QPID_LOG(trace, "SEND GetResponse (v2) to=" << replyTo << " seq=" << cid); + QPID_LOG(trace, "SENT QueryResponse (empty with no 'partial' indicator) to=" << replyTo); } @@ -1742,7 +1783,7 @@ bool ManagementAgent::authorizeAgentMessageLH(Message& msg) string packageName; string className; string methodName; - std::string cid; + string cid; if (msg.encodedSize() > MA_BUFFER_SIZE) return false; @@ -1770,7 +1811,7 @@ bool ManagementAgent::authorizeAgentMessageLH(Message& msg) // extract object id and method name - std::string body; + string body; inBuffer.getRawData(body, bufferLen); Variant::Map inMap; MapCodec::decode(body, inMap); @@ -1852,24 +1893,13 @@ bool ManagementAgent::authorizeAgentMessageLH(Message& msg) if (p && p->hasReplyTo()) { const framing::ReplyTo& rt = p->getReplyTo(); string replyToKey = rt.getRoutingKey(); + string cid; + if (p && p->hasCorrelationId()) + cid = p->getCorrelationId(); if (mapMsg) { - Variant::Map _values; - Variant::Map outMap; - Variant::Map headers; - - headers["method"] = "response"; - headers["qmf.opcode"] = "_exception"; - headers["qmf.agent"] = name_address; - - _values["_status"] = Manageable::STATUS_FORBIDDEN; - _values["_status_text"] = Manageable::StatusText(Manageable::STATUS_FORBIDDEN); - outMap["_values"] = _values; - - string content; - MapCodec::encode(outMap, content); - sendBufferLH(content, cid, headers, "amqp/map", v2Direct, replyToKey); - + sendExceptionLH(replyToKey, cid, Manageable::StatusText(Manageable::STATUS_FORBIDDEN), + Manageable::STATUS_FORBIDDEN, false); } else { Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); @@ -1892,7 +1922,7 @@ bool ManagementAgent::authorizeAgentMessageLH(Message& msg) return true; } -void ManagementAgent::dispatchAgentCommandLH(Message& msg) +void ManagementAgent::dispatchAgentCommandLH(Message& msg, bool viaLocal) { string replyToKey; const framing::MessageProperties* p = @@ -1920,10 +1950,10 @@ void ManagementAgent::dispatchAgentCommandLH(Message& msg) const framing::FieldTable *headers = msg.getApplicationHeaders(); if (headers && msg.getAppId() == "qmf2") { - std::string opcode = headers->getAsString("qmf.opcode"); - std::string contentType = headers->getAsString("qmf.content"); - std::string body; - std::string cid; + string opcode = headers->getAsString("qmf.opcode"); + string contentType = headers->getAsString("qmf.content"); + string body; + string cid; inBuffer.getRawData(body, bufferLen); if (p && p->hasCorrelationId()) { @@ -1931,9 +1961,9 @@ void ManagementAgent::dispatchAgentCommandLH(Message& msg) } if (opcode == "_method_request") - return handleMethodRequestLH(body, replyToKey, cid, msg.getPublisher()); + return handleMethodRequestLH(body, replyToKey, cid, msg.getPublisher(), viaLocal); else if (opcode == "_query_request") - return handleGetQueryLH(body, replyToKey, cid, contentType); + return handleGetQueryLH(body, replyToKey, cid, viaLocal); else if (opcode == "_agent_locate_request") return handleLocateRequestLH(body, replyToKey, cid); @@ -2140,7 +2170,7 @@ ManagementObjectMap::iterator ManagementAgent::numericFind(const ObjectId& oid) return iter; } -void ManagementAgent::setAllocator(std::auto_ptr<IdAllocator> a) +void ManagementAgent::setAllocator(auto_ptr<IdAllocator> a) { sys::Mutex::ScopedLock lock (userLock); allocator = a; @@ -2153,8 +2183,8 @@ uint64_t ManagementAgent::allocateId(Manageable* object) return 0; } -void ManagementAgent::disallow(const std::string& className, const std::string& methodName, const std::string& message) { - disallowed[std::make_pair(className, methodName)] = message; +void ManagementAgent::disallow(const string& className, const string& methodName, const string& message) { + disallowed[make_pair(className, methodName)] = message; } void ManagementAgent::SchemaClassKey::mapEncode(Variant::Map& _map) const { @@ -2211,7 +2241,7 @@ void ManagementAgent::SchemaClass::mapDecode(const Variant::Map& _map) { } } -void ManagementAgent::exportSchemas(std::string& out) { +void ManagementAgent::exportSchemas(string& out) { Variant::List list_; Variant::Map map_, kmap, cmap; @@ -2318,7 +2348,7 @@ void ManagementAgent::RemoteAgent::mapDecode(const Variant::Map& map_) { mgmtObject->set_connectionRef(connectionRef); } -void ManagementAgent::exportAgents(std::string& out) { +void ManagementAgent::exportAgents(string& out) { Variant::List list_; Variant::Map map_, omap, amap; @@ -2348,7 +2378,7 @@ void ManagementAgent::importAgents(qpid::framing::Buffer& inBuf) { sys::Mutex::ScopedLock lock(userLock); for (l = content.begin(); l != content.end(); l++) { - std::auto_ptr<RemoteAgent> agent(new RemoteAgent(*this)); + auto_ptr<RemoteAgent> agent(new RemoteAgent(*this)); Variant::Map map_; Variant::Map::const_iterator i; @@ -2364,8 +2394,8 @@ void ManagementAgent::importAgents(qpid::framing::Buffer& inBuf) { } } -std::string ManagementAgent::debugSnapshot() { - std::ostringstream msg; +string ManagementAgent::debugSnapshot() { + ostringstream msg; msg << " management snapshot:"; for (RemoteAgentMap::const_iterator i=remoteAgents.begin(); i != remoteAgents.end(); ++i) @@ -2466,14 +2496,14 @@ boost::shared_ptr<FieldValue> ManagementAgent::toFieldValue(const Variant& in) // stolen from qpid/client/amqp0_10/Codecs.cpp - TODO: make Codecs public, and remove this dup. Variant ManagementAgent::toVariant(const boost::shared_ptr<FieldValue>& in) { - const std::string iso885915("iso-8859-15"); - const std::string utf8("utf8"); - const std::string utf16("utf16"); - //const std::string binary("binary"); - const std::string amqp0_10_binary("amqp0-10:binary"); - //const std::string amqp0_10_bit("amqp0-10:bit"); - const std::string amqp0_10_datetime("amqp0-10:datetime"); - const std::string amqp0_10_struct("amqp0-10:struct"); + const string iso885915("iso-8859-15"); + const string utf8("utf8"); + const string utf16("utf16"); + //const string binary("binary"); + const string amqp0_10_binary("amqp0-10:binary"); + //const string amqp0_10_bit("amqp0-10:bit"); + const string amqp0_10_datetime("amqp0-10:datetime"); + const string amqp0_10_struct("amqp0-10:struct"); Variant out; //based on AMQP 0-10 typecode, pick most appropriate variant type @@ -2522,30 +2552,30 @@ Variant ManagementAgent::toVariant(const boost::shared_ptr<FieldValue>& in) case 0x80: // str8 case 0x90: // str16 case 0xa0: // str32 - out = in->get<std::string>(); + out = in->get<string>(); out.setEncoding(amqp0_10_binary); break; case 0x84: // str8 case 0x94: // str16 - out = in->get<std::string>(); + out = in->get<string>(); out.setEncoding(iso885915); break; case 0x85: // str8 case 0x95: // str16 - out = in->get<std::string>(); + out = in->get<string>(); out.setEncoding(utf8); break; case 0x86: // str8 case 0x96: // str16 - out = in->get<std::string>(); + out = in->get<string>(); out.setEncoding(utf16); break; case 0xab: // str32 - out = in->get<std::string>(); + out = in->get<string>(); out.setEncoding(amqp0_10_struct); break; diff --git a/cpp/src/qpid/management/ManagementAgent.h b/cpp/src/qpid/management/ManagementAgent.h index ca3f742cb7..dd781c36d3 100644 --- a/cpp/src/qpid/management/ManagementAgent.h +++ b/cpp/src/qpid/management/ManagementAgent.h @@ -108,7 +108,8 @@ public: bool dispatchCommand (qpid::broker::Deliverable& msg, const std::string& routingKey, const framing::FieldTable* args, - const bool topic); + const bool topic, + int qmfVersion); const framing::Uuid& getUuid() const { return uuid; } @@ -118,6 +119,9 @@ public: /** Disallow a method. Attempts to call it will receive an exception with message. */ void disallow(const std::string& className, const std::string& methodName, const std::string& message); + /** Disallow all QMFv1 methods (used in clustered brokers). */ + void disallowV1Methods() { disallowAllV1Methods = true; } + /** Serialize my schemas as a binary blob into schemaOut */ void exportSchemas(std::string& schemaOut); @@ -281,6 +285,7 @@ private: typedef std::pair<std::string,std::string> MethodName; typedef std::map<MethodName, std::string> DisallowedMethods; DisallowedMethods disallowed; + bool disallowAllV1Methods; // Agent name and address qpid::types::Variant::Map attrMap; @@ -314,7 +319,7 @@ private: void moveNewObjectsLH(); bool authorizeAgentMessageLH(qpid::broker::Message& msg); - void dispatchAgentCommandLH(qpid::broker::Message& msg); + void dispatchAgentCommandLH(qpid::broker::Message& msg, bool viaLocal=false); PackageMap::iterator findOrAddPackageLH(std::string name); void addClassLH(uint8_t kind, @@ -331,20 +336,21 @@ private: uint32_t allocateNewBank (); uint32_t assignBankLH (uint32_t requestedPrefix); void deleteOrphanedAgentsLH(); - void sendCommandCompleteLH(std::string replyToKey, uint32_t sequence, - uint32_t code = 0, std::string text = std::string("OK")); - void handleBrokerRequestLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handlePackageQueryLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handlePackageIndLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleClassQueryLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleClassIndLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleSchemaRequestLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleSchemaResponseLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleAttachRequestLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence, const qpid::broker::ConnectionToken* connToken); - void handleGetQueryLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence); - void handleMethodRequestLH (framing::Buffer& inBuffer, std::string replyToKey, uint32_t sequence, const qpid::broker::ConnectionToken* connToken); - void handleGetQueryLH (const std::string& body, std::string replyToKey, const std::string& cid, const std::string& contentType); - void handleMethodRequestLH (const std::string& body, std::string replyToKey, const std::string& cid, const qpid::broker::ConnectionToken* connToken); + void sendCommandCompleteLH(const std::string& replyToKey, uint32_t sequence, + uint32_t code = 0, const std::string& text = "OK"); + void sendExceptionLH(const std::string& replyToKey, const std::string& cid, const std::string& text, uint32_t code=1, bool viaLocal=false); + void handleBrokerRequestLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handlePackageQueryLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handlePackageIndLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleClassQueryLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleClassIndLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleSchemaRequestLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleSchemaResponseLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleAttachRequestLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence, const qpid::broker::ConnectionToken* connToken); + void handleGetQueryLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence); + void handleMethodRequestLH (framing::Buffer& inBuffer, const std::string& replyToKey, uint32_t sequence, const qpid::broker::ConnectionToken* connToken); + void handleGetQueryLH (const std::string& body, const std::string& replyToKey, const std::string& cid, bool viaLocal); + void handleMethodRequestLH (const std::string& body, const std::string& replyToKey, const std::string& cid, const qpid::broker::ConnectionToken* connToken, bool viaLocal); void handleLocateRequestLH (const std::string& body, const std::string &replyToKey, const std::string& cid); diff --git a/cpp/src/qpid/management/ManagementDirectExchange.cpp b/cpp/src/qpid/management/ManagementDirectExchange.cpp index 6dc41ef073..1d5f8bbd6b 100644 --- a/cpp/src/qpid/management/ManagementDirectExchange.cpp +++ b/cpp/src/qpid/management/ManagementDirectExchange.cpp @@ -47,7 +47,7 @@ void ManagementDirectExchange::route(Deliverable& msg, bool routeIt = true; if (managementAgent) - routeIt = managementAgent->dispatchCommand(msg, routingKey, args, false /*direct*/); + routeIt = managementAgent->dispatchCommand(msg, routingKey, args, false, qmfVersion); if (routeIt) DirectExchange::route(msg, routingKey, args); diff --git a/cpp/src/qpid/management/ManagementObject.cpp b/cpp/src/qpid/management/ManagementObject.cpp index a29770f459..209c935947 100644 --- a/cpp/src/qpid/management/ManagementObject.cpp +++ b/cpp/src/qpid/management/ManagementObject.cpp @@ -236,7 +236,8 @@ std::ostream& operator<<(std::ostream& out, const ObjectId& i) "-" << ((virtFirst & 0x0FFF000000000000LL) >> 48) << "-" << ((virtFirst & 0x0000FFFFF0000000LL) >> 28) << "-" << i.agentName << - "-" << i.second; + "-" << i.second << + "(" << i.v2Key << ")"; return out; } diff --git a/cpp/src/qpid/management/ManagementTopicExchange.cpp b/cpp/src/qpid/management/ManagementTopicExchange.cpp index 7fdce133e5..ee8657646f 100644 --- a/cpp/src/qpid/management/ManagementTopicExchange.cpp +++ b/cpp/src/qpid/management/ManagementTopicExchange.cpp @@ -47,7 +47,7 @@ void ManagementTopicExchange::route(Deliverable& msg, // Intercept management agent commands if (managementAgent) - routeIt = managementAgent->dispatchCommand(msg, routingKey, args, true /* topic */); + routeIt = managementAgent->dispatchCommand(msg, routingKey, args, true, qmfVersion); if (routeIt) TopicExchange::route(msg, routingKey, args); diff --git a/cpp/src/qpid/types/Variant.cpp b/cpp/src/qpid/types/Variant.cpp index 2126c67fec..f22483fa65 100644 --- a/cpp/src/qpid/types/Variant.cpp +++ b/cpp/src/qpid/types/Variant.cpp @@ -217,17 +217,25 @@ uint8_t VariantImpl::asUint8() const switch(type) { case VAR_UINT8: return value.ui8; case VAR_STRING: return convertFromString<uint8_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT8))); + case VAR_INT64: + if (value.i64 >= 0 && value.i64 <= 0x00000000000000ff) + return uint8_t(value.i64); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT8))); } uint16_t VariantImpl::asUint16() const { switch(type) { case VAR_UINT8: return value.ui8; case VAR_UINT16: return value.ui16; + case VAR_INT64: + if (value.i64 >= 0 && value.i64 <= 0x000000000000ffff) + return uint16_t(value.i64); case VAR_STRING: return convertFromString<uint16_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT16))); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT16))); } uint32_t VariantImpl::asUint32() const { @@ -235,9 +243,13 @@ uint32_t VariantImpl::asUint32() const case VAR_UINT8: return value.ui8; case VAR_UINT16: return value.ui16; case VAR_UINT32: return value.ui32; + case VAR_INT64: + if (value.i64 >= 0 && value.i64 <= 0x00000000ffffffff) + return uint32_t(value.i64); case VAR_STRING: return convertFromString<uint32_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT32))); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_UINT32))); } uint64_t VariantImpl::asUint64() const { @@ -254,18 +266,26 @@ int8_t VariantImpl::asInt8() const { switch(type) { case VAR_INT8: return value.i8; + case VAR_INT64: + if (value.i64 <= 0x000000000000007f) + return int8_t(value.i64); case VAR_STRING: return convertFromString<int8_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT8))); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT8))); } int16_t VariantImpl::asInt16() const { switch(type) { case VAR_INT8: return value.i8; case VAR_INT16: return value.i16; + case VAR_INT64: + if (value.i64 <= 0x0000000000007fff) + return int16_t(value.i64); case VAR_STRING: return convertFromString<int16_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT16))); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT16))); } int32_t VariantImpl::asInt32() const { @@ -273,9 +293,13 @@ int32_t VariantImpl::asInt32() const case VAR_INT8: return value.i8; case VAR_INT16: return value.i16; case VAR_INT32: return value.i32; + case VAR_INT64: + if (value.i64 <= 0x000000007fffffff) + return int32_t(value.i64); case VAR_STRING: return convertFromString<int32_t>(); - default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT32))); + default: break; } + throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(VAR_INT32))); } int64_t VariantImpl::asInt64() const { diff --git a/cpp/src/tests/ManagementTest.cpp b/cpp/src/tests/ManagementTest.cpp index 99b9c1f03e..e9b8ac32b9 100644 --- a/cpp/src/tests/ManagementTest.cpp +++ b/cpp/src/tests/ManagementTest.cpp @@ -33,7 +33,7 @@ using namespace qpid::framing; using namespace qpid::management; QPID_AUTO_TEST_CASE(testObjectIdSerializeStream) { - std::string text("0-10-4-2500-80000000000"); + std::string text("0-10-4-2500-80000000000()"); std::stringstream input(text); ObjectId oid(input); @@ -45,7 +45,7 @@ QPID_AUTO_TEST_CASE(testObjectIdSerializeStream) { } QPID_AUTO_TEST_CASE(testObjectIdSerializeString) { - std::string text("0-10-4-2500-80000000000"); + std::string text("0-10-4-2500-80000000000()"); ObjectId oid(text); @@ -65,7 +65,7 @@ QPID_AUTO_TEST_CASE(testObjectIdEncode) { std::stringstream out1; out1 << oid; - BOOST_CHECK_EQUAL(out1.str(), "1-2-3-myAgent-9999"); + BOOST_CHECK_EQUAL(out1.str(), "1-2-3-myAgent-9999(testkey)"); } QPID_AUTO_TEST_CASE(testObjectIdAttach) { @@ -77,13 +77,13 @@ QPID_AUTO_TEST_CASE(testObjectIdAttach) { std::stringstream out1; out1 << oid; - BOOST_CHECK_EQUAL(out1.str(), "10-20-0-MrSmith-0"); + BOOST_CHECK_EQUAL(out1.str(), "10-20-0-MrSmith-0(GabbaGabbaHey)"); agent.setBanks(30, 40); std::stringstream out2; out2 << oid; - BOOST_CHECK_EQUAL(out2.str(), "10-20-30-MrSmith-0"); + BOOST_CHECK_EQUAL(out2.str(), "10-20-30-MrSmith-0(GabbaGabbaHey)"); } QPID_AUTO_TEST_CASE(testConsoleObjectId) { |