void ManagementAgent::handleGetQuery()

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(), &params)) {
                    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 */, &params)) {
            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);
}