http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/send-guarantees.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/send-guarantees.md b/docs/user-manual/en/send-guarantees.md index 79b9097..da631e4 100644 --- a/docs/user-manual/en/send-guarantees.md +++ b/docs/user-manual/en/send-guarantees.md @@ -32,15 +32,15 @@ has definitely reached the server, and a response has been sent back to the client. This can be configured individually for durable and non-durable messages, and is determined by the following two URL parameters: -- `blockOnDurableSend`. If this is set to `true` then all calls to - send for durable messages on non transacted sessions will block - until the message has reached the server, and a response has been - sent back. The default value is `true`. - -- `blockOnNonDurableSend`. If this is set to `true` then all calls to - send for non-durable messages on non transacted sessions will block - until the message has reached the server, and a response has been - sent back. The default value is `false`. +- `blockOnDurableSend`. If this is set to `true` then all calls to + send for durable messages on non transacted sessions will block + until the message has reached the server, and a response has been + sent back. The default value is `true`. + +- `blockOnNonDurableSend`. If this is set to `true` then all calls to + send for non-durable messages on non transacted sessions will block + until the message has reached the server, and a response has been + sent back. The default value is `false`. Setting block on sends to `true` can reduce performance since each send requires a network round trip before the next send can be performed.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/slow-consumers.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/slow-consumers.md b/docs/user-manual/en/slow-consumers.md index 49d5141..fc85d38 100644 --- a/docs/user-manual/en/slow-consumers.md +++ b/docs/user-manual/en/slow-consumers.md @@ -36,5 +36,5 @@ the detection algorithm. See [thread pooling](thread-pooling.md) for more detail ## Example -See the [examples](examples.md) chapter for an example which shows how to detect a slow consumer +See the [slow consumer example](examples.md#slow-consumer) which shows how to detect a slow consumer with Apache ActiveMQ Artemis. http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/spring-integration.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/spring-integration.md b/docs/user-manual/en/spring-integration.md index 9c7c939..f63df5c 100644 --- a/docs/user-manual/en/spring-integration.md +++ b/docs/user-manual/en/spring-integration.md @@ -1,39 +1,16 @@ # Spring Integration Apache ActiveMQ Artemis provides a simple bootstrap class, -`org.apache.activemq.integration.spring.SpringJmsBootstrap`, for -integration with Spring. To use it, you configure Apache ActiveMQ Artemis as you always -would, through its various configuration files like -`broker.xml`. +`org.apache.activemq.artemis.integration.spring.SpringJmsBootstrap`, for +integration with Spring. To use it, you configure Apache ActiveMQ Artemis as +you always would, through its various configuration files like `broker.xml`. -Here we've specified a `javax.jms.ConnectionFactory` we want bound to a -`ConnectionFactory` entry as well as a queue destination bound to a -`/queue/exampleQueue` entry. Using the `SpringJmsBootStrap` bean will -automatically populate the Spring context with references to those beans -so that you can use them. Below is an example Spring JMS bean file -taking advantage of this feature: +The `SpringJmsBootstrap` class extends the EmbeddedJMS class talked about in +[embedding ActiveMQ](embedding-activemq.md) and the same defaults and +configuration options apply. See the javadocs for more details on other +properties of the bean class. -```xml -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> +## Example - <bean id="EmbeddedJms" class="org.apache.activemq.integration.spring.SpringJmsBootstrap" init-method="start"/> - - <bean id="listener" class="org.apache.activemq.tests.integration.spring.ExampleListener"/> - - <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> - <property name="connectionFactory" ref="ConnectionFactory"/> - <property name="destination" ref="/queue/exampleQueue"/> - <property name="messageListener" ref="listener"/> - </bean> -</beans> -``` - -As you can see, the `listenerContainer` bean references the components -defined in the `activemq-jms.xml` file. The `SpringJmsBootstrap` class -extends the EmbeddedJMS class talked about in [JMS API](embedding-activemq.md) and the same defaults -and configuration options apply. Also notice that an `init-method` must -be declared with a start value so that the bean's lifecycle is executed. -See the javadocs for more details on other properties of the bean class. +See the [Spring Integration Example](examples.md#spring-integration) for a +demonstration of how this can work. http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/stomp.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/stomp.md b/docs/user-manual/en/stomp.md new file mode 100644 index 0000000..8ba11f2 --- /dev/null +++ b/docs/user-manual/en/stomp.md @@ -0,0 +1,293 @@ +# STOMP + +[STOMP](https://stomp.github.io/) is a text-orientated wire protocol that +allows STOMP clients to communicate with STOMP Brokers. Apache ActiveMQ Artemis +supports STOMP 1.0, 1.1 and 1.2. + +STOMP clients are available for several languages and platforms making it a +good choice for interoperability. + +By default there are `acceptor` elements configured to accept STOMP connections +on ports `61616` and `61613`. + +See the general [Protocols and Interoperability](protocols-interoperability.md) +chapter for details on configuring an `acceptor` for STOMP. + +Refer to the STOMP examples for a look at some of this functionality in action. + +## Limitations + +The STOMP specification identifies **transactional acknowledgements** as an +optional feature. Support for transactional acknowledgements is not implemented +in Apache ActiveMQ Artemis. The `ACK` frame can not be part of a transaction. +It will be ignored if its `transaction` header is set. + +## Virtual Hosting + +Apache ActiveMQ Artemis currently doesn't support virtual hosting, which means +the `host` header in `CONNECT` frame will be ignored. + +## Mapping STOMP destinations to addresses and queues + +STOMP clients deals with *destinations* when sending messages and subscribing. +Destination names are simply strings which are mapped to some form of +destination on the server - how the server translates these is left to the +server implementation. + +In Apache ActiveMQ Artemis, these destinations are mapped to *addresses* and +*queues* depending on the operation being done and the desired semantics (e.g. +anycast or multicast). + +## Sending + +When a STOMP client sends a message (using a `SEND` frame), the protocol +manager looks at the message to determine where to route it and potentially how +to create the address and/or queue to which it is being sent. The protocol +manager uses either of the following bits of information from the frame to +determine the routing type: + +1. The value of the `destination-type` header. Valid values are `ANYCAST` and + `MULTICAST` (case sensitive). + +2. The "prefix" on the `destination` header. See [additional + info](address-model.md#using-prefixes-to-determine-routing-type) on + prefixes. + +If no indication of routing type is supplied then anycast semantics are used. + +The `destination` header maps to an address of the same name. If the +`destination` header used a prefix then the prefix is stripped. + +## Subscribing + +When a STOMP client subscribes to a destination (using a `SUBSCRIBE` frame), +the protocol manager looks at the frame to determine what subscription +semantics to use and potentially how to create the address and/or queue for the +subscription. The protocol manager uses either of the following bits of +information from the frame to determine the routing type: + +1. The value of the `subscription-type` header. Valid values are `ANYCAST` and + `MULTICAST` (case sensitive). + +2. The "prefix" on the `destination` header. See [additional + info](address-model.md#using-prefixes-to-determine-routing-type) on + prefixes. + +If no indication of routing type is supplied then anycast semantics are used. + +The `destination` header maps to an address of the same name if multicast is +used or to a queue of the same name if anycast is used. If the `destination` +header used a prefix then the prefix is stripped. + +## STOMP heart-beating and connection-ttl + +Well behaved STOMP clients will always send a `DISCONNECT` frame before closing +their connections. In this case the server will clear up any server side +resources such as sessions and consumers synchronously. However if STOMP +clients exit without sending a `DISCONNECT` frame or if they crash the server +will have no way of knowing immediately whether the client is still alive or +not. STOMP connections therefore default to a `connection-ttl` value of 1 +minute (see chapter on [connection-ttl](connection-ttl.md) for more +information. This value can be overridden using the `connection-ttl-override` +property or if you need a specific connectionTtl for your stomp connections +without affecting the broker-wide `connection-ttl-override` setting, you can +configure your stomp acceptor with the `connectionTtl` property, which is used +to set the ttl for connections that are created from that acceptor. For +example: + +```xml +<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;connectionTtl=20000</acceptor> +``` + +The above configuration will make sure that any STOMP connection that is +created from that acceptor and does not include a `heart-beat` header or +disables client-to-server heart-beats by specifying a `0` value will have its +`connection-ttl` set to 20 seconds. The `connectionTtl` set on an acceptor will +take precedence over `connection-ttl-override`. The default `connectionTtl` is +60,000 milliseconds. + +Since STOMP 1.0 does not support heart-beating then all connections from STOMP +1.0 clients will have a connection TTL imposed upon them by the broker based on +the aforementioned configuration options. Likewise, any STOMP 1.1 or 1.2 +clients that don't specify a `heart-beat` header or disable client-to-server +heart-beating (e.g. by sending `0,X` in the `heart-beat` header) will have a +connection TTL imposed upon them by the broker. + +For STOMP 1.1 and 1.2 clients which send a non-zero client-to-server +`heart-beat` header value then their connection TTL will be set accordingly. +However, the broker will not strictly set the connection TTL to the same value +as the specified in the `heart-beat` since even small network delays could then +cause spurious disconnects. Instead, the client-to-server value in the +`heart-beat` will be multiplied by the `heartBeatConnectionTtlModifer` +specified on the acceptor. The `heartBeatConnectionTtlModifer` is a decimal +value that defaults to `2.0` so for example, if a client sends a `heart-beat` +header of `1000,0` the the connection TTL will be set to `2000` so that the +data or ping frames sent every 1000 milliseconds will have a sufficient cushion +so as not to be considered late and trigger a disconnect. This is also in +accordance with the STOMP 1.1 and 1.2 specifications which both state, "because +of timing inaccuracies, the receiver SHOULD be tolerant and take into account +an error margin." + +The minimum and maximum connection TTL allowed can also be specified on the +acceptor via the `connectionTtlMin` and `connectionTtlMax` properties +respectively. The default `connectionTtlMin` is 1000 and the default +`connectionTtlMax` is Java's `Long.MAX_VALUE` meaning there essentially is no +max connection TTL by default. Keep in mind that the +`heartBeatConnectionTtlModifer` is relevant here. For example, if a client +sends a `heart-beat` header of `20000,0` and the acceptor is using a +`connectionTtlMax` of `30000` and a default `heartBeatConnectionTtlModifer` of +`2.0` then the connection TTL would be `40000` (i.e. `20000` * `2.0`) which +would exceed the `connectionTtlMax`. In this case the server would respond to +the client with a `heart-beat` header of `0,15000` (i.e. `30000` / `2.0`). As +described previously, this is to make sure there is a sufficient cushion for +the client heart-beats in accordance with the STOMP 1.1 and 1.2 specifications. +The same kind of calculation is done for `connectionTtlMin`. + +The minimum server-to-client heart-beat value is 500ms. + +> **Note:** +> +> Please note that the STOMP protocol version 1.0 does not contain any +> heart-beat frame. It is therefore the user's responsibility to make sure data +> is sent within connection-ttl or the server will assume the client is dead +> and clean up server side resources. With STOMP 1.1 users can use heart-beats +> to maintain the life cycle of stomp connections. + +## Selector/Filter expressions + +STOMP subscribers can specify an expression used to select or filter what the +subscriber receives using the `selector` header. The filter expression syntax +follows the *core filter syntax* described in the [Filter +Expressions](filter-expressions.md) documentation. + +## STOMP and JMS interoperability + +### Sending and consuming STOMP message from JMS or Core API + +STOMP is mainly a text-orientated protocol. To make it simpler to interoperate +with JMS and Core API, our STOMP implementation checks for presence of the +`content-length` header to decide how to map a STOMP 1.0 message to a JMS +Message or a Core message. + +If the STOMP 1.0 message does *not* have a `content-length` header, it will be +mapped to a JMS *TextMessage* or a Core message with a *single nullable +SimpleString in the body buffer*. + +Alternatively, if the STOMP 1.0 message *has* a `content-length` header, it +will be mapped to a JMS *BytesMessage* or a Core message with a *byte[] in the +body buffer*. + +The same logic applies when mapping a JMS message or a Core message to STOMP. A +STOMP 1.0 client can check the presence of the `content-length` header to +determine the type of the message body (String or bytes). + +### Message IDs for STOMP messages + +When receiving STOMP messages via a JMS consumer or a QueueBrowser, the +messages have no properties like JMSMessageID by default. However this may +bring some inconvenience to clients who wants an ID for their purpose. The +broker STOMP provides a parameter to enable message ID on each incoming STOMP +message. If you want each STOMP message to have a unique ID, just set the +`stompEnableMessageId` to true. For example: + +```xml +<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompEnableMessageId=true</acceptor> +``` + +When the server starts with the above setting, each stomp message sent through +this acceptor will have an extra property added. The property key is +`amq-message-id` and the value is a String representation of a long type +internal message id prefixed with `STOMP`, like: + +``` +amq-message-id : STOMP12345 +``` + +The default `stomp-enable-message-id` value is `false`. + +## Durable Subscriptions + +The `SUBSCRIBE` and `UNSUBSCRIBE` frames can be augmented with special headers +to create and destroy durable subscriptions respectively. + +To create a durable subscription the `client-id` header must be set on the +`CONNECT` frame and the `durable-subscription-name` must be set on the +`SUBSCRIBE` frame. The combination of these two headers will form the identity +of the durable subscription. + +To delete a durable subscription the `client-id` header must be set on the +`CONNECT` frame and the `durable-subscription-name` must be set on the +`UNSUBSCRIBE` frame. The values for these headers should match what was set on +the `SUBSCRIBE` frame to delete the corresponding durable subscription. + +It is possible to pre-configure durable subscriptions since the STOMP +implementation creates the queue used for the durable subscription in a +deterministic way (i.e. using the format of `client-id`.`subscription-name`). +For example, if you wanted to configure a durable subscription on the address +`myAddress` with a client-id of `myclientid` and a subscription name of +`mysubscription` then configure the durable subscription: + +```xml +<addresses> + <address name="myAddress"> + <multicast> + <queue name="myclientid.mysubscription"/> + </multicast> + </address> +</addresses> +``` + +## Handling of Large Messages with STOMP + +STOMP clients may send very large frame bodies which can exceed the size of the +broker's internal buffer, causing unexpected errors. To prevent this situation +from happening, the broker provides a STOMP configuration attribute +`stompMinLargeMessageSize`. This attribute can be configured inside a stomp +acceptor, as a parameter. For example: + +```xml +<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompMinLargeMessageSize=10240</acceptor> +``` + +The type of this attribute is integer. When this attributed is configured, the +broker will check the size of the body of each STOMP frame arrived from +connections established with this acceptor. If the size of the body is equal or +greater than the value of `stompMinLargeMessageSize`, the message will be +persisted as a large message. When a large message is delievered to a STOMP +consumer, the broker will automatically handle the conversion from a large +message to a normal message, before sending it to the client. + +If a large message is compressed, the server will uncompressed it before +sending it to stomp clients. The default value of `stompMinLargeMessageSize` is +the same as the default value of +[min-large-message-size](large-messages.md#configuring-parameters). + +## Web Sockets + +Apache ActiveMQ Artemis also support STOMP over [Web +Sockets](https://html.spec.whatwg.org/multipage/web-sockets.html). Modern web +browsers which support Web Sockets can send and receive STOMP messages. + +STOMP over Web Sockets is supported via the normal STOMP acceptor: + +```xml +<acceptor name="stomp-ws-acceptor">tcp://localhost:61614?protocols=STOMP</acceptor> +``` + +With this configuration, Apache ActiveMQ Artemis will accept STOMP connections +over Web Sockets on the port `61614`. Web browsers can then connect to +`ws://<server>:61614` using a Web Socket to send and receive STOMP messages. + +A companion JavaScript library to ease client-side development is available +from [GitHub](https://github.com/jmesnil/stomp-websocket) (please see its +[documentation](http://jmesnil.net/stomp-websocket/doc/) for a complete +description). + +The payload length of Web Socket frames can vary between client +implementations. By default the broker will accept frames with a payload length +of 65,536. If the client needs to send payloads longer than this in a single +frame this length can be adjusted by using the `stompMaxFramePayloadLength` URL +parameter on the acceptor. + +The `stomp-websockets` example shows how to configure an Apache ActiveMQ +Artemis broker to have web browsers and Java applications exchanges messages. http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/syntax.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/syntax.md b/docs/user-manual/en/syntax.md index 71db615..c37820d 100644 --- a/docs/user-manual/en/syntax.md +++ b/docs/user-manual/en/syntax.md @@ -11,7 +11,7 @@ Somejava s = new SomeJava(); ``` -> **Note** +> **Note:** > > This is a Note http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/tools.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/tools.md b/docs/user-manual/en/tools.md deleted file mode 100644 index 4a6aa0d..0000000 --- a/docs/user-manual/en/tools.md +++ /dev/null @@ -1,216 +0,0 @@ -# Tools - -You can use the artemis cli interface to execute data maintenance tools: - -This is a list of sub-commands available - -Name | Description -:--- | :--- -exp | Export the message data using a special and independent XML format -imp | Imports the journal to a running broker using the output from expt -data | Prints a report about journal records and summary of existent records, as well a report on paging -encode | shows an internal format of the journal encoded to String -decode | imports the internal journal format from encode - -You can use the help at the tool for more information on how to execute each of the tools. For example: - -``` -$ ./artemis help data print -NAME - artemis data print - Print data records information (WARNING: don't use - while a production server is running) - -SYNOPSIS - artemis data print [--bindings <binding>] [--journal <journal>] - [--paging <paging>] - -OPTIONS - --bindings <binding> - The folder used for bindings (default ../data/bindings) - - --journal <journal> - The folder used for messages journal (default ../data/journal) - - --paging <paging> - The folder used for paging (default ../data/paging) - - -``` - - -For a full list of data tools commands available use: - -``` -NAME - artemis data - data tools group - (print|imp|exp|encode|decode|compact) (example ./artemis data print) - -SYNOPSIS - artemis data - artemis data compact [--broker <brokerConfig>] [--verbose] - [--paging <paging>] [--journal <journal>] - [--large-messages <largeMessges>] [--bindings <binding>] - artemis data decode [--broker <brokerConfig>] [--suffix <suffix>] - [--verbose] [--paging <paging>] [--prefix <prefix>] [--file-size <size>] - [--directory <directory>] --input <input> [--journal <journal>] - [--large-messages <largeMessges>] [--bindings <binding>] - artemis data encode [--directory <directory>] [--broker <brokerConfig>] - [--suffix <suffix>] [--verbose] [--paging <paging>] [--prefix <prefix>] - [--file-size <size>] [--journal <journal>] - [--large-messages <largeMessges>] [--bindings <binding>] - artemis data exp [--broker <brokerConfig>] [--verbose] - [--paging <paging>] [--journal <journal>] - [--large-messages <largeMessges>] [--bindings <binding>] - artemis data imp [--host <host>] [--verbose] [--port <port>] - [--password <password>] [--transaction] --input <input> [--user <user>] - artemis data print [--broker <brokerConfig>] [--verbose] - [--paging <paging>] [--journal <journal>] - [--large-messages <largeMessges>] [--bindings <binding>] - -COMMANDS - With no arguments, Display help information - - print - Print data records information (WARNING: don't use while a - production server is running) - - With --broker option, This would override the broker configuration - from the bootstrap - - With --verbose option, Adds more information on the execution - - With --paging option, The folder used for paging (default from - broker.xml) - - With --journal option, The folder used for messages journal (default - from broker.xml) - - With --large-messages option, The folder used for large-messages - (default from broker.xml) - - With --bindings option, The folder used for bindings (default from - broker.xml) - - exp - Export all message-data using an XML that could be interpreted by - any system. - - With --broker option, This would override the broker configuration - from the bootstrap - - With --verbose option, Adds more information on the execution - - With --paging option, The folder used for paging (default from - broker.xml) - - With --journal option, The folder used for messages journal (default - from broker.xml) - - With --large-messages option, The folder used for large-messages - (default from broker.xml) - - With --bindings option, The folder used for bindings (default from - broker.xml) - - imp - Import all message-data using an XML that could be interpreted by - any system. - - With --host option, The host used to import the data (default - localhost) - - With --verbose option, Adds more information on the execution - - With --port option, The port used to import the data (default 61616) - - With --password option, User name used to import the data. (default - null) - - With --transaction option, If this is set to true you will need a - whole transaction to commit at the end. (default false) - - With --input option, The input file name (default=exp.dmp) - - With --user option, User name used to import the data. (default - null) - - decode - Decode a journal's internal format into a new journal set of files - - With --broker option, This would override the broker configuration - from the bootstrap - - With --suffix option, The journal suffix (default amq) - - With --verbose option, Adds more information on the execution - - With --paging option, The folder used for paging (default from - broker.xml) - - With --prefix option, The journal prefix (default activemq-data) - - With --file-size option, The journal size (default 10485760) - - With --directory option, The journal folder (default journal folder - from broker.xml) - - With --input option, The input file name (default=exp.dmp) - - With --journal option, The folder used for messages journal (default - from broker.xml) - - With --large-messages option, The folder used for large-messages - (default from broker.xml) - - With --bindings option, The folder used for bindings (default from - broker.xml) - - encode - Encode a set of journal files into an internal encoded data format - - With --directory option, The journal folder (default the journal - folder from broker.xml) - - With --broker option, This would override the broker configuration - from the bootstrap - - With --suffix option, The journal suffix (default amq) - - With --verbose option, Adds more information on the execution - - With --paging option, The folder used for paging (default from - broker.xml) - - With --prefix option, The journal prefix (default activemq-data) - - With --file-size option, The journal size (default 10485760) - - With --journal option, The folder used for messages journal (default - from broker.xml) - - With --large-messages option, The folder used for large-messages - (default from broker.xml) - - With --bindings option, The folder used for bindings (default from - broker.xml) - - compact - Compacts the journal of a non running server - - With --broker option, This would override the broker configuration - from the bootstrap - - With --verbose option, Adds more information on the execution - - With --paging option, The folder used for paging (default from - broker.xml) - - With --journal option, The folder used for messages journal (default - from broker.xml) - - With --large-messages option, The folder used for large-messages - (default from broker.xml) - - With --bindings option, The folder used for bindings (default from - broker.xml) -``` \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/undelivered-messages.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/undelivered-messages.md b/docs/user-manual/en/undelivered-messages.md index 6156c8f..5ef5565 100644 --- a/docs/user-manual/en/undelivered-messages.md +++ b/docs/user-manual/en/undelivered-messages.md @@ -8,18 +8,18 @@ in the queue indefinitely, clogging the system. There are 2 ways to deal with these undelivered messages: -- Delayed redelivery. +- Delayed redelivery. - It is possible to delay messages redelivery. This gives the client some - time to recover from any transient failures and to prevent overloading - its network or CPU resources. + It is possible to delay messages redelivery. This gives the client some + time to recover from any transient failures and to prevent overloading + its network or CPU resources. -- Dead Letter Address. +- Dead Letter Address. - It is also possible to configure a dead letter address so that after - a specified number of unsuccessful deliveries, messages are removed - from their queue and sent to the dead letter address. These messages - will not be delivered again from this queue. + It is also possible to configure a dead letter address so that after + a specified number of unsuccessful deliveries, messages are removed + from their queue and sent to the dead letter address. These messages + will not be delivered again from this queue. Both options can be combined for maximum flexibility. @@ -130,15 +130,15 @@ set of addresses (see [Understanding the Wildcard Syntax](wildcard-syntax.md)). Dead letter messages which are consumed from a dead letter address have the following properties: -- `_AMQ_ORIG_ADDRESS` +- `_AMQ_ORIG_ADDRESS` - a String property containing the *original address* of the dead - letter message + a String property containing the *original address* of the dead + letter message -- `_AMQ_ORIG_QUEUE` +- `_AMQ_ORIG_QUEUE` - a String property containing the *original queue* of the dead letter - message + a String property containing the *original queue* of the dead letter + message ### Example http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/unit-testing.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/unit-testing.md b/docs/user-manual/en/unit-testing.md index 7beb311..859ec00 100644 --- a/docs/user-manual/en/unit-testing.md +++ b/docs/user-manual/en/unit-testing.md @@ -1,29 +1,26 @@ # Unit Testing -The package ```artemis-junit``` provides tools to facilitate how to run Artemis resources inside Junit Tests. +The package `artemis-junit` provides tools to facilitate how to run Artemis resources inside JUnit Tests. -These are provided as junit rules and can make it easier to embed Messaging functionality on your tests. +These are provided as JUnit "rules" and can make it easier to embed messaging functionality on your tests. ## Example - ### Import this on your pom.xml ```xml <dependency> - <groupId>org.apache.activemq</groupId> - <artifactId>artemis-junit</artifactId> - <!-- replace this for the version you are using --> - <version>1.5.0</version> - <scope>test</scope> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-junit</artifactId> + <!-- replace this for the version you are using --> + <version>2.5.0</version> + <scope>test</scope> </dependency> ``` - ### Declare a rule on your JUnit Test - ```java import org.apache.activemq.artemis.junit.EmbeddedJMSResource; import org.junit.Rule; @@ -44,34 +41,31 @@ public class MyTest { This will start a server that will be available for your test: ``` -ain] 17:00:16,644 INFO [org.apache.activemq.artemis.core.server] AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging) +[main] 17:00:16,644 INFO [org.apache.activemq.artemis.core.server] AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging) [main] 17:00:16,666 INFO [org.apache.activemq.artemis.core.server] AMQ221045: libaio is not available, switching the configuration into NIO [main] 17:00:16,688 INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE [main] 17:00:16,801 INFO [org.apache.activemq.artemis.core.server] AMQ221007: Server is now live [main] 17:00:16,801 INFO [org.apache.activemq.artemis.core.server] AMQ221001: Apache ActiveMQ Artemis Message Broker version 1.5.0-SNAPSHOT [embedded-jms-server, nodeID=39e78380-842c-11e6-9e43-f45c8992f3c7] [main] 17:00:16,891 INFO [org.apache.activemq.artemis.core.server] AMQ221002: Apache ActiveMQ Artemis Message Broker version 1.5.0-SNAPSHOT [39e78380-842c-11e6-9e43-f45c8992f3c7] stopped, uptime 0.272 seconds - ``` - ### Ordering rules -This is actually a Junit feature, but this could be helpful on pre-determining the order on which rules are executed. +This is actually a JUnit feature, but this could be helpful on pre-determining the order on which rules are executed. ```java - ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL()); - - @Rule - public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer); +ActiveMQDynamicProducerResource producer = new ActiveMQDynamicProducerResource(server.getVmURL()); +@Rule +public RuleChain ruleChain = RuleChain.outerRule(new ThreadLeakCheckRule()).around(server).around(producer); ``` ### Available Rules Name | Description -:--- | :--- -EmbeddedActiveMQResource | It will run a Server, without the JMS manager -EmbeddedJMSResource | It will run a Server, including the JMS Manager -ActiveMQConsumerResource | It will automate the creation of a consumer -ActiveMQProducerResource | It will automate the creation of a producer -ThreadLeakCheckRule | It will check that all threads have been finished after the test is finished +--- | --- +EmbeddedActiveMQResource | Run a Server, without the JMS manager +EmbeddedJMSResource | Run a Server, including the JMS Manager +ActiveMQConsumerResource | Automate the creation of a consumer +ActiveMQProducerResource | Automate the creation of a producer +ThreadLeakCheckRule | Check that all threads have been finished after the test is finished http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/upgrading.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/upgrading.md b/docs/user-manual/en/upgrading.md index e564f49..61609b8 100644 --- a/docs/user-manual/en/upgrading.md +++ b/docs/user-manual/en/upgrading.md @@ -1,38 +1,41 @@ # Upgrading the Broker -Apache ActiveMQ 5.x (and previous versions) is runnable out of the box by executing -the command: `./bin/activemq run`. The ActiveMQ Artemis broker follows a different -paradigm where the project distribution serves as the broker "home" and one or more -broker "instances" are created which reference the "home" for resources (e.g. jar files) -which can be safely shared between broker instances. Therefore, an instance of the broker -must be created before it can be run. This may seems like an overhead at first -glance, but it becomes very practical when updating to a new Artemis version for example. - -To create an Artemis broker instance navigate into the Artemis home folder and run: -`./bin/artemis create /path/to/myBrokerInstance` on the command line. - -> **Note** -> -> It's recommended to choose a folder different than the on where Apache Artemis was -> downloaded. This separation allows you run multiple broker instances with the same -> Artemis "home" for example. It also simplifies updating to newer versions of Artemis. +Apache ActiveMQ 5.x (and previous versions) is runnable out of the box by +executing the command: `./bin/activemq run`. The ActiveMQ Artemis broker +follows a different paradigm where the project distribution serves as the +broker "home" and one or more broker "instances" are created which reference +the "home" for resources (e.g. jar files) which can be safely shared between +broker instances. Therefore, an instance of the broker must be created before +it can be run. This may seems like an overhead at first glance, but it becomes +very practical when updating to a new Artemis version for example. + +To create an Artemis broker instance navigate into the Artemis home folder and +run: `./bin/artemis create /path/to/myBrokerInstance` on the command line. -Because of this separation it's very easy to upgrade Artemis in most cases. +Because of this separation it's very easy to upgrade Artemis in most cases. + +> **Note:** +> +> It's recommended to choose a folder different than the on where Apache +> Artemis was downloaded. This separation allows you run multiple broker +> instances with the same Artemis "home" for example. It also simplifies +> updating to newer versions of Artemis. ## General Upgrade Procedure -Upgrading may require some specific steps noted in the [versions](versions.md), but the -general process is as follows: +Upgrading may require some specific steps noted in the [versions](versions.md), +but the general process is as follows: 1. Navigate to the `etc` folder of the broker instance that's being upgraded -1. Open `artemis.profile` (`artemis.profile.cmd` on Windows). It contains a property - which is relevant for the upgrade: +1. Open `artemis.profile` (`artemis.profile.cmd` on Windows). It contains a + property which is relevant for the upgrade: ``` ARTEMIS_HOME='/path/to/apache-artemis-version' ``` -The `ARTEMIS_HOME` property is used to link the instance with the home. -_In most cases_ the instance can be upgraded to a newer version simply by changing the -value of this property to the location of the new broker home. Please refer to the -aforementioned [versions](versions.md) document for additional upgrade steps (if required). \ No newline at end of file +The `ARTEMIS_HOME` property is used to link the instance with the home. _In +most cases_ the instance can be upgraded to a newer version simply by changing +the value of this property to the location of the new broker home. Please refer +to the aforementioned [versions](versions.md) document for additional upgrade +steps (if required). http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/using-AMQP.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/using-AMQP.md b/docs/user-manual/en/using-AMQP.md deleted file mode 100644 index 49d0478..0000000 --- a/docs/user-manual/en/using-AMQP.md +++ /dev/null @@ -1,74 +0,0 @@ -# Using AMQP - -Apache ActiveMQ Artemis is also a pure AMQP 1.0 broker, with a high performant and feature complete protocol manager for AMQP. - -You can use *any* AMQP 1.0 compatible clients. - -A short list includes: - -- qpid clients at the [qpid project](https://qpid.apache.org/download.html) -- [.NET Clients](https://blogs.apache.org/activemq/entry/using-net-libraries-with-activemq) -- [Javascript NodeJS](https://github.com/noodlefrenzy/node-amqp10) -- [Java Script RHEA](https://github.com/grs/rhea) - - -... and many others. - - -# Message Conversions - -The broker will not perform any message conversion to any other protocols when sending AMQP and receiving AMQP. - -However if you intend your message to be received on a AMQP JMS Client, you must follow the JMS Mapping convention: - -- [JMS Mapping Conventions](https://www.oasis-open.org/committees/download.php/53086/amqp-bindmap-jms-v1.0-wd05.pdf) - - -If you send a body type that is not recognized by this specification the conversion between AMQP and any other protocol will make it a Binary Message. - -So, make sure you follow these conventions if you intend to cross protocols or languages. Especially on the message body. - -A compatibility setting, allows aligning the naming convention of AMQP queues (JMS Durable and Shared Subscriptions) with CORE. -For backwards compatibility reasons, you need to explicitly enable this via broker configuration: - -* amqp-use-core-subscription-naming - * true - use queue naming convention that is aligned with CORE. - * false (DEFAULT) - use older naming convention. - - -# Example - -We have a few examples as part of the Artemis distribution: - - -- .NET: - * ./examples/protocols/amqp/dotnet - -- ProtonCPP - * ./examples/protocols/amqp/proton-cpp - -- Ruby - * ./examples/protocols/amqp/proton-ruby - -- Java (Using the qpid JMS Client) - * ./examples/protocols/amqp/queue - -- Interceptors - * ./examples/features/standard/broker-plugin - - - # Intercepting and changing messages - - We don't recommend changing messages at the server's side for a few reasons: - - - AMQPMessages are meant to be immutable - - The message won't be the original message the user sent - - AMQP has the possibility of signing messages. The signature would be broken. - - For performance reasons. We try not to re-encode (or even decode) messages. - -If regardless these recommendations you still need and want to intercept and change AMQP Messages, look at the example under ./examples/features/standard/broker-plugin. - -This example will send AMQP Message and modify properties before they reach the journals and are sent to the consumers. - - - http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/using-core.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/using-core.md b/docs/user-manual/en/using-core.md deleted file mode 100644 index 78c08a5..0000000 --- a/docs/user-manual/en/using-core.md +++ /dev/null @@ -1,212 +0,0 @@ -# Using Core - -Apache ActiveMQ Artemis core is a completely JMS-agnostic messaging system with its own -API. We call this the *core API*. - -If you don't want to use JMS or other protocols you can use the core API directly. The core -API provides all the functionality of JMS but without much of the -complexity. It also provides features that are not available using JMS. - -## Core Messaging Concepts - -Some of the core messaging concepts are similar to JMS concepts, but -core messaging concepts differ in some ways. In general the core -messaging API is simpler than the JMS API, since we remove distinctions -between queues, topics and subscriptions. We'll discuss each of the -major core messaging concepts in turn, but to see the API in detail, -please consult the Javadoc. - -### Message - -- A message is the unit of data which is sent between clients and - servers. - -- A message has a body which is a buffer containing convenient methods - for reading and writing data into it. - -- A message has a set of properties which are key-value pairs. Each - property key is a string and property values can be of type integer, - long, short, byte, byte[], String, double, float or boolean. - -- A message has an *address* it is being sent to. When the message - arrives on the server it is routed to any queues that are bound to - the address - if the queues are bound with any filter, the message - will only be routed to that queue if the filter matches. An address - may have many queues bound to it or even none. There may also be - entities other than queues, like *diverts* bound to addresses. - -- Messages can be either durable or non durable. Durable messages in a - durable queue will survive a server crash or restart. Non durable - messages will never survive a server crash or restart. - -- Messages can be specified with a priority value between 0 and 9. 0 - represents the lowest priority and 9 represents the highest. - Apache ActiveMQ Artemis will attempt to deliver higher priority messages before - lower priority ones. - -- Messages can be specified with an optional expiry time. Apache ActiveMQ Artemis - will not deliver messages after its expiry time has been exceeded. - -- Messages also have an optional timestamp which represents the time - the message was sent. - -- Apache ActiveMQ Artemis also supports the sending/consuming of very large messages - much larger than can fit in available RAM at any one time. - -### Address - -A server maintains a mapping between an address and a set of queues. -Zero or more queues can be bound to a single address. Each queue can be -bound with an optional message filter. When a message is routed, it is -routed to the set of queues bound to the message's address. If any of -the queues are bound with a filter expression, then the message will -only be routed to the subset of bound queues which match that filter -expression. - -Other entities, such as *diverts* can also be bound to an address and -messages will also be routed there. - -> **Note** -> -> In core, there is no concept of a Topic, Topic is a JMS only term. -> Instead, in core, we just deal with *addresses* and *queues*. -> -> For example, a JMS topic would be implemented by a single address to -> which many queues are bound. Each queue represents a subscription of -> the topic. A JMS Queue would be implemented as a single address to -> which one queue is bound - that queue represents the JMS queue. - -### Queue - -Queues can be durable, meaning the messages they contain survive a -server crash or restart, as long as the messages in them are durable. -Non durable queues do not survive a server restart or crash even if the -messages they contain are durable. - -Queues can also be temporary, meaning they are automatically deleted -when the client connection is closed, if they are not explicitly deleted -before that. - -Queues can be bound with an optional filter expression. If a filter -expression is supplied then the server will only route messages that -match that filter expression to any queues bound to the address. - -Many queues can be bound to a single address. A particular queue is only -bound to a maximum of one address. - -### ServerLocator - -Clients use `ServerLocator` instances to create `ClientSessionFactory` -instances. `ServerLocator` instances are used to locate servers and -create connections to them. - -In JMS terms think of a `ServerLocator` in the same way you would a JMS -Connection Factory. - -`ServerLocator` instances are created using the `ActiveMQClient` factory -class. - -### ClientSessionFactory - -Clients use `ClientSessionFactory` instances to create `ClientSession` -instances. `ClientSessionFactory` instances are basically the connection -to a server - -In JMS terms think of them as JMS Connections. - -`ClientSessionFactory` instances are created using the `ServerLocator` -class. - -### ClientSession - -A client uses a ClientSession for consuming and producing messages and -for grouping them in transactions. ClientSession instances can support -both transactional and non transactional semantics and also provide an -`XAResource` interface so messaging operations can be performed as part -of a -[JTA](http://www.oracle.com/technetwork/java/javaee/tech/jta-138684.html) -transaction. - -ClientSession instances group ClientConsumers and ClientProducers. - -ClientSession instances can be registered with an optional -`SendAcknowledgementHandler`. This allows your client code to be -notified asynchronously when sent messages have successfully reached the -server. This unique Apache ActiveMQ Artemis feature, allows you to have full guarantees -that sent messages have reached the server without having to block on -each message sent until a response is received. Blocking on each -messages sent is costly since it requires a network round trip for each -message sent. By not blocking and receiving send acknowledgements -asynchronously you can create true end to end asynchronous systems which -is not possible using the standard JMS API. For more information on this -advanced feature please see the section [Guarantees of sends and commits](send-guarantees.md). - -### ClientConsumer - -Clients use `ClientConsumer` instances to consume messages from a queue. -Core Messaging supports both synchronous and asynchronous message -consumption semantics. `ClientConsumer` instances can be configured with -an optional filter expression and will only consume messages which match -that expression. - -### ClientProducer - -Clients create `ClientProducer` instances on `ClientSession` instances -so they can send messages. ClientProducer instances can specify an -address to which all sent messages are routed, or they can have no -specified address, and the address is specified at send time for the -message. - -> **Warning** -> -> Please note that ClientSession, ClientProducer and ClientConsumer -> instances are *designed to be re-used*. -> -> It's an anti-pattern to create new ClientSession, ClientProducer and -> ClientConsumer instances for each message you produce or consume. If -> you do this, your application will perform very poorly. This is -> discussed further in the section on performance tuning [Performance Tuning](perf-tuning.md). - -## A simple example of using Core - -Here's a very simple program using the core messaging API to send and -receive a message. Logically it's comprised of two sections: firstly -setting up the producer to write a message to an *addresss*, and -secondly, creating a *queue* for the consumer, creating the consumer and -*starting* it. -```java -ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration( - InVMConnectorFactory.class.getName())); - -// In this simple example, we just use one session for both producing and receiving - -ClientSessionFactory factory = locator.createClientSessionFactory(); -ClientSession session = factory.createSession(); - -// A producer is associated with an address ... - -ClientProducer producer = session.createProducer("example"); -ClientMessage message = session.createMessage(true); -message.getBodyBuffer().writeString("Hello"); - -// We need a queue attached to the address ... - -session.createQueue("example", "example", true); - -// And a consumer attached to the queue ... - -ClientConsumer consumer = session.createConsumer("example"); - -// Once we have a queue, we can send the message ... - -producer.send(message); - -// We need to start the session before we can -receive- messages ... - -session.start(); -ClientMessage msgReceived = consumer.receive(); - -System.out.println("message = " + msgReceived.getBodyBuffer().readString()); - -session.close(); -``` http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/40b66d13/docs/user-manual/en/using-jms.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/using-jms.md b/docs/user-manual/en/using-jms.md index bf654b9..bc9f3f2 100644 --- a/docs/user-manual/en/using-jms.md +++ b/docs/user-manual/en/using-jms.md @@ -1,186 +1,193 @@ # Using JMS -Although Apache ActiveMQ Artemis provides a JMS agnostic messaging API, many users will -be more comfortable using JMS. +Although Apache ActiveMQ Artemis provides a JMS agnostic messaging API, many +users will be more comfortable using JMS. -JMS is a very popular API standard for messaging, and most messaging -systems provide a JMS API. If you are completely new to JMS we suggest -you follow the [Oracle JMS tutorial](https://docs.oracle.com/javaee/7/tutorial/partmessaging.htm) - -a full JMS tutorial is out of scope for this guide. +JMS is a very popular API standard for messaging, and most messaging systems +provide a JMS API. If you are completely new to JMS we suggest you follow the +[Oracle JMS +tutorial](https://docs.oracle.com/javaee/7/tutorial/partmessaging.htm) - a full +JMS tutorial is out of scope for this guide. Apache ActiveMQ Artemis also ships with a wide range of examples, many of which -demonstrate JMS API usage. A good place to start would be to play around -with the simple JMS Queue and Topic example, but we also provide -examples for many other parts of the JMS API. A full description of the -examples is available in [Examples](examples.md). +demonstrate JMS API usage. A good place to start would be to play around with +the simple JMS Queue and Topic example, but we also provide examples for many +other parts of the JMS API. A full description of the examples is available in +[Examples](examples.md). -In this section we'll go through the main steps in configuring the -server for JMS and creating a simple JMS program. We'll also show how to -configure and use JNDI, and also how to use JMS with Apache ActiveMQ Artemis without -using any JNDI. +In this section we'll go through the main steps in configuring the server for +JMS and creating a simple JMS program. We'll also show how to configure and use +JNDI, and also how to use JMS with Apache ActiveMQ Artemis without using any +JNDI. ## A simple ordering system For this chapter we're going to use a very simple ordering system as our -example. It is a somewhat contrived example because of its extreme -simplicity, but it serves to demonstrate the very basics of setting up -and using JMS. - -We will have a single JMS Queue called `OrderQueue`, and we will have a -single `MessageProducer` sending an order message to the queue and a -single `MessageConsumer` consuming the order message from the queue. - -The queue will be a `durable` queue, i.e. it will survive a server -restart or crash. We also want to pre-deploy the queue, i.e. specify the -queue in the server configuration so it is created automatically -without us having to explicitly create it from the client. - -## JNDI Configuration - -The JMS specification establishes the convention that *administered -objects* (i.e. JMS queue, topic and connection factory instances) are -made available via the JNDI API. Brokers are free to implement JNDI as -they see fit assuming the implementation fits the API. Apache ActiveMQ Artemis does not -have a JNDI server. Rather, it uses a client-side JNDI implementation -that relies on special properties set in the environment to construct -the appropriate JMS objects. In other words, no objects are stored in -JNDI on the Apache ActiveMQ Artemis server, instead they are simply instantiated on the -client based on the provided configuration. Let's look at the different -kinds of administered objects and how to configure them. - -> **Note** +example. It is a somewhat contrived example because of its extreme simplicity, +but it serves to demonstrate the very basics of setting up and using JMS. + +We will have a single JMS Queue called `OrderQueue`, and we will have a single +`MessageProducer` sending an order message to the queue and a single +`MessageConsumer` consuming the order message from the queue. + +The queue will be a `durable` queue, i.e. it will survive a server restart or +crash. We also want to pre-deploy the queue, i.e. specify the queue in the +server configuration so it is created automatically without us having to +explicitly create it from the client. + +## JNDI + +The JMS specification establishes the convention that *administered objects* +(i.e. JMS queue, topic and connection factory instances) are made available via +the JNDI API. Brokers are free to implement JNDI as they see fit assuming the +implementation fits the API. Apache ActiveMQ Artemis does not have a JNDI +server. Rather, it uses a client-side JNDI implementation that relies on +special properties set in the environment to construct the appropriate JMS +objects. In other words, no objects are stored in JNDI on the Apache ActiveMQ +Artemis server, instead they are simply instantiated on the client based on the +provided configuration. Let's look at the different kinds of administered +objects and how to configure them. + +> **Note:** > -> The following configuration properties *are strictly required when -> Apache ActiveMQ Artemis is running in stand-alone mode*. When Apache ActiveMQ Artemis is integrated -> to an application server (e.g. Wildfly) the application server itself -> will almost certainly provide a JNDI client with its own properties. +> The following configuration properties *are strictly required when Apache +> ActiveMQ Artemis is running in stand-alone mode*. When Apache ActiveMQ +> Artemis is integrated to an application server (e.g. Wildfly) the application +> server itself will almost certainly provide a JNDI client with its own +> properties. ### ConnectionFactory JNDI -A JMS connection factory is used by the client to make connections to -the server. It knows the location of the server it is connecting to, as -well as many other configuration parameters. +A JMS connection factory is used by the client to make connections to the +server. It knows the location of the server it is connecting to, as well as +many other configuration parameters. -Here's a simple example of the JNDI context environment for a client -looking up a connection factory to access an *embedded* instance of -Apache ActiveMQ Artemis: +Here's a simple example of the JNDI context environment for a client looking up +a connection factory to access an *embedded* instance of Apache ActiveMQ +Artemis: - java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory - connectionFactory.invmConnectionFactory=vm://0 -In this instance we have created a connection factory that is bound to -`invmConnectionFactory`, any entry with prefix `connectionFactory.` will - create a connection factory. +```properties +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +connectionFactory.invmConnectionFactory=vm://0 +``` -In certain situations there could be multiple server instances running -within a particular JVM. In that situation each server would typically -have an InVM acceptor with a unique server-ID. A client using JMS and -JNDI can account for this by specifying a connction factory for each -server, like so: +In this instance we have created a connection factory that is bound to +`invmConnectionFactory`, any entry with prefix `connectionFactory.` will create +a connection factory. - java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory - connectionFactory.invmConnectionFactory0=vm://0 - connectionFactory.invmConnectionFactory1=vm://1 - connectionFactory.invmConnectionFactory2=vm://2 +In certain situations there could be multiple server instances running within a +particular JVM. In that situation each server would typically have an InVM +acceptor with a unique server-ID. A client using JMS and JNDI can account for +this by specifying a connction factory for each server, like so: -Here is a list of all the supported URL schemes: -- `vm` +```properties +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +connectionFactory.invmConnectionFactory0=vm://0 +connectionFactory.invmConnectionFactory1=vm://1 +connectionFactory.invmConnectionFactory2=vm://2 +``` -- `tcp` +Here is a list of all the supported URL schemes: -- `udp` +- `vm` +- `tcp` +- `udp` +- `jgroups` -- `jgroups` +Most clients won't be connecting to an embedded broker. Clients will most +commonly connect across a network a remote broker. Here's a simple example of a +client configuring a connection factory to connect to a remote broker running +on myhost:5445: -Most clients won't be connecting to an embedded broker. Clients will -most commonly connect across a network a remote broker. Here's a simple -example of a client configuring a connection factory to connect to a -remote broker running on myhost:5445: - java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory - connectionFactory.ConnectionFactory=tcp://myhost:5445 +```properties +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +connectionFactory.ConnectionFactory=tcp://myhost:5445 +``` -In the example above the client is using the `tcp` scheme for the -provider URL. A client may also specify multiple comma-delimited -host:port combinations in the URL (e.g. -`(tcp://remote-host1:5445,remote-host2:5445)`). Whether there is one or -many host:port combinations in the URL they are treated as the *initial +In the example above the client is using the `tcp` scheme for the provider URL. +A client may also specify multiple comma-delimited host:port combinations in +the URL (e.g. `(tcp://remote-host1:5445,remote-host2:5445)`). Whether there is +one or many host:port combinations in the URL they are treated as the *initial connector(s)* for the underlying connection. -The `udp` scheme is also supported which should use a host:port -combination that matches the `group-address` and `group-port` from the -corresponding `broadcast-group` configured on the ActiveMQ Artemis server(s). +The `udp` scheme is also supported which should use a host:port combination +that matches the `group-address` and `group-port` from the corresponding +`broadcast-group` configured on the ActiveMQ Artemis server(s). Each scheme has a specific set of properties which can be set using the traditional URL query string format (e.g. -`scheme://host:port?key1=value1&key2=value2`) to customize the -underlying transport mechanism. For example, if a client wanted to -connect to a remote server using TCP and SSL it would create a connection -factory like so, `tcp://remote-host:5445?ssl-enabled=true`. +`scheme://host:port?key1=value1&key2=value2`) to customize the underlying +transport mechanism. For example, if a client wanted to connect to a remote +server using TCP and SSL it would create a connection factory like so, +`tcp://remote-host:5445?ssl-enabled=true`. All the properties available for the `tcp` scheme are described in [the documentation regarding the Netty transport](configuring-transports.md#configuring-the-netty-transport). -Note if you are using the `tcp` scheme and multiple addresses then a query -can be applied to all the url's or just to an individual connector, so where -you have +Note if you are using the `tcp` scheme and multiple addresses then a query can +be applied to all the url's or just to an individual connector, so where you +have -- `(tcp://remote-host1:5445?httpEnabled=true,remote-host2:5445?httpEnabled=true)?clientID=1234` +- `(tcp://remote-host1:5445?httpEnabled=true,remote-host2:5445?httpEnabled=true)?clientID=1234` -then the `httpEnabled` property is only set on the individual connectors where as the `clientId` -is set on the actual connection factory. Any connector specific properties set on the whole -URI will be applied to all the connectors. +then the `httpEnabled` property is only set on the individual connectors where +as the `clientId` is set on the actual connection factory. Any connector +specific properties set on the whole URI will be applied to all the connectors. The `udp` scheme supports 4 properties: -- `localAddress` - If you are running with multiple network - interfaces on the same machine, you may want to specify that the - discovery group listens only only a specific interface. To do this - you can specify the interface address with this parameter. - -- `localPort` - If you want to specify a local port to which the - datagram socket is bound you can specify it here. Normally you would - just use the default value of -1 which signifies that an anonymous - port should be used. This parameter is always specified in - conjunction with `localAddress`. - -- `refreshTimeout` - This is the period the discovery group waits - after receiving the last broadcast from a particular server before - removing that servers connector pair entry from its list. You would - normally set this to a value significantly higher than the - broadcast-period on the broadcast group otherwise servers might - intermittently disappear from the list even though they are still - broadcasting due to slight differences in timing. This parameter is - optional, the default value is 10000 milliseconds (10 seconds). - -- `discoveryInitialWaitTimeout` - If the connection factory is used - immediately after creation then it may not have had enough time to - received broadcasts from all the nodes in the cluster. On first - usage, the connection factory will make sure it waits this long - since creation before creating the first connection. The default - value for this parameter is 10000 milliseconds. - -Lastly, the `jgroups` scheme is supported which provides an alternative -to the `udp` scheme for server discovery. The URL pattern is either +- `localAddress` - If you are running with multiple network + interfaces on the same machine, you may want to specify that the + discovery group listens only only a specific interface. To do this + you can specify the interface address with this parameter. + +- `localPort` - If you want to specify a local port to which the + datagram socket is bound you can specify it here. Normally you would + just use the default value of -1 which signifies that an anonymous + port should be used. This parameter is always specified in + conjunction with `localAddress`. + +- `refreshTimeout` - This is the period the discovery group waits after + receiving the last broadcast from a particular server before removing that + servers connector pair entry from its list. You would normally set this to a + value significantly higher than the broadcast-period on the broadcast group + otherwise servers might intermittently disappear from the list even though they + are still broadcasting due to slight differences in timing. This parameter is + optional, the default value is 10000 milliseconds (10 seconds). + +- `discoveryInitialWaitTimeout` - If the connection factory is used immediately + after creation then it may not have had enough time to received broadcasts + from all the nodes in the cluster. On first usage, the connection factory will + make sure it waits this long since creation before creating the first + connection. The default value for this parameter is 10000 milliseconds. + +Lastly, the `jgroups` scheme is supported which provides an alternative to the +`udp` scheme for server discovery. The URL pattern is either `jgroups://channelName?file=jgroups-xml-conf-filename` -where`jgroups-xml-conf-filename` refers to an XML file on the classpath -that contains the JGroups configuration or it can be -`jgroups://channelName?properties=some-jgroups-properties`. In both instance the -`channelName` is the name given to the jgroups channel created. +where`jgroups-xml-conf-filename` refers to an XML file on the classpath that +contains the JGroups configuration or it can be +`jgroups://channelName?properties=some-jgroups-properties`. In both instance +the `channelName` is the name given to the jgroups channel created. + +The `refreshTimeout` and `discoveryInitialWaitTimeout` properties are supported +just like with `udp`. -The `refreshTimeout` and `discoveryInitialWaitTimeout` properties -are supported just like with `udp`. +The default type for the default connection factory is of type +`javax.jms.ConnectionFactory`. This can be changed by setting the type like so -The default type for the default connection factory is of type `javax.jms.ConnectionFactory`. -This can be changed by setting the type like so - java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory - java.naming.provider.url=tcp://localhost:5445?type=CF +```properties +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +java.naming.provider.url=tcp://localhost:5445?type=CF +``` -In this example it is still set to the default, below shows a list of types that can be set. +In this example it is still set to the default, below shows a list of types +that can be set. #### Configuration for Connection Factory Types @@ -195,42 +202,46 @@ TOPIC_XA_CF | javax.jms.XATopicConnectionFactory ### Destination JNDI -JMS destinations are also typically looked up via JNDI. As with -connection factories, destinations can be configured using special -properties in the JNDI context environment. The property *name* should -follow the pattern: `queue.<jndi-binding>` or `topic.<jndi-binding>`. -The property *value* should be the name of the queue hosted by the -Apache ActiveMQ Artemis server. For example, if the server had a JMS queue configured -like so: +JMS destinations are also typically looked up via JNDI. As with connection +factories, destinations can be configured using special properties in the JNDI +context environment. The property *name* should follow the pattern: +`queue.<jndi-binding>` or `topic.<jndi-binding>`. The property *value* should +be the name of the queue hosted by the Apache ActiveMQ Artemis server. For +example, if the server had a JMS queue configured like so: ```xml -<queue name="OrderQueue"/> +<address name="OrderQueue"> + <queue name="OrderQueue"/> +</address> ``` -And if the client wanted to bind this queue to "queues/OrderQueue" then -the JNDI properties would be configured like so: +And if the client wanted to bind this queue to "queues/OrderQueue" then the +JNDI properties would be configured like so: - java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory - java.naming.provider.url=tcp://myhost:5445 - queue.queues/OrderQueue=OrderQueue +```properties +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +java.naming.provider.url=tcp://myhost:5445 +queue.queues/OrderQueue=OrderQueue +``` -It is also possible to look-up JMS destinations which haven't been -configured explicitly in the JNDI context environment. This is possible -using `dynamicQueues/` or `dynamicTopics/` in the look-up string. For -example, if the client wanted to look-up the aforementioned "OrderQueue" -it could do so simply by using the string "dynamicQueues/OrderQueue". -Note, the text that follows `dynamicQueues/` or `dynamicTopics/` must -correspond *exactly* to the name of the destination on the server. +It is also possible to look-up JMS destinations which haven't been configured +explicitly in the JNDI context environment. This is possible using +`dynamicQueues/` or `dynamicTopics/` in the look-up string. For example, if the +client wanted to look-up the aforementioned "OrderQueue" it could do so simply +by using the string "dynamicQueues/OrderQueue". Note, the text that follows +`dynamicQueues/` or `dynamicTopics/` must correspond *exactly* to the name of +the destination on the server. ### The code Here's the code for the example: -First we'll create a JNDI initial context from which to lookup our JMS -objects. If the above properties are set in `jndi.properties` and it is -on the classpath then any new, empty `InitialContext` will be -initialized using those properties: -```java +First we'll create a JNDI initial context from which to lookup our JMS objects. +If the above properties are set in `jndi.properties` and it is on the classpath +then any new, empty `InitialContext` will be initialized using those +properties: + +```java InitialContext ic = new InitialContext(); //Now we'll look up the connection factory from which we can create @@ -280,35 +291,36 @@ see the examples directory in the distribution. > **Warning** > -> Please note that JMS connections, sessions, producers and consumers -> are *designed to be re-used*. +> Please note that JMS connections, sessions, producers and consumers are +> *designed to be re-used*. > -> It is an anti-pattern to create new connections, sessions, producers -> and consumers for each message you produce or consume. If you do this, -> your application will perform very poorly. This is discussed further -> in the section on performance tuning [Performance Tuning](perf-tuning.md). +> It is an anti-pattern to create new connections, sessions, producers and +> consumers for each message you produce or consume. If you do this, your +> application will perform very poorly. This is discussed further in the +> section on performance tuning [Performance Tuning](perf-tuning.md). ## Directly instantiating JMS Resources without using JNDI -Although it is a very common JMS usage pattern to lookup JMS -*Administered Objects* (that's JMS Queue, Topic and ConnectionFactory -instances) from JNDI, in some cases you just think "Why do I need JNDI? -Why can't I just instantiate these objects directly?" +Although it is a very common JMS usage pattern to lookup JMS *Administered +Objects* (that's JMS Queue, Topic and ConnectionFactory instances) from JNDI, +in some cases you just think "Why do I need JNDI? Why can't I just instantiate +these objects directly?" -With Apache ActiveMQ Artemis you can do exactly that. Apache ActiveMQ Artemis supports the direct -instantiation of JMS Queue, Topic and ConnectionFactory instances, so -you don't have to use JNDI at all. +With Apache ActiveMQ Artemis you can do exactly that. Apache ActiveMQ Artemis +supports the direct instantiation of JMS Queue, Topic and ConnectionFactory +instances, so you don't have to use JNDI at all. ->For a full working example of direct instantiation please look at the ->"Instantiate JMS Objects Directly" example under the JMS section of the ->examples. See the [Examples](examples.md) section for more info. +> For a full working example of direct instantiation please look at the +> [Instantiate JMS Objects +> Directly](examples.md#instantiate-jms-objects-directly) example under the JMS +> section of the examples. Here's our simple example, rewritten to not use JNDI at all: -We create the JMS ConnectionFactory object via the ActiveMQJMSClient -Utility class, note we need to provide connection parameters and specify -which transport we are using, for more information on connectors please -see [Configuring the Transport](configuring-transports.md). +We create the JMS ConnectionFactory object via the ActiveMQJMSClient Utility +class, note we need to provide connection parameters and specify which +transport we are using, for more information on connectors please see +[Configuring the Transport](configuring-transports.md). ```java TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName()); @@ -355,35 +367,33 @@ System.out.println("Got order: " + receivedMessage.getText()); ## Setting The Client ID -This represents the client id for a JMS client and is needed for -creating durable subscriptions. It is possible to configure this on the -connection factory and can be set via the `clientId` element. Any -connection created by this connection factory will have this set as its -client id. +This represents the client id for a JMS client and is needed for creating +durable subscriptions. It is possible to configure this on the connection +factory and can be set via the `clientId` element. Any connection created by +this connection factory will have this set as its client id. ## Setting The Batch Size for DUPS_OK -When the JMS acknowledge mode is set to `DUPS_OK` it is possible to -configure the consumer so that it sends acknowledgements in batches -rather that one at a time, saving valuable bandwidth. This can be -configured via the connection factory via the `dupsOkBatchSize` -element and is set in bytes. The default is 1024 \* 1024 bytes = 1 MiB. +When the JMS acknowledge mode is set to `DUPS_OK` it is possible to configure +the consumer so that it sends acknowledgements in batches rather that one at a +time, saving valuable bandwidth. This can be configured via the connection +factory via the `dupsOkBatchSize` element and is set in bytes. The default is +1024 \* 1024 bytes = 1 MiB. ## Setting The Transaction Batch Size When receiving messages in a transaction it is possible to configure the -consumer to send acknowledgements in batches rather than individually -saving valuable bandwidth. This can be configured on the connection -factory via the `transactionBatchSize` element and is set in bytes. -The default is 1024 \* 1024. +consumer to send acknowledgements in batches rather than individually saving +valuable bandwidth. This can be configured on the connection factory via the +`transactionBatchSize` element and is set in bytes. The default is 1024 \* +1024. ## Setting The Destination Cache -Many frameworks such as Spring resolve the destination by name on every operation, -this can cause a performance issue and extra calls to the broker, -in a scenario where destinations (addresses) are permanent broker side, -such as they are managed by a platform or operations team. -using `destinationCache` element, you can toggle on the destination cache -to improve the performance and reduce the calls to the broker. -This should not be used if destinations (addresses) are not permanent broker side, -as in dynamic creation/deletion. +Many frameworks such as Spring resolve the destination by name on every +operation, this can cause a performance issue and extra calls to the broker, in +a scenario where destinations (addresses) are permanent broker side, such as +they are managed by a platform or operations team. using `destinationCache` +element, you can toggle on the destination cache to improve the performance and +reduce the calls to the broker. This should not be used if destinations +(addresses) are not permanent broker side, as in dynamic creation/deletion.
