http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/configuration-index.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/configuration-index.xml b/docs/user-manual/en/configuration-index.xml new file mode 100644 index 0000000..b3cc162 --- /dev/null +++ b/docs/user-manual/en/configuration-index.xml @@ -0,0 +1,705 @@ +<?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 AttributionâShare 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. a --> +<!-- ============================================================================= --> + +<!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 "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="configuration-index"> + <title>Configuration Reference</title> + <para>This section is a quick index for looking up configuration. Click on the element name to + go to the specific chapter.</para> + <section id="server.configuration"> + <title>Server Configuration</title> + <section> + <title>hornetq-configuration.xml</title> + <para>This is the main core server configuration file.</para> + <table frame="topbot" border="2"> + <title>Server Configuration</title> + <tgroup cols="4"> + <colspec colname="c1" colnum="1"/> + <colspec colname="c2" colnum="2"/> + <colspec colname="c3" colnum="3"/> + <colspec colname="c4" colnum="4"/> + <thead> + <row> + <entry>Element Name</entry> + <entry>Element Type</entry> + <entry>Description</entry> + <entry>Default</entry> + </row> + </thead> + <!-- The options reference is generated from the schema. If something is wrong + in the reference, it must be fixed in the annotations present in the + schema. --> + <xi:include href="../target/generated-resources/xml/xslt/hornetq-configuration.xml" + xmlns:xi="http://www.w3.org/2001/XInclude"/> + </tgroup> + </table> + </section> + <section> + <title>hornetq-jms.xml</title> + <para>This is the configuration file used by the server side JMS service to load JMS + Queues, Topics and Connection Factories.</para> + <table frame="topbot" border="2"> + <title>JMS Server Configuration</title> + <tgroup cols="4"> + <colspec colname="c1" colnum="1"/> + <colspec colname="c2" colnum="2"/> + <colspec colname="c3" colnum="3"/> + <colspec colname="c4" colnum="4"/> + <thead> + <row> + <entry>Element Name</entry> + <entry>Element Type</entry> + <entry>Description</entry> + <entry>Default</entry> + </row> + </thead> + <tbody> + <row> + <entry> + <link linkend="using-jms.server.configuration">connection-factory</link> + </entry> + <entry>ConnectionFactory</entry> + <entry>a list of connection factories to create and add to JNDI</entry> + <entry/> + </row> + </tbody> + </tgroup> + </table> + <para></para> + <para></para> + <para>Continued..</para> + <informaltable frame="topbot"> + <tgroup cols="4"> + <colspec colname="c1" colnum="1"/> + <colspec colname="c2" colnum="2"/> + <colspec colname="c3" colnum="3"/> + <colspec colname="c4" colnum="4"/> + <tbody> + <row> + <entry id="configuration.connection-factory.signature"> + <link linkend="using-jms.configure.factory.types">connection-factory.signature (attribute)</link> + </entry> + <entry>String</entry> + <entry>Type of connection factory</entry> + <entry>generic</entry> + </row> + <row> + <entry id="configuration.connection-factory.signature.xa"> + <link linkend="using-jms.configure.factory.types">connection-factory.xa</link> + </entry> + <entry>Boolean</entry> + <entry>If it is a XA connection factory</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.auto-group"> + <link linkend="message-grouping.jmsconfigure">connection-factory.auto-group</link> + </entry> + <entry>Boolean</entry> + <entry>whether or not message grouping is automatically used</entry> + <entry>false</entry> + </row> + <row> + <entry><link linkend="clusters">connection-factory.connectors</link> + </entry> + <entry>String</entry> + <entry>A list of connectors used by the connection factory</entry> + <entry /> + </row> + <row> + <entry><link linkend="clusters" + >connection-factory.connectors.connector-ref.connector-name (attribute)</link> + </entry> + <entry>String</entry> + <entry>Name of the connector to connect to the live server</entry> + <entry /> + </row> + <row> + <entry><link linkend="clusters" + >connection-factory.discovery-group-ref.discovery-group-name (attribute)</link> + </entry> + <entry>String</entry> + <entry>Name of discovery group used by this connection factory</entry> + <entry /> + </row> + <row> + <!-- FIXME documented but does not exist? --> + <entry id="configuration.connection-factory.discovery-initial-wait-timeout"> + <link linkend="clusters" + >connection-factory.discovery-initial-wait-timeout</link> + </entry> + <entry>Long</entry> + <entry>the initial time to wait (in ms) for discovery groups to wait for + broadcasts</entry> + <entry>10000</entry> + </row> + <row> + <entry id="configuration.connection-factory.block-on-acknowledge"> + <link linkend="send-guarantees.nontrans.acks">connection-factory.block-on-acknowledge</link> + </entry> + <entry>Boolean</entry> + <entry>whether or not messages are acknowledged synchronously</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.block-on-non-durable-send"> + <link linkend="non-transactional-sends">connection-factory.block-on-non-durable-send</link> + </entry> + <entry>Boolean</entry> + <entry>whether or not non-durable messages are sent synchronously</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.block-on-durable-send"> + <link linkend="non-transactional-sends">connection-factory.block-on-durable-send</link> + </entry> + <entry>Boolean</entry> + <entry>whether or not durable messages are sent synchronously</entry> + <entry>true</entry> + </row> + <row> + <entry id="configuration.connection-factory.call-timeout">connection-factory.call-timeout</entry> + <entry>Long</entry> + <entry>the timeout (in ms) for remote calls</entry> + <entry>30000</entry> + </row> + <row> + <entry id="configuration.connection-factory.client-failure-check-period"> + <link linkend="dead.connections">connection-factory.client-failure-check-period</link> + </entry> + <entry>Long</entry> + <entry>the period (in ms) after which the client will consider the + connection failed after not receiving packets from the + server</entry> + <entry>30000</entry> + </row> + <row> + <entry id="configuration.connection-factory.client-id"> + <link linkend="using-jms.clientid">connection-factory.client-id</link> + </entry> + <entry>String</entry> + <entry>the pre-configured client ID for the connection factory</entry> + <entry>null</entry> + </row> + <row> + <entry id="configuration.connection-factory.connection-load-balancing-policy-class-name"> + <link linkend="clusters"> + connection-factory.connection-load-balancing-policy-class-name</link> + </entry> + <entry>String</entry> + <entry>the name of the load balancing class</entry> + <entry>org.hornetq.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy</entry> + </row> + <row> + <entry id="configuration.connection-factory.connection-ttl"> + <link linkend="dead.connections">connection-factory.connection-ttl</link> + </entry> + <entry>Long</entry> + <entry>the time to live (in ms) for connections</entry> + <entry>1 * 60000</entry> + </row> + <row> + <entry id="configuration.connection-factory.consumer-max-rate"> + <link linkend="flow-control.rate.core.api">connection-factory.consumer-max-rate</link></entry> + <entry>Integer</entry> + <entry>the fastest rate a consumer may consume messages per + second</entry> + <entry>-1</entry> + </row> + <row> + <entry id="configuration.connection-factory.consumer-window-size"> + <link linkend="flow-control.core.api">connection-factory.consumer-window-size</link></entry> + <entry>Integer</entry> + <entry>the window size (in bytes) for consumer flow control</entry> + <entry>1024 * 1024</entry> + </row> + <row> + <entry id="configuration.connection-factory.dups-ok-batch-size"> + <link linkend="using-jms.dupsokbatchsize">connection-factory.dups-ok-batch-size</link></entry> + <entry>Integer</entry> + <entry>the batch size (in bytes) between acknowledgements when using + DUPS_OK_ACKNOWLEDGE mode</entry> + <entry>1024 * 1024</entry> + </row> + <row> + <entry><link linkend="ha.automatic.failover" + >connection-factory.failover-on-initial-connection</link></entry> + <entry>Boolean</entry> + <entry>whether or not to failover to backup on event that initial connection to live server fails</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.failover-on-server-shutdown"> + <link linkend="ha.automatic.failover">connection-factory.failover-on-server-shutdown</link></entry> + <entry>Boolean</entry> + <entry>whether or not to failover on server shutdown</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.min-large-message-size"> + <link linkend="large-messages.core.config">connection-factory.min-large-message-size</link></entry> + <entry>Integer</entry> + <entry>the size (in bytes) before a message is treated as large</entry> + <entry>100 * 1024</entry> + </row> + <row> + <entry id="configuration.connection-factory.avoid-large-messages"> + <link linkend="large.message.configuring">connection-factory.avoid-large-messages</link></entry> + <entry>Boolean</entry> + <entry>If compress large messages and send them as regular messages if possible</entry> + <entry>false</entry> + </row> + <row> + <entry><link linkend="clusters" + >connection-factory.cache-large-message-client</link></entry> + <entry>Boolean</entry> + <entry>If true clients using this connection factory will hold the large + message body on temporary files.</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.pre-acknowledge"> + <link linkend="pre-acknowledge.configure">connection-factory.pre-acknowledge</link></entry> + <entry>Boolean</entry> + <entry>whether messages are pre acknowledged by the server before + sending</entry> + <entry>false</entry> + </row> + <row> + <entry id="configuration.connection-factory.producer-max-rate"> + <link linkend="flow-control.producer.rate.core.api">connection-factory.producer-max-rate</link></entry> + <entry>Integer</entry> + <entry>the maximum rate of messages per second that can be sent</entry> + <entry>-1</entry> + </row> + <row> + <entry><link linkend="client-reconnection" + >connection-factory.producer-window-size</link></entry> + <entry>Integer</entry> + <entry>the window size in bytes for producers sending messages</entry> + <entry>1024 * 1024</entry> + </row> + <row> + <entry id="configuration.connection-factory.confirmation-window-size"> + <link linkend="client-reconnection">connection-factory.confirmation-window-size</link> + </entry> + <entry>Integer</entry> + <entry>the window size (in bytes) for reattachment confirmations</entry> + <entry>1024 * 1024</entry> + </row> + <row> + <entry id="configuration.connection-factory.reconnect-attempts"> + <link linkend="client-reconnection">connection-factory.reconnect-attempts</link> + </entry> + <entry>Integer</entry> + <entry>maximum number of retry attempts, -1 signifies infinite</entry> + <entry>0</entry> + </row> + <row> + <entry id="configuration.connection-factory.retry-interval"> + <link linkend="client-reconnection">connection-factory.retry-interval</link> + </entry> + <entry>Long</entry> + <entry>the time (in ms) to retry a connection after failing</entry> + <entry>2000</entry> + </row> + <row> + <entry id="configuration.connection-factory.retry-interval-multiplier"> + <link linkend="client-reconnection">connection-factory.retry-interval-multiplier</link> + </entry> + <entry>Double</entry> + <entry>multiplier to apply to successive retry intervals</entry> + <entry>1.0</entry> + </row> + <row> + <entry><link linkend="client-reconnection" + >connection-factory.max-retry-interval</link></entry> + <entry>Integer</entry> + <entry>The maximum retry interval in the case a retry-interval-multiplier has been specified</entry> + <entry>2000</entry> + </row> + <row> + <entry id="configuration.connection-factory.scheduled-thread-pool-max-size"> + <link linkend="thread-pooling.client.side">connection-factory.scheduled-thread-pool-max-size</link> + </entry> + <entry>Integer</entry> + <entry>the size of the <emphasis>scheduled thread</emphasis> pool</entry> + <entry>5</entry> + </row> + <row> + <entry id="configuration.connection-factory.thread-pool-max-size"> + <link linkend="thread-pooling.client.side">connection-factory.thread-pool-max-size</link> + </entry> + <entry>Integer</entry> + <entry>the size of the thread pool</entry> + <entry>-1</entry> + </row> + <row> + <entry id="configuration.connection-factory.transaction-batch-size"> + <link linkend="using-jms.txbatchsize"> + connection-factory.transaction-batch-size</link> + </entry> + <entry>Integer</entry> + <entry>the batch size (in bytes) between acknowledgements when using a + transactional session</entry> + <entry>1024 * 1024</entry> + </row> + <row> + <entry id="configuration.connection-factory.use-global-pools"> + <link linkend="thread-pooling.client.side">connection-factory.use-global-pools</link> + </entry> + <entry>Boolean</entry> + <entry>whether or not to use a global thread pool for threads</entry> + <entry>true</entry> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >queue</link></entry> + <entry>Queue</entry> + <entry>a queue to create and add to JNDI</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration">queue.name + (attribute)</link></entry> + <entry>String</entry> + <entry>unique name of the queue</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >queue.entry</link></entry> + <entry>String</entry> + <entry>context where the queue will be bound in JNDI (there can be + many)</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >queue.durable</link></entry> + <entry>Boolean</entry> + <entry>is the queue durable?</entry> + <entry>true</entry> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >queue.filter</link></entry> + <entry>String</entry> + <entry>optional filter expression for the queue</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >topic</link></entry> + <entry>Topic</entry> + <entry>a topic to create and add to JNDI</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration">topic.name + (attribute)</link></entry> + <entry>String</entry> + <entry>unique name of the topic</entry> + <entry/> + </row> + <row> + <entry><link linkend="using-jms.server.configuration" + >topic.entry</link></entry> + <entry>String</entry> + <entry>context where the topic will be bound in JNDI (there can be + many)</entry> + <entry/> + </row> + </tbody> + </tgroup> + </informaltable> + </section> + + <section id="configuration.masked-password"> + <title>Using Masked Passwords in Configuration Files</title> + <para>By default all passwords in HornetQ server's configuration files are in plain text form. This usually poses no security issues as those + files should be well protected from unauthorized accessing. However, in some circumstances a user doesn't want to expose its passwords to more + eyes than necessary. </para> + + <para>HornetQ can be configured to use 'masked' passwords in its configuration files. A masked password is an obscure string representation + of a real password. To mask a password a user will use an 'encoder'. The encoder takes in the real password and outputs the masked version. + A user can then replace the real password in the configuration files with the new masked password. + When HornetQ loads a masked password, it uses a suitable 'decoder' to decode it into real password.</para> + + <para>HornetQ provides a default password encoder and decoder. Optionally users can use or implement their own encoder and decoder for + masking the passwords.</para> + + <section> <title>Password Masking in Server Configuration File</title> + + <section> <title>The password masking property</title> + + <para>The server configuration file has a property that defines the default masking behaviors over the entire file scope.</para> + + <para><literal>mask-password</literal>: this boolean type property indicates if a password should be masked or not. Set it to "true" + if you want your passwords masked. The default value is "false".</para> + </section> + + <section> <title>Specific masking behaviors</title> + + <section> <title>cluster-password</title> + + <para>The nature of the value of cluster-password is subject to the value of property 'mask-password'. If it is true + the cluster-password is masked.</para> + </section> + + <section> <title>Passwords in connectors and acceptors</title> + + <para>In the server configuration, Connectors and Acceptors sometimes needs to specify passwords. For example + if a users wants to use an SSL-enabled NettyAcceptor, it can specify a key-store-password and a trust-store-password. Because + Acceptors and Connectors are pluggable implementations, each transport will have different password masking needs.</para> + + <para>When a Connector or Acceptor configuration is initialised, HornetQ will add the "mask-password" and + "password-codec" values to the Connector or Acceptors params using the keys <literal>hornetq.usemaskedpassword</literal> + and <literal>hornetq.passwordcodec</literal> respectively. The Netty and InVM implementations will use these + as needed and any other implementations will have access to these to use if they so wish.</para> + </section> + + <section> <title>Passwords in Core Bridge configurations</title> + + <para>Core Bridges are configured in the server configuration file and so the masking of its 'password' properties + follows the same rules as that of 'cluster-password'.</para> + </section> + </section> + + <section> <title>Examples</title> + + <para>The following table summarizes the relations among the above-mentioned properties</para> + + <table frame="topbot" border="2"> + <tgroup cols="4"> + <colspec colname="c1" colnum="1"/> + <colspec colname="c2" colnum="2"/> + <colspec colname="c3" colnum="3"/> + <colspec colname="c4" colnum="4"/> + <thead> + <row> + <entry>mask-password</entry> + <entry>cluster-password</entry> + <entry>acceptor/connector passwords</entry> + <entry>bridge password</entry> + </row> + </thead> + <tbody> + <row> + <entry>absent</entry> + <entry>plain text</entry> + <entry>plain text</entry> + <entry>plain text</entry> + </row> + <row> + <entry>false</entry> + <entry>plain text</entry> + <entry>plain text</entry> + <entry>plain text</entry> + </row> + <row> + <entry>true</entry> + <entry>masked</entry> + <entry>masked</entry> + <entry>masked</entry> + </row> + </tbody> + </tgroup> + </table> + +<para>Examples</para> + +<para>Note: In the following examples if related attributed or properties are absent, it means they are not specified in the configure file.</para> + +<para>example 1</para> + +<programlisting> +<cluster-password>bbc</cluster-password></programlisting> + +<para>This indicates the cluster password is a plain text value ("bbc").</para> + +<para>example 2</para> + +<programlisting> +<mask-password>true</mask-password> +<cluster-password>80cf731af62c290</cluster-password></programlisting> + + <para>This indicates the cluster password is a masked value and HornetQ will use its built-in decoder to decode it. All other + passwords in the configuration file, Connectors, Acceptors and Bridges, will also use masked passwords.</para> + </section> + </section> + + <section> <title>JMS Bridge password masking</title> + + <para>The JMS Bridges are configured and deployed as separate beans so they need separate configuration to control the password masking. + A JMS Bridge has two password parameters in its constructor, SourcePassword and TargetPassword. It uses the following two optional + properties to control their masking:</para> + + <para><literal>useMaskedPassword</literal> -- If set to "true" the passwords are masked. Default is false.</para> + <para><literal>passwordCodec</literal> -- Class name and its parameters for the Decoder used to decode the masked password. Ignored if + <literal>useMaskedPassword</literal> is false. The format of this property is a full qualified class name optionally followed by key/value pairs, + separated by semi-colons. For example:</para> + +<literal> +<property name="useMaskedPassword">true</property> +</literal><para></para> +<literal> +<property name="passwordCodec">com.foo.FooDecoder;key=value</property> +</literal> + <para>HornetQ will load this property and initialize the class with a parameter map containing the "key"->"value" pair. + If <literal>passwordCodec</literal> is not specified, the built-in decoder is used.</para> + + </section> + + <section> <title>Masking passwords in HornetQ ResourceAdapters and MDB activation configurations</title> + + <para>Both ra.xml and MDB activation configuration have a 'password' property that can be masked. They are controlled by the following two + optional Resource Adapter properties in ra.xml:</para> + + <para><literal>UseMaskedPassword</literal> -- If setting to "true" the passwords are masked. Default is false.</para> + <para><literal>PasswordCodec</literal> -- Class name and its parameters for the Decoder used to decode the masked password. + Ignored if UseMaskedPassword is false. The format of this property is a full qualified class name optionally followed by key/value pairs. + It is the same format as that for JMS Bridges. Example:</para> + +<programlisting> +<config-property> + <config-property-name>UseMaskedPassword</config-property-name> + <config-property-type>boolean</config-property-type> + <config-property-value>true</config-property-value> +</config-property> +<config-property> + <config-property-name>PasswordCodec</config-property-name> + <config-property-type>java.lang.String</config-property-type> + <config-property-value>com.foo.ADecoder;key=helloworld</config-property-value> +</config-property></programlisting> + + <para>With this configuration, both passwords in ra.xml and all of its MDBs will have to be in masked form.</para> + + </section> + + <section> <title>Masking passwords in hornetq-users.xml</title> + + <para>HornetQ's built-in security manager uses plain configuration files where the user passwords are specified in plaintext + forms by default. To mask those parameters the following two properties are needed:</para> + + <para> <literal>mask-password</literal> -- If set to "true" all the passwords are masked. Default is false.</para> + <para> <literal>password-codec</literal> -- Class name and its parameters for the Decoder used to decode the masked password. + Ignored if <literal>mask-password</literal> is false. The format of this property is a full qualified class name optionally + followed by key/value pairs. It is the same format as that for JMS Bridges. Example:</para> + +<programlisting> +<mask-password>true</mask-password> +<password-codec>org.hornetq.utils.DefaultSensitiveStringCodec;key=hello world</password-codec></programlisting> + + <para>When so configured, the HornetQ security manager will initialize a DefaultSensitiveStringCodec with the parameters + "key"->"hello world", then use it to decode all the masked passwords in this configuration file.</para> + + </section> + + <section> <title>Choosing a decoder for password masking</title> + + <para>As described in the previous sections, all password masking requires a decoder. A decoder uses an algorithm to + convert a masked password into its original clear text form in order to be used in various security operations. The algorithm + used for decoding must match that for encoding. Otherwise the decoding may not be successful.</para> + + <para>For user's convenience HornetQ provides a default built-in Decoder. However a user can if they so wish implement their own.</para> + + <section><title>The built-in Decoder</title> + + <para>Whenever no decoder is specified in the configuration file, the built-in decoder is used. The class name for the built-in + decoder is org.hornetq.utils.DefaultSensitiveStringCodec. It has both encoding and decoding capabilities. It uses java.crypto.Cipher + utilities to encrypt (encode) a plaintext password and decrypt a mask string using same algorithm. Using this decoder/encoder is + pretty straightforward. To get a mask for a password, just run the following in command line:</para> + +<programlisting> +java org.hornetq.utils.DefaultSensitiveStringCodec "your plaintext password"</programlisting> + + <para>Make sure the classpath is correct. You'll get something like</para> + +<programlisting> +Encoded password: 80cf731af62c290</programlisting> + + <para>Just copy "80cf731af62c290" and replace your plaintext password with it.</para> + </section> + + <section><title>Using a different decoder</title> + + <para>It is possible to use a different decoder rather than the built-in one. Simply make sure the decoder + is in HornetQ's classpath and configure the server to use it as follows:</para> + +<programlisting> +<password-codec>com.foo.SomeDecoder;key1=value1;key2=value2</password-codec></programlisting> + + <para>If your decoder needs params passed to it you can do this via key/value pairs when configuring. + For instance if your decoder needs say a "key-location" parameter, you can define like so:</para> + +<programlisting> +<password-codec>com.foo.NewDecoder;key-location=/some/url/to/keyfile</password-codec></programlisting> + + <para>Then configure your cluster-password like this:</para> + +<programlisting> +<mask-password>true</mask-password> +<cluster-password>masked_password</cluster-password></programlisting> + + <para>When HornetQ reads the cluster-password it will initialize the NewDecoder and use it to decode "mask_password". + It also process all passwords using the new defined decoder.</para> + </section> + + <section><title>Implementing your own codecs</title> + + <para>To use a different decoder than the built-in one, you either pick one from existing libraries or you implement it yourself. + All decoders must implement the <literal>org.hornetq.utils.SensitiveDataCodec<T></literal> interface:</para> + +<programlisting> +public interface SensitiveDataCodec<T> +{ + T decode(Object mask) throws Exception; + + void init(Map<String, String> params); +}</programlisting> + + <para>This is a generic type interface but normally for a password you just need String type. + So a new decoder would be defined like </para> + +<programlisting> +public class MyNewDecoder implements SensitiveDataCodec<String> +{ + public String decode(Object mask) throws Exception + { + //decode the mask into clear text password + return "the password"; + } + + public void init(Map<String, String> params) + { + //initialization done here. It is called right after the decoder has been created. + } +}</programlisting> + + <para>Last but not least, once you get your own decoder, please add it to the classpath. Otherwise HornetQ will + fail to load it!</para> + </section> + </section> + </section> + </section> +</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/configuring-transports.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/configuring-transports.xml b/docs/user-manual/en/configuring-transports.xml new file mode 100644 index 0000000..066e783 --- /dev/null +++ b/docs/user-manual/en/configuring-transports.xml @@ -0,0 +1,453 @@ +<?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 AttributionâShare 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 "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="configuring-transports"> + <title>Configuring the Transport</title> + <para>HornetQ has a fully pluggable and highly flexible transport layer and defines its own + Service Provider Interface (SPI) to make plugging in a new transport provider relatively + straightforward.</para> + <para>In this chapter we'll describe the concepts required for understanding HornetQ transports + and where and how they're configured.</para> + <section id="configuring-transports.acceptors"> + <title>Understanding Acceptors</title> + <para>One of the most important concepts in HornetQ transports is the + <emphasis>acceptor</emphasis>. Let's dive straight in and take a look at an acceptor + defined in xml in the configuration file <literal + >hornetq-configuration.xml</literal>.</para> + <programlisting> +<acceptors> + <acceptor name="netty"> + <factory-class> + org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory + </factory-class> + <param key="port" value="5446"/> + </acceptor> +</acceptors></programlisting> + <para>Acceptors are always defined inside an <literal>acceptors</literal> element. There can + be one or more acceptors defined in the <literal>acceptors</literal> element. There's no + upper limit to the number of acceptors per server.</para> + <para>Each acceptor defines a way in which connections can be made to the HornetQ + server.</para> + <para>In the above example we're defining an acceptor that uses <ulink + url="http://jboss.org/netty">Netty</ulink> to listen for connections at port + <literal>5446</literal>. </para> + <para>The <literal>acceptor</literal> element contains a sub-element <literal + >factory-class</literal>, this element defines the factory used to create acceptor + instances. In this case we're using Netty to listen for connections so we use the Netty + implementation of an <literal>AcceptorFactory</literal> to do this. Basically, the + <literal>factory-class</literal> element determines which pluggable transport we're + going to use to do the actual listening.</para> + <para>The <literal>acceptor</literal> element can also be configured with zero or more + <literal>param</literal> sub-elements. Each <literal>param</literal> element defines + a key-value pair. These key-value pairs are used to configure the specific transport, + the set of valid key-value pairs depends on the specific transport be used and are + passed straight through to the underlying transport.</para> + <para>Examples of key-value pairs for a particular transport would be, say, to configure the + IP address to bind to, or the port to listen at.</para> + <para>Note that unlike versions before 2.4 an Acceptor can now support multiple protocols. By default this will + be all available protocols but can be limited by either the now deprecated <literal>protocol</literal> param or + by setting a comma seperated list to the newly added <literal>protocols</literal> parameter.</para> + </section> + <section id="configuring-transports.connectors"> + <title>Understanding Connectors</title> + <para>Whereas acceptors are used on the server to define how we accept connections, + connectors are used by a client to define how it connects to a server.</para> + <para>Let's look at a connector defined in our <literal>hornetq-configuration.xml</literal> + file:</para> + <programlisting> +<connectors> + <connector name="netty"> + <factory-class> + org.hornetq.core.remoting.impl.netty.NettyConnectorFactory + </factory-class> + <param key="port" value="5446"/> + </connector> +</connectors></programlisting> + <para>Connectors can be defined inside a <literal>connectors</literal> element. There can be + one or more connectors defined in the <literal>connectors</literal> element. There's no + upper limit to the number of connectors per server.</para> + <para>You make ask yourself, if connectors are used by the <emphasis>client</emphasis> to + make connections then why are they defined on the <emphasis>server</emphasis>? There are + a couple of reasons for this:</para> + <itemizedlist> + <listitem> + <para>Sometimes the server acts as a client itself when it connects to another + server, for example when one server is bridged to another, or when a server + takes part in a cluster. In this cases the server needs to know how to connect + to other servers. That's defined by <emphasis>connectors</emphasis>.</para> + </listitem> + <listitem> + <para>If you're using JMS and the server side JMS service to instantiate JMS + ConnectionFactory instances and bind them in JNDI, then when creating the + <literal>HornetQConnectionFactory</literal> it needs to know what server + that connection factory will create connections to.</para> + <para>That's defined by the <literal>connector-ref</literal> element in the <literal + >hornetq-jms.xml</literal> file on the server side. Let's take a look at a + snipped from a <literal>hornetq-jms.xml</literal> file that shows a JMS + connection factory that references our netty connector defined in our <literal + >hornetq-configuration.xml</literal> file:</para> + <programlisting> +<connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty"/> + </connectors> + <entries> + <entry name="ConnectionFactory"/> + <entry name="XAConnectionFactory"/> + </entries> +</connection-factory></programlisting> + </listitem> + </itemizedlist> + </section> + <section id="configuring-transports.client.side"> + <title>Configuring the transport directly from the client side.</title> + <para>How do we configure a core <literal>ClientSessionFactory</literal> with the + information that it needs to connect with a server?</para> + <para>Connectors are also used indirectly when directly configuring a core <literal + >ClientSessionFactory</literal> to directly talk to a server. Although in this case + there's no need to define such a connector in the server side configuration, instead we + just create the parameters and tell the <literal>ClientSessionFactory</literal> which + connector factory to use.</para> + <para>Here's an example of creating a <literal>ClientSessionFactory</literal> which will + connect directly to the acceptor we defined earlier in this chapter, it uses the + standard Netty TCP transport and will try and connect on port 5446 to localhost + (default):</para> + <programlisting> +Map<String, Object> connectionParams = new HashMap<String, Object>(); + +connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, + 5446); + +TransportConfiguration transportConfiguration = + new TransportConfiguration( + "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory", + connectionParams); + +ServerLocator locator = HornetQClient.createServerLocatorWithoutHA(transportConfiguration); + +ClientSessionFactory sessionFactory = locator.createClientSessionFactory(); + +ClientSession session = sessionFactory.createSession(...); + +etc</programlisting> + <para>Similarly, if you're using JMS, you can configure the JMS connection factory directly + on the client side without having to define a connector on the server side or define a + connection factory in <literal>hornetq-jms.xml</literal>:</para> + <programlisting> +Map<String, Object> connectionParams = new HashMap<String, Object>(); + +connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5446); + +TransportConfiguration transportConfiguration = + new TransportConfiguration( + "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory", + connectionParams); + +ConnectionFactory connectionFactory = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration); + +Connection jmsConnection = connectionFactory.createConnection(); + +etc</programlisting> + </section> + <section> + <title>Configuring the Netty transport</title> + <para>Out of the box, HornetQ currently uses <ulink url="http://www.jboss.org/netty/" + >Netty</ulink>, a high performance low level network library.</para> + <para>Our Netty transport can be configured in several different ways; to use old (blocking) + Java IO, or NIO (non-blocking), also to use straightforward TCP sockets, SSL, or to + tunnel over HTTP or HTTPS..</para> + <para>We believe this caters for the vast majority of transport requirements.</para> + <section> + <title>Single Port Support</title> + <para>As of version 2.4 HornetQ now supports using a single port for all protocols, HornetQ will automatically + detect which protocol is being used CORE, AMQP or STOMP and use the appropriate HornetQ handler. It will also detect + whether protocols such as HTTP or Web Sockets are being used and also use the appropriate decoders</para> + <para>It is possible to limit which protocols are supported by using the <literal>protocols</literal> parameter + on the Acceptor like so:</para> + <programlisting> + <param key="protocols" value="CORE,AMQP"/> + </programlisting> + <note><para>The <literal>protocol</literal> parameter is now deprecated</para></note> + </section> + <section> + <title>Configuring Netty TCP</title> + <para>Netty TCP is a simple unencrypted TCP sockets based transport. Netty TCP can be + configured to use old blocking Java IO or non blocking Java NIO. We recommend you + use the Java NIO on the server side for better scalability with many concurrent + connections. However using Java old IO can sometimes give you better latency than + NIO when you're not so worried about supporting many thousands of concurrent + connections. </para> + <para>If you're running connections across an untrusted network please bear in mind this + transport is unencrypted. You may want to look at the SSL or HTTPS + configurations.</para> + <para>With the Netty TCP transport all connections are initiated from the client side. + I.e. the server does not initiate any connections to the client. This works well + with firewall policies that typically only allow connections to be initiated in one + direction.</para> + <para>All the valid Netty transport keys are defined in the class <literal + >org.hornetq.core.remoting.impl.netty.TransportConstants</literal>. Most + parameters can be used either with acceptors or connectors, some only work with + acceptors. The following parameters can be used to configure Netty for simple + TCP:</para> + <itemizedlist> + <listitem> + <para><literal>use-nio</literal>. If this is <literal>true</literal> then Java + non blocking NIO will be used. If set to <literal>false</literal> then old + blocking Java IO will be used.</para> + <para>If you require the server to handle many concurrent connections, we highly + recommend that you use non blocking Java NIO. Java NIO does not maintain a + thread per connection so can scale to many more concurrent connections than + with old blocking IO. If you don't require the server to handle many + concurrent connections, you might get slightly better performance by using + old (blocking) IO. The default value for this property is <literal + >false</literal> on the server side and <literal>false</literal> on the + client side.</para> + </listitem> + <listitem> + <para><literal>host</literal>. This specifies the host name or IP address to + connect to (when configuring a connector) or to listen on (when configuring + an acceptor). The default value for this property is <literal + >localhost</literal>. When configuring acceptors, multiple hosts or IP + addresses can be specified by separating them with commas. It is also + possible to specify <code>0.0.0.0</code> to accept connection from all the + host's network interfaces. It's not valid to specify multiple addresses when + specifying the host for a connector; a connector makes a connection to one + specific address.</para> + <note> + <para>Don't forget to specify a host name or IP address! If you want your + server able to accept connections from other nodes you must specify a + hostname or IP address at which the acceptor will bind and listen for + incoming connections. The default is localhost which of course is not + accessible from remote nodes!</para> + </note> + </listitem> + <listitem> + <para><literal>port</literal>. This specified the port to connect to (when + configuring a connector) or to listen on (when configuring an acceptor). The + default value for this property is <literal>5445</literal>.</para> + </listitem> + <listitem> + <para><literal>tcp-no-delay</literal>. If this is <literal>true</literal> then + <ulink url="http://en.wikipedia.org/wiki/Nagle%27s_algorithm">Nagle's + algorithm</ulink> will be disabled. This is a + <ulink url="http://docs.oracle.com/javase/7/docs/technotes/guides/net/socketOpt.html">Java (client) socket option</ulink>. The default value for this property is <literal>true</literal>.</para> + </listitem> + <listitem> + <para><literal>tcp-send-buffer-size</literal>. This parameter determines the + size of the TCP send buffer in bytes. The default value for this property is + <literal>32768</literal> bytes (32KiB).</para> + <para>TCP buffer sizes should be tuned according to the bandwidth and latency of + your network. Here's a good link that explains the theory behind <ulink + url="http://www-didc.lbl.gov/TCP-tuning/">this</ulink>.</para> + <para>In summary TCP send/receive buffer sizes should be calculated as:</para> + <programlisting> +buffer_size = bandwidth * RTT.</programlisting> + <para>Where bandwidth is in <emphasis>bytes per second</emphasis> and network + round trip time (RTT) is in seconds. RTT can be easily measured using the + <literal>ping</literal> utility.</para> + <para>For fast networks you may want to increase the buffer sizes from the + defaults.</para> + </listitem> + <listitem> + <para><literal>tcp-receive-buffer-size</literal>. This parameter determines the + size of the TCP receive buffer in bytes. The default value for this property + is <literal>32768</literal> bytes (32KiB).</para> + </listitem> + <listitem> + <para><literal>batch-delay</literal>. Before writing packets to the transport, + HornetQ can be configured to batch up writes for a maximum of <literal + >batch-delay</literal> milliseconds. This can increase overall + throughput for very small messages. It does so at the expense of an increase + in average latency for message transfer. The default value for this property + is <literal>0</literal> ms.</para> + </listitem> + <listitem> + <para><literal>direct-deliver</literal>. When a message arrives on the server + and is delivered to waiting consumers, by default, the delivery is done on + the same thread as that on which the message arrived. This gives good latency + in environments with relatively small messages and a small number of consumers, + but at the cost of overall throughput and scalability - especially on multi-core + machines. If you want the lowest latency and a possible reduction in throughput + then you can use the default value for <literal>direct-deliver</literal> (i.e. + true). If you are willing to take some small extra hit on latency but want the + highest throughput set <literal>direct-deliver</literal> to <literal>false + </literal>.</para> + </listitem> + <listitem> + <para><literal>nio-remoting-threads</literal>. When configured to use NIO, + HornetQ will, by default, use a number of threads equal to three times the + number of cores (or hyper-threads) as reported by <literal + >Runtime.getRuntime().availableProcessors()</literal> for processing + incoming packets. If you want to override this value, you can set the number + of threads by specifying this parameter. The default value for this + parameter is <literal>-1</literal> which means use the value from <literal + >Runtime.getRuntime().availableProcessors()</literal> * 3.</para> + </listitem> + <listitem> + <para><literal>local-address</literal>. When configured a Netty Connector it is possible to specify + which local address the client will use when connecting to the remote address. This is typically used + in the Application Server or when running Embedded to control which address is used for outbound + connections. If the local-address is not set then the connector will use any local address available</para> + </listitem> + <listitem> + <para><literal>local-port</literal>. When configured a Netty Connector it is possible to specify + which local port the client will use when connecting to the remote address. This is typically used + in the Application Server or when running Embedded to control which port is used for outbound + connections. If the local-port default is used, which is 0, then the connector will let the + system pick up an ephemeral port. valid ports are 0 to 65535</para> + </listitem> + </itemizedlist> + </section> + <section> + <title>Configuring Netty SSL</title> + <para>Netty SSL is similar to the Netty TCP transport but it provides additional + security by encrypting TCP connections using the Secure Sockets Layer SSL</para> + <para>Please see the examples for a full working example of using Netty SSL.</para> + <para>Netty SSL uses all the same properties as Netty TCP but adds the following + additional properties:</para> + <itemizedlist> + <listitem> + <para><literal>ssl-enabled</literal></para> + <para>Must be <literal>true</literal> to enable SSL. Default is <literal>false</literal>.</para> + </listitem> + <listitem> + <para><literal>key-store-path</literal></para> + <para>When used on an <literal>acceptor</literal> this is the path to the SSL key + store on the server which holds the server's certificates (whether self-signed + or signed by an authority).</para> + <para>When used on a <literal>connector</literal> this is the path to the client-side + SSL key store which holds the client certificates. This is only relevant + for a <literal>connector</literal> if you are using 2-way SSL (i.e. mutual + authentication). Although this value is configured on the server, it is + downloaded and used by the client. If the client needs to use a different path + from that set on the server then it can override the server-side setting by either + using the customary "javax.net.ssl.keyStore" system property or the HornetQ-specific + "org.hornetq.ssl.keyStore" system property. The HornetQ-specific system property + is useful if another component on client is already making use of the standard, Java + system property.</para> + </listitem> + <listitem> + <para><literal>key-store-password</literal></para> + <para>When used on an <literal>acceptor</literal> this is the password for the + server-side keystore.</para> + <para>When used on a <literal>connector</literal> this is the password for the + client-side keystore. This is only relevant for a <literal>connector</literal> + if you are using 2-way SSL (i.e. mutual authentication). Although this value can + be configured on the server, it is downloaded and used by the client. If the client + needs to use a different password from that set on the server then it can override + the server-side setting by either using the customary "javax.net.ssl.keyStorePassword" + system property or the HornetQ-specific "org.hornetq.ssl.keyStorePassword" system + property. The HornetQ-specific system property is useful if another component on client + is already making use of the standard, Java system property.</para> + </listitem> + <listitem> + <para><literal>trust-store-path</literal></para> + <para>When used on an <literal>acceptor</literal> this is the path to the server-side + SSL key store that holds the keys of all the clients that the server trusts. This + is only relevant for an <literal>acceptor</literal> if you are using 2-way SSL + (i.e. mutual authentication).</para> + <para>When used on a <literal>connector</literal> this is the path to the client-side + SSL key store which holds the public keys of all the servers that the client + trusts. Although this value can be configured on the server, it is downloaded and + used by the client. If the client needs to use a different path + from that set on the server then it can override the server-side setting by either + using the customary "javax.net.ssl.trustStore" system property or the HornetQ-specific + "org.hornetq.ssl.trustStore" system property. The HornetQ-specific system property + is useful if another component on client is already making use of the standard, Java + system property.</para> + </listitem> + <listitem> + <para><literal>trust-store-password</literal></para> + <para>When used on an <literal>acceptor</literal> this is the password for the + server-side trust store. This is only relevant for an <literal>acceptor</literal> + if you are using 2-way SSL (i.e. mutual authentication).</para> + <para>When used on a <literal>connector</literal> this is the password for the + client-side truststore. Although this value can be configured on the server, it is + downloaded and used by the client. If the client + needs to use a different password from that set on the server then it can override + the server-side setting by either using the customary "javax.net.ssl.trustStorePassword" + system property or the HornetQ-specific "org.hornetq.ssl.trustStorePassword" system + property. The HornetQ-specific system property is useful if another component on client + is already making use of the standard, Java system property.</para> + </listitem> + <listitem> + <para><literal>enabled-cipher-suites</literal></para> + <para>Whether used on an <literal>acceptor</literal> or <literal>connector</literal> this is a + comma separated list of cipher suites used for SSL communication. The default value is + <literal>null</literal> which means the JVM's default will be used.</para> + </listitem> + <listitem> + <para><literal>enabled-protocols</literal></para> + <para>Whether used on an <literal>acceptor</literal> or <literal>connector</literal> this is a + comma separated list of protocols used for SSL communication. The default value is + <literal>null</literal> which means the JVM's default will be used.</para> + </listitem> + <listitem> + <para><literal>need-client-auth</literal></para> + <para>This property is only for an <literal>acceptor</literal>. It tells a client connecting to this + acceptor that 2-way SSL is required. Valid values are <literal>true</literal> or + <literal>false</literal>. Default is <literal>false</literal>.</para> + </listitem> + </itemizedlist> + </section> + <section> + <title>Configuring Netty HTTP</title> + <para>Netty HTTP tunnels packets over the HTTP protocol. It can be useful in scenarios + where firewalls only allow HTTP traffic to pass.</para> + <para>Please see the examples for a full working example of using Netty HTTP.</para> + <para>Netty HTTP uses the same properties as Netty TCP but adds the following additional + properties:</para> + <itemizedlist> + <listitem> + <para><literal>http-enabled</literal>. This is now no longer needed as of version 2.4. With single + port support HornetQ will now automatically detect if http is being used and configure itself.</para> + </listitem> + <listitem> + <para><literal>http-client-idle-time</literal>. How long a client can be idle + before sending an empty http request to keep the connection alive</para> + </listitem> + <listitem> + <para><literal>http-client-idle-scan-period</literal>. How often, in + milliseconds, to scan for idle clients</para> + </listitem> + <listitem> + <para><literal>http-response-time</literal>. How long the server can wait before + sending an empty http response to keep the connection alive</para> + </listitem> + <listitem> + <para><literal>http-server-scan-period</literal>. How often, in milliseconds, to + scan for clients needing responses</para> + </listitem> + <listitem> + <para><literal>http-requires-session-id</literal>. If true the client will wait + after the first call to receive a session id. Used the http connector is + connecting to servlet acceptor (not recommended) </para> + </listitem> + </itemizedlist> + </section> + <section> + <title>Configuring Netty Servlet</title> + <para>As of 2.4 HornetQ Servlet support will be provided via Undertow in Wildfly</para> + </section> + </section> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/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 new file mode 100644 index 0000000..b9b4182 --- /dev/null +++ b/docs/user-manual/en/connection-ttl.xml @@ -0,0 +1,203 @@ +<?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 AttributionâShare 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 "HornetQ_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 HornetQ + 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 HornetQ 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 = HornetQClient.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 = HornetQJMSClient.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. HornetQ 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>HornetQ 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>HornetQConnectionFactory</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, HornetQ 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.hornetq.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.hornetq.core.client.impl.DelegatingSession] The session you didn't close was created here: +java.lang.Exception + at org.hornetq.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83) + at org.acme.yourproject.YourClass (YourClass.java:666)</programlisting> + <para>HornetQ 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>HornetQConnectionFactory</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>hornetq-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.hornetq.core.protocol.core.impl.wireformat.RollbackMessage</literal></para> + </listitem> + <listitem> + <para><literal>org.hornetq.core.protocol.core.impl.wireformat.SessionCloseMessage</literal></para> + </listitem> + <listitem> + <para><literal>org.hornetq.core.protocol.core.impl.wireformat.SessionCommitMessage</literal></para> + </listitem> + <listitem> + <para><literal>org.hornetq.core.protocol.core.impl.wireformat.SessionXACommitMessage</literal></para> + </listitem> + <listitem> + <para><literal>org.hornetq.core.protocol.core.impl.wireformat.SessionXAPrepareMessage</literal></para> + </listitem> + <listitem> + <para><literal>org.hornetq.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>hornetq-configuration.xml</literal> to <literal>false</literal> (default value is + <literal>true</literal>).</para> + </section> +</chapter>