Search in sources :

Example 11 with Console

use of org.apache.qpid.qmf2.console.Console 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)

Example 12 with Console

use of org.apache.qpid.qmf2.console.Console in project qpid by apache.

the class Agent method raiseException.

/**
     * Send an exception back to the Console.
     * @param handle the reply handle that contains the replyTo Address.
     * @param message the exception message.
     */
public final void raiseException(final Handle handle, final String message) {
    try {
        MapMessage response = _syncSession.createMapMessage();
        response.setJMSCorrelationID(handle.getCorrelationId());
        response.setStringProperty("x-amqp-0-10.app-id", "qmf2");
        response.setStringProperty("method", "response");
        response.setStringProperty("qmf.opcode", "_exception");
        response.setStringProperty("qmf.agent", _name);
        response.setStringProperty("qpid.subject", handle.getRoutingKey());
        QmfData exception = new QmfData();
        exception.setValue("error_text", message);
        response.setObject("_values", exception.mapEncode());
        sendResponse(handle, response);
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in handleLocateRequest()", jmse.getMessage());
    }
}
Also used : QmfData(org.apache.qpid.qmf2.common.QmfData) MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException)

Example 13 with Console

use of org.apache.qpid.qmf2.console.Console in project qpid by apache.

the class ConnectionProxy method createConnection.

/**
     * Actually create the Qpid Connection and QMF2 Console specified in the Constructor.
     */
private synchronized void createConnection() {
    //System.out.println("ConnectionProxy createConnection() name: " + _name + ", thread: " + Thread.currentThread().getId() + ", creating connection to " + _url + ", options " + _connectionOptions);
    try {
        _connection = ConnectionHelper.createConnection(_url, _connectionOptions);
        if (_connection != null) {
            _connection.setExceptionListener(this);
            // front of the WorkQueue if it exceeds a particular size.
            if (_disableEvents) {
                _console = new Console(_name, null, null, null);
                _console.disableEvents();
            } else {
                BlockingNotifier notifier = new BlockingNotifier();
                _console = new Console(_name, null, notifier, null);
            }
            _console.addConnection(_connection);
            _connected = true;
            _expireCount = UNUSED_THRESHOLD;
            notifyAll();
        }
    } catch (Exception ex) {
        _log.info("Exception {} caught in ConnectionProxy constructor.", ex.getMessage());
        _connected = false;
    }
}
Also used : BlockingNotifier(org.apache.qpid.qmf2.common.BlockingNotifier) Console(org.apache.qpid.qmf2.console.Console) QmfException(org.apache.qpid.qmf2.common.QmfException) JMSException(javax.jms.JMSException)

Example 14 with Console

use of org.apache.qpid.qmf2.console.Console in project qpid by apache.

the class Console method removeConnection.

/**
     * Remove the AMQP connection from the console. Un-does the addConnection() operation, and releases
     * any Agents associated with the connection. All blocking methods are unblocked and given a failure
     * status. All outstanding asynchronous operations are cancelled without producing WorkItems.
     *
     * @param conn a javax.jms.Connection
     */
public void removeConnection(final Connection conn) throws QmfException {
    if (conn != _connection) {
        throw new QmfException("Attempt to delete unknown connection");
    }
    try {
        _timer.cancel();
        // Should we close() the connection here or just stop() it ???
        _connection.close();
    } catch (JMSException jmse) {
        throw new QmfException("Failed to remove connection, caught JMSException " + jmse.getMessage());
    }
    _connection = null;
}
Also used : JMSException(javax.jms.JMSException) QmfException(org.apache.qpid.qmf2.common.QmfException)

Example 15 with Console

use of org.apache.qpid.qmf2.console.Console in project qpid by apache.

the class Console method refreshSubscription.

/**
     * Renews a subscription identified by SubscriptionId.
     * <p>
     * The Console may request a new subscription duration by providing a requested lifetime. This method may be called 
     * asynchronously by providing a replyHandle argument.
     * <p>
     * When called asynchronously, the result of this method call is returned in a SUBSCRIBE_RESPONSE WorkItem.
     * <p>
     * Timeout can be used to override the console's default reply timeout.
     * <p>  
     * When called synchronously, this method returns a class SubscribeParams object containing the result of the       
     * subscription request.
     *
     * @param subscriptionId the ID of the subscription to be refreshed
     * @param options a String representation of a Map containing the options in the form
     *        <pre>"{lifetime:&lt;value&gt;, replyHandle:&lt;value&gt;, timeout:&lt;value&gt;}"</pre>
     *        they are optional and may appear in any order.
     * <pre>
     *        <b>lifetime</b> requests a new subscription duration.
     *        <b>replyHandle</b> the correlation handle used to tie asynchronous method requests with responses.
     *        <b>timeout</b> the time to wait for a reply from the Agent.
     * </pre>
     */
