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; + } + +}