You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2014/12/08 16:49:47 UTC
[16/25] activemq-6 git commit: ACTIVEMQ6-9 - port to markdown
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/connection-ttl.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/connection-ttl.xml b/docs/user-manual/en/connection-ttl.xml
deleted file mode 100644
index dceca73..0000000
--- a/docs/user-manual/en/connection-ttl.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- ============================================================================= -->
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
-<!-- contributor license agreements. See the NOTICE file distributed with -->
-<!-- this work for additional information regarding copyright ownership. -->
-<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
-<!-- (the "License"); you may not use this file except in compliance with -->
-<!-- the License. You may obtain a copy of the License at -->
-<!-- -->
-<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
-<!-- -->
-<!-- Unless required by applicable law or agreed to in writing, software -->
-<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
-<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
-<!-- See the License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-<!-- ============================================================================= -->
-
-<!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="connection-ttl">
- <title>Detecting Dead Connections</title>
- <para>In this section we will discuss connection time-to-live (TTL) and explain how ActiveMQ
- deals with crashed clients and clients which have exited without cleanly closing their
- resources.</para>
- <section id="dead.connections">
- <title>Cleaning up Dead Connection Resources on the Server</title>
- <para>Before a ActiveMQ client application exits it is considered good practice that it
- should close its resources in a controlled manner, using a <literal>finally</literal>
- block.</para>
- <para>Here's an example of a well behaved core client application closing its session and
- session factory in a finally block:</para>
- <programlisting>
-ServerLocator locator = null;
-ClientSessionFactory sf = null;
-ClientSession session = null;
-
-try
-{
- locator = ActiveMQClient.createServerLocatorWithoutHA(..);
-
- sf = locator.createClientSessionFactory();;
-
- session = sf.createSession(...);
-
- ... do some stuff with the session...
-}
-finally
-{
- if (session != null)
- {
- session.close();
- }
-
- if (sf != null)
- {
- sf.close();
- }
-
- if(locator != null)
- {
- locator.close();
- }
-}</programlisting>
- <para>And here's an example of a well behaved JMS client application:</para>
- <programlisting>
-Connection jmsConnection = null;
-
-try
-{
- ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(...);
-
- jmsConnection = jmsConnectionFactory.createConnection();
-
- ... do some stuff with the connection...
-}
-finally
-{
- if (connection != null)
- {
- connection.close();
- }
-}</programlisting>
- <para>Unfortunately users don't always write well behaved applications, and sometimes
- clients just crash so they don't have a chance to clean up their resources!</para>
- <para>If this occurs then it can leave server side resources, like sessions, hanging on the
- server. If these were not removed they would cause a resource leak on the server and
- over time this result in the server running out of memory or other resources.</para>
- <para>We have to balance the requirement for cleaning up dead client resources with the fact
- that sometimes the network between the client and the server can fail and then come
- back, allowing the client to reconnect. ActiveMQ supports client reconnection, so we
- don't want to clean up "dead" server side resources too soon or this will prevent any
- client from reconnecting, as it won't be able to find its old sessions on the
- server.</para>
- <para>ActiveMQ makes all of this configurable. For each <literal
- >ClientSessionFactory</literal> we define a <emphasis>connection TTL</emphasis>.
- Basically, the TTL determines how long the server will keep a connection alive in the
- absence of any data arriving from the client. The client will automatically send "ping"
- packets periodically to prevent the server from closing it down. If the server doesn't
- receive any packets on a connection for the connection TTL time, then it will
- automatically close all the sessions on the server that relate to that
- connection.</para>
- <para>If you're using JMS, the connection TTL is defined by the <literal
- >ConnectionTTL</literal> attribute on a <literal>ActiveMQConnectionFactory</literal>
- instance, or if you're deploying JMS connection factory instances direct into JNDI on
- the server side, you can specify it in the xml config, using the parameter <literal
- >connection-ttl</literal>.</para>
- <para>The default value for connection ttl on an "unreliable" connection (e.g. a Netty
- connection) is <literal>60000</literal>ms, i.e. 1 minute. The default value for connection
- ttl on a "reliable" connection (e.g. an in-vm connection) is <literal>-1</literal>. A
- value of <literal>-1</literal> for <literal>ConnectionTTL</literal> means the server
- will never time out the connection on the server side.</para>
- <para id="connection-ttl.override">If you do not wish clients to be able to specify their own connection TTL, you can
- override all values used by a global value set on the server side. This can be done by
- specifying the <literal>connection-ttl-override</literal> attribute in the server side
- configuration. The default value for <literal>connection-ttl-override</literal> is
- <literal>-1</literal> which means "do not override" (i.e. let clients use their own
- values).</para>
- <section>
- <title>Closing core sessions or JMS connections that you have failed to close</title>
- <para>As previously discussed, it's important that all core client sessions and JMS
- connections are always closed explicitly in a <literal>finally</literal> block when
- you are finished using them. </para>
- <para>If you fail to do so, ActiveMQ will detect this at garbage collection time, and log
- a warning similar to the following in the logs (If you are using JMS the warning
- will involve a JMS connection not a client session):</para>
- <programlisting>
-[Finalizer] 20:14:43,244 WARNING [org.apache.activemq.core.client.impl.DelegatingSession] I'm closing a ClientSession you left open. Please make sure you close all ClientSessions explicitly before let
-ting them go out of scope!
-[Finalizer] 20:14:43,244 WARNING [org.apache.activemq.core.client.impl.DelegatingSession] The session you didn't close was created here:
-java.lang.Exception
- at org.apache.activemq.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83)
- at org.acme.yourproject.YourClass (YourClass.java:666)</programlisting>
- <para>ActiveMQ will then close the connection / client session for you.</para>
- <para>Note that the log will also tell you the exact line of your user code where you
- created the JMS connection / client session that you later did not close. This will
- enable you to pinpoint the error in your code and correct it appropriately.</para>
- </section>
- </section>
- <section>
- <title>Detecting failure from the client side.</title>
- <para>In the previous section we discussed how the client sends pings to the server and how
- "dead" connection resources are cleaned up by the server. There's also another reason
- for pinging, and that's for the <emphasis>client</emphasis> to be able to detect that
- the server or network has failed.</para>
- <para>As long as the client is receiving data from the server it will consider the
- connection to be still alive. </para>
- <para>If the client does not receive any packets for <literal
- >client-failure-check-period</literal> milliseconds then it will consider the
- connection failed and will either initiate failover, or call any <literal
- >FailureListener</literal> instances (or <literal>ExceptionListener</literal>
- instances if you are using JMS) depending on how it has been configured.</para>
- <para>If you're using JMS it's defined by the <literal>ClientFailureCheckPeriod</literal>
- attribute on a <literal>ActiveMQConnectionFactory</literal> instance, or if you're
- deploying JMS connection factory instances direct into JNDI on the server side, you can
- specify it in the <literal>activemq-jms.xml </literal> configuration file, using the
- parameter <literal>client-failure-check-period</literal>.</para>
- <para>The default value for client failure check period on an "unreliable" connection (e.g.
- a Netty connection) is <literal>30000</literal>ms, i.e. 30 seconds. The default value
- for client failure check period on a "reliable" connection (e.g. an in-vm connection)
- is <literal>-1</literal>. A value of <literal>-1</literal> means the client will never fail the
- connection on the client side if no data is received from the server. Typically this is
- much lower than connection TTL to allow clients to reconnect in case of transitory
- failure.</para>
- </section>
- <section id="connection-ttl.async-connection-execution">
- <title>Configuring Asynchronous Connection Execution</title>
- <para>Most packets received on the server side are executed on the remoting thread. These packets
- represent short-running operations and are always executed on the remoting thread for
- performance reasons.</para>
- <para>However, by default some kinds of packets are executed using a thread from a
- thread pool so that the remoting thread is not tied up for too long. Please note that
- processing operations asynchronously on another thread adds a little more latency. These packets
- are:</para>
- <itemizedlist>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.RollbackMessage</literal></para>
- </listitem>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.SessionCloseMessage</literal></para>
- </listitem>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.SessionCommitMessage</literal></para>
- </listitem>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.SessionXACommitMessage</literal></para>
- </listitem>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.SessionXAPrepareMessage</literal></para>
- </listitem>
- <listitem>
- <para><literal>org.apache.activemq.core.protocol.core.impl.wireformat.SessionXARollbackMessage</literal></para>
- </listitem>
- </itemizedlist>
- <para>To disable asynchronous connection execution, set the parameter
- <literal>async-connection-execution-enabled</literal> in
- <literal>activemq-configuration.xml</literal> to <literal>false</literal> (default value is
- <literal>true</literal>).</para>
- </section>
-</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/core-bridges.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/core-bridges.md b/docs/user-manual/en/core-bridges.md
new file mode 100644
index 0000000..6b6b90f
--- /dev/null
+++ b/docs/user-manual/en/core-bridges.md
@@ -0,0 +1,225 @@
+Core Bridges
+============
+
+The function of a bridge is to consume messages from a source queue, and
+forward them to a target address, typically on a different ActiveMQ
+server.
+
+The source and target servers do not have to be in the same cluster
+which makes bridging suitable for reliably sending messages from one
+cluster to another, for instance across a WAN, or internet and where the
+connection may be unreliable.
+
+The bridge has built in resilience to failure so if the target server
+connection is lost, e.g. due to network failure, the bridge will retry
+connecting to the target until it comes back online. When it comes back
+online it will resume operation as normal.
+
+In summary, bridges are a way to reliably connect two separate ActiveMQ
+servers together. With a core bridge both source and target servers must
+be ActiveMQ servers.
+
+Bridges can be configured to provide *once and only once* delivery
+guarantees even in the event of the failure of the source or the target
+server. They do this by using duplicate detection (described in ?).
+
+> **Note**
+>
+> Although they have similar function, don't confuse core bridges with
+> JMS bridges!
+>
+> Core bridges are for linking a ActiveMQ node with another ActiveMQ
+> node and do not use the JMS API. A JMS Bridge is used for linking any
+> two JMS 1.1 compliant JMS providers. So, a JMS Bridge could be used
+> for bridging to or from different JMS compliant messaging system. It's
+> always preferable to use a core bridge if you can. Core bridges use
+> duplicate detection to provide *once and only once* guarantees. To
+> provide the same guarantee using a JMS bridge you would have to use XA
+> which has a higher overhead and is more complex to configure.
+
+Configuring Bridges
+===================
+
+Bridges are configured in `activemq-configuration.xml`. Let's kick off
+with an example (this is actually from the bridge example):
+
+ <bridge name="my-bridge">
+ <queue-name>jms.queue.sausage-factory</queue-name>
+ <forwarding-address>jms.queue.mincing-machine</forwarding-address>
+ <filter-string="name='aardvark'"/>
+ <transformer-class-name>
+ org.apache.activemq.jms.example.HatColourChangeTransformer
+ </transformer-class-name>
+ <retry-interval>1000</retry-interval>
+ <ha>true</ha>
+ <retry-interval-multiplier>1.0</retry-interval-multiplier>
+ <initial-connect-attempts>-1</initial-connect-attempts>
+ <reconnect-attempts>-1</reconnect-attempts>
+ <failover-on-server-shutdown>false</failover-on-server-shutdown>
+ <use-duplicate-detection>true</use-duplicate-detection>
+ <confirmation-window-size>10000000</confirmation-window-size>
+ <user>foouser</user>
+ <password>foopassword</password>
+ <static-connectors>
+ <connector-ref>remote-connector</connector-ref>
+ </static-connectors>
+ <!-- alternative to static-connectors
+ <discovery-group-ref discovery-group-name="bridge-discovery-group"/>
+ -->
+ </bridge>
+
+In the above example we have shown all the parameters its possible to
+configure for a bridge. In practice you might use many of the defaults
+so it won't be necessary to specify them all explicitly.
+
+Let's take a look at all the parameters in turn:
+
+- `name` attribute. All bridges must have a unique name in the server.
+
+- `queue-name`. This is the unique name of the local queue that the
+ bridge consumes from, it's a mandatory parameter.
+
+ The queue must already exist by the time the bridge is instantiated
+ at start-up.
+
+ > **Note**
+ >
+ > If you're using JMS then normally the JMS configuration
+ > `activemq-jms.xml` is loaded after the core configuration file
+ > `activemq-configuration.xml` is loaded. If your bridge is
+ > consuming from a JMS queue then you'll need to make sure the JMS
+ > queue is also deployed as a core queue in the core configuration.
+ > Take a look at the bridge example for an example of how this is
+ > done.
+
+- `forwarding-address`. This is the address on the target server that
+ the message will be forwarded to. If a forwarding address is not
+ specified, then the original address of the message will be
+ retained.
+
+- `filter-string`. An optional filter string can be supplied. If
+ specified then only messages which match the filter expression
+ specified in the filter string will be forwarded. The filter string
+ follows the ActiveMQ filter expression syntax described in ?.
+
+- `transformer-class-name`. An optional transformer-class-name can be
+ specified. This is the name of a user-defined class which implements
+ the `org.apache.activemq.core.server.cluster.Transformer` interface.
+
+ If this is specified then the transformer's `transform()` method
+ will be invoked with the message before it is forwarded. This gives
+ you the opportunity to transform the message's header or body before
+ forwarding it.
+
+- `ha`. This optional parameter determines whether or not this bridge
+ should support high availability. True means it will connect to any
+ available server in a cluster and support failover. The default
+ value is `false`.
+
+- `retry-interval`. This optional parameter determines the period in
+ milliseconds between subsequent reconnection attempts, if the
+ connection to the target server has failed. The default value is
+ `2000`milliseconds.
+
+- `retry-interval-multiplier`. This optional parameter determines
+ determines a multiplier to apply to the time since the last retry to
+ compute the time to the next retry.
+
+ This allows you to implement an *exponential backoff* between retry
+ attempts.
+
+ Let's take an example:
+
+ If we set `retry-interval`to `1000` ms and we set
+ `retry-interval-multiplier` to `2.0`, then, if the first reconnect
+ attempt fails, we will wait `1000` ms then `2000` ms then `4000` ms
+ between subsequent reconnection attempts.
+
+ The default value is `1.0` meaning each reconnect attempt is spaced
+ at equal intervals.
+
+- `initial-connect-attempts`. This optional parameter determines the
+ total number of initial connect attempts the bridge will make before
+ giving up and shutting down. A value of `-1` signifies an unlimited
+ number of attempts. The default value is `-1`.
+
+- `reconnect-attempts`. This optional parameter determines the total
+ number of reconnect attempts the bridge will make before giving up
+ and shutting down. A value of `-1` signifies an unlimited number of
+ attempts. The default value is `-1`.
+
+- `failover-on-server-shutdown`. This optional parameter determines
+ whether the bridge will attempt to failover onto a backup server (if
+ specified) when the target server is cleanly shutdown rather than
+ crashed.
+
+ The bridge connector can specify both a live and a backup server, if
+ it specifies a backup server and this parameter is set to `true`
+ then if the target server is *cleanly* shutdown the bridge
+ connection will attempt to failover onto its backup. If the bridge
+ connector has no backup server configured then this parameter has no
+ effect.
+
+ Sometimes you want a bridge configured with a live and a backup
+ target server, but you don't want to failover to the backup if the
+ live server is simply taken down temporarily for maintenance, this
+ is when this parameter comes in handy.
+
+ The default value for this parameter is `false`.
+
+- `use-duplicate-detection`. This optional parameter determines
+ whether the bridge will automatically insert a duplicate id property
+ into each message that it forwards.
+
+ Doing so, allows the target server to perform duplicate detection on
+ messages it receives from the source server. If the connection fails
+ or server crashes, then, when the bridge resumes it will resend
+ unacknowledged messages. This might result in duplicate messages
+ being sent to the target server. By enabling duplicate detection
+ allows these duplicates to be screened out and ignored.
+
+ This allows the bridge to provide a *once and only once* delivery
+ guarantee without using heavyweight methods such as XA (see ? for
+ more information).
+
+ The default value for this parameter is `true`.
+
+- `confirmation-window-size`. This optional parameter determines the
+ `confirmation-window-size` to use for the connection used to forward
+ messages to the target node. This attribute is described in section
+ ?
+
+ > **Warning**
+ >
+ > When using the bridge to forward messages to an address which uses
+ > the `BLOCK` `address-full-policy` from a queue which has a
+ > `max-size-bytes` set it's important that
+ > `confirmation-window-size` is less than or equal to
+ > `max-size-bytes` to prevent the flow of messages from ceasing.
+
+- `user`. This optional parameter determines the user name to use when
+ creating the bridge connection to the remote server. If it is not
+ specified the default cluster user specified by `cluster-user` in
+ `activemq-configuration.xml` will be used.
+
+- `password`. This optional parameter determines the password to use
+ when creating the bridge connection to the remote server. If it is
+ not specified the default cluster password specified by
+ `cluster-password` in `activemq-configuration.xml` will be used.
+
+- `static-connectors` or `discovery-group-ref`. Pick either of these
+ options to connect the bridge to the target server.
+
+ The `static-connectors` is a list of `connector-ref` elements
+ pointing to `connector` elements defined elsewhere. A *connector*
+ encapsulates knowledge of what transport to use (TCP, SSL, HTTP etc)
+ as well as the server connection parameters (host, port etc). For
+ more information about what connectors are and how to configure
+ them, please see ?.
+
+ The `discovery-group-ref` element has one attribute -
+ `discovery-group-name`. This attribute points to a `discovery-group`
+ defined elsewhere. For more information about what discovery-groups
+ are and how to configure them, please see ?.
+
+
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/core-bridges.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/core-bridges.xml b/docs/user-manual/en/core-bridges.xml
deleted file mode 100644
index 2276a2e..0000000
--- a/docs/user-manual/en/core-bridges.xml
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- ============================================================================= -->
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
-<!-- contributor license agreements. See the NOTICE file distributed with -->
-<!-- this work for additional information regarding copyright ownership. -->
-<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
-<!-- (the "License"); you may not use this file except in compliance with -->
-<!-- the License. You may obtain a copy of the License at -->
-<!-- -->
-<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
-<!-- -->
-<!-- Unless required by applicable law or agreed to in writing, software -->
-<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
-<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
-<!-- See the License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-<!-- ============================================================================= -->
-
-<!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="core-bridges">
- <title>Core Bridges</title>
- <para>The function of a bridge is to consume messages from a source queue, and forward them to a
- target address, typically on a different ActiveMQ server.</para>
- <para>The source and target servers do not have to be in the same cluster which makes bridging
- suitable for reliably sending messages from one cluster to another, for instance across a
- WAN, or internet and where the connection may be unreliable.</para>
- <para>The bridge has built in resilience to failure so if the target server connection is lost,
- e.g. due to network failure, the bridge will retry connecting to the target until it comes
- back online. When it comes back online it will resume operation as normal.</para>
- <para>In summary, bridges are a way to reliably connect two separate ActiveMQ servers together.
- With a core bridge both source and target servers must be ActiveMQ servers.</para>
- <para>Bridges can be configured to provide <emphasis>once and only once</emphasis> delivery
- guarantees even in the event of the failure of the source or the target server. They do this
- by using duplicate detection (described in <xref linkend="duplicate-detection"/>).</para>
- <note>
- <para>Although they have similar function, don't confuse core bridges with JMS
- bridges!</para>
- <para>Core bridges are for linking a ActiveMQ node with another ActiveMQ node and do not use
- the JMS API. A JMS Bridge is used for linking any two JMS 1.1 compliant JMS providers.
- So, a JMS Bridge could be used for bridging to or from different JMS compliant messaging
- system. It's always preferable to use a core bridge if you can. Core bridges use
- duplicate detection to provide <emphasis>once and only once</emphasis> guarantees. To
- provide the same guarantee using a JMS bridge you would have to use XA which has a
- higher overhead and is more complex to configure.</para>
- </note>
- <section>
- <title>Configuring Bridges</title>
- <para>Bridges are configured in <literal>activemq-configuration.xml</literal>. Let's kick off
- with an example (this is actually from the bridge example):</para>
- <programlisting>
-<bridge name="my-bridge">
- <queue-name>jms.queue.sausage-factory</queue-name>
- <forwarding-address>jms.queue.mincing-machine</forwarding-address>
- <filter-string="name='aardvark'"/>
- <transformer-class-name>
- org.apache.activemq.jms.example.HatColourChangeTransformer
- </transformer-class-name>
- <retry-interval>1000</retry-interval>
- <ha>true</ha>
- <retry-interval-multiplier>1.0</retry-interval-multiplier>
- <initial-connect-attempts>-1</initial-connect-attempts>
- <reconnect-attempts>-1</reconnect-attempts>
- <failover-on-server-shutdown>false</failover-on-server-shutdown>
- <use-duplicate-detection>true</use-duplicate-detection>
- <confirmation-window-size>10000000</confirmation-window-size>
- <user>foouser</user>
- <password>foopassword</password>
- <static-connectors>
- <connector-ref>remote-connector</connector-ref>
- </static-connectors>
- <!-- alternative to static-connectors
- <discovery-group-ref discovery-group-name="bridge-discovery-group"/>
- -->
-</bridge></programlisting>
- <para>In the above example we have shown all the parameters its possible to configure for a
- bridge. In practice you might use many of the defaults so it won't be necessary to
- specify them all explicitly.</para>
- <para>Let's take a look at all the parameters in turn:</para>
- <itemizedlist>
- <listitem>
- <para><literal>name</literal> attribute. All bridges must have a unique name in the
- server.</para>
- </listitem>
- <listitem>
- <para><literal>queue-name</literal>. This is the unique name of the local queue that
- the bridge consumes from, it's a mandatory parameter.</para>
- <para>The queue must already exist by the time the bridge is instantiated at
- start-up.</para>
- <note>
- <para>If you're using JMS then normally the JMS configuration <literal
- >activemq-jms.xml</literal> is loaded after the core configuration file
- <literal>activemq-configuration.xml</literal> is loaded. If your bridge
- is consuming from a JMS queue then you'll need to make sure the JMS queue is
- also deployed as a core queue in the core configuration. Take a look at the
- bridge example for an example of how this is done.</para>
- </note>
- </listitem>
- <listitem>
- <para><literal>forwarding-address</literal>. This is the address on the target
- server that the message will be forwarded to. If a forwarding address is not
- specified, then the original address of the message will be retained.</para>
- </listitem>
- <listitem>
- <para><literal>filter-string</literal>. An optional filter string can be supplied.
- If specified then only messages which match the filter expression specified in
- the filter string will be forwarded. The filter string follows the ActiveMQ
- filter expression syntax described in <xref linkend="filter-expressions"
- />.</para>
- </listitem>
- <listitem>
- <para><literal>transformer-class-name</literal>. An optional transformer-class-name
- can be specified. This is the name of a user-defined class which implements the
- <literal>org.apache.activemq.core.server.cluster.Transformer</literal>
- interface.</para>
- <para>If this is specified then the transformer's <literal>transform()</literal>
- method will be invoked with the message before it is forwarded. This gives you
- the opportunity to transform the message's header or body before forwarding
- it.</para>
- </listitem>
- <listitem>
- <para><literal>ha</literal>. This optional parameter determines whether or not this
- bridge should support high availability. True means it will connect to any available
- server in a cluster and support failover. The default value is <literal
- >false</literal>.</para>
- </listitem>
- <listitem>
- <para><literal>retry-interval</literal>. This optional parameter determines the
- period in milliseconds between subsequent reconnection attempts, if the
- connection to the target server has failed. The default value is <literal
- >2000</literal>milliseconds.</para>
- </listitem>
- <listitem>
- <para><literal>retry-interval-multiplier</literal>. This optional parameter
- determines determines a multiplier to apply to the time since the last retry to
- compute the time to the next retry.</para>
- <para>This allows you to implement an <emphasis>exponential backoff</emphasis>
- between retry attempts.</para>
- <para>Let's take an example:</para>
- <para>If we set <literal>retry-interval</literal>to <literal>1000</literal> ms and
- we set <literal>retry-interval-multiplier</literal> to <literal>2.0</literal>,
- then, if the first reconnect attempt fails, we will wait <literal>1000</literal>
- ms then <literal>2000</literal> ms then <literal>4000</literal> ms between
- subsequent reconnection attempts.</para>
- <para>The default value is <literal>1.0</literal> meaning each reconnect attempt is
- spaced at equal intervals.</para>
- </listitem>
- <listitem>
- <para><literal>initial-connect-attempts</literal>. This optional parameter determines the
- total number of initial connect attempts the bridge will make before giving up and
- shutting down. A value of <literal>-1</literal> signifies an unlimited number of
- attempts. The default value is <literal>-1</literal>.</para>
- </listitem>
- <listitem>
- <para><literal>reconnect-attempts</literal>. This optional parameter determines the
- total number of reconnect attempts the bridge will make before giving up and
- shutting down. A value of <literal>-1</literal> signifies an unlimited number of
- attempts. The default value is <literal>-1</literal>.</para>
- </listitem>
- <listitem>
- <para><literal>failover-on-server-shutdown</literal>. This optional parameter
- determines whether the bridge will attempt to failover onto a backup server (if
- specified) when the target server is cleanly shutdown rather than
- crashed.</para>
- <para>The bridge connector can specify both a live and a backup server, if it
- specifies a backup server and this parameter is set to <literal>true</literal>
- then if the target server is <emphasis>cleanly</emphasis> shutdown the bridge
- connection will attempt to failover onto its backup. If the bridge connector has
- no backup server configured then this parameter has no effect. </para>
- <para>Sometimes you want a bridge configured with a live and a backup target server,
- but you don't want to failover to the backup if the live server is simply taken
- down temporarily for maintenance, this is when this parameter comes in
- handy.</para>
- <para>The default value for this parameter is <literal>false</literal>.</para>
- </listitem>
- <listitem>
- <para><literal>use-duplicate-detection</literal>. This optional parameter determines
- whether the bridge will automatically insert a duplicate id property into each
- message that it forwards.</para>
- <para>Doing so, allows the target server to perform duplicate detection on messages
- it receives from the source server. If the connection fails or server crashes,
- then, when the bridge resumes it will resend unacknowledged messages. This might
- result in duplicate messages being sent to the target server. By enabling
- duplicate detection allows these duplicates to be screened out and
- ignored.</para>
- <para>This allows the bridge to provide a <emphasis>once and only once</emphasis>
- delivery guarantee without using heavyweight methods such as XA (see <xref
- linkend="duplicate-detection"/> for more information).</para>
- <para>The default value for this parameter is <literal>true</literal>.</para>
- </listitem>
- <listitem>
- <para><literal>confirmation-window-size</literal>. This optional parameter
- determines the <literal>confirmation-window-size</literal> to use for the
- connection used to forward messages to the target node. This attribute is
- described in section <xref linkend="client-reconnection"/></para>
-
- <warning><para>When using the bridge to forward messages to an address which uses
- the <literal>BLOCK</literal> <literal>address-full-policy</literal> from a
- queue which has a <literal>max-size-bytes</literal> set it's important that
- <literal>confirmation-window-size</literal> is less than or equal to
- <literal>max-size-bytes</literal> to prevent the flow of messages from
- ceasing.</para>
- </warning>
-
- </listitem>
- <listitem>
- <para><literal>user</literal>. This optional parameter determines the user name to
- use when creating the bridge connection to the remote server. If it is not
- specified the default cluster user specified by <literal>cluster-user</literal>
- in <literal>activemq-configuration.xml</literal> will be used. </para>
- </listitem>
- <listitem>
- <para><literal>password</literal>. This optional parameter determines the password
- to use when creating the bridge connection to the remote server. If it is not
- specified the default cluster password specified by <literal
- >cluster-password</literal> in <literal>activemq-configuration.xml</literal>
- will be used. </para>
- </listitem>
- <listitem>
- <para><literal>static-connectors</literal> or <literal>discovery-group-ref</literal>.
- Pick either of these options to connect the bridge to the target server.
- </para>
- <para> The <literal>static-connectors</literal> is a list of <literal>connector-ref</literal>
- elements pointing to <literal>connector</literal> elements defined elsewhere.
- A <emphasis>connector</emphasis> encapsulates knowledge of what transport to
- use (TCP, SSL, HTTP etc) as well as the server connection parameters (host, port
- etc). For more information about what connectors are and how to configure them,
- please see <xref linkend="configuring-transports"/>.
- </para>
- <para>The <literal>discovery-group-ref</literal> element has one attribute -
- <literal>discovery-group-name</literal>. This attribute points to a
- <literal>discovery-group</literal> defined elsewhere. For more information about
- what discovery-groups are and how to configure them, please see
- <xref linkend="clusters.discovery-groups"/>.
- </para>
- </listitem>
- </itemizedlist>
- </section>
-</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/diverts.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/diverts.md b/docs/user-manual/en/diverts.md
new file mode 100644
index 0000000..60b00f7
--- /dev/null
+++ b/docs/user-manual/en/diverts.md
@@ -0,0 +1,114 @@
+Diverting and Splitting Message Flows
+=====================================
+
+ActiveMQ allows you to configure objects called *diverts* with some
+simple server configuration.
+
+Diverts allow you to transparently divert messages routed to one address
+to some other address, without making any changes to any client
+application logic.
+
+Diverts can be *exclusive*, meaning that the message is diverted to the
+new address, and does not go to the old address at all, or they can be
+*non-exclusive* which means the message continues to go the old address,
+and a *copy* of it is also sent to the new address. Non-exclusive
+diverts can therefore be used for *splitting* message flows, e.g. there
+may be a requirement to monitor every order sent to an order queue.
+
+Diverts can also be configured to have an optional message filter. If
+specified then only messages that match the filter will be diverted.
+
+Diverts can also be configured to apply a `Transformer`. If specified,
+all diverted messages will have the opportunity of being transformed by
+the `Transformer`.
+
+A divert will only divert a message to an address on the *same server*,
+however, if you want to divert to an address on a different server, a
+common pattern would be to divert to a local store-and-forward queue,
+then set up a bridge which consumes from that queue and forwards to an
+address on a different server.
+
+Diverts are therefore a very sophisticated concept, which when combined
+with bridges can be used to create interesting and complex routings. The
+set of diverts on a server can be thought of as a type of routing table
+for messages. Combining diverts with bridges allows you to create a
+distributed network of reliable routing connections between multiple
+geographically distributed servers, creating your global messaging mesh.
+
+Diverts are defined as xml in the `activemq-configuration.xml` file.
+There can be zero or more diverts in the file.
+
+Please see ? for a full working example showing you how to configure and
+use diverts.
+
+Let's take a look at some divert examples:
+
+Exclusive Divert
+================
+
+Let's take a look at an exclusive divert. An exclusive divert diverts
+all matching messages that are routed to the old address to the new
+address. Matching messages do not get routed to the old address.
+
+Here's some example xml configuration for an exclusive divert, it's
+taken from the divert example:
+
+ <divert name="prices-divert">
+ <address>jms.topic.priceUpdates</address>
+ <forwarding-address>jms.queue.priceForwarding</forwarding-address>
+ <filter string="office='New York'"/>
+ <transformer-class-name>
+ org.apache.activemq.jms.example.AddForwardingTimeTransformer
+ </transformer-class-name>
+ <exclusive>true</exclusive>
+ </divert>
+
+We define a divert called '`prices-divert`' that will divert any
+messages sent to the address '`jms.topic.priceUpdates`' (this
+corresponds to any messages sent to a JMS Topic called '`priceUpdates`')
+to another local address '`jms.queue.priceForwarding`' (this corresponds
+to a local JMS queue called '`priceForwarding`'
+
+We also specify a message filter string so only messages with the
+message property `office` with value `New York` will get diverted, all
+other messages will continue to be routed to the normal address. The
+filter string is optional, if not specified then all messages will be
+considered matched.
+
+In this example a transformer class is specified. Again this is
+optional, and if specified the transformer will be executed for each
+matching message. This allows you to change the messages body or
+properties before it is diverted. In this example the transformer simply
+adds a header that records the time the divert happened.
+
+This example is actually diverting messages to a local store and forward
+queue, which is configured with a bridge which forwards the message to
+an address on another ActiveMQ server. Please see the example for more
+details.
+
+Non-exclusive Divert
+====================
+
+Now we'll take a look at a non-exclusive divert. Non exclusive diverts
+are the same as exclusive diverts, but they only forward a *copy* of the
+message to the new address. The original message continues to the old
+address
+
+You can therefore think of non-exclusive diverts as *splitting* a
+message flow.
+
+Non exclusive diverts can be configured in the same way as exclusive
+diverts with an optional filter and transformer, here's an example
+non-exclusive divert, again from the divert example:
+
+ <divert name="order-divert">
+ <address>jms.queue.orders</address>
+ <forwarding-address>jms.topic.spyTopic</forwarding-address>
+ <exclusive>false</exclusive>
+ </divert>
+
+The above divert example takes a copy of every message sent to the
+address '`jms.queue.orders`' (Which corresponds to a JMS Queue called
+'`orders`') and sends it to a local address called
+'`jms.topic.SpyTopic`' (which corresponds to a JMS Topic called
+'`SpyTopic`').
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/diverts.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/diverts.xml b/docs/user-manual/en/diverts.xml
deleted file mode 100644
index b83c5c5..0000000
--- a/docs/user-manual/en/diverts.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- ============================================================================= -->
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
-<!-- contributor license agreements. See the NOTICE file distributed with -->
-<!-- this work for additional information regarding copyright ownership. -->
-<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
-<!-- (the "License"); you may not use this file except in compliance with -->
-<!-- the License. You may obtain a copy of the License at -->
-<!-- -->
-<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
-<!-- -->
-<!-- Unless required by applicable law or agreed to in writing, software -->
-<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
-<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
-<!-- See the License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-<!-- ============================================================================= -->
-
-<!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="diverts">
- <title>Diverting and Splitting Message Flows</title>
- <para>ActiveMQ allows you to configure objects called <emphasis>diverts</emphasis> with
- some simple server configuration.</para>
- <para>Diverts allow you to transparently divert messages routed to one address to some other
- address, without making any changes to any client application logic.</para>
- <para>Diverts can be <emphasis>exclusive</emphasis>, meaning that the message is diverted
- to the new address, and does not go to the old address at all, or they can be
- <emphasis>non-exclusive</emphasis> which means the message continues to go the old
- address, and a <emphasis>copy</emphasis> of it is also sent to the new address.
- Non-exclusive diverts can therefore be used for <emphasis>splitting</emphasis> message
- flows, e.g. there may be a requirement to monitor every order sent to an order queue.</para>
- <para>Diverts can also be configured to have an optional message filter. If specified then only
- messages that match the filter will be diverted.</para>
- <para>Diverts can also be configured to apply a <literal>Transformer</literal>. If specified,
- all diverted messages will have the opportunity of being transformed by the <literal
- >Transformer</literal>.</para>
- <para>A divert will only divert a message to an address on the <emphasis>same server</emphasis>,
- however, if you want to divert to an address on a different server, a common pattern would
- be to divert to a local store-and-forward queue, then set up a bridge which consumes from
- that queue and forwards to an address on a different server.</para>
- <para>Diverts are therefore a very sophisticated concept, which when combined with bridges can
- be used to create interesting and complex routings. The set of diverts on a server can be
- thought of as a type of routing table for messages. Combining diverts with bridges allows
- you to create a distributed network of reliable routing connections between multiple
- geographically distributed servers, creating your global messaging mesh.</para>
- <para>Diverts are defined as xml in the <literal>activemq-configuration.xml</literal> file. There can
- be zero or more diverts in the file.</para>
- <para>Please see <xref linkend="divert-example" /> for a full working
- example showing you how to configure and use diverts.</para>
- <para>Let's take a look at some divert examples:</para>
- <section>
- <title>Exclusive Divert</title>
- <para>Let's take a look at an exclusive divert. An exclusive divert diverts all matching
- messages that are routed to the old address to the new address. Matching messages do not
- get routed to the old address.</para>
- <para>Here's some example xml configuration for an exclusive divert, it's taken from the
- divert example:</para>
- <programlisting>
-<divert name="prices-divert">
- <address>jms.topic.priceUpdates</address>
- <forwarding-address>jms.queue.priceForwarding</forwarding-address>
- <filter string="office='New York'"/>
- <transformer-class-name>
- org.apache.activemq.jms.example.AddForwardingTimeTransformer
- </transformer-class-name>
- <exclusive>true</exclusive>
-</divert></programlisting>
- <para>We define a divert called '<literal>prices-divert</literal>' that will divert any
- messages sent to the address '<literal>jms.topic.priceUpdates</literal>' (this
- corresponds to any messages sent to a JMS Topic called '<literal
- >priceUpdates</literal>') to another local address '<literal
- >jms.queue.priceForwarding</literal>' (this corresponds to a local JMS queue called
- '<literal>priceForwarding</literal>'</para>
- <para>We also specify a message filter string so only messages with the message property
- <literal>office</literal> with value <literal>New York</literal> will get diverted,
- all other messages will continue to be routed to the normal address. The filter string
- is optional, if not specified then all messages will be considered matched.</para>
- <para>In this example a transformer class is specified. Again this is optional, and if
- specified the transformer will be executed for each matching message. This allows you to
- change the messages body or properties before it is diverted. In this example the
- transformer simply adds a header that records the time the divert happened.</para>
- <para>This example is actually diverting messages to a local store and forward queue, which
- is configured with a bridge which forwards the message to an address on another ActiveMQ
- server. Please see the example for more details.</para>
- </section>
- <section>
- <title>Non-exclusive Divert</title>
- <para>Now we'll take a look at a non-exclusive divert. Non exclusive diverts are the same as
- exclusive diverts, but they only forward a <emphasis>copy</emphasis> of the message to
- the new address. The original message continues to the old address</para>
- <para>You can therefore think of non-exclusive diverts as <emphasis>splitting</emphasis> a
- message flow.</para>
- <para>Non exclusive diverts can be configured in the same way as exclusive diverts with an
- optional filter and transformer, here's an example non-exclusive divert, again from the
- divert example:</para>
- <programlisting>
-<divert name="order-divert">
- <address>jms.queue.orders</address>
- <forwarding-address>jms.topic.spyTopic</forwarding-address>
- <exclusive>false</exclusive>
-</divert></programlisting>
- <para>The above divert example takes a copy of every message sent to the address '<literal
- >jms.queue.orders</literal>' (Which corresponds to a JMS Queue called '<literal
- >orders</literal>') and sends it to a local address called '<literal
- >jms.topic.SpyTopic</literal>' (which corresponds to a JMS Topic called '<literal
- >SpyTopic</literal>').</para>
- </section>
-</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/duplicate-detection.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/duplicate-detection.md b/docs/user-manual/en/duplicate-detection.md
new file mode 100644
index 0000000..b7776eb
--- /dev/null
+++ b/docs/user-manual/en/duplicate-detection.md
@@ -0,0 +1,161 @@
+Duplicate Message Detection
+===========================
+
+ActiveMQ includes powerful automatic duplicate message detection,
+filtering out duplicate messages without you having to code your own
+fiddly duplicate detection logic at the application level. This chapter
+will explain what duplicate detection is, how ActiveMQ uses it and how
+and where to configure it.
+
+When sending messages from a client to a server, or indeed from a server
+to another server, if the target server or connection fails sometime
+after sending the message, but before the sender receives a response
+that the send (or commit) was processed successfully then the sender
+cannot know for sure if the message was sent successfully to the
+address.
+
+If the target server or connection failed after the send was received
+and processed but before the response was sent back then the message
+will have been sent to the address successfully, but if the target
+server or connection failed before the send was received and finished
+processing then it will not have been sent to the address successfully.
+From the senders point of view it's not possible to distinguish these
+two cases.
+
+When the server recovers this leaves the client in a difficult
+situation. It knows the target server failed, but it does not know if
+the last message reached its destination ok. If it decides to resend the
+last message, then that could result in a duplicate message being sent
+to the address. If each message was an order or a trade then this could
+result in the order being fulfilled twice or the trade being double
+booked. This is clearly not a desirable situation.
+
+Sending the message(s) in a transaction does not help out either. If the
+server or connection fails while the transaction commit is being
+processed it is also indeterminate whether the transaction was
+successfully committed or not!
+
+To solve these issues ActiveMQ provides automatic duplicate messages
+detection for messages sent to addresses.
+
+Using Duplicate Detection for Message Sending
+=============================================
+
+Enabling duplicate message detection for sent messages is simple: you
+just need to set a special property on the message to a unique value.
+You can create the value however you like, as long as it is unique. When
+the target server receives the message it will check if that property is
+set, if it is, then it will check in its in memory cache if it has
+already received a message with that value of the header. If it has
+received a message with the same value before then it will ignore the
+message.
+
+> **Note**
+>
+> Using duplicate detection to move messages between nodes can give you
+> the same *once and only once* delivery guarantees as if you were using
+> an XA transaction to consume messages from source and send them to the
+> target, but with less overhead and much easier configuration than
+> using XA.
+
+If you're sending messages in a transaction then you don't have to set
+the property for *every* message you send in that transaction, you only
+need to set it once in the transaction. If the server detects a
+duplicate message for any message in the transaction, then it will
+ignore the entire transaction.
+
+The name of the property that you set is given by the value of
+`org.apache.activemq.api.core.Message.HDR_DUPLICATE_DETECTION_ID`, which
+is `_HQ_DUPL_ID`
+
+The value of the property can be of type `byte[]` or `SimpleString` if
+you're using the core API. If you're using JMS it must be a `String`,
+and its value should be unique. An easy way of generating a unique id is
+by generating a UUID.
+
+Here's an example of setting the property using the core API:
+
+ ...
+
+ ClientMessage message = session.createMessage(true);
+
+ SimpleString myUniqueID = "This is my unique id"; // Could use a UUID for this
+
+ message.setStringProperty(HDR_DUPLICATE_DETECTION_ID, myUniqueID);
+
+ ...
+
+And here's an example using the JMS API:
+
+ ...
+
+ Message jmsMessage = session.createMessage();
+
+ String myUniqueID = "This is my unique id"; // Could use a UUID for this
+
+ message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID);
+
+ ...
+
+Configuring the Duplicate ID Cache
+==================================
+
+The server maintains caches of received values of the
+`org.apache.activemq.core.message.impl.HDR_DUPLICATE_DETECTION_ID`
+property sent to each address. Each address has its own distinct cache.
+
+The cache is a circular fixed size cache. If the cache has a maximum
+size of `n` elements, then the `n + 1`th id stored will overwrite the
+`0`th element in the cache.
+
+The maximum size of the cache is configured by the parameter
+`id-cache-size` in `activemq-configuration.xml`, the default value is
+`2000` elements.
+
+The caches can also be configured to persist to disk or not. This is
+configured by the parameter `persist-id-cache`, also in
+`activemq-configuration.xml`. If this is set to `true` then each id will
+be persisted to permanent storage as they are received. The default
+value for this parameter is `true`.
+
+> **Note**
+>
+> When choosing a size of the duplicate id cache be sure to set it to a
+> larger enough size so if you resend messages all the previously sent
+> ones are in the cache not having been overwritten.
+
+Duplicate Detection and Bridges
+===============================
+
+Core bridges can be configured to automatically add a unique duplicate
+id value (if there isn't already one in the message) before forwarding
+the message to it's target. This ensures that if the target server
+crashes or the connection is interrupted and the bridge resends the
+message, then if it has already been received by the target server, it
+will be ignored.
+
+To configure a core bridge to add the duplicate id header, simply set
+the `use-duplicate-detection` to `true` when configuring a bridge in
+`activemq-configuration.xml`.
+
+The default value for this parameter is `true`.
+
+For more information on core bridges and how to configure them, please
+see ?.
+
+Duplicate Detection and Cluster Connections
+===========================================
+
+Cluster connections internally use core bridges to move messages
+reliable between nodes of the cluster. Consequently they can also be
+configured to insert the duplicate id header for each message they move
+using their internal bridges.
+
+To configure a cluster connection to add the duplicate id header, simply
+set the `use-duplicate-detection` to `true` when configuring a cluster
+connection in `activemq-configuration.xml`.
+
+The default value for this parameter is `true`.
+
+For more information on cluster connections and how to configure them,
+please see ?.
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/duplicate-detection.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/duplicate-detection.xml b/docs/user-manual/en/duplicate-detection.xml
deleted file mode 100644
index 605107a..0000000
--- a/docs/user-manual/en/duplicate-detection.xml
+++ /dev/null
@@ -1,148 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- ============================================================================= -->
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
-<!-- contributor license agreements. See the NOTICE file distributed with -->
-<!-- this work for additional information regarding copyright ownership. -->
-<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
-<!-- (the "License"); you may not use this file except in compliance with -->
-<!-- the License. You may obtain a copy of the License at -->
-<!-- -->
-<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
-<!-- -->
-<!-- Unless required by applicable law or agreed to in writing, software -->
-<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
-<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
-<!-- See the License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-<!-- ============================================================================= -->
-
-<!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="duplicate-detection">
- <title>Duplicate Message Detection</title>
- <para>ActiveMQ includes powerful automatic duplicate message detection, filtering out
- duplicate messages without you having to code your own fiddly duplicate detection logic at
- the application level. This chapter will explain what duplicate detection is, how ActiveMQ
- uses it and how and where to configure it.</para>
- <para>When sending messages from a client to a server, or indeed from a server to another
- server, if the target server or connection fails sometime after sending the message, but
- before the sender receives a response that the send (or commit) was processed successfully
- then the sender cannot know for sure if the message was sent successfully to the
- address.</para>
- <para>If the target server or connection failed after the send was received and processed but
- before the response was sent back then the message will have been sent to the address
- successfully, but if the target server or connection failed before the send was received and
- finished processing then it will not have been sent to the address successfully. From the
- senders point of view it's not possible to distinguish these two cases.</para>
- <para>When the server recovers this leaves the client in a difficult situation. It knows the
- target server failed, but it does not know if the last message reached its destination ok.
- If it decides to resend the last message, then that could result in a duplicate message
- being sent to the address. If each message was an order or a trade then this could result in
- the order being fulfilled twice or the trade being double booked. This is clearly not a
- desirable situation.</para>
- <para>Sending the message(s) in a transaction does not help out either. If the server or
- connection fails while the transaction commit is being processed it is also indeterminate
- whether the transaction was successfully committed or not!</para>
- <para>To solve these issues ActiveMQ provides automatic duplicate messages detection for
- messages sent to addresses.</para>
- <section>
- <title>Using Duplicate Detection for Message Sending</title>
- <para>Enabling duplicate message detection for sent messages is simple: you just need to set
- a special property on the message to a unique value. You can create the value however
- you like, as long as it is unique. When the target server receives the message it will
- check if that property is set, if it is, then it will check in its in memory cache if it
- has already received a message with that value of the header. If it has received a
- message with the same value before then it will ignore the message.</para>
- <note>
- <para>Using duplicate detection to move messages between nodes can give you the same
- <emphasis>once and only once</emphasis> delivery guarantees as if you were using
- an XA transaction to consume messages from source and send them to the target, but
- with less overhead and much easier configuration than using XA.</para>
- </note>
- <para>If you're sending messages in a transaction then you don't have to set the property
- for <emphasis>every</emphasis> message you send in that transaction, you only need to
- set it once in the transaction. If the server detects a duplicate message for any
- message in the transaction, then it will ignore the entire transaction.</para>
- <para>The name of the property that you set is given by the value of <literal
- >org.apache.activemq.api.core.Message.HDR_DUPLICATE_DETECTION_ID</literal>, which
- is <literal>_HQ_DUPL_ID</literal></para>
- <para>The value of the property can be of type <literal>byte[]</literal> or <literal
- >SimpleString</literal> if you're using the core API. If you're using JMS it must be
- a <literal>String</literal>, and its value should be unique. An easy way of generating
- a unique id is by generating a UUID.</para>
- <para>Here's an example of setting the property using the core API:</para>
- <programlisting>
-...
-
-ClientMessage message = session.createMessage(true);
-
-SimpleString myUniqueID = "This is my unique id"; // Could use a UUID for this
-
-message.setStringProperty(HDR_DUPLICATE_DETECTION_ID, myUniqueID);
-
-...</programlisting>
- <para>And here's an example using the JMS API:</para>
- <programlisting>
-...
-
-Message jmsMessage = session.createMessage();
-
-String myUniqueID = "This is my unique id"; // Could use a UUID for this
-
-message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID);
-
-...</programlisting>
- </section>
- <section id="duplicate.id.cache">
- <title>Configuring the Duplicate ID Cache</title>
- <para>The server maintains caches of received values of the <literal
- >org.apache.activemq.core.message.impl.HDR_DUPLICATE_DETECTION_ID</literal> property
- sent to each address. Each address has its own distinct cache.</para>
- <para>The cache is a circular fixed size cache. If the cache has a maximum size of <literal
- >n</literal> elements, then the <literal>n + 1</literal>th id stored will overwrite
- the <literal>0</literal>th element in the cache.</para>
- <para>The maximum size of the cache is configured by the parameter <literal
- >id-cache-size</literal> in <literal>activemq-configuration.xml</literal>, the default
- value is <literal>2000</literal> elements.</para>
- <para>The caches can also be configured to persist to disk or not. This is configured by the
- parameter <literal>persist-id-cache</literal>, also in <literal
- >activemq-configuration.xml</literal>. If this is set to <literal>true</literal> then
- each id will be persisted to permanent storage as they are received. The default value
- for this parameter is <literal>true</literal>.</para>
- <note>
- <para>When choosing a size of the duplicate id cache be sure to set it to a larger
- enough size so if you resend messages all the previously sent ones are in the cache
- not having been overwritten.</para>
- </note>
- </section>
- <section>
- <title>Duplicate Detection and Bridges</title>
- <para>Core bridges can be configured to automatically add a unique duplicate id value (if there
- isn't already one in the message) before forwarding the message to it's target. This
- ensures that if the target server crashes or the connection is interrupted and the
- bridge resends the message, then if it has already been received by the target server,
- it will be ignored.</para>
- <para>To configure a core bridge to add the duplicate id header, simply set the <parameter
- >use-duplicate-detection</parameter> to <literal>true</literal> when configuring a
- bridge in <literal>activemq-configuration.xml</literal>.</para>
- <para>The default value for this parameter is <literal>true</literal>.</para>
- <para>For more information on core bridges and how to configure them, please see
- <xref linkend="core-bridges" />.</para>
- </section>
- <section>
- <title>Duplicate Detection and Cluster Connections</title>
- <para>Cluster connections internally use core bridges to move messages reliable between
- nodes of the cluster. Consequently they can also be configured to insert the duplicate
- id header for each message they move using their internal bridges.</para>
- <para>To configure a cluster connection to add the duplicate id header, simply set the
- <parameter>use-duplicate-detection</parameter> to <literal>true</literal> when
- configuring a cluster connection in <literal>activemq-configuration.xml</literal>.</para>
- <para>The default value for this parameter is <literal>true</literal>.</para>
- <para>For more information on cluster connections and how to configure them, please see <xref
- linkend="clusters"/>.</para>
- </section>
-</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/4245a6b4/docs/user-manual/en/embedding-activemq.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/embedding-activemq.md b/docs/user-manual/en/embedding-activemq.md
new file mode 100644
index 0000000..0c29d59
--- /dev/null
+++ b/docs/user-manual/en/embedding-activemq.md
@@ -0,0 +1,225 @@
+Embedding ActiveMQ
+==================
+
+ActiveMQ is designed as set of simple Plain Old Java Objects (POJOs).
+This means ActiveMQ can be instantiated and run in any dependency
+injection framework such as JBoss Microcontainer, Spring or Google
+Guice. It also means that if you have an application that could use
+messaging functionality internally, then it can *directly instantiate*
+ActiveMQ clients and servers in its own application code to perform that
+functionality. We call this *embedding* ActiveMQ.
+
+Examples of applications that might want to do this include any
+application that needs very high performance, transactional, persistent
+messaging but doesn't want the hassle of writing it all from scratch.
+
+Embedding ActiveMQ can be done in very few easy steps. Instantiate the
+configuration object, instantiate the server, start it, and you have a
+ActiveMQ running in your virtual machine. It's as simple and easy as
+that.
+
+Simple Config File Embedding
+============================
+
+The simplest way to embed ActiveMQ is to use the embedded wrapper
+classes and configure ActiveMQ through its configuration files. There
+are two different helper classes for this depending on whether your
+using the ActiveMQ Core API or JMS.
+
+Core API Only
+-------------
+
+For instantiating a core ActiveMQ Server only, the steps are pretty
+simple. The example requires that you have defined a configuration file
+`activemq-configuration.xml` in your classpath:
+
+ import org.apache.activemq.core.server.embedded.EmbeddedActiveMQ;
+
+ ...
+
+ EmbeddedActiveMQ embedded = new EmbeddedActiveMQ();
+ embedded.start();
+
+ ClientSessionFactory nettyFactory = ActiveMQClient.createClientSessionFactory(
+ new TransportConfiguration(
+ InVMConnectorFactory.class.getName()));
+
+ ClientSession session = factory.createSession();
+
+ session.createQueue("example", "example", true);
+
+ ClientProducer producer = session.createProducer("example");
+
+ ClientMessage message = session.createMessage(true);
+
+ message.getBody().writeString("Hello");
+
+ producer.send(message);
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer("example");
+
+ ClientMessage msgReceived = consumer.receive();
+
+ System.out.println("message = " + msgReceived.getBody().readString());
+
+ session.close();
+
+The `EmbeddedActiveMQ` class has a few additional setter methods that
+allow you to specify a different config file name as well as other
+properties. See the javadocs for this class for more details.
+
+JMS API
+-------
+
+JMS embedding is simple as well. This example requires that you have
+defined the config files `activemq-configuration.xml`,
+`activemq-jms.xml`, and a `activemq-users.xml` if you have security
+enabled. Let's also assume that a queue and connection factory has been
+defined in the `activemq-jms.xml` config file.
+
+ import org.apache.activemq.jms.server.embedded.EmbeddedJMS;
+
+ ...
+
+ EmbeddedJMS jms = new EmbeddedJMS();
+ jms.start();
+
+ // This assumes we have configured activemq-jms.xml with the appropriate config information
+ ConnectionFactory connectionFactory = jms.lookup("ConnectionFactory");
+ Destination destination = jms.lookup("/example/queue");
+
+ ... regular JMS code ...
+
+By default, the `EmbeddedJMS` class will store component entries defined
+within your `activemq-jms.xml` file in an internal concurrent hash map.
+The `EmbeddedJMS.lookup()` method returns components stored in this map.
+If you want to use JNDI, call the `EmbeddedJMS.setContext()` method with
+the root JNDI context you want your components bound into. See the
+javadocs for this class for more details on other config options.
+
+POJO instantiation - Embedding Programmatically
+===============================================
+
+You can follow this step-by-step guide to programmatically embed the
+core, non-JMS ActiveMQ Server instance:
+
+Create the configuration object - this contains configuration
+information for a ActiveMQ instance. The setter methods of this class
+allow you to programmatically set configuration options as describe in
+the ? section.
+
+The acceptors are configured through `ConfigurationImpl`. Just add the
+`NettyAcceptorFactory` on the transports the same way you would through
+the main configuration file.
+
+ import org.apache.activemq.core.config.Configuration;
+ import org.apache.activemq.core.config.impl.ConfigurationImpl;
+
+ ...
+
+ Configuration config = new ConfigurationImpl();
+ HashSet<TransportConfiguration> transports = new HashSet<TransportConfiguration>();
+
+ transports.add(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
+ transports.add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
+
+ config.setAcceptorConfigurations(transports);
+
+You need to instantiate an instance of
+`org.apache.activemq.api.core.server.embedded.EmbeddedActiveMQ` and add
+the configuration object to it.
+
+ import org.apache.activemq.api.core.server.ActiveMQ;
+ import org.apache.activemq.core.server.embedded.EmbeddedActiveMQ;
+
+ ...
+
+ EmbeddedActiveMQ server = new EmbeddedActiveMQ();
+ server.setConfiguration(config);
+
+ server.start();
+
+You also have the option of instantiating `ActiveMQServerImpl` directly:
+
+ ActiveMQServer server = new ActiveMQServerImpl(config);
+ server.start();
+
+For JMS POJO instantiation, you work with the EmbeddedJMS class instead
+as described earlier. First you define the configuration
+programmatically for your ConnectionFactory and Destination objects,
+then set the JmsConfiguration property of the EmbeddedJMS class. Here is
+an example of this:
+
+ // Step 1. Create ActiveMQ core configuration, and set the properties accordingly
+ Configuration configuration = new ConfigurationImpl();
+ configuration.setPersistenceEnabled(false);
+ configuration.setSecurityEnabled(false);
+ configuration.getAcceptorConfigurations().add(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
+
+ // Step 2. Create the JMS configuration
+ JMSConfiguration jmsConfig = new JMSConfigurationImpl();
+
+ // Step 3. Configure the JMS ConnectionFactory
+ TransportConfiguration connectorConfig = new TransportConfiguration(NettyConnectorFactory.class.getName());
+ ConnectionFactoryConfiguration cfConfig = new ConnectionFactoryConfigurationImpl("cf", connectorConfig, "/cf");
+ jmsConfig.getConnectionFactoryConfigurations().add(cfConfig);
+
+ // Step 4. Configure the JMS Queue
+ JMSQueueConfiguration queueConfig = new JMSQueueConfigurationImpl("queue1", null, false, "/queue/queue1");
+ jmsConfig.getQueueConfigurations().add(queueConfig);
+
+ // Step 5. Start the JMS Server using the ActiveMQ core server and the JMS configuration
+ EmbeddedJMS jmsServer = new EmbeddedJMS();
+ jmsServer.setConfiguration(configuration);
+ jmsServer.setJmsConfiguration(jmsConfig);
+ jmsServer.start();
+
+Please see ? for an example which shows how to setup and run ActiveMQ
+embedded with JMS.
+
+Dependency Frameworks
+=====================
+
+You may also choose to use a dependency injection framework such as
+JBoss Micro Container or Spring Framework. See ? for more details on
+Spring and ActiveMQ, but here's how you would do things with the JBoss
+Micro Container.
+
+ActiveMQ standalone uses JBoss Micro Container as the injection
+framework. `ActiveMQBootstrapServer` and `activemq-beans.xml` which are
+part of the ActiveMQ distribution provide a very complete implementation
+of what's needed to bootstrap the server using JBoss Micro Container.
+
+When using JBoss Micro Container, you need to provide an XML file
+declaring the `ActiveMQServer` and `Configuration` object, you can also
+inject a security manager and a MBean server if you want, but those are
+optional.
+
+A very basic XML Bean declaration for the JBoss Micro Container would
+be:
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <deployment xmlns="urn:jboss:bean-deployer:2.0">
+ <!-- The core configuration -->
+ <bean name="Configuration"
+ class="org.apache.activemq.core.config.impl.FileConfiguration">
+ </bean>
+
+ <!-- The core server -->
+ <bean name="ActiveMQServer"
+ class="org.apache.activemq.core.server.impl.ActiveMQServerImpl">
+ <constructor>
+ <parameter>
+ <inject bean="Configuration"/>
+ </parameter>
+ </constructor>
+ </bean>
+ </deployment>
+
+`ActiveMQBootstrapServer` provides an easy encapsulation of JBoss Micro
+Container.
+
+ ActiveMQBootstrapServer bootStrap = new ActiveMQBootstrapServer(new String[] {"activemq-beans.xml"});
+ bootStrap.run();