Search in sources :

Example 1 with MapMessage

use of javax.jms.MapMessage in project qpid by apache.

the class Agent method handleLocateRequest.

/**
     * Send an _agent_locate_response back to the Console that requested the locate.
     * @param handle the reply handle that contains the replyTo Address.
     */
private final void handleLocateRequest(final Handle handle) {
    try {
        MapMessage response = _syncSession.createMapMessage();
        response.setStringProperty("x-amqp-0-10.app-id", "qmf2");
        response.setStringProperty("method", "indication");
        response.setStringProperty("qmf.opcode", "_agent_locate_response");
        response.setStringProperty("qmf.agent", _name);
        response.setStringProperty("qpid.subject", handle.getRoutingKey());
        setValue("_timestamp", System.currentTimeMillis() * 1000000l);
        response.setObject("_values", mapEncode());
        sendResponse(handle, response);
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in handleLocateRequest()", jmse.getMessage());
    }
}
Also used : MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException)

Example 2 with MapMessage

use of javax.jms.MapMessage in project qpid by apache.

the class Agent method methodResponse.

/**
     * Indicate to the Agent that the application has completed processing a method request.
     * <p>
     * See the description of the METHOD_CALL WorkItem.
     * @param methodName the method's name.
     * @param handle the reply handle from WorkItem.
     * @param outArgs the output argument map.
     * @param error the error object that was created if the method failed in any way, otherwise null.
     */
public final void methodResponse(final String methodName, final Handle handle, final QmfData outArgs, final QmfData error) {
    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", "_method_response");
        response.setStringProperty("qmf.agent", _name);
        response.setStringProperty("qpid.subject", handle.getRoutingKey());
        if (error == null) {
            if (outArgs != null) {
                response.setObject("_arguments", outArgs.mapEncode());
                if (outArgs.getSubtypes() != null) {
                    response.setObject("_subtypes", outArgs.getSubtypes());
                }
            }
        } else {
            Map<String, Object> errorMap = error.mapEncode();
            for (Map.Entry<String, Object> entry : errorMap.entrySet()) {
                response.setObject(entry.getKey(), entry.getValue());
            }
        }
        sendResponse(handle, response);
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in methodResponse()", jmse.getMessage());
    }
}
Also used : MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 3 with MapMessage

use of javax.jms.MapMessage in project qpid by apache.

the class AMQPMessage method getList.

/**
     * JMS QMF returns amqp/list types as a BytesMessage this method decodes that into a java.util.List
     * <p>
     * Taken from Gordon Sim's initial JMS QMF Example using the BBDecoder
     * <p>
     * Trivia: This block of code from Gordon Sim is the seed that spawned the whole of this Java QMF2 API
     * implementation - cheers Gordon.
     *
     * @param message amqp/list encoded JMS Message
     * @return a java.util.List decoded from Message
     */
@SuppressWarnings("unchecked")
public static <T> List<T> getList(final Message message) throws JMSException {
    if (message == null) {
        throw new MessageFormatException("Attempting to do AMQPMessage.getList() on null Message");
    } else if (message instanceof BytesMessage) {
        BytesMessage msg = (BytesMessage) message;
        //only handles responses up to 2^31-1 bytes long
        byte[] data = new byte[(int) msg.getBodyLength()];
        msg.readBytes(data);
        BBDecoder decoder = new BBDecoder();
        decoder.init(ByteBuffer.wrap(data));
        return (List<T>) decoder.readList();
    } else if (message instanceof MapMessage) {
        /*
             * In Qpid version 0.20 instead of exposing amqp/list as a BytesMessage as above rather it is exposed
             * as a MapMessage!!??? the Object Keys are the indices into the List. We create a java.util.List
             * out of this by iterating through the getMapNames() Enumeration and copying the Objects into the List.
             * This amount of copying doesn't feel healthy and we can't even work out the capacity for the List
             * a priori, but I'm not sure of a better way at present. I can't say I much like how amqp/list or indeed
             * amqp/map are currently encoded. I'd *much* prefer to see them exposed as JMS ObjectMessage.
             */
        MapMessage msg = (MapMessage) message;
        // Initial capacity of 50, can we better estimate this?
        List resultList = new ArrayList(50);
        for (Enumeration e = msg.getMapNames(); e.hasMoreElements(); ) {
            String key = (String) e.nextElement();
            resultList.add(msg.getObject(key));
        }
        return resultList;
    } else {
        return null;
    }
}
Also used : MessageFormatException(javax.jms.MessageFormatException) Enumeration(java.util.Enumeration) MapMessage(javax.jms.MapMessage) ArrayList(java.util.ArrayList) BytesMessage(javax.jms.BytesMessage) ArrayList(java.util.ArrayList) List(java.util.List) BBDecoder(org.apache.qpid.transport.codec.BBDecoder)

