http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/queue-message-redistribution/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/queue-message-redistribution/src/main/resources/activemq/server1/broker.xml b/examples/features/clustered/queue-message-redistribution/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..6fc6f32 --- /dev/null +++ b/examples/features/clustered/queue-message-redistribution/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,107 @@ +<?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"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector">tcp://localhost:61617</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61617</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!--security for example queue--> + <security-setting match="jms.queue.exampleQueue"> + <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> + <!-- We set a redistribution delay of zero on all jms queues and topic subscriptions + Default redistribution delay as -1 which means "disable redistribution" + Setting it to a value > 0 means how long to wait before redistributing, if a consumer is closed + then another one quickly recreated you might want to set it thus, to avoid unnecessary + redistribution --> + <address-setting match="jms.#"> + <redistribution-delay>0</redistribution-delay> + </address-setting> + </address-settings> + + </core> +</configuration>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/pom.xml b/examples/features/clustered/symmetric-cluster/pom.xml new file mode 100644 index 0000000..5be9c1d --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/pom.xml @@ -0,0 +1,320 @@ +<?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.clustered</groupId> + <artifactId>broker-clustered</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>symmetric-cluster</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Symmetric Cluster 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>create0</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server0</instance> + <configuration>${basedir}/target/classes/activemq/server0</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>create1</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server1</instance> + <configuration>${basedir}/target/classes/activemq/server1</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>create2</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server2</instance> + <configuration>${basedir}/target/classes/activemq/server2</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>create3</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server3</instance> + <configuration>${basedir}/target/classes/activemq/server3</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>create4</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server4</instance> + <configuration>${basedir}/target/classes/activemq/server4</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>create5</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <instance>${basedir}/target/server5</instance> + <configuration>${basedir}/target/classes/activemq/server5</configuration> + <javaOptions>-Dudp-address=${udp-address}</javaOptions> + </configuration> + </execution> + <execution> + <id>start0</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server0</location> + <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>${noSever}</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>start2</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server2</location> + <testURI>tcp://localhost:61618</testURI> + <args> + <param>run</param> + </args> + <name>server2</name> + </configuration> + </execution> + <execution> + <id>start3</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server3</location> + <testURI>tcp://localhost:61619</testURI> + <args> + <param>run</param> + </args> + <name>server3</name> + </configuration> + </execution> + <execution> + <id>start4</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server4</location> + <testURI>tcp://localhost:61620</testURI> + <args> + <param>run</param> + </args> + <name>server4</name> + </configuration> + </execution> + <execution> + <id>start5</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server5</location> + <testURI>tcp://localhost:61621</testURI> + <args> + <param>run</param> + </args> + <name>server5</name> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.SymmetricClusterExample</clientClass> + </configuration> + </execution> + <execution> + <id>stop0</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server0</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop1</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server1</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop2</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server2</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop3</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server3</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop4</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server4</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop5</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noSever}</ignore> + <location>${basedir}/target/server5</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.clustered</groupId> + <artifactId>symmetric-cluster</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/clustered/symmetric-cluster/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/readme.html b/examples/features/clustered/symmetric-cluster/readme.html new file mode 100644 index 0000000..043057d --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/readme.html @@ -0,0 +1,74 @@ +<!-- +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 Symmetric Cluster 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>JMS Symmetric Cluster 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 examples demonstrates a <b>symmetric cluster</b> set-up with ActiveMQ Artemis.</p> + <p>ActiveMQ Artemis has extremely flexible clustering which allows you to set-up servers in + many different topologies.</p> + <p>The most common topology that you'll perhaps be familiar with if you are used to application + server clustering is a <b>symmetric cluster</b>.</p> + <p>With a symmetric cluster, the cluster is homogeneous, i.e. each node is configured the same + as every other node, and every node is connected to every other node in the cluster.</p> + <p>By connecting node in such a way, we can, from a JMS point of view, give the impression of distributed + JMS queues and topics.</p> + <p>The configuration used in this example is very similar to the configuration used by ActiveMQ + when installed as a clustered profile in JBoss Application Server.</p> + <p>To set up ActiveMQ Artemis to form a symmetric cluster we simply need to mark each server as <code>clustered</code> + and we need to define a <code>cluster-connection</code> in <code>broker.xml</code>.</p> + <p>The <code>cluster-connection</code> tells the nodes what other nodes to make connections to. + With a <code>cluster-connection</code> each node that we connect to can either be specified + indivually, or we can use UDP discovery to find out what other nodes are in the cluster.</p> + <p>Using UDP discovery makes configuration simpler since we don't have to know what nodes are + available at any one time.</p> + <p>Here's the relevant snippet from the server configuration, which tells the server to form a cluster + with the other nodes:</p> + <pre class="prettyprint"> + <code> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>STRICT</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </code> + </pre> + <p>In this example we create a symmetric cluster of six live nodes, and we also pair each live node + with it's own backup node. (A backup node is not strictly necessary for a symmetric cluster).</p> + <p>In this example will we will demonstrate this by deploying a JMS topic and Queue on all nodes of the cluster + , sending messages to the queue and topic from different nodes, and verifying messages are received correctly + by consumers on different nodes.</p> + <p>For more information on configuring ActiveMQ Artemis clustering in general, please see the clustering + section of the user manual.</p> + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/java/org/apache/activemq/artemis/jms/example/SymmetricClusterExample.java ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/java/org/apache/activemq/artemis/jms/example/SymmetricClusterExample.java b/examples/features/clustered/symmetric-cluster/src/main/java/org/apache/activemq/artemis/jms/example/SymmetricClusterExample.java new file mode 100644 index 0000000..1163ec8 --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/java/org/apache/activemq/artemis/jms/example/SymmetricClusterExample.java @@ -0,0 +1,222 @@ +/* + * 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.jms.Topic; + +import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; +import org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory; +import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; +import org.apache.activemq.artemis.api.jms.JMSFactoryType; + +/** + * This example demonstrates a cluster of three nodes set up in a symmetric topology - i.e. each + * node is connected to every other node in the cluster. Also each node, has it's own backup node. + * <p> + * This is probably the most obvious clustering topology and the one most people will be familiar + * with from using clustering in an app server, where every node has pretty much identical + * configuration to every other node. + * <p> + * By clustering nodes symmetrically, ActiveMQ Artemis can give the impression of clustered queues, topics + * and durable subscriptions. + * <p> + * In this example we send some messages to a distributed queue and topic and kill all the live + * servers at different times, and verify that they transparently fail over onto their backup + * servers. + * <p> + * Please see the readme.html file for more information. + */ +public class SymmetricClusterExample { + + public static void main(final String[] args) throws Exception { + Connection connection0 = null; + + Connection connection1 = null; + + Connection connection2 = null; + + Connection connection3 = null; + + Connection connection4 = null; + + Connection connection5 = null; + + try { + // Step 1 - We instantiate a connection factory directly, specifying the UDP address and port for discovering + // the list of servers in the cluster. + // We could use JNDI to look-up a connection factory, but we'd need to know the JNDI server host and port for + // the + // specific server to do that, and that server might not be available at the time. By creating the + // connection factory directly we avoid having to worry about a JNDI look-up. + // In an app server environment you could use HA-JNDI to lookup from the clustered JNDI servers without + // having to know about a specific one. + UDPBroadcastEndpointFactory udpCfg = new UDPBroadcastEndpointFactory(); + udpCfg.setGroupAddress("231.7.7.7").setGroupPort(9876); + DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(); + groupConfiguration.setBroadcastEndpointFactory(udpCfg); + + ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.CF); + + // We give a little while for each server to broadcast its whereabouts to the client + Thread.sleep(2000); + + // Step 2. Directly instantiate JMS Queue and Topic objects + Queue queue = ActiveMQJMSClient.createQueue("exampleQueue"); + + Topic topic = ActiveMQJMSClient.createTopic("exampleTopic"); + + // Step 3. We create six connections, they should be to different nodes of the cluster in a round-robin fashion + // and start them + connection0 = cf.createConnection(); + + connection1 = cf.createConnection(); + + connection2 = cf.createConnection(); + + connection3 = cf.createConnection(); + + connection4 = cf.createConnection(); + + connection5 = cf.createConnection(); + + connection0.start(); + + connection1.start(); + + connection2.start(); + + connection3.start(); + + connection4.start(); + + connection5.start(); + + // Step 4. We create a session on each connection + + Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session session3 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session session4 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session session5 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 5. We create a topic subscriber on each server + + MessageConsumer subscriber0 = session0.createConsumer(topic); + + MessageConsumer subscriber1 = session1.createConsumer(topic); + + MessageConsumer subscriber2 = session2.createConsumer(topic); + + MessageConsumer subscriber3 = session3.createConsumer(topic); + + MessageConsumer subscriber4 = session4.createConsumer(topic); + + MessageConsumer subscriber5 = session5.createConsumer(topic); + + // Step 6. We create a queue consumer on server 0 + + MessageConsumer consumer0 = session0.createConsumer(queue); + + // Step 7. We create an anonymous message producer on just one server 2 + + MessageProducer producer2 = session2.createProducer(null); + + // Step 8. We send 500 messages each to the queue and topic + + final int numMessages = 500; + + for (int i = 0; i < numMessages; i++) { + TextMessage message1 = session2.createTextMessage("Topic message " + i); + + producer2.send(topic, message1); + + TextMessage message2 = session2.createTextMessage("Queue message " + i); + + producer2.send(queue, message2); + } + + // Step 9. Verify all subscribers and the consumer receive the messages + + for (int i = 0; i < numMessages; i++) { + TextMessage received0 = (TextMessage) subscriber0.receive(5000); + + if (received0 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received1 = (TextMessage) subscriber1.receive(5000); + + if (received1 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received2 = (TextMessage) subscriber2.receive(5000); + + if (received2 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received3 = (TextMessage) subscriber3.receive(5000); + + if (received3 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received4 = (TextMessage) subscriber4.receive(5000); + + if (received4 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received5 = (TextMessage) subscriber5.receive(5000); + + if (received5 == null) { + throw new IllegalStateException("Message is null!"); + } + + TextMessage received6 = (TextMessage) consumer0.receive(5000); + + if (received6 == null) { + throw new IllegalStateException("Message is null!"); + } + } + } + finally { + // Step 15. Be sure to close our resources! + + connection0.close(); + connection1.close(); + connection2.close(); + connection3.close(); + connection4.close(); + connection5.close(); + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server0/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..cd89de7 --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,99 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector">tcp://localhost:61616</connector> + + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server1/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..d95a1cd --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,97 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector">tcp://localhost:61617</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61617</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server2/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server2/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server2/broker.xml new file mode 100644 index 0000000..ef006fd --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server2/broker.xml @@ -0,0 +1,97 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector">tcp://localhost:61618</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61618</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server3/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server3/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server3/broker.xml new file mode 100644 index 0000000..a780ace --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server3/broker.xml @@ -0,0 +1,97 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector">tcp://localhost:61619</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61619</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server4/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server4/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server4/broker.xml new file mode 100644 index 0000000..20b622e --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server4/broker.xml @@ -0,0 +1,96 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector">tcp://localhost:61620</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61620</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server5/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server5/broker.xml b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server5/broker.xml new file mode 100644 index 0000000..033af43 --- /dev/null +++ b/examples/features/clustered/symmetric-cluster/src/main/resources/activemq/server5/broker.xml @@ -0,0 +1,96 @@ +<?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"> + <queue name="exampleQueue"/> + + <topic name="exampleTopic"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>./data/bindings</bindings-directory> + + <journal-directory>./data/journal</journal-directory> + + <large-messages-directory>./data/largemessages</large-messages-directory> + + <paging-directory>./data/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector">tcp://localhost:61621</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61621</acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broadcast-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>100</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="my-discovery-group"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>10000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <message-load-balancing>ON_DEMAND</message-load-balancing> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- Other config --> + + <security-settings> + <!-- Default JMS security --> + <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> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/application-layer-failover/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/application-layer-failover/pom.xml b/examples/features/ha/application-layer-failover/pom.xml new file mode 100644 index 0000000..c0d9b84 --- /dev/null +++ b/examples/features/ha/application-layer-failover/pom.xml @@ -0,0 +1,102 @@ +<?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.failover</groupId> + <artifactId>broker-failover</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>application-layer-failover</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Application Layer Failover Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-cli</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> + <instance>${basedir}/target/server0</instance> + </configuration> + </execution> + <execution> + <id>create1</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <instance>${basedir}/target/server1</instance> + <portOffset>1</portOffset> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.ApplicationLayerFailoverExample</clientClass> + <args> + <param>${basedir}/target/server0</param> + <param>${basedir}/target/server1</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.failover</groupId> + <artifactId>application-layer-failover</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/ha/application-layer-failover/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/ha/application-layer-failover/readme.html b/examples/features/ha/application-layer-failover/readme.html new file mode 100644 index 0000000..b60a66d --- /dev/null +++ b/examples/features/ha/application-layer-failover/readme.html @@ -0,0 +1,169 @@ +<!-- +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 Application-Layer Failover 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>Application-Layer Failover Example</h1> + + <pre>To run the example, simply type <b>mvn verify</b> from this directory. This example will always spawn and stop multiple servers.</pre> + + <p>ActiveMQ Artemis implements fully transparent <b>automatic</b> failover of connections from a live node to a backup node which requires + no special coding. This is described in a different example and requires server replication.</p> + <p>However, ActiveMQ Artemis also supports <b>Application-Layer</b> failover which is useful in the case where replication is not enabled.</p> + <p>With Application-Layer failover, it's up to the application to register a JMS ExceptionListener with ActiveMQ Artemis. + This listener will then be called by ActiveMQ Artemis in the event that connection failure is detected.</p> + <p>User code in the ExceptionListener can then recreate any JMS Connection, Session, etc on another node and the application + can continue.</p> + <p>Application-Layer failover is an alternative approach to High Availabilty (HA).</p> + <p>Application-Layer failover differs from automatic failover in that some client side coding is required in order + to implement this. Also, with Application-Layer failover, since the old Session object dies and a new is created, any uncommitted + work in the old Session will be lost, and any unacknowledged messages might be redelivered.</p> + <p>For more information on ActiveMQ Artemis failover and HA, and clustering in general, please see the clustering + section of the user manual.</p> + + <h2>Example step-by-step</h2> + <p>In this example, the live server is server 1, which will failover onto server 0.</p> + <p>The connection will initially be created to server1, server 1 will crash, and the client will carry on + on server 0, the new server. With Application-Layer failover the node that is failed over onto, does not need to + be specially configured as a backup server, it can be any node.</p> + + <ol> + <li> We create our JMS Connection, Session, MessageProducer and MessageConsumer on server 1</li> + <pre class="prettyprint"> + <code>createJMSObjects(1);</code> + </pre> + + <li>We set a JMS ExceptionListener on the connection. On failure this will be called and the connection, + session, etc. will be manually recreated on the backup node.</li> + <pre class="prettyprint"> + <code>connection.setExceptionListener(new ExampleListener());</code> + </pre> + + <li>We send some messages to server 1, the live server.</li> + <pre class="prettyprint"> + <code> + final int numMessages = 10; + + 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()); + } + </code> + </pre> + + <li>We consume those messages on server 1.</li> + <pre class="prettyprint"> + <code> + for (int i = 0; i < numMessages; i++) + { + TextMessage message0 = (TextMessage)consumer.receive(5000); + + System.out.println("Got message: " + message0.getText()); + } + </code> + </pre> + + <li>We now cause server 1, the live server to crash. After a little while the connection's + ExceptionListener will register the failure and reconnection will occur.</li> + <pre class="prettyprint"> + <code>killServer(1);</code> + </pre> + + <li>The connection's ExceptionListener gets called, and we lookup the JMS objects and + recreate the connection, session, etc on the other node 0.</li> + <pre class="prettyprint"> + <code> + private class ExampleListener implements ExceptionListener + { + public void onException(JMSException exception) + { + try + { + // Close the old resources + + closeResources(); + + // Create new JMS objects on the backup server + + createJMSObjects(0); + + failoverLatch.countDown(); + } + catch (Exception e) + { + System.err.println("Failed to handle failover"); + + e.printStackTrace(); + } + } + } + </code> + </pre> + + <li>We are now connected to the other node. We now send some more messages.</li> + <pre class="prettyprint"> + <code> + for (int i = numMessages; i < numMessages * 2; i++) + { + TextMessage message = session.createTextMessage("This is text message " + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + </code> + </pre> + + <li>And consume them.</li> + <pre class="prettyprint"> + <code> + for (int i = 0; i < numMessages; i++) + { + TextMessage message0 = (TextMessage)consumer.receive(5000); + + System.out.println("Got message: " + message0.getText()); + } + </code> + </pre> + + + <li>And finally (no pun intended), <b>always</b> remember to close your resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> + + <pre class="prettyprint"> + <code> + finally + { + closeResources(); + } + </code> + </pre> + + </ol> + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/application-layer-failover/src/main/java/org/apache/activemq/artemis/jms/example/ApplicationLayerFailoverExample.java ---------------------------------------------------------------------- diff --git a/examples/features/ha/application-layer-failover/src/main/java/org/apache/activemq/artemis/jms/example/ApplicationLayerFailoverExample.java b/examples/features/ha/application-layer-failover/src/main/java/org/apache/activemq/artemis/jms/example/ApplicationLayerFailoverExample.java new file mode 100644 index 0000000..2d0dc0c --- /dev/null +++ b/examples/features/ha/application-layer-failover/src/main/java/org/apache/activemq/artemis/jms/example/ApplicationLayerFailoverExample.java @@ -0,0 +1,221 @@ +/* + * 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.ExceptionListener; +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; +import javax.naming.NamingException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; +import org.apache.activemq.artemis.util.ServerUtil; + +/** + * A simple example that demonstrates application-layer failover of the JMS connection from one node to another + * when the live server crashes + */ +public class ApplicationLayerFailoverExample { + + private static InitialContext initialContext; + + private static Connection connection; + + private static Session session; + + private static MessageConsumer consumer; + + private static MessageProducer producer; + + private static final CountDownLatch failoverLatch = new CountDownLatch(1); + + private static Process server0; + + private static Process server1; + + public static void main(final String[] args) throws Exception { + try { + server0 = ServerUtil.startServer(args[0], ApplicationLayerFailoverExample.class.getSimpleName() + "0", 0, 5000); + server1 = ServerUtil.startServer(args[1], ApplicationLayerFailoverExample.class.getSimpleName() + "1", 1, 5000); + + // Step 1. We create our JMS Connection, Session, MessageProducer and MessageConsumer on server 1. + createJMSObjects(0); + + // Step 2. We set a JMS ExceptionListener on the connection. On failure this will be called and the connection, + // session, etc. will be then recreated on the backup node. + connection.setExceptionListener(new ExampleListener()); + + System.out.println("The initial JMS objects have been created, and the ExceptionListener set"); + + // Step 3. We send some messages to server 1, the live server + + final int numMessages = 10; + + 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 4. We consume those messages on server 1. + + for (int i = 0; i < numMessages; i++) { + TextMessage message0 = (TextMessage) consumer.receive(5000); + + System.out.println("Got message: " + message0.getText()); + } + + // Step 5. We now cause server 1, the live server to crash. After a little while the connection's + // ExceptionListener will register the failure and reconnection will occur. + + System.out.println("Killing the server"); + + ServerUtil.killServer(server0); + + // Step 6. Wait for the client side to register the failure and reconnect + + boolean ok = failoverLatch.await(5000, TimeUnit.MILLISECONDS); + + System.out.println("Reconnection has occurred. Now sending more messages."); + + // Step 8. We now send some more messages + + for (int i = numMessages; i < numMessages * 2; i++) { + TextMessage message = session.createTextMessage("This is text message " + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + + // Step 9. And consume them. + + for (int i = 0; i < numMessages; i++) { + TextMessage message0 = (TextMessage) consumer.receive(5000); + + System.out.println("Got message: " + message0.getText()); + } + } + catch (Throwable t) { + t.printStackTrace(); + } + finally { + // Step 14. Be sure to close our resources! + closeResources(); + ServerUtil.killServer(server0); + ServerUtil.killServer(server1); + } + } + + private static void createJMSObjects(final int server) throws Exception { + // Step 1. Instantiate a JMS Connection Factory object from JNDI on server 1 + ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:" + (61616 + server)); + + // Step 2. We create a JMS Connection connection + connection = connectionFactory.createConnection(); + + // Step 3. We start the connection to ensure delivery occurs + connection.start(); + + // Step 4. We create a JMS Session + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 5. Look-up the JMS Queue object from JNDI + Queue queue = session.createQueue("exampleQueue"); + + // Step 6. We create a JMS MessageConsumer object + consumer = session.createConsumer(queue); + + // Step 7. We create a JMS MessageProducer object + producer = session.createProducer(queue); + } + + private static void closeResources() { + if (initialContext != null) { + try { + initialContext.close(); + } + catch (NamingException e) { + e.printStackTrace(); + } + } + + if (connection != null) { + try { + connection.close(); + } + catch (JMSException e) { + e.printStackTrace(); + } + } + } + + private static class ExampleListener implements ExceptionListener { + + public void onException(final JMSException exception) { + try { + connection.close(); + } + catch (JMSException e) { + //ignore + } + for (int i = 0; i < 10; i++) { + try { + // Step 7. The ExceptionListener gets called and we recreate the JMS objects on the new node + + System.out.println("Connection failure has been detected on a the client."); + + // Close the old resources + + // closeResources(); + + System.out.println("The old resources have been closed."); + + // Create new JMS objects on the backup server + + createJMSObjects(1); + + System.out.println("The new resources have been created."); + + failoverLatch.countDown(); + + return; + } + catch (Exception e) { + System.out.println("Failed to handle failover, trying again."); + try { + Thread.sleep(500); + } + catch (InterruptedException e1) { + //ignored + } + } + } + System.out.println("tried 10 times to reconnect, giving up"); + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/ha/client-side-failoverlistener/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/ha/client-side-failoverlistener/pom.xml b/examples/features/ha/client-side-failoverlistener/pom.xml new file mode 100644 index 0000000..03101ac --- /dev/null +++ b/examples/features/ha/client-side-failoverlistener/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.failover</groupId> + <artifactId>broker-failover</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>client-side-fileoverlistener</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Client Side Failover listener Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-cli</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> + <instance>${basedir}/target/server0</instance> + <dataFolder>../shared</dataFolder> + <sharedStore>true</sharedStore> + <slave>false</slave> + <failoverOnShutdown>true</failoverOnShutdown> + </configuration> + </execution> + <execution> + <id>create1</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <instance>${basedir}/target/server1</instance> + <dataFolder>../shared</dataFolder> + <sharedStore>true</sharedStore> + <slave>true</slave> + <portOffset>1</portOffset> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.ClientSideFailoverListerExample</clientClass> + <args> + <param>${basedir}/target/server0</param> + <param>${basedir}/target/server1</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.failover</groupId> + <artifactId>client-side-fileoverlistener</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/ha/client-side-failoverlistener/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/ha/client-side-failoverlistener/readme.html b/examples/features/ha/client-side-failoverlistener/readme.html new file mode 100644 index 0000000..3fe1f4d --- /dev/null +++ b/examples/features/ha/client-side-failoverlistener/readme.html @@ -0,0 +1,37 @@ +<!-- +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 Side Failover Listener 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 Side Kickoff Example</h1> + <pre>To run the example, simply type <b>mvn verify</b> from this directory. This example will always spawn and stop multiple servers.</pre> + + <p>This example demonstrates how you can listen on failover event on the client side.</p> + + <p>In this example there are two nodes running in a cluster, both server will be running for start, + but after a while the first server will crash. This will trigger a fail-over event.</p> + + </body> +</html>