Search in sources :

Example 1 with QmfQueryTarget

use of org.apache.qpid.qmf2.common.QmfQueryTarget in project qpid by apache.

the class Agent method handleQueryRequest.

/**
 * Handle the query request and send the response back to the Console.
 * @param handle the reply handle that contains the replyTo Address.
 * @param query the inbound query from the Console.
 */
@SuppressWarnings("unchecked")
private final void handleQueryRequest(final Handle handle, final QmfQuery query) {
    QmfQueryTarget target = query.getTarget();
    if (target == QmfQueryTarget.SCHEMA_ID) {
        List<Map> results = new ArrayList<Map>(_schemaCache.size());
        // Look up all SchemaClassId objects
        for (SchemaClassId classId : _schemaCache.keySet()) {
            results.add(classId.mapEncode());
        }
        // Send the response back to the Console.
        queryResponse(handle, results, "_schema_id");
    } else if (target == QmfQueryTarget.SCHEMA) {
        List<Map> results = new ArrayList<Map>(1);
        // Look up a SchemaClass object by the SchemaClassId obtained from the query
        SchemaClassId classId = query.getSchemaClassId();
        SchemaClass schema = _schemaCache.get(classId);
        if (schema != null) {
            results.add(schema.mapEncode());
        }
        // Send the response back to the Console.
        queryResponse(handle, results, "_schema");
    } else if (target == QmfQueryTarget.OBJECT_ID) {
        List<Map> results = new ArrayList<Map>(_objectIndex.size());
        // Look up all ObjectId objects
        for (ObjectId objectId : _objectIndex.keySet()) {
            results.add(objectId.mapEncode());
        }
        // Send the response back to the Console.
        queryResponse(handle, results, "_object_id");
    } else if (target == QmfQueryTarget.OBJECT) {
        // If this is implementing the AgentExternal model we pass the QmfQuery on in a QueryWorkItem
        if (this instanceof AgentExternal) {
            _eventListener.onEvent(new QueryWorkItem(handle, query));
            return;
        } else {
            // qmfContentType = "_data";
            if (query.getObjectId() != null) {
                List<Map> results = new ArrayList<Map>(1);
                // Look up a QmfAgentData object by the ObjectId obtained from the query
                ObjectId objectId = query.getObjectId();
                QmfAgentData object = _objectIndex.get(objectId);
                if (object != null && !object.isDeleted()) {
                    results.add(object.mapEncode());
                }
                // Send the response back to the Console.
                queryResponse(handle, results, "_data");
            } else {
                // Look up QmfAgentData objects by the SchemaClassId obtained from the query
                // This is implemented by a linear search and allows searches with only the className specified.
                // Linear searches clearly don't scale brilliantly, but the number of QmfAgentData objects managed
                // by an Agent is generally fairly small, so it should be OK. Note that this is the same approach
                // taken by the C++ broker ManagementAgent, so if it's a problem here........
                // N.B. the results list declared here is a generic List of Objects. We *must* only pass a List of
                // Map to queryResponse(), but conversely if the response items are sortable we need to sort them
                // before doing mapEncode(). Unfortunately we don't know if the items are sortable a priori so
                // we either add a Map or we add a QmfAgentData, then sort then mapEncode() each item. I'm not
                // sure of a more elegant way to do this without creating two lists, which might not be so bad
                // but we don't know the size of the list a priori either.
                List results = new ArrayList(_objectIndex.size());
                // It's unlikely that evaluating this query will return a mixture of sortable and notSortable
                // QmfAgentData objects, but it's best to check if that has occurred as accidentally passing a
                // List of QmfAgentData instead of a List of Map to queryResponse() will break things.
                boolean sortable = false;
                boolean notSortable = false;
                for (QmfAgentData object : _objectIndex.values()) {
                    if (!object.isDeleted() && query.evaluate(object)) {
                        if (object.isSortable()) {
                            // If QmfAgentData is marked sortable we add the QmfAgentData object to the List
                            // so we can sort first before mapEncoding.
                            results.add(object);
                            sortable = true;
                        } else {
                            // If QmfAgentData is not marked sortable we mapEncode immediately and add the Map to List.
                            results.add(object.mapEncode());
                            notSortable = true;
                        }
                    }
                }
                // results List to avoid sending unconvertable data. Hopefully this condition should never occur.
                if (sortable && notSortable) {
                    _log.info("Query resulted in inconsistent mixture of sortable and non-sortable data.");
                    results.clear();
                } else if (sortable) {
                    Collections.sort(results);
                    int length = results.size();
                    for (int i = 0; i < length; i++) {
                        QmfAgentData object = (QmfAgentData) results.get(i);
                        results.set(i, object.mapEncode());
                    }
                }
                // Send the response back to the Console.
                queryResponse(handle, results, "_data");
            }
        }
    } else {
        raiseException(handle, "Query for _what => '" + target + "' not supported");
        return;
    }
}
Also used : ObjectId(org.apache.qpid.qmf2.common.ObjectId) ArrayList(java.util.ArrayList) QmfQueryTarget(org.apache.qpid.qmf2.common.QmfQueryTarget) SchemaClassId(org.apache.qpid.qmf2.common.SchemaClassId) SchemaClass(org.apache.qpid.qmf2.common.SchemaClass) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ObjectId (org.apache.qpid.qmf2.common.ObjectId)1 QmfQueryTarget (org.apache.qpid.qmf2.common.QmfQueryTarget)1 SchemaClass (org.apache.qpid.qmf2.common.SchemaClass)1 SchemaClassId (org.apache.qpid.qmf2.common.SchemaClassId)1