Example 4 with MapMessage

use of javax.jms.MapMessage in project qpid by apache.

the class Console method invokeMethod.

/**
     * Invoke the named method on the named Agent.
     * <p>
     * Intended to by called by the AgentProxy. Shouldn't generally be called directly by Console applications.
     *
     * @param agent the Agent to invoke the method on.
     * @param content an unordered set of key/value pairs comprising the method arguments.
     * @param replyHandle the correlation handle used to tie asynchronous method requests with responses
     * @param timeout the time to wait for a reply from the Agent, a value of -1 means use the default timeout
     * @return the method response Arguments in Map form
     */
public MethodResult invokeMethod(final Agent agent, final Map<String, Object> content, final String replyHandle, int timeout) throws QmfException {
    if (!agent.isActive()) {
        throw new QmfException("Called invokeMethod() with inactive agent");
    }
    String agentName = agent.getName();
    timeout = (timeout < 1) ? _replyTimeout : timeout;
    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", "_method_request");
        request.setStringProperty("qpid.subject", agentName);
        for (Map.Entry<String, Object> entry : content.entrySet()) {
            request.setObject(entry.getKey(), entry.getValue());
        }
        // it would be somewhat unfortunate if their response got interleaved with ours!!
        synchronized (this) {
            _requester.send(request);
            if (replyHandle == null) {
                // If this is a synchronous request get the response
                Message response = _responder.receive(timeout * 1000);
                if (response == null) {
                    _log.info("No response received in invokeMethod()");
                    throw new QmfException("No response received for Console.invokeMethod()");
                }
                MethodResult result = new MethodResult(AMQPMessage.getMap(response));
                QmfException exception = result.getQmfException();
                if (exception != null) {
                    throw exception;
                }
                return result;
            }
        }
        // If this is an asynchronous request return without waiting for a response
        return null;
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in invokeMethod()", jmse.getMessage());
        throw new QmfException(jmse.getMessage());
    }
}
Also used : Destination(javax.jms.Destination) AMQPMessage(org.apache.qpid.qmf2.common.AMQPMessage) MapMessage(javax.jms.MapMessage) Message(javax.jms.Message) MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) QmfException(org.apache.qpid.qmf2.common.QmfException)

Example 5 with MapMessage

use of javax.jms.MapMessage in project qpid by apache.

the class Console method createSubscription.

