Return-Path: X-Original-To: apmail-activemq-commits-archive@www.apache.org Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BFB5A184A5 for ; Thu, 13 Aug 2015 04:13:22 +0000 (UTC) Received: (qmail 10521 invoked by uid 500); 13 Aug 2015 04:13:22 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 10402 invoked by uid 500); 13 Aug 2015 04:13:22 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 8704 invoked by uid 99); 13 Aug 2015 04:13:20 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Aug 2015 04:13:20 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 60D2DE363C; Thu, 13 Aug 2015 04:13:20 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: clebertsuconic@apache.org To: commits@activemq.apache.org Date: Thu, 13 Aug 2015 04:13:36 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [18/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/ha/replicated-failback/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-failback/src/main/resources/activemq/server1/broker.xml b/examples/features/ha/replicated-failback/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..da5a656 --- /dev/null +++ b/examples/features/ha/replicated-failback/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + exampleUser + + secret + + + + + true + + + + + + + tcp://localhost:61616 + tcp://localhost:61617 + + + + + tcp://localhost:61617 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 5000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-failback/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-failback/src/main/resources/jndi.properties b/examples/features/ha/replicated-failback/src/main/resources/jndi.properties new file mode 100644 index 0000000..7f7a19f --- /dev/null +++ b/examples/features/ha/replicated-failback/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?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=-1 +queue.queue/exampleQueue=exampleQueue http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/pom.xml b/examples/features/ha/replicated-multiple-failover/pom.xml new file mode 100644 index 0000000..23dcfd7 --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/pom.xml @@ -0,0 +1,118 @@ + + + + + 4.0.0 + + + org.apache.activemq.examples.failover + broker-failover + 1.0.1-SNAPSHOT + + + replicated-multiple-failover + jar + ActiveMQ Artemis JMS Replicated Multiple Failover Example + + + ${project.basedir}/../../../.. + + + + + org.apache.activemq + artemis-cli + ${project.version} + + + org.apache.activemq + artemis-jms-client + ${project.version} + + + + + + + org.apache.activemq + artemis-maven-plugin + + + create0 + + create + + + ${basedir}/target/server0 + ${basedir}/target/classes/activemq/server0 + -Dudp-address=${udp-address} + + + + create1 + + create + + + ${basedir}/target/server1 + ${basedir}/target/classes/activemq/server1 + -Dudp-address=${udp-address} + + + + create2 + + create + + + ${basedir}/target/server2 + ${basedir}/target/classes/activemq/server2 + -Dudp-address=${udp-address} + + + + runClient + + runClient + + + org.apache.activemq.artemis.jms.example.ReplicatedMultipleFailoverExample + + + ${basedir}/target/server0 + ${basedir}/target/server1 + ${basedir}/target/server2 + + + + + + + org.apache.activemq.examples.failover + replicated-multiple-failover + ${project.version} + + + + + + + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/readme.html b/examples/features/ha/replicated-multiple-failover/readme.html new file mode 100644 index 0000000..da37085 --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/readme.html @@ -0,0 +1,45 @@ + + + + + ActiveMQ Artemis JMS Multiple Failover using Replication Example + + + + + +

JMS Multiple Failover using Replication Example

+ +
To run the example, simply type mvn verify from this directory.
+ + +

This example demonstrates three servers coupled as a live-backup-backup group for high availability (HA) using replication, and a client + connection failing over from live to backup when the live server is crashed and then to the second backup once the new live fails.

+ +

For more information on ActiveMQ Artemis failover and HA, and clustering in general, please see the clustering + section of the user manual.

+ +

Example step-by-step

+

To run the example, simply type mvn verify -Pexample from this directory

+

In this example, the live server is server 1, and the backup server is server 0

+

The connection will initially be created to server1, server 1 will crash, and the client will carry on + seamlessly on server 0, the backup server.

+ + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedMultipleFailoverExample.java ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedMultipleFailoverExample.java b/examples/features/ha/replicated-multiple-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedMultipleFailoverExample.java new file mode 100644 index 0000000..491d792 --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedMultipleFailoverExample.java @@ -0,0 +1,149 @@ +/* + * 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.util.ServerUtil; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +public class ReplicatedMultipleFailoverExample { + + private static Process server0; + + private static Process server1; + + private static Process server2; + + public static void main(final String[] args) throws Exception { + final int numMessages = 30; + + Connection connection = null; + + InitialContext initialContext = null; + + try { + server0 = ServerUtil.startServer(args[0], ReplicatedMultipleFailoverExample.class.getSimpleName() + "0", 0, 5000); + server1 = ServerUtil.startServer(args[1], ReplicatedMultipleFailoverExample.class.getSimpleName() + "1", 1, 5000); + server2 = ServerUtil.startServer(args[2], ReplicatedMultipleFailoverExample.class.getSimpleName() + "2", 2, 5000); + + Process[] processes = new Process[]{server0, server1, server2}; + + // Step 1. Get an initial context for looking up JNDI from the server #1 + initialContext = new InitialContext(); + + // Step 2. Look up the JMS resources from JNDI + Queue queue = (Queue) initialContext.lookup("queue/exampleQueue"); + ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + + // Step 3. Create a JMS Connection + connection = connectionFactory.createConnection(); + + // Step 4. Create a *non-transacted* JMS Session with client acknowledgement + Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); + + // Step 5. Start the connection to ensure delivery occurs + connection.start(); + + // Step 6. Create a JMS MessageProducer and a MessageConsumer + MessageProducer producer = session.createProducer(queue); + MessageConsumer consumer = session.createConsumer(queue); + + // Step 7. Send some messages to server #1, the live server + for (int i = 0; i < numMessages; i++) { + TextMessage message = session.createTextMessage("This is text message " + i); + producer.send(message); + System.out.println("Sent message: " + message.getText()); + } + + // Step 8. Receive and acknowledge a third of the sent messages + TextMessage message0 = null; + for (int i = 0; i < numMessages / 3; i++) { + message0 = (TextMessage) consumer.receive(5000); + System.out.println("Got message: " + message0.getText()); + } + message0.acknowledge(); + + // Step 9. Receive the rest third of the sent messages but *do not* acknowledge them yet + for (int i = numMessages / 3; i < numMessages; i++) { + message0 = (TextMessage) consumer.receive(5000); + System.out.println("Got message: " + message0.getText()); + } + + // Step 10. Crash server #0, the live server, and wait a little while to make sure + // it has really crashed + ServerUtil.killServer(server0); + Thread.sleep(5000); + + // Step 11. Acknowledging the 2nd half of the sent messages will fail as failover to the + // backup server has occurred + try { + message0.acknowledge(); + } + catch (JMSException e) { + System.err.println("Got exception while acknowledging message: " + e.getMessage()); + } + + // Step 12. Consume again the 2nd third of the messages again. Note that they are not considered as redelivered. + for (int i = numMessages / 3; i < (numMessages / 3) * 2; i++) { + message0 = (TextMessage) consumer.receive(5000); + System.out.printf("Got message: %s (redelivered?: %s)%n", message0.getText(), message0.getJMSRedelivered()); + } + message0.acknowledge(); + + ServerUtil.killServer(processes[ServerUtil.getServer(connection)]); + + // Step 11. Acknowledging the 2nd half of the sent messages will fail as failover to the + // backup server has occurred + try { + message0.acknowledge(); + } + catch (JMSException e) { + System.err.println("Got exception while acknowledging message: " + e.getMessage()); + } + + // Step 12. Consume again the 2nd third of the messages again. Note that they are not considered as redelivered. + for (int i = (numMessages / 3) * 2; i < numMessages; i++) { + message0 = (TextMessage) consumer.receive(5000); + System.out.printf("Got message: %s (redelivered?: %s)%n", message0.getText(), message0.getJMSRedelivered()); + } + message0.acknowledge(); + } + finally { + // Step 13. Be sure to close our resources! + + if (connection != null) { + connection.close(); + } + + if (initialContext != null) { + initialContext.close(); + } + + ServerUtil.killServer(server0); + ServerUtil.killServer(server1); + ServerUtil.killServer(server2); + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server0/broker.xml b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..43f1693 --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + + + + + + + tcp://localhost:61616 + + + + + tcp://localhost:61616 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 60000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server1/broker.xml b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..7f17fb8 --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + + + + + + + tcp://localhost:61617 + + + + + tcp://localhost:61617 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 60000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server2/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server2/broker.xml b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server2/broker.xml new file mode 100644 index 0000000..c5f06cc --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/src/main/resources/activemq/server2/broker.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + + + + + + + tcp://localhost:61618 + + + + + tcp://localhost:61618 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 60000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-multiple-failover/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-multiple-failover/src/main/resources/jndi.properties b/examples/features/ha/replicated-multiple-failover/src/main/resources/jndi.properties new file mode 100644 index 0000000..7f7a19f --- /dev/null +++ b/examples/features/ha/replicated-multiple-failover/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?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=-1 +queue.queue/exampleQueue=exampleQueue http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/pom.xml b/examples/features/ha/replicated-transaction-failover/pom.xml new file mode 100644 index 0000000..4c1839e --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/pom.xml @@ -0,0 +1,104 @@ + + + + + 4.0.0 + + + org.apache.activemq.examples.failover + broker-failover + 1.0.1-SNAPSHOT + + + replicated-transaction-failover + jar + ActiveMQ Artemis JMS Replicated Transaction Failover Example + + + ${project.basedir}/../../../.. + + + + + org.apache.activemq + artemis-cli + ${project.version} + + + org.apache.activemq + artemis-jms-client + ${project.version} + + + + + + org.apache.activemq + artemis-maven-plugin + + + create0 + + create + + + ${basedir}/target/server0 + ${basedir}/target/classes/activemq/server0 + -Dudp-address=${udp-address} + + + + create1 + + create + + + ${basedir}/target/server1 + ${basedir}/target/classes/activemq/server1 + -Dudp-address=${udp-address} + + + + runClient + + runClient + + + org.apache.activemq.artemis.jms.example.ReplicatedTransactionFailoverExample + + + ${basedir}/target/server0 + ${basedir}/target/server1 + + + + + + + org.apache.activemq.examples.failover + replicated-transaction-failover + ${project.version} + + + + + + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/readme.html b/examples/features/ha/replicated-transaction-failover/readme.html new file mode 100644 index 0000000..4206588 --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/readme.html @@ -0,0 +1,148 @@ + + + + + ActiveMQ Artemis JMS Failover With Transaction using Replication Example + + + + + +

JMS Failover With Transaction using Replication Example

+ +

This example demonstrates two servers coupled as a live-backup pair for high availability (HA) using replication, and a client + connection failing over from live to backup when the live server is crashed.

+

Failover behavior differs whether the JMS session is transacter or not.

+

When a transacted JMS session is used, once-and-only once delivery is guaranteed.

+
    +
  • if the failover occurs while there is an in-flight transaction, the transaction will be flagged as rollback only. In that case, the JMS client + will need to retry the transaction work.
  • +
  • if the failover occurs while there is no in-flight transaction, the failover will be transparent to the user.
  • +
+

ActiveMQ Artemis also provides an example for non-transaction failover.

+

For more information on ActiveMQ Artemis failover and HA, and clustering in general, please see the clustering + section of the user manual.

+ +

Example step-by-step

+

To run the example, simply type mvn verify -Pexample from this directory

+

In this example, the live server is server 1, and the backup server is server 0

+

The connection will initially be created to server1, server 1 will crash, and the client will carry on + seamlessly on server 0, the backup server.

+ +
    +
  1. Get an initial context for looking up JNDI from server #1.
  2. +
    +           initialContext = getContext(1);
    +        
    + +
  3. Look up the JMS resources from JNDI on server #1.
  4. +
    +           Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
    +           ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
    +        
    + +
  5. Create a JMS Connection
  6. +
    +           connection = connectionFactory.createConnection();
    +        
    + +
  7. Create a JMS transacted Session
  8. +
    +           Session session = connection.createSession(true, 0);
    +        
    + +
  9. Start the connection to ensure delivery occurs
  10. +
    +           connection.start();
    +        
    + +
  11. Create a JMS MessageProducer
  12. +
    +           MessageProducer producer = session.createProducer(queue);
    +        
    + +
  13. Create a JMS MessageConsumer
  14. +
    +           MessageConsumer consumer = session.createConsumer(queue);
    +        
    + +
  15. Send half of the messages, kill the live server and send the remaining messages
  16. +
    +           sendMessages(session, producer, numMessages, true);
    +        
    + +

    When server #1 crashes, the client automatically detects the failure and automatically + fails over from server #1 to server #0 (in your real program you wouldn't need to sleep). +

    + +
  17. As failover occurred during transaction, the session has been marked for rollback only and commit will fail
  18. +
    +           try
    +           {
    +              session.commit();
    +           } catch (TransactionRolledBackException e)
    +           {
    +              System.err.println("transaction has been rolled back: " + e.getMessage());
    +           }
    +        
    + +
  19. We resend all the messages
  20. +
    +           sendMessages(session, producer, numMessages, false);
    +        
    + +
  21. We commit the session successfully: the messages will be all delivered to the activated backup server
  22. +
    +           session.commit();
    +        
    + + +
  23. We are now transparently reconnected to server #0, the backup server. + We consume the messages sent before the crash of the live server, commit the session, and check there are no other message on the queue
  24. +
    +        for (int i = 0; i < numMessages; i++)
    +        {
    +           TextMessage message0 = (TextMessage)consumer.receive(5000);
    +           System.out.println("Got message: " + message0.getText());
    +        }
    +        session.commit();
    +        System.out.println("Other message on the server? " + consumer.receive(5000));
    +        
    + +
  25. And finally, always remember to close your resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  26. + +
    +           finally
    +           {
    +              if (connection != null)
    +              {
    +                 connection.close();
    +              }
    +
    +              if (initialContext != null)
    +              {
    +                 initialContext.close();
    +              }
    +           }
    +        
    + +
+ + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedTransactionFailoverExample.java ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedTransactionFailoverExample.java b/examples/features/ha/replicated-transaction-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedTransactionFailoverExample.java new file mode 100644 index 0000000..e6887c7 --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/src/main/java/org/apache/activemq/artemis/jms/example/ReplicatedTransactionFailoverExample.java @@ -0,0 +1,168 @@ +/* + * 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.Message; +import org.apache.activemq.artemis.util.ServerUtil; + +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.jms.TransactionRolledBackException; +import javax.naming.InitialContext; + +/** + * A simple example that demonstrates failover of the JMS connection from one node to another + * when the live server crashes using a JMS transacted session and replication. + */ +public class ReplicatedTransactionFailoverExample { + + private static Process server0; + + private static Process server1; + + // You need to guarantee uniqueIDs when using duplicate detection + // It needs to be unique even after a restart + // as these IDs are stored on the journal for control + // We recommend some sort of UUID, but for this example the Current Time as string would be enough + private static String uniqueID = Long.toString(System.currentTimeMillis()); + + public static void main(final String[] args) throws Exception { + final int numMessages = 10; + + Connection connection = null; + + InitialContext initialContext = null; + + try { + server0 = ServerUtil.startServer(args[0], ReplicatedTransactionFailoverExample.class.getSimpleName() + "0", 0, 5000); + server1 = ServerUtil.startServer(args[1], ReplicatedTransactionFailoverExample.class.getSimpleName() + "1", 1, 5000); + + // Step 1. Get an initial context for looking up JNDI from the server #1 + initialContext = new InitialContext(); + + // Step 2. Look-up the JMS resources from JNDI + Queue queue = (Queue) initialContext.lookup("queue/exampleQueue"); + ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + + // Step 3. We create a JMS Connection + connection = connectionFactory.createConnection(); + + // Step 4. We create a *transacted* JMS Session + Session session = connection.createSession(true, 0); + + // Step 5. We start the connection to ensure delivery occurs + connection.start(); + + // Step 6. We create a JMS MessageProducer + MessageProducer producer = session.createProducer(queue); + + // Step 7. We create a JMS MessageConsumer + MessageConsumer consumer = session.createConsumer(queue); + + // Step 8. We send half of the messages, kill the live server and send the remaining messages + sendMessages(session, producer, numMessages, true); + + // Step 9. As failover occurred during transaction, the session has been marked for rollback only + try { + session.commit(); + } + catch (TransactionRolledBackException e) { + System.err.println("transaction has been rolled back: " + e.getMessage()); + } + + // Step 10. We resend all the messages + sendMessages(session, producer, numMessages, false); + + // Step 11. We commit the session successfully: the messages will be all delivered to the activated backup + // server + session.commit(); + + // Step 12. We are now transparently reconnected to server #0, the backup server. + // We consume the messages sent before the crash of the live server and commit the session. + for (int i = 0; i < numMessages; i++) { + TextMessage message0 = (TextMessage) consumer.receive(5000); + + if (message0 == null) { + throw new IllegalStateException("Example failed - message wasn't received"); + } + + System.out.println("Got message: " + message0.getText()); + } + + session.commit(); + + System.out.println("Other message on the server? " + consumer.receive(5000)); + } + finally { + // Step 13. Be sure to close our resources! + + if (connection != null) { + connection.close(); + } + + if (initialContext != null) { + initialContext.close(); + } + + ServerUtil.killServer(server0); + ServerUtil.killServer(server1); + } + } + + private static void sendMessages(final Session session, + final MessageProducer producer, + final int numMessages, + final boolean killServer) throws Exception { + // We send half of messages + for (int i = 0; i < numMessages / 2; i++) { + TextMessage message = session.createTextMessage("This is text message " + i); + + // We set the duplicate detection header - so the server will ignore the same message + // if sent again after failover + + message.setStringProperty(Message.HDR_DUPLICATE_DETECTION_ID.toString(), uniqueID + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + + if (killServer) { + ServerUtil.killServer(server0); + } + + // We send the remaining half of messages + for (int i = numMessages / 2; i < numMessages; i++) { + TextMessage message = session.createTextMessage("This is text message " + i); + + // We set the duplicate detection header - so the server will ignore the same message + // if sent again after failover + + message.setStringProperty(Message.HDR_DUPLICATE_DETECTION_ID.toString(), uniqueID + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + } + +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server0/broker.xml b/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..f8b076a --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + + + + + + + + tcp://localhost:61616 + + + + + tcp://localhost:61616 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 60000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server1/broker.xml b/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..f64af4e --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + + + + + + + + tcp://localhost:61617 + + + + + tcp://localhost:61617 + + + + + ${udp-address:231.7.7.7} + 9876 + 1000 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 60000 + + + + + +
jms
+ netty-connector + +
+
+ + + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/replicated-transaction-failover/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/ha/replicated-transaction-failover/src/main/resources/jndi.properties b/examples/features/ha/replicated-transaction-failover/src/main/resources/jndi.properties new file mode 100644 index 0000000..7f7a19f --- /dev/null +++ b/examples/features/ha/replicated-transaction-failover/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?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=-1 +queue.queue/exampleQueue=exampleQueue http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/scale-down/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/scale-down/pom.xml b/examples/features/ha/scale-down/pom.xml new file mode 100644 index 0000000..e722413 --- /dev/null +++ b/examples/features/ha/scale-down/pom.xml @@ -0,0 +1,105 @@ + + + + + 4.0.0 + + + org.apache.activemq.examples.failover + broker-failover + 1.0.1-SNAPSHOT + + + scale-down + jar + ActiveMQ Artemis JMS Scale Down Example + + + ${project.basedir}/../../../.. + + + + + org.apache.activemq + artemis-cli + ${project.version} + + + org.apache.activemq + artemis-jms-client + ${project.version} + + + + + + + org.apache.activemq + artemis-maven-plugin + + + create0 + + create + + + ${basedir}/target/server0 + ${basedir}/target/classes/activemq/server0 + -Dudp-address=${udp-address} + + + + create1 + + create + + + ${basedir}/target/server1 + ${basedir}/target/classes/activemq/server1 + -Dudp-address=${udp-address} + + + + runClient + + runClient + + + org.apache.activemq.artemis.jms.example.ScaleDownExample + + ${basedir}/target/server0 + ${basedir}/target/server1 + + + + + + + org.apache.activemq.examples.failover + scale-down + ${project.version} + + + + + + + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/scale-down/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/ha/scale-down/readme.html b/examples/features/ha/scale-down/readme.html new file mode 100644 index 0000000..4786db3 --- /dev/null +++ b/examples/features/ha/scale-down/readme.html @@ -0,0 +1,51 @@ + + + + + ActiveMQ Artemis JMS Scale Down Example + + + + + +

JMS Colocated Failover Shared Store Example

+ +
To run the example, simply type mvn verify from this directory.
+ + +

This example demonstrates how you can configure a live server to scale down messages to another live server on shutdown. +

This example starts 2 live servers each one with a connector configured for the other live server.

+

The second live server is killed and its messages are scaled down to the first server on shutdown.

+

The following shows how to configure the live servers to scale down to one another.

+
+     
+     <ha-policy>
+         <live-only>
+             <scale-down>
+                 <connectors>
+                     <connector-ref>server0-connector</connector-ref>
+                 </connectors>
+             </scale-down>
+         </live-only>
+     </ha-policy>
+     
+     
+ + http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/scale-down/src/main/java/org/apache/activemq/artemis/jms/example/ScaleDownExample.java ---------------------------------------------------------------------- diff --git a/examples/features/ha/scale-down/src/main/java/org/apache/activemq/artemis/jms/example/ScaleDownExample.java b/examples/features/ha/scale-down/src/main/java/org/apache/activemq/artemis/jms/example/ScaleDownExample.java new file mode 100644 index 0000000..3d81a38 --- /dev/null +++ b/examples/features/ha/scale-down/src/main/java/org/apache/activemq/artemis/jms/example/ScaleDownExample.java @@ -0,0 +1,132 @@ +/* + * 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.util.ServerUtil; + +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; +import java.util.Hashtable; + +/** + * A simple example that demonstrates a colocated server + */ +public class ScaleDownExample { + + private static Process server0; + + private static Process server1; + + public static void main(final String[] args) throws Exception { + final int numMessages = 30; + + Connection connection = null; + Connection connection1 = null; + + InitialContext initialContext = null; + InitialContext initialContext1 = null; + + try { + server0 = ServerUtil.startServer(args[0], ScaleDownExample.class.getSimpleName() + "0", 0, 5000); + server1 = ServerUtil.startServer(args[1], ScaleDownExample.class.getSimpleName() + "1", 1, 5000); + + // Step 1. Get an initial context for looking up JNDI for both servers + Hashtable properties = new Hashtable(); + properties.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory"); + properties.put("connectionFactory.ConnectionFactory", "tcp://localhost:61616?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=-1"); + properties.put("queue.queue/exampleQueue", "exampleQueue"); + initialContext = new InitialContext(properties); + + properties = new Hashtable(); + properties.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory"); + properties.put("connectionFactory.ConnectionFactory", "tcp://localhost:61617?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=-1"); + initialContext1 = new InitialContext(properties); + + // Step 2. Look up the JMS resources from JNDI + Queue queue = (Queue) initialContext.lookup("queue/exampleQueue"); + ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + ConnectionFactory connectionFactory1 = (ConnectionFactory) initialContext1.lookup("ConnectionFactory"); + + // Step 3. Create a JMS Connections + connection = connectionFactory.createConnection(); + connection1 = connectionFactory1.createConnection(); + + // Step 4. Create a *non-transacted* JMS Session with client acknowledgement + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 5. Create a JMS MessageProducers + MessageProducer producer = session.createProducer(queue); + MessageProducer producer1 = session1.createProducer(queue); + + // Step 6. Send some messages to both servers + for (int i = 0; i < numMessages; i++) { + TextMessage message = session.createTextMessage("This is text message " + i); + producer.send(message); + System.out.println("Sent message: " + message.getText()); + message = session1.createTextMessage("This is another text message " + i); + producer1.send(message); + System.out.println("Sent message: " + message.getText()); + } + + // Step 7. Crash server #1 + ServerUtil.killServer(server1); + + // Step 8. start the connection ready to receive messages + connection.start(); + + // Step 9.create a consumer + MessageConsumer consumer = session.createConsumer(queue); + + // Step 10. Receive and acknowledge all of the sent messages, the backup server that is colocated with server 1 + // will have become live and is now handling messages for server 0. + TextMessage message0 = null; + for (int i = 0; i < numMessages * 2; i++) { + message0 = (TextMessage) consumer.receive(5000); + System.out.println("Got message: " + message0.getText()); + } + message0.acknowledge(); + } + finally { + // Step 11. Be sure to close our resources! + + if (connection != null) { + connection.close(); + } + + if (initialContext != null) { + initialContext.close(); + } + if (connection1 != null) { + connection1.close(); + } + + if (initialContext1 != null) { + initialContext1.close(); + } + + ServerUtil.killServer(server0); + ServerUtil.killServer(server1); + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/scale-down/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/scale-down/src/main/resources/activemq/server0/broker.xml b/examples/features/ha/scale-down/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..559bb5a --- /dev/null +++ b/examples/features/ha/scale-down/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + tcp://localhost:61616 + + + + + tcp://localhost:61616 + + + + + + ${udp-address:231.7.7.7} + 9876 + 100 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 10000 + + + + + +
jms
+ netty-connector + 500 + 5 + true + STRICT + 1 + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/scale-down/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/scale-down/src/main/resources/activemq/server1/broker.xml b/examples/features/ha/scale-down/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..6211cd3 --- /dev/null +++ b/examples/features/ha/scale-down/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + ./data/bindings + + ./data/journal + + ./data/largemessages + + ./data/paging + + + + tcp://localhost:61617 + tcp://localhost:61616 + + + + + tcp://localhost:61617 + + + + + + ${udp-address:231.7.7.7} + 9876 + 100 + netty-connector + + + + + + ${udp-address:231.7.7.7} + 9876 + 10000 + + + + + +
jms
+ netty-connector + 500 + 5 + true + STRICT + 1 + +
+
+ + + + + + + server0-connector + + + + + + + + + + + + + + + + + + + +
+