in src/qpid/management/ManagementAgent.cpp [1790:1917]
void ManagementAgent::handleGetQuery(Buffer& inBuffer, const string& replyToKey, uint32_t sequence, const string& userId)
{
FieldTable ft;
FieldTable::ValuePtr value;
AclModule* acl = broker->getAcl();
moveNewObjects();
ft.decode(inBuffer);
QPID_LOG(debug, "RECV GetQuery (v1) query=" << ft << " seq=" << sequence);
value = ft.get("_class");
if (value.get() == 0 || !value->convertsTo<string>()) {
value = ft.get("_objectid");
if (value.get() == 0 || !value->convertsTo<string>())
return;
ObjectId selector(value->get<string>());
ManagementObject::shared_ptr object;
{
sys::Mutex::ScopedLock lock(objectLock);
ManagementObjectMap::iterator iter = numericFind(selector);
if (iter != managementObjects.end())
object = iter->second;
}
if (object) {
ResizableBuffer outBuffer (qmfV1BufferSize);
if (acl != 0) {
map<acl::Property, string> params;
params[acl::PROP_SCHEMACLASS] = object->getClassName();
if (!acl->authorise(userId, acl::ACT_ACCESS, acl::OBJ_QUERY, object->getObjectId().getV2Key(), ¶ms)) {
throw framing::UnauthorizedAccessException(QPID_MSG("unauthorized-access: ACL denied QMF query of object " << object->getObjectId().getV2Key() << " from " << userId));
}
}
if (object->getConfigChanged() || object->getInstChanged())
object->setUpdateTime();
if (!object->isDeleted()) {
string sBuf;
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(sBuf);
outBuffer.putRawData(sBuf);
sBuf.clear();
object->writeStatistics(sBuf, true);
outBuffer.putRawData(sBuf);
sendBuffer(outBuffer, dExchange, replyToKey);
QPID_LOG(debug, "SEND GetResponse (v1) to=" << replyToKey << " seq=" << sequence);
}
}
sendCommandComplete(replyToKey, sequence);
return;
}
string className (value->get<string>());
std::list<ManagementObject::shared_ptr> matches;
if (acl != 0) {
map<acl::Property, string> params;
params[acl::PROP_SCHEMACLASS] = className;
if (!acl->authorise(userId, acl::ACT_ACCESS, acl::OBJ_QUERY, className /* class-wide query */, ¶ms)) {
throw framing::UnauthorizedAccessException(QPID_MSG("unauthorized-access: ACL denied QMF query of object class " << className << " from " << userId));
}
}
if (className == "memory")
qpid::sys::MemStat::loadMemInfo(memstat.get());
if (className == "broker") {
uint64_t uptime = sys::Duration(startTime, sys::now());
boost::dynamic_pointer_cast<_qmf::Broker>(broker->GetManagementObject())->set_uptime(uptime);
}
// build up a set of all objects to be dumped
{
sys::Mutex::ScopedLock lock(objectLock);
for (ManagementObjectMap::iterator iter = managementObjects.begin();
iter != managementObjects.end();
iter++) {
ManagementObject::shared_ptr object = iter->second;
if (object->getClassName () == className) {
matches.push_back(object);
}
}
}
// send them
ResizableBuffer outBuffer (qmfV1BufferSize);
while (matches.size()) {
ManagementObject::shared_ptr object = matches.front();
if (object->getConfigChanged() || object->getInstChanged())
object->setUpdateTime();
if (!object->isDeleted()) {
string sProps, sStats;
object->writeProperties(sProps);
object->writeStatistics(sStats, true);
size_t len = 8 + sProps.length() + sStats.length(); // 8 == size of header in bytes.
if (len > qmfV1BufferSize) {
QPID_LOG(error, "Object " << object->getObjectId() << " too large for output buffer - discarded!");
} else {
if (outBuffer.available() < len) { // not enough room in current buffer, send it.
sendBuffer(outBuffer, dExchange, replyToKey);
QPID_LOG(debug, "SEND GetResponse (v1) to=" << replyToKey << " seq=" << sequence);
continue; // lock dropped, need to re-find _SAME_ objid as it may have been deleted.
}
encodeHeader(outBuffer, 'g', sequence);
outBuffer.putRawData(sProps);
outBuffer.putRawData(sStats);
}
}
matches.pop_front();
}
if (outBuffer.getPosition() > 0) {
sendBuffer(outBuffer, dExchange, replyToKey);
QPID_LOG(debug, "SEND GetResponse (v1) to=" << replyToKey << " seq=" << sequence);
}
sendCommandComplete(replyToKey, sequence);
}