/**
     * Creates a subscription to the agent using the given Query.
     * <p>
     * The consoleHandle is an application-provided handle that will accompany each subscription update sent from
     * the Agent. Subscription updates will appear as SUBSCRIPTION_INDICATION WorkItems on the Console's work queue.
     * <p>
     * The publishInterval is the requested time interval in seconds on which the Agent should publish updates.
     * <p>
     * The lifetime parameter is the requested time interval in seconds for which this subscription should remain in
     * effect. Both the requested lifetime and publishInterval may be overridden by the Agent, as indicated in the 
     * subscription response.
     * <p>
     * This method may be called asynchronously by providing a replyHandle argument. When called
     * asynchronously, the result of this method call is returned in a SUBSCRIBE_RESPONSE WorkItem with a
     * handle matching the value of replyHandle.
     * <p>
     * Timeout can be used to override the console's default reply timeout.
     * <p>
     * When called synchronously, this method returns a SubscribeParams object containing the result of the
     * subscription request.
     *
     * @param agent the Agent on which to create the subscription.
     * @param query the Query to perform on the Agent
     * @param consoleHandle an application-provided handle that will accompany each subscription update sent
     *        from the Agent.
     * @param options a String representation of a Map containing the options in the form
     *        <pre>"{lifetime:&lt;value&gt;, publishInterval:&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> the requested time interval in seconds for which this subscription should remain in effect.
     *        <b>publishInterval</b> the requested time interval in seconds on which the Agent should publish updates
     *        <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 synchronized SubscribeParams createSubscription(final Agent agent, final QmfQuery query, final String consoleHandle, final String options) throws QmfException {
    if (consoleHandle == null) {
        throw new QmfException("Called createSubscription() with null consoleHandle");
    }
    if (_subscriptionByHandle.get(consoleHandle) != null) {
        throw new QmfException("Called createSubscription() with a consoleHandle that is already in use");
    }
    if (agent == null) {
        throw new QmfException("Called createSubscription() with null agent");
    }
    if (!agent.isActive()) {
        throw new QmfException("Called createSubscription() with inactive agent");
    }
    String agentName = agent.getName();
    // Initialise optional values to defaults;
    long lifetime = _subscriptionDuration;
    long publishInterval = 10000;
    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("publishInterval")) {
            // Multiply publishInterval by 1000 because the QMF2 protocol spec says interval is
            // "The request time (in milliseconds) between periodic updates of data in this subscription"
            publishInterval = 1000 * optMap.getLongValue("publishInterval");
        }
        if (optMap.hasValue("timeout")) {
            timeout = optMap.getLongValue("timeout");
        }
        if (optMap.hasValue("replyHandle")) {
            replyHandle = optMap.getStringValue("replyHandle");
        }
    }
    try {
        MapMessage request = _syncSession.createMapMessage();
        // Deliberately forcing all replies to the _asyncReplyAddress
        request.setJMSReplyTo(_asyncReplyAddress);
        // Deliberately using consoleHandle not replyHandle here
        request.setJMSCorrelationID(consoleHandle);
        request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
        request.setStringProperty("method", "request");
        request.setStringProperty("qmf.opcode", "_subscribe_request");
        request.setStringProperty("qpid.subject", agentName);
        request.setObject("_query", query.mapEncode());
        request.setObject("_interval", publishInterval);
        request.setObject("_duration", lifetime);
        SubscriptionManager subscription = new SubscriptionManager(agent, query, consoleHandle, replyHandle, publishInterval, lifetime);
        _subscriptionByHandle.put(consoleHandle, subscription);
        _timer.schedule(subscription, 0, publishInterval);
        if (_subscriptionEmulationEnabled && agentName.equals(_brokerAgentName)) {
            // If the Agent is the broker Agent we emulate the Subscription on the Console
            String subscriptionId = UUID.randomUUID().toString();
            _subscriptionById.put(subscriptionId, subscription);
            subscription.setSubscriptionId(subscriptionId);
            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
            subscription.await(timeout * 1000);
            if (subscription.getSubscriptionId() == null) {
                _log.info("No response received in createSubscription()");
                throw new QmfException("No response received for Console.createSubscription()");
            }
            return new SubscribeParams(consoleHandle, subscription.mapEncode());
        }
        // If this is an asynchronous request return without waiting for a response
        return null;
    } catch (JMSException jmse) {
        _log.info("JMSException {} caught in createSubscription()", jmse.getMessage());
        throw new QmfException(jmse.getMessage());
    }
}
Also used : QmfData(org.apache.qpid.qmf2.common.QmfData) AddressParser(org.apache.qpid.messaging.util.AddressParser) MapMessage(javax.jms.MapMessage) JMSException(javax.jms.JMSException) QmfException(org.apache.qpid.qmf2.common.QmfException) Handle(org.apache.qpid.qmf2.common.Handle)

Aggregations

MapMessage (javax.jms.MapMessage)30 JMSException (javax.jms.JMSException)23 HashMap (java.util.HashMap)12 Map (java.util.Map)9 TextMessage (javax.jms.TextMessage)9 BytesMessage (javax.jms.BytesMessage)8 Message (javax.jms.Message)8 Session (javax.jms.Session)8 Destination (javax.jms.Destination)7 ObjectMessage (javax.jms.ObjectMessage)7 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)6 Test (org.junit.Test)6 AMQPMessage (org.apache.qpid.qmf2.common.AMQPMessage)5 Connection (javax.jms.Connection)4 MessageProducer (javax.jms.MessageProducer)4 QmfException (org.apache.qpid.qmf2.common.QmfException)4 MessageFormatException (javax.jms.MessageFormatException)3 StreamMessage (javax.jms.StreamMessage)3 QmfData (org.apache.qpid.qmf2.common.QmfData)3 SimpleMessageConverter (org.springframework.jms.support.converter.SimpleMessageConverter)3