Skip to content

Commit

Permalink
user manual edits part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
purplefox committed Jan 7, 2010
1 parent 3f0f168 commit ce3b8a3
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 60 deletions.
27 changes: 13 additions & 14 deletions docs/user-manual/en/client-classpath.xml
Expand Up @@ -19,35 +19,34 @@
<chapter id="client-classpath">
<title>The Client Classpath</title>
<para>HornetQ requires several jars on the <emphasis>Client Classpath</emphasis> depending on
whether the client uses HornetQ Core API, JMS, and JNDI.</para>
<note>
whether the client uses HornetQ Core API, JMS, and JNDI.</para>
<warning>
<para>All the jars mentioned here can be found in the <literal>lib</literal> directory of
the HornetQ distribution. Be sure you only use the jars from the correct version of the
release, you <emphasis>must not</emphasis> mix and match versions of jars from different
HornetQ versions. Mixing and matching different jar versions may cause subtle errors and
failures to occur.</para>
</note>
</warning>
<section>
<title>HornetQ Core Client</title>
<para>If you are using just a pure HornetQ Core client (i.e. no JMS) then you need <literal
>hornetq-core-client.jar</literal>, <literal>hornetq-transports.jar</literal>
and <literal>netty.jar</literal> on your client classpath.</para>
>hornetq-core-client.jar</literal>, <literal>hornetq-transports.jar</literal> and
<literal>netty.jar</literal> on your client classpath.</para>
</section>
<section>
<title>JMS Client</title>
<para>If you are using JMS on the client side, then you will also need to include
<literal>hornetq-jms-client.jar</literal> and <literal>jboss-jms-api.jar</literal>.</para>
<para>If you are using JMS on the client side, then you will also need to include <literal
>hornetq-jms-client.jar</literal> and <literal>jboss-jms-api.jar</literal>.</para>
<note>
<para><literal>jboss-jms-api.jar</literal>
just contains Java EE API interface classes needed for the <literal
>javax.jms.*</literal> classes. If you already have a jar with these interface
classes on your classpath, you will not need it.</para>
</note>
<para><literal>jboss-jms-api.jar</literal> just contains Java EE API interface classes
needed for the <literal>javax.jms.*</literal> classes. If you already have a jar
with these interface classes on your classpath, you will not need it.</para>
</note>
</section>
<section>
<title>JMS Client with JNDI</title>
<para>If you are looking up JMS resources from the JNDI server co-located with the HornetQ
standalone server, you wil also need the jar <literal>jnp-client.jar</literal> jar on your
client classpath as well as any other jars mentioned previously.</para>
standalone server, you wil also need the jar <literal>jnp-client.jar</literal> jar on
your client classpath as well as any other jars mentioned previously.</para>
</section>
</chapter>
104 changes: 76 additions & 28 deletions docs/user-manual/en/using-core.xml
Expand Up @@ -18,48 +18,76 @@
<!-- ============================================================================= -->
<chapter id="using-core">
<title>Using Core</title>
<para>HornetQ core is a completely JMS-agnostic messaging system with its own core API.</para>
<para>HornetQ core is a completely JMS-agnostic messaging system with its own non-JMS API. We
call this the <emphasis>core API</emphasis>.</para>
<para>If you don't want to use JMS you can use the core API directly. The core API provides all
the functionality of JMS but without much of the complexity. It also provides features that
are not available using JMS.</para>
<section>
<title>Core Messaging Concepts</title>
<para>Some of the core messaging concepts are similar to JMS concepts, but core messaging
concepts differ in some ways. In general the core messaging API is simpler than the JMS
API, since we remove distinctions between queues, topics and subscriptions. We'll
API, since we remove distinctions between queues, topics and subscriptions. We'll
discuss each of the major core messaging concepts in turn, but to see the API in detail,
please consult the Javadoc.</para>
<section>
<title>Message</title>
<para>A message is the unit of data which is sent between clients and servers.</para>
<para>A message has a body which is effectively a byte[], it also has a set of
properties which are key-value pairs. Each property key is a string and property
values can be of type integer, long, short, byte, byte[], String, double, float or
boolean.</para>
<para>A message has an <emphasis>address</emphasis> it is being sent to.
When the message arrives on the server it is routed to any queues
that are bound to the address. An address may have many queues bound to it or even
none. There may also be entities other than queues, like <emphasis role="italic"
>diverts</emphasis> bound to addresses.</para>
<para>Messages can be either durable or non durable. Durable messages in a durable queue
will survive a server crash or restart. Non durable messages will never survive a
server crash or restart.</para>
<para>Messages can be specified with a priority value between 0 and 9. 0 represents the
lowest priority and 9 represents the highest. HornetQ will attempt to deliver higher
priority messages before lower priority ones.</para>
<para>Messages can be specified with an optional expiry time. HornetQ will not deliver
messages after its expiry time has been exceeded.</para>
<para>Messages also have an optional timestamp which represents the time the message was
sent.</para>
<itemizedlist>
<listitem>
<para>A message is the unit of data which is sent between clients and
servers.</para>
</listitem>
<listitem>
<para>A message has a body which is a buffer containing convenient methods for
reading and writing data into it.</para>
</listitem>
<listitem>
<para>A message has a set of properties which are key-value pairs. Each property
key is a string and property values can be of type integer, long, short,
byte, byte[], String, double, float or boolean.</para>
</listitem>
<listitem>
<para>A message has an <emphasis>address</emphasis> it is being sent to. When
the message arrives on the server it is routed to any queues that are bound
to the address - if the queues are bound with any filter, the message will
only be routed to that queue if the filter matches. An address may have many
queues bound to it or even none. There may also be entities other than
queues, like <emphasis role="italic">diverts</emphasis> bound to
addresses.</para>
</listitem>
<listitem>
<para>Messages can be either durable or non durable. Durable messages in a
durable queue will survive a server crash or restart. Non durable messages
will never survive a server crash or restart.</para>
</listitem>
<listitem>
<para>Messages can be specified with a priority value between 0 and 9. 0
represents the lowest priority and 9 represents the highest. HornetQ will
attempt to deliver higher priority messages before lower priority
ones.</para>
</listitem>
<listitem>
<para>Messages can be specified with an optional expiry time. HornetQ will not
deliver messages after its expiry time has been exceeded.</para>
</listitem>
<listitem>
<para>Messages also have an optional timestamp which represents the time the
message was sent.</para>
</listitem>
<listitem>
<para>HornetQ also supports the sending/consuming of very large messages - much
larger than can fit in available RAM at any one time.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Address</title>
<para>A server maintains a mapping between an address and a set of queues. Zero or more
queues can be bound to a single address. Each queue can be bound with an optional
message filter. When a message is routed, it is in fact routed to the set of
queues bound to the message's address. If any of the queues are bound
with a filter expression, then the message will only be routed to the subset of
bound queues which match that filter expression.</para>
message filter. When a message is routed, it is routed to the set of queues bound to
the message's address. If any of the queues are bound with a filter expression, then
the message will only be routed to the subset of bound queues which match that
filter expression.</para>
<para>Other entities, such as <emphasis role="italic">diverts</emphasis> can also be
bound to an address and messages will also be routed there.</para>
<note>
Expand Down Expand Up @@ -92,6 +120,8 @@
>ClientSession</literal> instances. <literal>ClientSessionFactory</literal>
instances know how to connect to the server to create sessions, and are configurable
with many settings.</para>
<para><literal>ClientSessionFactory</literal> instances are created using the <literal
>HornetQClient</literal> factory class.</para>
</section>
<section>
<title>ClientSession</title>
Expand All @@ -102,6 +132,16 @@
of a <ulink url="http://java.sun.com/javaee/technologies/jta/index.jsp">JTA</ulink>
transaction.</para>
<para>ClientSession instances group ClientConsumers and ClientProducers.</para>
<para>ClientSession instances can be registered with an optional <literal
>SendAcknowledgementHandler</literal>. This allows your client code to be
notified asynchronously when sent messages have successfully reached the server.
This unique HornetQ feature, allows you to have full guarantees that sent messages
have reached the server without having to block on each message sent until a
response is received. Blocking on each messages sent is costly since it requires a
network round trip for each message sent. By not blocking and receiving send
acknowledgements asynchronously you can create true end to end asynchronous systems
which is not possible using the standard JMS API. For more information on this
advanced feature please see the section <xref linkend="send-guarantees"/>.</para>
</section>
<section>
<title>ClientConsumer</title>
Expand All @@ -119,6 +159,14 @@
have no specified address, and the address is specified at send time for the
message.</para>
</section>
<warning>
<para>Please note that ClientSession, ClientProducer and ClientConsumer instances are
<emphasis>designed to be re-used</emphasis>.</para>
<para>It's an anti-pattern to create new ClientSession, ClientProducer and ClientConsumer instances
for each message you produce or consume. If you do this, your application will
perform very poorly. This is discussed further in the section on performance tuning
<xref linkend="perf-tuning"/>.</para>
</warning>
</section>
<section>
<title>A simple example of using Core</title>
Expand All @@ -137,7 +185,7 @@ ClientProducer producer = session.createProducer("example");