public SubscribeParams refreshSubscription(String subscriptionId, final String options) throws QmfException {
    if (subscriptionId == null) {
        throw new QmfException("Called refreshSubscription() with null subscriptionId");
    }
    SubscriptionManager subscription = _subscriptionById.get(subscriptionId);
    if (subscription == null) {
        throw new QmfException("Called refreshSubscription() with invalid subscriptionId");
    }
    String consoleHandle = subscription.getConsoleHandle();
    Agent agent = subscription.getAgent();
    if (!agent.isActive()) {
        throw new QmfException("Called refreshSubscription() with inactive agent");
    }
    String agentName = agent.getName();
    // Initialise optional values to defaults;
    long lifetime = 0;
    long timeout = _replyTimeout;
    String replyHandle = null;
    if (options != null) {
        // We wrap the Map in a QmfData object to avoid potential class cast issues with the parsed options
        QmfData optMap = new QmfData(new AddressParser(options).map());
        if (optMap.hasValue("lifetime")) {
            lifetime = optMap.getLongValue("lifetime");
        }
        if (optMap.hasValue("timeout")) {
            timeout = optMap.getLongValue("timeout");
        }
        if (optMap.hasValue("replyHandle")) {
            replyHandle = optMap.getStringValue("replyHandle");
        }
    }
    try {
        Destination destination = (replyHandle == null) ? _replyAddress : _asyncReplyAddress;
        MapMessage request = _syncSession.createMapMessage();
        request.setJMSReplyTo(destination);
        request.setJMSCorrelationID(replyHandle);
        request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
        request.setStringProperty("method", "request");
        request.setStringProperty("qmf.opcode", "_subscribe_refresh_indication");
        request.setStringProperty("qpid.subject", agentName);
        request.setObject("_subscription_id", subscriptionId);
        if (lifetime > 0) {
            request.setObject("_duration", lifetime);
        }
        // it would be somewhat unfortunate if their response got interleaved with ours!!
        synchronized (this) {
            if (_subscriptionEmulationEnabled && agentName.equals(_brokerAgentName)) {
                // If the Agent is the broker Agent we emulate the Subscription on the Console
                subscription.refresh();
                final SubscribeParams params = new SubscribeParams(consoleHandle, subscription.mapEncode());
                if (replyHandle == null) {
                    return params;
                } else {
                    final String handle = replyHandle;
                    Thread thread = new Thread() {

                        public void run() {
                            _eventListener.onEvent(new SubscribeResponseWorkItem(new Handle(handle), params));
                        }
                    };
                    thread.start();
                }
                return null;
            }
            _requester.send(request);
            if (replyHandle == null) {
                // If this is an synchronous request get the response
                Message response = _responder.receive(timeout * 1000);
                if (response == null) {
                    subscription.cancel();
                    _log.info("No response received in refreshSubscription()");
                    throw new QmfException("No response received for Console.refreshSubscription()");
                }
                SubscribeParams result = new SubscribeParams(consoleHandle, AMQPMessage.getMap(response));
                subscriptionId = result.getSubscriptionId();
                if (subscriptionId == null) {
                    subscription.cancel();
                } else {
                    subscription.setDuration(result.getLifetime());
                    subscription.refresh();
                }
                return result;
            }
        }
        // If this is an asynchronous request return without waiting for a response
        return null;
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in refreshSubscription()", jmse.getMessage());
        throw new QmfException(jmse.getMessage());
    }
}
Also used : Destination(javax.jms.Destination) QmfData(org.apache.qpid.qmf2.common.QmfData) AddressParser(org.apache.qpid.messaging.util.AddressParser) AMQPMessage(org.apache.qpid.qmf2.common.AMQPMessage) MapMessage(javax.jms.MapMessage) Message(javax.jms.Message) MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException) Handle(org.apache.qpid.qmf2.common.Handle) QmfException(org.apache.qpid.qmf2.common.QmfException)

Aggregations

JMSException (javax.jms.JMSException)11 QmfException (org.apache.qpid.qmf2.common.QmfException)8 MapMessage (javax.jms.MapMessage)6 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 QmfData (org.apache.qpid.qmf2.common.QmfData)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Message (javax.jms.Message)4 AMQPMessage (org.apache.qpid.qmf2.common.AMQPMessage)4 Handle (org.apache.qpid.qmf2.common.Handle)4 List (java.util.List)3 Destination (javax.jms.Destination)3 ObjectId (org.apache.qpid.qmf2.common.ObjectId)3 Console (org.apache.qpid.qmf2.console.Console)3 ArrayList (java.util.ArrayList)2 AddressParser (org.apache.qpid.messaging.util.AddressParser)2 QmfEvent (org.apache.qpid.qmf2.common.QmfEvent)2 QmfQuery (org.apache.qpid.qmf2.common.QmfQuery)2 SchemaClassId (org.apache.qpid.qmf2.common.SchemaClassId)2 Agent (org.apache.qpid.qmf2.console.Agent)2