You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2015/08/13 06:13:33 UTC
[15/48] activemq-artemis git commit: renaming broker-features ->
features on examples
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/client-kickoff/readme.html
----------------------------------------------------------------------
diff --git a/examples/features/standard/client-kickoff/readme.html b/examples/features/standard/client-kickoff/readme.html
new file mode 100644
index 0000000..8400e6a
--- /dev/null
+++ b/examples/features/standard/client-kickoff/readme.html
@@ -0,0 +1,54 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <head>
+ <title>ActiveMQ Artemis Client Kickoff Example</title>
+ <link rel="stylesheet" type="text/css" href="../../../common/common.css" />
+ <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" />
+ <script type="text/javascript" src="../../../common/prettify.js"></script>
+ </head>
+ <body onload="prettyPrint()">
+ <h1>Client Kickoff Example</h1>
+
+ <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre>
+
+ <p>This example shows how to kick off a client connected to ActiveMQ
+ using <a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/">JMX</a></p>
+
+ <p>The example will connect to ActiveMQ Artemis. Using JMX, we will list the remote addresses connected to the
+ server and close the corresponding connections. The client will be kicked off from ActiveMQ Artemis receiving
+ an exception that its JMS connection was interrupted.</p>
+
+ <h2>Example configuration</h2>
+
+ <p>ActiveMQ Artemis exposes its managed resources by default on the platform MBeanServer.</p>
+ <p>To access this MBeanServer remotely, the Java Virtual machine must be started with system properties:
+ <pre class="prettyprint">
+ <code>-Dcom.sun.management.jmxremote
+ -Dcom.sun.management.jmxremote.port=3000
+ -Dcom.sun.management.jmxremote.ssl=false
+ -Dcom.sun.management.jmxremote.authenticate=false</code>
+ </pre>
+ <p>These properties are explained in the Java 5 <a href="http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html#remote">Management guide</a>
+ (please note that for this example, we will disable user authentication for simplicity).</p>
+ <p>With these properties, ActiveMQ Artemis server will be manageable remotely using standard JMX URL on port <code>3000</code>.</p>
+ </p>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/client-kickoff/src/main/java/org/apache/activemq/artemis/jms/example/ClientKickoffExample.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/client-kickoff/src/main/java/org/apache/activemq/artemis/jms/example/ClientKickoffExample.java b/examples/features/standard/client-kickoff/src/main/java/org/apache/activemq/artemis/jms/example/ClientKickoffExample.java
new file mode 100644
index 0000000..14e9f37
--- /dev/null
+++ b/examples/features/standard/client-kickoff/src/main/java/org/apache/activemq/artemis/jms/example/ClientKickoffExample.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.naming.InitialContext;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
+import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
+
+/**
+ * An example that shows how to kick off a client connected to ActiveMQ Artemis by using JMX.
+ */
+public class ClientKickoffExample {
+
+ private static final String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi";
+
+ public static void main(final String[] args) throws Exception {
+ QueueConnection connection = null;
+ InitialContext initialContext = null;
+ try {
+ // Step 1. Create an initial context to perform the JNDI lookup.
+ initialContext = new InitialContext();
+
+ // Step 2. Perform a lookup on the Connection Factory
+ QueueConnectionFactory cf = (QueueConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+ // Step 3.Create a JMS Connection
+ connection = cf.createQueueConnection();
+
+ // Step 4. Set an exception listener on the connection to be notified after a problem occurred
+ final AtomicReference<JMSException> exception = new AtomicReference<JMSException>();
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(final JMSException e) {
+ exception.set(e);
+ }
+ });
+
+ // Step 5. We start the connection
+ connection.start();
+
+ // Step 6. Create an ActiveMQServerControlMBean proxy to manage the server
+ ObjectName on = ObjectNameBuilder.DEFAULT.getActiveMQServerObjectName();
+ JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), new HashMap<String, String>());
+ MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+ ActiveMQServerControl serverControl = MBeanServerInvocationHandler.newProxyInstance(mbsc, on, ActiveMQServerControl.class, false);
+
+ // Step 7. List the remote address connected to the server
+ System.out.println("List of remote addresses connected to the server:");
+ System.out.println("----------------------------------");
+ String[] remoteAddresses = serverControl.listRemoteAddresses();
+ for (String remoteAddress : remoteAddresses) {
+ System.out.println(remoteAddress);
+ }
+ System.out.println("----------------------------------");
+
+ // Step 8. Close the connections for the 1st remote address and kickoff the client
+ serverControl.closeConnectionsForAddress(remoteAddresses[0]);
+
+ // Sleep a little bit so that the stack trace from the server won't be
+ // mingled with the JMSException received on the ExceptionListener
+ Thread.sleep(1000);
+
+ // Step 9. Display the exception received by the connection's ExceptionListener
+ System.err.println("\nException received from the server:");
+ System.err.println("----------------------------------");
+ exception.get().printStackTrace();
+ System.err.println("----------------------------------");
+ }
+ finally {
+ // Step 10. Be sure to close the resources!
+ if (initialContext != null) {
+ initialContext.close();
+ }
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/client-kickoff/src/main/resources/activemq/server0/broker.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/client-kickoff/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/client-kickoff/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..3b5a465
--- /dev/null
+++ b/examples/features/standard/client-kickoff/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,47 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:activemq"
+ xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+ <jms xmlns="urn:activemq:jms">
+
+ </jms>
+
+ <core xmlns="urn:activemq:core">
+
+ <bindings-directory>${data.dir:../data}/bindings</bindings-directory>
+
+ <journal-directory>${data.dir:../data}/journal</journal-directory>
+
+ <large-messages-directory>${data.dir:../data}/largemessages</large-messages-directory>
+
+ <paging-directory>${data.dir:../data}/paging</paging-directory>
+
+ <!-- true to expose ActiveMQ Artemis resources through JMX -->
+ <jmx-management-enabled>true</jmx-management-enabled>
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="netty">tcp://localhost:61616</acceptor>
+ </acceptors>
+ </core>
+
+</configuration>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/client-kickoff/src/main/resources/jndi.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/client-kickoff/src/main/resources/jndi.properties b/examples/features/standard/client-kickoff/src/main/resources/jndi.properties
new file mode 100644
index 0000000..5cbe72c
--- /dev/null
+++ b/examples/features/standard/client-kickoff/src/main/resources/jndi.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/consumer-rate-limit/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/consumer-rate-limit/pom.xml b/examples/features/standard/consumer-rate-limit/pom.xml
new file mode 100644
index 0000000..c1db582
--- /dev/null
+++ b/examples/features/standard/consumer-rate-limit/pom.xml
@@ -0,0 +1,109 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>jms-examples</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>consumer-rate-limit</artifactId>
+ <packaging>jar</packaging>
+ <name>ActiveMQ Artemis JMS Consumer Rate Limit Example</name>
+
+ <properties>
+ <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-jms-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>start</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <spawn>true</spawn>
+ <testURI>tcp://localhost:61616</testURI>
+ <args>
+ <param>run</param>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <id>runClient</id>
+ <goals>
+ <goal>runClient</goal>
+ </goals>
+ <configuration>
+ <clientClass>org.apache.activemq.artemis.jms.example.ConsumerRateLimitExample</clientClass>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <args>
+ <param>stop</param>
+ </args>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>consumer-rate-limit</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/consumer-rate-limit/readme.html
----------------------------------------------------------------------
diff --git a/examples/features/standard/consumer-rate-limit/readme.html b/examples/features/standard/consumer-rate-limit/readme.html
new file mode 100644
index 0000000..415de00
--- /dev/null
+++ b/examples/features/standard/consumer-rate-limit/readme.html
@@ -0,0 +1,47 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <head>
+ <title>ActiveMQ Artemis JMS Message Consumer Rate Limiting</title>
+ <link rel="stylesheet" type="text/css" href="../../../common/common.css" />
+ <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" />
+ <script type="text/javascript" src="../../../common/prettify.js"></script>
+ </head>
+ <body onload="prettyPrint()">
+ <h1>JMS Message Consumer Rate Limiting</h1>
+ <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre>
+
+ <p>With ActiveMQ Artemis you can specify a maximum consume rate at which a JMS MessageConsumer will consume messages.
+ This can be specified when creating or configuring the connection factory. See <code>jndi.properties</code>.</p>
+ <p>If this value is specified then ActiveMQ Artemis will ensure that messages are never consumed at a rate higher than
+ the specified rate. This is a form of consumer <i>throttling</i>.</p>
+ <h2>Example step-by-step</h2>
+ <p>In this example we specify a <code>consumer-max-rate</code> of <code>10</code> messages per second in the <code>jndi.properties</code>
+ file when configuring the connection factory:</p>
+ <pre class="prettyprint">
+ <code>
+connectionFactory.ConnectionFactory=tcp://localhost:61616?consumerMaxRate=10
+ </code>
+ </pre>
+ <p>We then simply consume as many messages as we can in 10 seconds and note how many messages are actually consumed.</p>
+ <p>We note that the number of messages consumed per second never exceeds the specified value of <code>10</code> messages per second.</p>
+
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/consumer-rate-limit/src/main/java/org/apache/activemq/artemis/jms/example/ConsumerRateLimitExample.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/consumer-rate-limit/src/main/java/org/apache/activemq/artemis/jms/example/ConsumerRateLimitExample.java b/examples/features/standard/consumer-rate-limit/src/main/java/org/apache/activemq/artemis/jms/example/ConsumerRateLimitExample.java
new file mode 100644
index 0000000..fb98c76
--- /dev/null
+++ b/examples/features/standard/consumer-rate-limit/src/main/java/org/apache/activemq/artemis/jms/example/ConsumerRateLimitExample.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+
+/**
+ * This example demonstrates how a message consumer can be limited to consumer messages at a maximum rate
+ * specified in messages per sec.
+ */
+public class ConsumerRateLimitExample {
+
+ public static void main(final String[] args) throws Exception {
+ Connection connection = null;
+ InitialContext initialContext = null;
+ try {
+ // Step 1. Create an initial context to perform the JNDI lookup.
+ initialContext = new InitialContext();
+
+ // Step 2. Perfom a lookup on the queue
+ Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
+
+ // Step 3. Perform a lookup on the Connection Factory
+ ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+ // Step 4. Create a JMS Connection
+ connection = cf.createConnection();
+
+ // Step 5. Create a JMS Session
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // Step 6. Create a JMS Message Producer
+ MessageProducer producer = session.createProducer(queue);
+
+ // Step 7. Create a JMS Message Consumer
+
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ // Step 8. Start the connection
+
+ connection.start();
+
+ // Step 9. Send a bunch of messages
+
+ final int numMessages = 150;
+
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage("This is text message: " + i);
+
+ producer.send(message);
+ }
+
+ System.out.println("Sent messages");
+
+ System.out.println("Will now try and consume as many as we can in 10 seconds ...");
+
+ // Step 10. Consume as many messages as we can in 10 seconds
+
+ final long duration = 10000;
+
+ int i = 0;
+
+ long start = System.currentTimeMillis();
+
+ while (System.currentTimeMillis() - start <= duration) {
+ TextMessage message = (TextMessage) consumer.receive(2000);
+
+ if (message == null) {
+ throw new RuntimeException("Message was null");
+ }
+
+ i++;
+ }
+
+ long end = System.currentTimeMillis();
+
+ double rate = 1000 * (double) i / (end - start);
+
+ System.out.println("We consumed " + i + " messages in " + (end - start) + " milliseconds");
+
+ System.out.println("Actual consume rate was " + rate + " messages per second");
+ }
+ finally {
+ // Step 9. Be sure to close our resources!
+ if (initialContext != null) {
+ initialContext.close();
+ }
+
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/consumer-rate-limit/src/main/resources/jndi.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/consumer-rate-limit/src/main/resources/jndi.properties b/examples/features/standard/consumer-rate-limit/src/main/resources/jndi.properties
new file mode 100644
index 0000000..74729fe
--- /dev/null
+++ b/examples/features/standard/consumer-rate-limit/src/main/resources/jndi.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616?consumerMaxRate=10
+queue.queue/exampleQueue=exampleQueue
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/pom.xml b/examples/features/standard/dead-letter/pom.xml
new file mode 100644
index 0000000..9c5c5a0
--- /dev/null
+++ b/examples/features/standard/dead-letter/pom.xml
@@ -0,0 +1,110 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>jms-examples</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>dead-letter</artifactId>
+ <packaging>jar</packaging>
+ <name>ActiveMQ Artemis JMS Dead Letter Example</name>
+
+ <properties>
+ <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-jms-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/activemq/server0</configuration>
+ <ignore>${noServer}</ignore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>start</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <spawn>true</spawn>
+ <testURI>tcp://localhost:61616</testURI>
+ <args>
+ <param>run</param>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <id>runClient</id>
+ <goals>
+ <goal>runClient</goal>
+ </goals>
+ <configuration>
+ <clientClass>org.apache.activemq.artemis.jms.example.DeadLetterExample</clientClass>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <args>
+ <param>stop</param>
+ </args>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>dead-letter</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/readme.html
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/readme.html b/examples/features/standard/dead-letter/readme.html
new file mode 100644
index 0000000..e293936
--- /dev/null
+++ b/examples/features/standard/dead-letter/readme.html
@@ -0,0 +1,66 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <head>
+ <title>ActiveMQ Artemis Dead Letter Example</title>
+ <link rel="stylesheet" type="text/css" href="../../../common/common.css" />
+ <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" />
+ <script type="text/javascript" src="../../../common/prettify.js"></script>
+ </head>
+ <body onload="prettyPrint()">
+ <h1>Dead Letter Example</h1>
+ <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre>
+
+ <p>This example shows you how to define and deal with dead letter messages.</p>
+ <p>Messages can be delivered unsuccessfully (e.g. if the transacted session used to consume them is rolled back).
+ Such a message goes back to the JMS destination ready to be redelivered.
+ However, this means it is possible for a message to be delivered again and again without any success and remain in the destination, clogging the system.</p>
+ <p>To prevent this, messaging systems define dead letter messages: after a specified unsuccessful delivery attempts, the message is removed from the destination
+ and instead routed to a <em>dead letter address</em> where they can be consumed for further investigation.
+ <p>
+ The example will show how to configure ActiveMQ Artemis to route a message to a dead letter address after 3 unsuccessful delivery attempts.<br />
+ The example will send 1 message to a queue. We will deliver the message 3 times and rollback the session every time.<br />
+ On the 4th attempt, there won't be any message to consume: it will have been moved to a <em>dead letter address</em>.<br />
+ We will then consume this dead letter message.
+ </p>
+ <h2>Example setup</h2>
+ <p><em>Dead letter addresses</em> and <em>maximum delivery attempts</em> are defined in the configuration file <a href="src/main/resources/activemq/server0/broker.xml">broker.xml</a>:</p>
+ <pre class="prettyprint">
+ <code><address-setting match="jms.queue.exampleQueue">
+ <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
+ <max-delivery-attempts>3</max-delivery-attempts>
+ </address-setting>
+ </code>
+ </pre>
+ <p>This configuration will moved dead letter messages from <code>exampleQueue</code> to the <code>deadLetterQueue</code>.</p>
+ <p>ActiveMQ Artemis allows to specify either a <code>Queue</code> by prefixing the <code>dead-letter-address</code> with <code>jms.queue.</code>
+ or a <code>Topic</code> by prefixing with <code>jms.topic.</code>.<br />
+ In this example, we will use a <code>Queue</code> to hold the dead letter messages.</p>
+ <p>The maximum attempts of delivery is <code>3</code>. Once this figure is reached, a message is considered a dead letter message and is moved to
+ the <code>deadLetterQueue</code>.
+ <p>Since we want to consume messages from this deadLetterQueue, we also need to add a JNDI binding to perform a lookup.
+ This is configured in <a href="src/main/resources/activemq/server0/activemq-jms.xml">activemq-jms.xml</a></p>
+ <pre class="prettyprint">
+ <code><queue name="deadLetterQueue">
+ <entry name="/queue/deadLetterQueue"/>
+ </queue></code>
+ </pre>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/src/main/java/org/apache/activemq/artemis/jms/example/DeadLetterExample.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/src/main/java/org/apache/activemq/artemis/jms/example/DeadLetterExample.java b/examples/features/standard/dead-letter/src/main/java/org/apache/activemq/artemis/jms/example/DeadLetterExample.java
new file mode 100644
index 0000000..db28568
--- /dev/null
+++ b/examples/features/standard/dead-letter/src/main/java/org/apache/activemq/artemis/jms/example/DeadLetterExample.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+
+/**
+ * An example showing how messages are moved to dead letter destination when they are unsuccessfully delivered multiple times
+ */
+public class DeadLetterExample {
+
+ public static void main(final String[] args) throws Exception {
+ Connection connection = null;
+ InitialContext initialContext = null;
+
+ try {
+ // Step 1. Create an initial context to perform the JNDI lookup.
+ initialContext = new InitialContext();
+
+ // Step 2. Perfom a lookup on the queue
+ Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
+
+ // Step 3. Perform a lookup on the Connection Factory
+ ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+ // Step 4.Create a JMS Connection
+ connection = cf.createConnection();
+
+ // Step 5. Create a * transacted* JMS Session
+ Session session = connection.createSession(true, 0);
+
+ // Step 6. Create a JMS Message Producer
+ MessageProducer producer = session.createProducer(queue);
+
+ // Step 7. Create a Text Message
+ TextMessage message = session.createTextMessage("this is a text message");
+
+ // Step 8. Send the Message
+ producer.send(message);
+ System.out.println("Sent message to " + queue.getQueueName() + ": " + message.getText());
+
+ // Step 9. Commit the session to effectively send the message
+ session.commit();
+
+ // Step 10. Create a JMS Message Consumer for the queue
+ MessageConsumer messageConsumer = session.createConsumer(queue);
+
+ // Step 11. Start the Connection
+ connection.start();
+
+ // Step 12. We receive a message...
+ TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
+ System.out.println("1st delivery from " + queue.getQueueName() + ": " + messageReceived.getText());
+
+ // Step 13. ... but we roll back the session. the message returns to the queue ready to be redelivered
+ session.rollback();
+
+ // Step 14. We receive a message and roll back the session a second time
+ messageReceived = (TextMessage) messageConsumer.receive(5000);
+ System.out.println("2nd delivery from " + queue.getQueueName() + ": " + messageReceived.getText());
+ session.rollback();
+
+ // Step 15. We receive a message and roll back the session a third time
+ messageReceived = (TextMessage) messageConsumer.receive(5000);
+ System.out.println("3rd delivery from " + queue.getQueueName() + ": " + messageReceived.getText());
+ session.rollback();
+
+ // The message has been delivered unsuccessfully 3 times -> it is moved to the dead letter queue.
+
+ // Step 16. The 4th time, call will timeout after 5000ms and messageReceived will be null
+ messageReceived = (TextMessage) messageConsumer.receive(5000);
+ System.out.println("4th delivery from " + queue.getQueueName() + ": " + messageReceived);
+
+ // We will now consume the message from the dead letter queue
+
+ // Step 17. Perform a lookup on the dead letter queue
+ Queue deadLetterQueue = (Queue) initialContext.lookup("queue/deadLetterQueue");
+
+ // Step 18. Create a JMS Message Consumer for the dead letter queue
+ MessageConsumer deadLetterConsumer = session.createConsumer(deadLetterQueue);
+
+ // Step 19. Receive the message from the dead letter queue
+ messageReceived = (TextMessage) deadLetterConsumer.receive(5000);
+
+ // Step 20. The message sent to the queue was moved to the dead letter queue after 3 unsuccessful deliveries
+ System.out.println("Received message from " + deadLetterQueue.getQueueName() +
+ ": " +
+ messageReceived.getText());
+
+ // The message received from the dead letter queue has the same content than the undelivered message but its
+ // JMS headers
+ // differ (from JMS point of view, it's not the same message).
+ // ActiveMQ Artemis defines additional properties for messages received from the dead letter queue
+
+ System.out.println();
+ // Step 21. the messageReceived's destination is now the dead letter queue.
+ System.out.println("Destination of the message: " + ((Queue) messageReceived.getJMSDestination()).getQueueName());
+
+ // Step 22. the *origin* destination is stored in the _AMQ_ORIG_ADDRESS property
+ System.out.println("*Origin destination* of the message: " + messageReceived.getStringProperty("_AMQ_ORIG_ADDRESS"));
+
+ // Step 23. This time, we commit the session, the delivery from the dead letter queue is successful!
+ session.commit();
+ }
+ finally {
+ // Step 24. Be sure to close our JMS resources!
+ if (initialContext != null) {
+ initialContext.close();
+ }
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-roles.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-roles.properties b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-roles.properties
new file mode 100644
index 0000000..4e2d44c
--- /dev/null
+++ b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-roles.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+guest=guest
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-users.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-users.properties b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-users.properties
new file mode 100644
index 0000000..4e2d44c
--- /dev/null
+++ b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/artemis-users.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+guest=guest
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/src/main/resources/activemq/server0/broker.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..fdf88cc
--- /dev/null
+++ b/examples/features/standard/dead-letter/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,71 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:activemq"
+ xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+
+ <jms xmlns="urn:activemq:jms">
+ <!--the queue used by the example-->
+ <queue name="exampleQueue"/>
+
+ <!-- the dead letter queue where dead messages will be sent-->
+ <queue name="deadLetterQueue"/>
+ </jms>
+
+ <core xmlns="urn:activemq:core">
+
+ <bindings-directory>${data.dir:../data}/bindings</bindings-directory>
+
+ <journal-directory>${data.dir:../data}/journal</journal-directory>
+
+ <large-messages-directory>${data.dir:../data}/largemessages</large-messages-directory>
+
+ <paging-directory>${data.dir:../data}/paging</paging-directory>
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor>
+ </acceptors>
+
+ <!-- Other config -->
+
+ <security-settings>
+ <!--security for example queue-->
+ <security-setting match="jms.#">
+ <permission type="createDurableQueue" roles="guest"/>
+ <permission type="deleteDurableQueue" roles="guest"/>
+ <permission type="createNonDurableQueue" roles="guest"/>
+ <permission type="deleteNonDurableQueue" roles="guest"/>
+ <permission type="consume" roles="guest"/>
+ <permission type="send" roles="guest"/>
+ </security-setting>
+ </security-settings>
+
+ <address-settings>
+ <!--override the max-delivery-attempts and dead letter address for the example queue-->
+ <address-setting match="jms.queue.exampleQueue">
+ <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
+ <max-delivery-attempts>3</max-delivery-attempts>
+ </address-setting>
+ </address-settings>
+
+ </core>
+</configuration>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/dead-letter/src/main/resources/jndi.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/dead-letter/src/main/resources/jndi.properties b/examples/features/standard/dead-letter/src/main/resources/jndi.properties
new file mode 100644
index 0000000..3e1a366
--- /dev/null
+++ b/examples/features/standard/dead-letter/src/main/resources/jndi.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616
+queue.queue/exampleQueue=exampleQueue
+queue.queue/deadLetterQueue=deadLetterQueue
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/pom.xml b/examples/features/standard/delayed-redelivery/pom.xml
new file mode 100644
index 0000000..e82469c
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/pom.xml
@@ -0,0 +1,110 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>jms-examples</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>delayed-redelivery</artifactId>
+ <packaging>jar</packaging>
+ <name>ActiveMQ Artemis JMS Delayed Redelivery Example</name>
+
+ <properties>
+ <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-jms-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/activemq/server0</configuration>
+ <ignore>${noServer}</ignore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>start</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <spawn>true</spawn>
+ <testURI>tcp://localhost:61616</testURI>
+ <args>
+ <param>run</param>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <id>runClient</id>
+ <goals>
+ <goal>runClient</goal>
+ </goals>
+ <configuration>
+ <clientClass>org.apache.activemq.artemis.jms.example.DelayedRedeliveryExample</clientClass>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <args>
+ <param>stop</param>
+ </args>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>delayed-redelivery</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/readme.html
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/readme.html b/examples/features/standard/delayed-redelivery/readme.html
new file mode 100644
index 0000000..e535c47
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/readme.html
@@ -0,0 +1,56 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <head>
+ <title>ActiveMQ Artemis Delayed Redelivery Example</title>
+ <link rel="stylesheet" type="text/css" href="../../../common/common.css" />
+ <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" />
+ <script type="text/javascript" src="../../../common/prettify.js"></script>
+ </head>
+ <body onload="prettyPrint()">
+ <h1>Delayed Redelivery Example</h1>
+ <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre>
+
+ <p>This example demonstrates how ActiveMQ Artemis can be configured to provide a delayed redelivery in the case
+ where a message needs to be redelivered.</p>
+ <p>Delaying redelivery can often be useful in the case that clients regularly fail or roll-back. Without a delayed
+ redelivery, the system can get into a "thrashing" state, with delivery being attempted, the client rolling back, and
+ delivery being re-attempted ad infinitum in quick succession, using up valuable CPU and network resources.</p>
+ <p>Re-delivery occurs when the session is closed with unacknowledged messages. The unacknowledged messages will
+ be redelivered.</p>
+ <p>By providing a redelivery delay, it can be specified that a delay of, say, 10 seconds is implemented between rollback
+ and redelivery. The specific delay is configurable on both a global and per destination level, by using wild-card
+ matching on the address settings.</p>
+
+ <h2>Example setup</h2>
+ <p>Redelivery delay is specified in the configuration file <a href="src/main/resources/activemq/server0/broker.xml">broker.xml</a>:</p>
+ <p>In this example we set the redelivery delay to 5 seconds for the specific example queue. We could set redelivery delay on
+ on multiple queues by specifying a wild-card in the match, e.g. <code>match="jms.#"</code> would apply the settings
+ to all JMS queues and topics.</p>
+ <p>We then consume a message in a transacted session, and rollback, and note that the message is not redelivered until
+ after 5 seconds.</p>
+ <pre class="prettyprint">
+ <code><address-setting match="jms.queue.exampleQueue">
+ <redelivery-delay>5000</redelivery-delay>
+ </address-setting>
+ </code>
+ </pre>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/src/main/java/org/apache/activemq/artemis/jms/example/DelayedRedeliveryExample.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/src/main/java/org/apache/activemq/artemis/jms/example/DelayedRedeliveryExample.java b/examples/features/standard/delayed-redelivery/src/main/java/org/apache/activemq/artemis/jms/example/DelayedRedeliveryExample.java
new file mode 100644
index 0000000..afa538f
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/src/main/java/org/apache/activemq/artemis/jms/example/DelayedRedeliveryExample.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+
+/**
+ * This example demonstrates how ActiveMQ Artemis can be configured with a redelivery delay in the event a message
+ * is redelivered.
+ *
+ * Please see the readme.html for more information
+ */
+public class DelayedRedeliveryExample {
+
+ public static void main(final String[] args) throws Exception {
+ Connection connection = null;
+ InitialContext initialContext = null;
+
+ try {
+ // Step 1. Create an initial context to perform the JNDI lookup.
+ initialContext = new InitialContext();
+
+ // Step 2. Perform a lookup on the queue
+ Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
+
+ // Step 3. Perform a lookup on the Connection Factory
+ ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+ // Step 4. Create a JMS Connection
+ connection = cf.createConnection();
+
+ // Step 5. Create a transacted JMS Session
+ Session session = connection.createSession(true, 0);
+
+ // Step 6. Create a JMS Message Producer
+ MessageProducer producer = session.createProducer(queue);
+
+ // Step 7. Create a Text Message
+ TextMessage message = session.createTextMessage("this is a text message");
+
+ // Step 8. Send the Message
+ producer.send(message);
+
+ System.out.println("Sent message to " + queue.getQueueName() + ": " + message.getText());
+
+ // Step 9. Commit the session to effectively send the message
+ session.commit();
+
+ // Step 10. Create a JMS Message Consumer for the queue
+ MessageConsumer messageConsumer = session.createConsumer(queue);
+
+ // Step 11. Start the Connection
+ connection.start();
+
+ // Step 12. We receive a message...
+ TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
+ System.out.println("1st delivery from " + queue.getQueueName() + ": " + messageReceived.getText());
+
+ // Step 13. ... but we roll back the session. the message returns to the queue, but only after a
+ // 5 second delay
+ session.rollback();
+
+ // Step 14. We try to receive the message but it's being delayed
+ messageReceived = (TextMessage) messageConsumer.receive(3000);
+
+ if (messageReceived != null) {
+ throw new IllegalStateException("Expected to recieve message.");
+ }
+
+ System.out.println("Redelivery has been delayed so received message is " + messageReceived);
+
+ // Step 15. We try and receive the message again, this time we should get it
+
+ messageReceived = (TextMessage) messageConsumer.receive(3000);
+
+ System.out.println("2nd delivery from " + queue.getQueueName() + ": " + messageReceived.getText());
+
+ // Step 16. We rollback the session again to cause another redelivery, and we time how long this one takes
+
+ long start = System.currentTimeMillis();
+
+ session.rollback();
+
+ messageReceived = (TextMessage) messageConsumer.receive(8000);
+
+ long end = System.currentTimeMillis();
+
+ System.out.println("3nd delivery from " + queue.getQueueName() +
+ ": " +
+ messageReceived.getText() +
+ " after " +
+ (end - start) +
+ " milliseconds.");
+ }
+ finally {
+ // Step 17. Be sure to close our JMS resources!
+ if (initialContext != null) {
+ initialContext.close();
+ }
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-roles.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-roles.properties b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-roles.properties
new file mode 100644
index 0000000..4e2d44c
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-roles.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+guest=guest
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-users.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-users.properties b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-users.properties
new file mode 100644
index 0000000..4e2d44c
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/artemis-users.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+guest=guest
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/broker.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..3e41664
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,70 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:activemq"
+ xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+
+ <jms xmlns="urn:activemq:jms">
+ <!--the queue used by the example-->
+ <queue name="exampleQueue"/>
+
+ <!-- the dead letter queue where dead messages will be sent-->
+ <queue name="deadLetterQueue"/>
+ </jms>
+
+ <core xmlns="urn:activemq:core">
+
+ <bindings-directory>${data.dir:../data}/bindings</bindings-directory>
+
+ <journal-directory>${data.dir:../data}/journal</journal-directory>
+
+ <large-messages-directory>${data.dir:../data}/largemessages</large-messages-directory>
+
+ <paging-directory>${data.dir:../data}/paging</paging-directory>
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor>
+ </acceptors>
+
+ <!-- Other config -->
+
+ <security-settings>
+ <!--security for example queue-->
+ <security-setting match="jms.#">
+ <permission type="createDurableQueue" roles="guest"/>
+ <permission type="deleteDurableQueue" roles="guest"/>
+ <permission type="createNonDurableQueue" roles="guest"/>
+ <permission type="deleteNonDurableQueue" roles="guest"/>
+ <permission type="consume" roles="guest"/>
+ <permission type="send" roles="guest"/>
+ </security-setting>
+ </security-settings>
+
+ <address-settings>
+ <!--override the redelivery-delay for the example queue-->
+ <address-setting match="jms.queue.exampleQueue">
+ <redelivery-delay>5000</redelivery-delay>
+ </address-setting>
+ </address-settings>
+
+ </core>
+</configuration>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/delayed-redelivery/src/main/resources/jndi.properties
----------------------------------------------------------------------
diff --git a/examples/features/standard/delayed-redelivery/src/main/resources/jndi.properties b/examples/features/standard/delayed-redelivery/src/main/resources/jndi.properties
new file mode 100644
index 0000000..93537c4
--- /dev/null
+++ b/examples/features/standard/delayed-redelivery/src/main/resources/jndi.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616
+queue.queue/exampleQueue=exampleQueue
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/divert/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/divert/pom.xml b/examples/features/standard/divert/pom.xml
new file mode 100644
index 0000000..69a7f98
--- /dev/null
+++ b/examples/features/standard/divert/pom.xml
@@ -0,0 +1,159 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>jms-examples</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>divert</artifactId>
+ <packaging>jar</packaging>
+ <name>ActiveMQ Artemis JMS Divert Example</name>
+
+ <properties>
+ <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-jms-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create0</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <libList><arg>org.apache.activemq.examples.broker:divert:${project.version}</arg></libList>
+ <instance>${basedir}/target/server0</instance>
+ <configuration>${basedir}/target/classes/activemq/server0</configuration>
+ </configuration>
+ </execution>
+ <execution>
+ <id>create1</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <libList><arg>org.apache.activemq.examples.broker:divert:${project.version}</arg></libList>
+ <instance>${basedir}/target/server1</instance>
+ <configuration>${basedir}/target/classes/activemq/server1</configuration>
+ </configuration>
+ </execution>
+ <execution>
+ <id>start0</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <spawn>true</spawn>
+ <testURI>tcp://localhost:61616</testURI>
+ <args>
+ <param>run</param>
+ </args>
+ <name>server0</name>
+ </configuration>
+ </execution>
+ <execution>
+ <id>start1</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <spawn>true</spawn>
+ <location>${basedir}/target/server1</location>
+ <testURI>tcp://localhost:61617</testURI>
+ <args>
+ <param>run</param>
+ </args>
+ <name>server1</name>
+ </configuration>
+ </execution>
+ <execution>
+ <id>runClient</id>
+ <goals>
+ <goal>runClient</goal>
+ </goals>
+ <configuration>
+ <clientClass>org.apache.activemq.artemis.jms.example.DivertExample</clientClass>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop0</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <location>${basedir}/target/server0</location>
+ <args>
+ <param>stop</param>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <id>stop1</id>
+ <goals>
+ <goal>cli</goal>
+ </goals>
+ <configuration>
+ <ignore>${noServer}</ignore>
+ <location>${basedir}/target/server1</location>
+ <args>
+ <param>stop</param>
+ </args>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.activemq.examples.broker</groupId>
+ <artifactId>divert</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/divert/readme.html
----------------------------------------------------------------------
diff --git a/examples/features/standard/divert/readme.html b/examples/features/standard/divert/readme.html
new file mode 100644
index 0000000..63fb710
--- /dev/null
+++ b/examples/features/standard/divert/readme.html
@@ -0,0 +1,119 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <head>
+ <title>ActiveMQ Artemis Divert Example</title>
+ <link rel="stylesheet" type="text/css" href="../../../common/common.css" />
+ <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" />
+ <script type="text/javascript" src="../../../common/prettify.js"></script>
+ </head>
+ <body onload="prettyPrint()">
+ <h1>Divert Example</h1>
+ <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre>
+
+ <p>ActiveMQ Artemis diverts allow messages to be transparently "diverted" from one address to another
+ with just some simple configuration defined on the server side.</p>
+ <p>Diverts can be defined to be <b>exclusive</b> or <b>non-exclusive</b>.</p>
+ <p>With an <b>exclusive</b> divert the message is intercepted and does not get sent to the queues originally
+ bound to that address - it only gets diverted.</p>
+ <p>With a <b>non-exclusive</b> divert the message continues to go to the queues bound to the address,
+ but also a <b>copy</b> of the message gets sent to the address specified in the divert. Consequently non-exclusive
+ diverts can be used to "snoop" on another address</p>
+ <p>Diverts can also be configured to have an optional filter. If specified then only matching messages
+ will be diverted.</p>
+ <p>Diverts can be configured to apply a Transformer. If specified, all diverted messages will have the
+ opportunity of being transformed by the Transformer.</p>
+ <p>Diverts are a very sophisticated concept, which when combined with bridges can be used to create
+ interesting and complex routings. The set of diverts can be thought of as a type of <i>routing table</i>
+ for messages.</p>
+
+ <h2>Example step-by-step</h2>
+ <p>In this example we will imagine a fictitious company which has two offices; one in London and another in New York.</p>
+ <p>The company accepts orders for it's products only at it's London office, and also generates price-updates
+ for it's products, also only from it's London office. However only the New York office is interested in receiving
+ price updates for New York products. Any prices for New York products need to be forwarded to the New York office.</p>
+ <p>There is an unreliable WAN linking the London and New York offices.</p>
+ <p>The company also requires a copy of any order received to be available to be inspected by management.</p>
+ <p>In order to achieve this, we will create a queue <code>orderQueue</code> on the London server in to which orders arrive.</p>
+ <p>We will create a topic, <code>spyTopic</code> on the London server, and there will be two subscribers both in London.</p>
+ <p>We will create a <i>non-exclusive</i> divert on the London server which will siphon off a copy of each order
+ received to the topic <code>spyTopic</code>.</p>
+ <p>Here's the xml config for that divert, from <code>broker.xml</code></p>
+ <pre class="prettyprint">
+ <code>
+ <divert name="order-divert">
+ <address>jms.queue.orders</address>
+ <forwarding-address>jms.topic.spyTopic</forwarding-address>
+ <exclusive>false</exclusive>
+ </divert>
+ </code>
+ </pre>
+ <p>For the prices we will create a topic on the London server, <code>priceUpdates</code> to which all price updates
+ are sent. We will create another topic on the New York server <code>newYorkPriceUpdates</code> to which all New York
+ price updates need to be forwarded.</p>
+ <p>Diverts can only be used to divert messages from one <b>local</b> address to another <b>local</b> address
+ so we cannot divert directly to an address on another server.</p>
+ <p>Instead we divert to a local <i>store and forward queue</i> they we define in the configuration. This is just a normal queue
+ that we use for storing messages before forwarding to another node.</p>
+ <p>Here's the configuration for it:</p>
+ <pre class="prettyprint">
+ <code>
+ <queues>
+ <queue name="jms.queue.priceForwarding">
+ <address>jms.queue.priceForwarding</address>
+ </queue>
+ </queues>
+ </code>
+ </pre>
+ <p>Here's the configuration for the divert:</p>
+ <pre class="prettyprint">
+ <code>
+ <divert name="prices-divert">
+ <address>jms.topic.priceUpdates</address>
+ <forwarding-address>jms.queue.priceForwarding</forwarding-address>
+ <filter string="office='New York'"/>
+ <transformer-class-name>org.apache.activemq.artemis.jms.example.AddForwardingTimeTransformer</transformer-class-name>
+ <exclusive>true</exclusive>
+ </divert>
+ </code>
+ </pre>
+ <p>Note we specify a filter in the divert, so only New York prices get diverted. We also specify a Transformer class
+ since we are going to insert a header in the message at divert time, recording the time the diversion happened.</p>
+ <p>And finally we define a bridge that moves messages from the local queue to the address on the New York server.
+ Bridges move messages from queues to remote addresses and are ideal to use when the target server may be stopped and
+ started independently, and/or the network might be unreliable. Bridges guarantee once and only once delivery
+ of messages from their source queues to their target addresses.</p>
+ <p>Here is the bridge configuration: </p>
+ <pre class="prettyprint">
+ <code>
+ <bridges>
+ <bridge name="price-forward-bridge">
+ <queue-name>jms.queue.priceForwarding</queue-name>
+ <forwarding-address>jms.topic.newYorkPriceUpdates</forwarding-address>
+ <reconnect-attempts>-1</reconnect-attempts>
+ <static-connectors>
+ <connector-ref>newyork-connector</connector-ref>
+ </static-connectors>
+ </bridge>
+ </bridges>
+ </code>
+ </pre>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/divert/src/main/java/org/apache/activemq/artemis/jms/example/AddForwardingTimeTransformer.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/divert/src/main/java/org/apache/activemq/artemis/jms/example/AddForwardingTimeTransformer.java b/examples/features/standard/divert/src/main/java/org/apache/activemq/artemis/jms/example/AddForwardingTimeTransformer.java
new file mode 100644
index 0000000..15d8e65
--- /dev/null
+++ b/examples/features/standard/divert/src/main/java/org/apache/activemq/artemis/jms/example/AddForwardingTimeTransformer.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.cluster.Transformer;
+
+public class AddForwardingTimeTransformer implements Transformer {
+
+ public ServerMessage transform(final ServerMessage message) {
+ message.putLongProperty(new SimpleString("time_of_forward"), System.currentTimeMillis());
+
+ return message;
+ }
+
+}