ClientMessage message = session.createMessage(true);

message.getBody().writeString("Hello");
message.getBodyBuffer().writeString("Hello");

producer.send(message);

Expand All @@ -147,7 +195,7 @@ ClientConsumer consumer = session.createConsumer("example");

ClientMessage msgReceived = consumer.receive();

System.out.println("message = " + msgReceived.getBody().readString());
System.out.println("message = " + msgReceived.getBodyBuffer().readString());

session.close();</programlisting>
</section>
Expand Down
47 changes: 29 additions & 18 deletions docs/user-manual/en/using-jms.xml
Expand Up @@ -21,7 +21,7 @@
<para>Although HornetQ provides a JMS agnostic messaging API, many users will be more
comfortable using JMS.</para>
<para>JMS is a very popular API standard for messaging, and most messaging systems provide a JMS
API. If you are completely new to JMS we suggest you following the<ulink
API. If you are completely new to JMS we suggest you follow the<ulink
url="http://java.sun.com/products/jms/tutorial/1_3_1-fcs/doc/jms_tutorialTOC.html"> Sun
JMS tutorial</ulink> - a full JMS tutorial is out of scope for this guide.</para>
<para>HornetQ also ships with a wide range of examples, many of which demonstrate JMS API usage.
Expand Down Expand Up @@ -107,7 +107,8 @@ java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
is the port used by the JNDI server and may vary depending on how you have configured
your JNDI server.</para>
<para>In the default standalone configuration, JNDI server ports are configured in the file
<literal>hornetq-beans.xml</literal> by setting properties on the <literal>JNDIServer</literal> bean:</para>
<literal>hornetq-beans.xml</literal> by setting properties on the <literal
>JNDIServer</literal> bean:</para>
<programlisting>
&lt;bean name="JNDIServer" class="org.jnp.server.Main"&gt;
&lt;property name="namingInfo"&gt;
Expand All @@ -125,11 +126,11 @@ java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
>localhost</literal>!</para>
</note>
<note>
<para>The JNDIServer bean must be defined <emphasis>only when HornetQ is running in stand-alone mode</emphasis>.
When HornetQ is integrated to JBoss Application Server, JBoss AS will provide a ready-to-use
JNDI server without any additional configuration.</para>
<para>The JNDIServer bean must be defined <emphasis>only when HornetQ is running in
stand-alone mode</emphasis>. When HornetQ is integrated to JBoss Application
Server, JBoss AS will provide a ready-to-use JNDI server without any additional
configuration.</para>
</note>

