in src/qpid/management/ManagementAgent.cpp [1354:1466]
void ManagementAgent::handleMethodRequest (const string& body, const string& rte, const string& rtk,
const string& cid, const string& userId, bool viaLocal)
{
moveNewObjects();
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"] = viaLocal ? "broker" : name_address;
if ((oid = inMap.find("_object_id")) == inMap.end() ||
(mid = inMap.find("_method_name")) == inMap.end()) {
sendException(rte, rtk, 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.
objId = ObjectId(oid->second.asMap());
methodName = mid->second.getString();
mid = inMap.find("_arguments");
if (mid != inMap.end()) {
inArgs = (mid->second).asMap();
}
} catch(exception& e) {
sendException(rte, rtk, cid, e.what(), Manageable::STATUS_EXCEPTION, viaLocal);
return;
}
ManagementObject::shared_ptr object;
{
sys::Mutex::ScopedLock lock(objectLock);
ManagementObjectMap::iterator iter = managementObjects.find(objId);
if (iter != managementObjects.end())
object = iter->second;
}
if (!object || object->isDeleted()) {
stringstream estr;
estr << "No object found with ID=" << objId;
sendException(rte, rtk, cid, estr.str(), 1, viaLocal);
return;
}
// validate
AclModule* acl = broker->getAcl();
DisallowedMethods::const_iterator i;
i = disallowed.find(make_pair(object->getClassName(), methodName));
if (i != disallowed.end()) {
sendException(rte, rtk, cid, i->second, Manageable::STATUS_FORBIDDEN, viaLocal);
return;
}
if (acl != 0) {
map<acl::Property, string> params;
params[acl::PROP_SCHEMAPACKAGE] = object->getPackageName();
params[acl::PROP_SCHEMACLASS] = object->getClassName();
if (!acl->authorise(userId, acl::ACT_ACCESS, acl::OBJ_METHOD, methodName, ¶ms)) {
sendException(rte, rtk, cid, Manageable::StatusText(Manageable::STATUS_FORBIDDEN),
Manageable::STATUS_FORBIDDEN, viaLocal);
return;
}
}
// invoke the method
QPID_LOG(debug, "RECV MethodRequest (v2) class=" << object->getPackageName()
<< ":" << object->getClassName() << " method=" <<
methodName << " replyTo=" << rte << "/" << rtk << " objId=" << objId << " inArgs=" << inArgs);
try {
object->doMethod(methodName, inArgs, callMap, userId);
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) {
sendException(rte, rtk, cid, e.what(), Manageable::STATUS_EXCEPTION, viaLocal);
return;
}
if (errorCode != 0) {
sendException(rte, rtk, cid, error, errorCode, viaLocal);
return;
}
MapCodec::encode(outMap, content);
sendBuffer(content, cid, headers, "amqp/map", rte, rtk);
QPID_LOG(debug, "SEND MethodResponse (v2) to=" << rte << "/" << rtk << " seq=" << cid << " map=" << outMap);
}