activemq-artemis/docs/user-manual/en/interoperability.xml

308 lines
20 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================================= -->
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
<!-- -->
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
<!-- a Creative Commons AttributionShare Alike 3.0 Unported license ("CC-BY-SA"). -->
<!-- -->
<!-- An explanation of CC-BY-SA is available at -->
<!-- -->
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
<!-- -->
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
<!-- of it, you must provide the URL for the original version. -->
<!-- -->
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "ActiveMQ_User_Manual.ent">
%BOOK_ENTITIES;
]>
<chapter id="interoperability">
<title>Interoperability</title>
<section id="stomp">
<title>Stomp</title>
<para><ulink url="http://stomp.github.com/">Stomp</ulink> is a text-orientated wire protocol that allows
Stomp clients to communicate with Stomp Brokers. ActiveMQ now supports Stomp 1.0, 1.1 and 1.2.</para>
<para>Stomp clients are available for
several languages and platforms making it a good choice for interoperability.</para>
<section id="stomp.native">
<title>Native Stomp support</title>
<para>ActiveMQ provides native support for Stomp. To be able to send and receive Stomp messages,
you must configure a <literal>NettyAcceptor</literal> with a <literal>protocols</literal>
parameter set to have <literal>stomp</literal>:</para>
<programlisting>
&lt;acceptor name="stomp-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="STOMP"/>
&lt;param key="port" value="61613"/>
&lt;/acceptor></programlisting>
<para>With this configuration, ActiveMQ will accept Stomp connections on
the port <literal>61613</literal> (which is the default port of the Stomp brokers).</para>
<para>See the <literal>stomp</literal> example which shows how to configure a ActiveMQ server with Stomp.</para>
<section>
<title>Limitations</title>
<para>Message acknowledgements are not transactional. The ACK frame can not be part of a transaction
(it will be ignored if its <literal>transaction</literal> header is set).</para>
</section>
<section>
<title>Stomp 1.1/1.2 Notes</title>
<section>
<title>Virtual Hosting</title>
<para>ActiveMQ currently doesn't support virtual hosting, which means the 'host' header
in CONNECT fram will be ignored.</para>
</section>
<section>
<title>Heart-beating</title>
<para>ActiveMQ specifies a minimum value for both client and server heart-beat intervals.
The minimum interval for both client and server heartbeats is 500 milliseconds. That means if
a client sends a CONNECT frame with heartbeat values lower than 500, the server will defaults
the value to 500 milliseconds regardless the values of the 'heart-beat' header in the frame.</para>
</section>
</section>
</section>
<section>
<title>Mapping Stomp destinations to ActiveMQ addresses and queues</title>
<para>Stomp clients deals with <emphasis>destinations</emphasis> when sending messages and subscribing.
Destination names are simply strings which are mapped to some form of destination on the
server - how the server translates these is left to the server implementation.</para>
<para>In ActiveMQ, these destinations are mapped to <emphasis>addresses</emphasis> and <emphasis>queues</emphasis>.
When a Stomp client sends a message (using a <literal>SEND</literal> frame), the specified destination is mapped
to an address.
When a Stomp client subscribes (or unsubscribes) for a destination (using a <literal>SUBSCRIBE</literal>
or <literal>UNSUBSCRIBE</literal> frame), the destination is mapped to a ActiveMQ queue.</para>
</section>
<section>
<title>STOMP and connection-ttl</title>
<para>Well behaved STOMP clients will always send a DISCONNECT frame before closing their connections. In this case the server
will clear up any server side resources such as sessions and consumers synchronously. However if STOMP clients exit without
sending a DISCONNECT frame or if they crash the server will have no way of knowing immediately whether the client is still alive
or not. STOMP connections therefore default to a connection-ttl value of 1 minute (see chapter on <link linkend="connection-ttl"
>connection-ttl</link> for more information. This value can be overridden using connection-ttl-override.
</para>
<para>If you need a specific connection-ttl for your stomp connections without affecting the connection-ttl-override setting, you
can configure your stomp acceptor with the "connection-ttl" property, which is used to set the ttl for connections that are
created from that acceptor. For example:
</para>
<programlisting>
&lt;acceptor name="stomp-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="STOMP"/>
&lt;param key="port" value="61613"/>
&lt;param key="connection-ttl" value="20000"/>
&lt;/acceptor></programlisting>
<para>The above configuration will make sure that any stomp connection that is created from that acceptor will have its
connection-ttl set to 20 seconds.</para>
<note><para>Please note that the STOMP protocol version 1.0 does not contain any heartbeat frame. It is therefore the user's
responsibility to make sure data is sent within connection-ttl or the server will assume the client is dead and clean up server
side resources. With <literal>Stomp 1.1</literal> users can use heart-beats to maintain the life cycle of stomp
connections.</para></note>
</section>
<section>
<title>Stomp and JMS interoperability</title>
<section>
<title>Using JMS destinations</title>
<para>As explained in <xref linkend="jms-core-mapping" />, JMS destinations are also mapped to ActiveMQ addresses and queues.
If you want to use Stomp to send messages to JMS destinations, the Stomp destinations must follow the same convention:</para>
<itemizedlist>
<listitem>
<para>send or subscribe to a JMS <emphasis>Queue</emphasis> by prepending the queue name by <literal>jms.queue.</literal>.</para>
<para>For example, to send a message to the <literal>orders</literal> JMS Queue, the Stomp client must send the frame:</para>
<programlisting>
SEND
destination:jms.queue.orders
hello queue orders
^@</programlisting>
</listitem>
<listitem>
<para>send or subscribe to a JMS <emphasis>Topic</emphasis> by prepending the topic name by <literal>jms.topic.</literal>.</para>
<para>For example to subscribe to the <literal>stocks</literal> JMS Topic, the Stomp client must send the frame:</para>
<programlisting>
SUBSCRIBE
destination:jms.topic.stocks
^@</programlisting>
</listitem>
</itemizedlist>
</section>
<section>
<title>Sending and consuming Stomp message from JMS or ActiveMQ Core API</title>
<para>Stomp is mainly a text-orientated protocol. To make it simpler to interoperate with JMS and ActiveMQ Core API,
our Stomp implementation checks for presence of the <literal>content-length</literal> header to decide how to map a Stomp message
to a JMS Message or a Core message.
</para>
<para>If the Stomp message does <emphasis>not</emphasis> have a <literal>content-length</literal> header, it will be mapped to a JMS <emphasis>TextMessage</emphasis>
or a Core message with a <emphasis>single nullable SimpleString in the body buffer</emphasis>.</para>
<para>Alternatively, if the Stomp message <emphasis>has</emphasis> a <literal>content-length</literal> header,
it will be mapped to a JMS <emphasis>BytesMessage</emphasis>
or a Core message with a <emphasis>byte[] in the body buffer</emphasis>.</para>
<para>The same logic applies when mapping a JMS message or a Core message to Stomp. A Stomp client can check the presence
of the <literal>content-length</literal> header to determine the type of the message body (String or bytes).</para>
</section>
<section>
<title>Message IDs for Stomp messages</title>
<para>When receiving Stomp messages via a JMS consumer or a QueueBrowser, the messages have
no properties like JMSMessageID by default. However this may bring some inconvenience to
clients who wants an ID for their purpose. ActiveMQ Stomp provides a parameter to enable
message ID on each incoming Stomp message. If you want each Stomp message to have a unique ID,
just set the <literal>stomp-enable-message-id</literal> to true. For example:</para>
<programlisting>
&lt;acceptor name="stomp-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="STOMP"/>
&lt;param key="port" value="61613"/>
&lt;param key="stomp-enable-message-id" value="true"/>
&lt;/acceptor></programlisting>
<para>When the server starts with the above setting, each stomp message sent through this
acceptor will have an extra property added. The property key is <literal>
hq-message-id</literal> and the value is a String representation of a long type internal
message id prefixed with "<literal>STOMP</literal>", like:
<programlisting>
hq-message-id : STOMP12345</programlisting>
If <literal>stomp-enable-message-id</literal> is not specified in the configuration, default
is <literal>false</literal>. </para>
</section>
<section>
<title>Handling of Large Messages with Stomp</title>
<para>Stomp clients may send very large bodys of frames which can exceed the size of ActiveMQ
server's internal buffer, causing unexpected errors. To prevent this situation from happening,
ActiveMQ provides a stomp configuration attribute <literal>stomp-min-large-message-size</literal>.
This attribute can be configured inside a stomp acceptor, as a parameter. For example: </para>
<programlisting>
&lt;acceptor name="stomp-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="STOMP"/>
&lt;param key="port" value="61613"/>
&lt;param key="stomp-min-large-message-size" value="10240"/>
&lt;/acceptor></programlisting>
<para>The type of this attribute is integer. When this attributed is configured, ActiveMQ server
will check the size of the body of each Stomp frame arrived from connections established with
this acceptor. If the size of the body is equal or greater than the value of
<literal>stomp-min-large-message</literal>, the message will be persisted as a large message.
When a large message is delievered to a stomp consumer, the HorentQ server will automatically
handle the conversion from a large message to a normal message, before sending it to the client.</para>
<para>If a large message is compressed, the server will uncompressed it before sending it to
stomp clients. The default value of <literal>stomp-min-large-message-size</literal> is the same
as the default value of <link linkend="large-messages.core.config">min-large-message-size</link>.</para>
</section>
</section>
<section id="stomp.websockets">
<title>Stomp Over Web Sockets</title>
<para>ActiveMQ also support Stomp over <ulink url="http://dev.w3.org/html5/websockets/">Web Sockets</ulink>. Modern web browser which support Web Sockets can send and receive
Stomp messages from ActiveMQ.</para>
<para>To enable Stomp over Web Sockets, you must configure a <literal>NettyAcceptor</literal> with a <literal>protocol</literal>
parameter set to <literal>stomp_ws</literal>:</para>
<programlisting>
&lt;acceptor name="stomp-ws-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="STOMP_WS"/>
&lt;param key="port" value="61614"/>
&lt;/acceptor></programlisting>
<para>With this configuration, ActiveMQ will accept Stomp connections over Web Sockets on
the port <literal>61614</literal> with the URL path <literal>/stomp</literal>.
Web browser can then connect to <literal>ws://&lt;server>:61614/stomp</literal> using a Web Socket to send and receive Stomp
messages.</para>
<para>A companion JavaScript library to ease client-side development is available from
<ulink url="http://github.com/jmesnil/stomp-websocket">GitHub</ulink> (please see
its <ulink url="http://jmesnil.net/stomp-websocket/doc/">documentation</ulink> for a complete description).</para>
<para>The <literal>stomp-websockets</literal> example shows how to configure ActiveMQ server to have web browsers and Java
applications exchanges messages on a JMS topic.</para>
</section>
<section id="stompconnect">
<title>StompConnect</title>
<para><ulink url="http://stomp.codehaus.org/StompConnect">StompConnect</ulink> is a server that
can act as a Stomp broker and proxy the Stomp protocol to the standard JMS API.
Consequently, using StompConnect it is possible to turn ActiveMQ into a Stomp Broker and
use any of the available stomp clients. These include clients written in C, C++, c# and
.net etc.</para>
<para>To run StompConnect first start the ActiveMQ server and make sure that it is using
JNDI.</para>
<para>Stomp requires the file <literal>jndi.properties</literal> to be available on the
classpath. This should look something like:</para>
<programlisting>
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces</programlisting>
<para>Make sure this file is in the classpath along with the StompConnect jar and the
ActiveMQ jars and simply run <literal>java org.codehaus.stomp.jms.Main</literal>.</para>
</section>
</section>
<section>
<title>REST</title>
<para>Please see <xref linkend="rest"/></para>
</section>
<section>
<title>AMQP</title>
<para>ActiveMQ supports the <ulink url="https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=amqp">AMQP 1.0</ulink>
specification. To enable AMQP you must configure a Netty Acceptor to receive AMQP clients, like so:</para>
<programlisting>
&lt;acceptor name="stomp-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="AMQP"/>
&lt;param key="port" value="5672"/>
&lt;/acceptor>
</programlisting>
<para>ActiveMQ will then accept AMQP 1.0 clients on port 5672 which is the default AMQP port.</para>
<para>There are 2 Stomp examples available see proton-j and proton-ruby which use the qpid Java and Ruby clients
respectively</para>
<section>
<title>AMQP and security</title>
<para>The ActiveMQ Server accepts AMQP SASL Authentication and will use this to map onto the underlying session created
for the connection so you can use the normal ActiveMQ security configuration.</para>
</section>
<section>
<title>AMQP Links</title>
<para>An AMQP Link is a uni directional transport for messages between a source and a target, i.e. a client and the
ActiveMQ Broker. A link will have an endpoint of which there are 2 kinds, a Sender and A Receiver. At the Broker a
Sender will have its messages converted into a ActiveMQ Message and forwarded to its destination or target. A
Receiver will map onto a ActiveMQ Server Consumer and convert ActiveMQ messages back into AMQP messages before being delivered.</para>
</section>
<section>
<title>AMQP and destinations</title>
<para>If an AMQP Link is dynamic then a temporary queue will be created and either the remote source or remote
target address will be set to the name of the temporary queue. If the Link is not dynamic then the the address
of the remote target or source will used for the queue. If this does not exist then an exception will be sent</para>
<note><para>For the next version we will add a flag to aut create durable queue but for now you will have to add them via
the configuration</para></note>
</section>
<section>
<title>AMQP and Coordinations - Handling Transactions</title>
<para>An AMQP links target can also be a Coordinator, the Coordinator is used to handle transactions. If a
coordinator is used the the underlying HormetQ Server session will be transacted and will be either rolled back
or committed via the coordinator.</para>
<note><para>AMQP allows the use of multiple transactions per session, <literal>amqp:multi-txns-per-ssn</literal>,
however in this version ActiveMQ will only support single transactions per session</para></note>
</section>
</section>
<section>
<title>OpenWire</title>
<para>ActiveMQ now supports the <ulink url="http://activemq.apache.org/openwire.html">OpenWire</ulink>
protocol so that an ActiveMQ JMS client can talk directly to a ActiveMQ server. To enable OpenWire support
you must configure a Netty Acceptor, like so:</para>
<programlisting>
&lt;acceptor name="openwire-acceptor">
&lt;factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory&lt;/factory-class>
&lt;param key="protocols" value="OPENWIRE"/>
&lt;param key="port" value="61616"/>
&lt;/acceptor>
</programlisting>
<para>The ActiveMQ server will then listens on port 61616 for incoming openwire commands. Please note the "protocols" is not mandatory here.
The openwire configuration conforms to ActiveMQ's "Single Port" feature. Please refer to
<link linkend="configuring-transports.single-port">Configuring Single Port</link> for details.</para>
<para>Please refer to the openwire example for more coding details.</para>
<para>Currently we support ActiveMQ clients that using standard JMS APIs. In the future we will get more supports
for some advanced, ActiveMQ specific features into ActiveMQ.</para>
</section>
</chapter>