</section>
<section>
<title>The code</title>
Expand Down Expand Up @@ -160,28 +161,38 @@ System.out.println("Got order: " + receivedMessage.getText());
</programlisting>
<para>It's as simple as that. For a wide range of working JMS examples please see the
examples directory in the distribution.</para>
<warning>
<para>Please note that JMS connections, sessions, producers and consumers are
<emphasis>designed to be re-used</emphasis>.</para>
<para>It's an anti-pattern to create new connections, sessions, producers and consumers
for each message you produce or consume. If you do this, your application will
perform very poorly. This is discussed further in the section on performance tuning
<xref linkend="perf-tuning"/>.</para>
</warning>
</section>
<section>
<title>Directly instantiating JMS Resources without using JNDI</title>
<para>Although it's a very common JMS usage pattern to lookup JMS <emphasis>Administered
Objects</emphasis> (that's JMS Queues, Topics and Connection Factories) from JNDI,
in some cases a JNDI server is not available and you still want to use JMS, or you just
think "Why do I need JNDI? Why can't I just instantiate these objects directly?"</para>
Objects</emphasis> (that's JMS Queue, Topic and ConnectionFactory instances) from
JNDI, in some cases a JNDI server is not available and you still want to use JMS, or you
just think "Why do I need JNDI? Why can't I just instantiate these objects
directly?"</para>
<para>With HornetQ you can do exactly that. HornetQ supports the direct instantiation of JMS
Queue, Topic and Connection Factory instances, so you don't have to use JNDI at
Queue, Topic and ConnectionFactory instances, so you don't have to use JNDI at
all.</para>
<para>For a full working example of direct instantiation please see the JMS examples in
<xref linkend="examples"/>.</para>
<para>Here's our simple example, rewritten to not use JNDI at all:</para>
<para>We create the JMS ConnectionFactory object via the HornetQJMSClient Utility class, note we need to provide
connection parameters and specify which transport we are using, for more information on
connectors please see <xref linkend="configuring-transports"/>.</para>
<para>We create the JMS ConnectionFactory object via the HornetQJMSClient Utility class,
note we need to provide connection parameters and specify which transport we are using,
for more information on connectors please see <xref linkend="configuring-transports"
/>.</para>
<programlisting>
TransportConfiguration transportConfiguration =
new TransportConfiguration(NettyConnectorFactory.class.getName());
ConnectionFactory cf = HornetQJMSClient.createConnectionFactory(transportConfiguration);
</programlisting>
<para>We create the JMS Queue Object via the HornetQJMSClient Utility class:</para>
<para>We also create the JMS Queue object via the HornetQJMSClient Utility class:</para>
<programlisting>Queue orderQueue = HornetQJMSClient.createQueue("OrderQueue");</programlisting>
<para>Next we create a JMS connection using the connection factory:</para>
<programlisting>Connection connection = cf.createConnection();</programlisting>
Expand Down Expand Up @@ -212,10 +223,10 @@ System.out.println("Got order: " + receivedMessage.getText());
<section id="using-jms.dupsokbatchsize">
<title>Setting The Batch Size for DUPS_OK </title>
<para>When the JMS acknowledge mode is set to <literal>DUPS_OK</literal> it is possible to
configure the consumer so that it sends the acknowledgements in batches rather that one
at a time, saving valuable bandwidth. This can be configured via the connection factory
via the <literal>dups-ok-batch-size</literal> element and is set in bytes. The default
is 1024 * 1024 bytes = 1 MiB.</para>
configure the consumer so that it sends acknowledgements in batches rather that one at a
time, saving valuable bandwidth. This can be configured via the connection factory via
the <literal>dups-ok-batch-size</literal> element and is set in bytes. The default is
1024 * 1024 bytes = 1 MiB.</para>
</section>
<section id="using-jms.txbatchsize">
<title>Setting The Transaction Batch Size</title>
Expand Down

0 comments on commit ce3b8a3

Please sign in to comment.