http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/java/org/hornetq/jms/example/ClientSideFailoverListerExample.java ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/java/org/hornetq/jms/example/ClientSideFailoverListerExample.java b/examples/jms/client-side-failoverlistener/src/main/java/org/hornetq/jms/example/ClientSideFailoverListerExample.java new file mode 100644 index 0000000..f5b3e57 --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/java/org/hornetq/jms/example/ClientSideFailoverListerExample.java @@ -0,0 +1,135 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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.hornetq.jms.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.hornetq.api.core.client.FailoverEventListener; +import org.hornetq.api.core.client.FailoverEventType; +import org.hornetq.common.example.HornetQExample; +import org.hornetq.jms.client.HornetQConnection; + +/** + * This example demonstrates how you can listen on failover event on the client side + * + * 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 an fail oever event + * + * @author <a href="flemming.ha...@gmail.com>Flemming Harms</a> + */ +public class ClientSideFailoverListerExample extends HornetQExample +{ + public static void main(final String[] args) + { + new ClientSideFailoverListerExample().run(args); + } + + @Override + public boolean runExample() throws Exception + { + InitialContext initialContext = null; + + Connection connectionA = null; + + try + { + // Step 1. Get an initial context for looking up JNDI from server 0 + initialContext = getContext(0); + + // Step 2. Look-up the JMS Queue object from JNDI + Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue"); + + // Step 3. Look-up a JMS Connection Factory object from JNDI on server 0 + ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory"); + + // Step 4. We create 1 JMS connections from the same connection factory. + // Wait a little while to make sure broadcasts from all nodes have reached the client + Thread.sleep(5000); + connectionA = connectionFactory.createConnection(); + ((HornetQConnection)connectionA).setFailoverListener(new FailoverListenerImpl()); + + // Step 5. We create JMS Sessions + Session sessionA = connectionA.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 6. We create JMS MessageProducer objects on the sessions + MessageProducer producerA = sessionA.createProducer(queue); + + // Step 7. We send some messages on each producer + final int numMessages = 10; + + for (int i = 0; i < numMessages; i++) + { + TextMessage messageA = sessionA.createTextMessage("A:This is text message " + i); + producerA.send(messageA); + System.out.println("Sent message: " + messageA.getText()); + + } + + // Step 8. We start the connection to consume messages + connectionA.start(); + + // Step 9. We consume messages from the session A, one at a time. + // We reached message no 5 the first server will crash + consume(sessionA, queue, numMessages, "A"); + + return true; + } + finally + { + // Step 10. Be sure to close our resources! + + if (connectionA != null) + { + connectionA.close(); + } + + if (initialContext != null) + { + initialContext.close(); + } + } + } + + private void consume(Session session, Queue queue, int numMessages, String node) throws Exception + { + MessageConsumer consumer = session.createConsumer(queue); + + for (int i = 0; i < numMessages; i++) + { + TextMessage message = (TextMessage)consumer.receive(2000); + System.out.println("Got message: " + message.getText() + " from node " + node); + if (i == 5) + { + killServer(0); + } + } + + System.out.println("receive other message from node " + node + ": " + consumer.receive(2000)); + + } + + private static class FailoverListenerImpl implements FailoverEventListener + { + public void failoverEvent(FailoverEventType eventType) + { + System.out.println("Failover event triggered :" + eventType.toString()); + } + } +}
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-configuration.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-configuration.xml new file mode 100644 index 0000000..f923f5e --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-configuration.xml @@ -0,0 +1,67 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq ../../../../../../../../hornetq-server/src/main/resources/schema/hornetq-configuration.xsd"> + + <bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory> + + <ha-policy template="SHARED_STORE"/> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5445"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5445"/> + </acceptor> + </acceptors> + + <broadcast-groups> + <broadcast-group name="bg-group1"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>1000</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="dg-group1"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>60000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <discovery-group-ref discovery-group-name="dg-group1"/> + </cluster-connection> + </cluster-connections> + + <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> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-jms.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-jms.xml new file mode 100644 index 0000000..5562cd7 --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-jms.xml @@ -0,0 +1,33 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty-connector"/> + </connectors> + + <entries> + <entry name="ConnectionFactory"/> + </entries> + + <ha>true</ha> + <!-- Pause 1 second between connect attempts --> + <retry-interval>1000</retry-interval> + + <!-- Multiply subsequent reconnect pauses by this multiplier. This can be used to + implement an exponential back-off. For our purposes we just set to 1.0 so each reconnect + pause is the same length --> + <retry-interval-multiplier>1.0</retry-interval-multiplier> + + <!-- Try reconnecting an unlimited number of times (-1 means "unlimited") --> + <reconnect-attempts>-1</reconnect-attempts> + + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-users.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server0/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-configuration.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-configuration.xml new file mode 100644 index 0000000..7d61f04 --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-configuration.xml @@ -0,0 +1,67 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq ../../../../../../../../hornetq-server/src/main/resources/schema/hornetq-configuration.xsd"> + + <bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory> + + <ha-policy template="BACKUP_SHARED_STORE"/> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5446"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5446"/> + </acceptor> + </acceptors> + + <broadcast-groups> + <broadcast-group name="bg-group1"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <broadcast-period>1000</broadcast-period> + <connector-ref>netty-connector</connector-ref> + </broadcast-group> + </broadcast-groups> + + <discovery-groups> + <discovery-group name="dg-group1"> + <group-address>${udp-address:231.7.7.7}</group-address> + <group-port>9876</group-port> + <refresh-timeout>60000</refresh-timeout> + </discovery-group> + </discovery-groups> + + <cluster-connections> + <cluster-connection name="my-cluster"> + <address>jms</address> + <connector-ref>netty-connector</connector-ref> + <discovery-group-ref discovery-group-name="dg-group1"/> + </cluster-connection> + </cluster-connections> + + <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> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-jms.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-jms.xml new file mode 100644 index 0000000..fb82d36 --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-jms.xml @@ -0,0 +1,32 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty-connector"/> + </connectors> + + <entries> + <entry name="ConnectionFactory"/> + </entries> + + <ha>true</ha> + <!-- Pause 1 second between connect attempts --> + <retry-interval>1000</retry-interval> + + <!-- Multiply subsequent reconnect pauses by this multiplier. This can be used to + implement an exponential back-off. For our purposes we just set to 1.0 so each reconnect + pause is the same length --> + <retry-interval-multiplier>1.0</retry-interval-multiplier> + + <!-- Try reconnecting an unlimited number of times (-1 means "unlimited") --> + <reconnect-attempts>-1</reconnect-attempts> + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-users.xml b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/client-side-failoverlistener/src/main/resources/hornetq/server1/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/pom.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/pom.xml b/examples/jms/client-side-load-balancing/pom.xml new file mode 100644 index 0000000..e95e396 --- /dev/null +++ b/examples/jms/client-side-load-balancing/pom.xml @@ -0,0 +1,198 @@ +<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.hornetq.examples.jms</groupId> + <artifactId>jms-examples</artifactId> + <version>2.5.0-SNAPSHOT</version> + </parent> + + <artifactId>hornetq-jms-client-side-load-balancing-example</artifactId> + <packaging>jar</packaging> + <name>HornetQ JMS Client Side Load Balancing Example</name> + + <dependencies> + <dependency> + <groupId>org.hornetq.examples.jms</groupId> + <artifactId>hornetq-jms-examples-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.spec.javax.jms</groupId> + <artifactId>jboss-jms-api_2.0_spec</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-maven-plugin</artifactId> + <executions> + <execution> + <id>start0</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server0</hornetqConfigurationDir> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + <property> + <name>udp-address</name> + <value>${udp-address}</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>start1</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + <jndiPort>1199</jndiPort> + <jndiRmiPort>1198</jndiRmiPort> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server1</hornetqConfigurationDir> + <fork>true</fork> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + <property> + <name>udp-address</name> + <value>${udp-address}</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>start2</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + <jndiPort>1299</jndiPort> + <jndiRmiPort>1298</jndiRmiPort> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server2</hornetqConfigurationDir> + <fork>true</fork> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + <property> + <name>udp-address</name> + <value>${udp-address}</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.hornetq.jms.example.ClientSideLoadBalancingExample</clientClass> + <args> + <param>jnp://localhost:1099</param> + <param>jnp://localhost:1199</param> + </args> + <systemProperties> + <property> + <name>exampleConfigDir</name> + <value>${basedir}/target/classes/hornetq</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>stop0</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server0</hornetqConfigurationDir> + </configuration> + </execution> + <execution> + <id>stop1</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server1</hornetqConfigurationDir> + </configuration> + </execution> + <execution> + <id>stop2</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server2</hornetqConfigurationDir> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.hornetq.examples.jms</groupId> + <artifactId>hornetq-jms-client-side-load-balancing-example</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-core-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-jms-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-jms-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + <version>${netty.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.javaee</groupId> + <artifactId>jboss-jms-api</artifactId> + <version>1.1.0.GA</version> + </dependency> + <dependency> + <groupId>org.jboss.naming</groupId> + <artifactId>jnpserver</artifactId> + <version>5.0.3.GA</version> + </dependency> + </dependencies> + <configuration> + <waitOnStart>false</waitOnStart> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + </systemProperties> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/readme.html ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/readme.html b/examples/jms/client-side-load-balancing/readme.html new file mode 100644 index 0000000..7793546 --- /dev/null +++ b/examples/jms/client-side-load-balancing/readme.html @@ -0,0 +1,149 @@ +<html> + <head> + <title>HornetQ JMS Client-Side Load-Balancing 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 Client-Side Load-Balancing Example</h1> + + <p>This example demonstrates how connnections created from a single JMS Connection factory can be created + to different nodes of the cluster. In other words it demonstrates how HornetQ does <b>client side load balancing</b> of + connections across the cluster.</p> + <p>The particular load-balancing policy can be chosen to be random, round-robin or user-defined. Please see the user + guide for more details of how to configure the specific load-balancing policy. In this example we will use + the default round-robin load balancing policy.</p> + <p>The list of servers over which HornetQ will round-robin the connections can either be specified explicitly + in the connection factory when instantiating it directly, when configuring it on the server or configured + to use UDP discovery to discover the list of servers over which to round-robin. This example will use UDP + discovery to obtain the list.</p> + <p>This example starts three servers which all broadcast their location using UDP discovery. The UDP broadcast configuration + can be seen in the <code>hornetq-configuration.xml</code> file.</p> + <p>A JMS ConnectionFactory is deployed on each server specifying the discovery group that will be used by that + connection factory.</p> + <p>For more information on HornetQ load balancing, and clustering in general, please see the clustering + section of the user manual.</p> + + <h2>Example step-by-step</h2> + <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p> + + <ol> + <li> Get an initial context for looking up JNDI from server 0.</li> + <pre class="prettyprint"> + <code>initialContext = getContext(0);</code> + </pre> + + <li>Look-up the JMS Queue object from JNDI</li> + <pre class="prettyprint"> + <code>Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");</code> + </pre> + + <li>Look-up a JMS Connection Factory object from JNDI on server 0</li> + <pre class="prettyprint"> + <code>ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code> + </pre> + + <li> We create 3 JMS connections from the same connection factory. Since we are using round-robin + load-balancing this should result in each sessions being connected to a different node of the cluster</li> + <pre class="prettyprint"> + <code> + Connection conn = connectionFactory.createConnection(); + connectionA = connectionFactory.createConnection(); + connectionB = connectionFactory.createConnection(); + connectionC = connectionFactory.createConnection(); + conn.close(); + </code> + </pre> + + <li>We create JMS Sessions</li> + <pre class="prettyprint"> + <code> + Session sessionA = connectionA.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session sessionB = connectionB.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session sessionC = connectionC.createSession(false, Session.AUTO_ACKNOWLEDGE); + </code> + </pre> + + <li>We create JMS MessageProducer objects on the sessions</li> + <pre class="prettyprint"> + <code> + MessageProducer producerA = sessionA.createProducer(queue); + MessageProducer producerB = sessionB.createProducer(queue); + MessageProducer producerC = sessionC.createProducer(queue); + </code> + </pre> + + <li>We send some messages on each producer</li> + <pre class="prettyprint"> + <code> + final int numMessages = 10; + + for (int i = 0; i < numMessages; i++) + { + TextMessage messageA = sessionA.createTextMessage("A:This is text message " + i); + producerA.send(messageA); + System.out.println("Sent message: " + messageA.getText()); + + TextMessage messageB = sessionB.createTextMessage("B:This is text message " + i); + producerB.send(messageB); + System.out.println("Sent message: " + messageB.getText()); + + TextMessage messageC = sessionC.createTextMessage("C:This is text message " + i); + producerC.send(messageC); + System.out.println("Sent message: " + messageC.getText()); + } + </code> + </pre> + + <li>We start the connection to consume messages</li> + <pre class="prettyprint"> + <code> + connectionA.start(); + connectionB.start(); + connectionC.start(); + </code> + </pre> + + <li>We consume messages from the 3 session, one at a time.<br> + We try to consume one more message than expected from each session. If + the session were not properly load-balanced, we would be missing a + message from one of the sessions at the end.</li> + <pre class="prettyprint"> + <code> + consume(sessionA, queue, numMessages, "A"); + consume(sessionB, queue, numMessages, "B"); + consume(sessionC, queue, numMessages, "C"); + </code> + </pre> + + <li>And finally (no pun intended), <b>always</b> remember to close your JMS 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 + { + if (connectionA != null) + { + connectionA.close(); + } + if (connectionB != null) + { + connectionB.close(); + } + if (connectionC != null) + { + connectionC.close(); + } + + if (initialContext != null) + { + initialContext.close(); + } + } + </code> + </pre> + + </ol> + </body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/java/org/hornetq/jms/example/ClientSideLoadBalancingExample.java ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/java/org/hornetq/jms/example/ClientSideLoadBalancingExample.java b/examples/jms/client-side-load-balancing/src/main/java/org/hornetq/jms/example/ClientSideLoadBalancingExample.java new file mode 100644 index 0000000..09705fe --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/java/org/hornetq/jms/example/ClientSideLoadBalancingExample.java @@ -0,0 +1,157 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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.hornetq.jms.example; + +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; + +import org.hornetq.common.example.HornetQExample; + +/** + * This example demonstrates how sessions created from a single connection can be load + * balanced across the different nodes of the cluster. + * + * In this example there are three nodes and we use a round-robin client side load-balancing + * policy. + * + * @author <a href="tim....@jboss.com>Tim Fox</a> + */ +public class ClientSideLoadBalancingExample extends HornetQExample +{ + public static void main(final String[] args) + { + new ClientSideLoadBalancingExample().run(args); + } + + @Override + public boolean runExample() throws Exception + { + InitialContext initialContext = null; + + Connection connectionA = null; + Connection connectionB = null; + Connection connectionC = null; + + try + { + // Step 1. Get an initial context for looking up JNDI from server 0 + initialContext = getContext(0); + + // Step 2. Look-up the JMS Queue object from JNDI + Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue"); + + // Step 3. Look-up a JMS Connection Factory object from JNDI on server 0 + ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory"); + + // Step 4. We create 3 JMS connections from the same connection factory. Since we are using round-robin + // load-balancing this should result in each sessions being connected to a different node of the cluster + Connection conn = connectionFactory.createConnection(); + // Wait a little while to make sure broadcasts from all nodes have reached the client + Thread.sleep(5000); + connectionA = connectionFactory.createConnection(); + connectionB = connectionFactory.createConnection(); + connectionC = connectionFactory.createConnection(); + conn.close(); + + // Step 5. We create JMS Sessions + Session sessionA = connectionA.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session sessionB = connectionB.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session sessionC = connectionC.createSession(false, Session.AUTO_ACKNOWLEDGE); + + System.out.println("Session A - " + ((org.hornetq.core.client.impl.DelegatingSession) ((org.hornetq.jms.client.HornetQSession) sessionA).getCoreSession()).getConnection().getRemoteAddress() ); + System.out.println("Session B - " + ((org.hornetq.core.client.impl.DelegatingSession) ((org.hornetq.jms.client.HornetQSession) sessionB).getCoreSession()).getConnection().getRemoteAddress() ); + System.out.println("Session C - " + ((org.hornetq.core.client.impl.DelegatingSession) ((org.hornetq.jms.client.HornetQSession) sessionC).getCoreSession()).getConnection().getRemoteAddress() ); + + // Step 6. We create JMS MessageProducer objects on the sessions + MessageProducer producerA = sessionA.createProducer(queue); + MessageProducer producerB = sessionB.createProducer(queue); + MessageProducer producerC = sessionC.createProducer(queue); + + // Step 7. We send some messages on each producer + final int numMessages = 10; + + for (int i = 0; i < numMessages; i++) + { + TextMessage messageA = sessionA.createTextMessage("A:This is text message " + i); + producerA.send(messageA); + System.out.println("Sent message: " + messageA.getText()); + + TextMessage messageB = sessionB.createTextMessage("B:This is text message " + i); + producerB.send(messageB); + System.out.println("Sent message: " + messageB.getText()); + + TextMessage messageC = sessionC.createTextMessage("C:This is text message " + i); + producerC.send(messageC); + System.out.println("Sent message: " + messageC.getText()); + } + + // Step 8. We start the connection to consume messages + connectionA.start(); + connectionB.start(); + connectionC.start(); + + // Step 9. We consume messages from the 3 session, one at a time. + // We try to consume one more message than expected from each session. If + // the session were not properly load-balanced, we would be missing a + // message from one of the sessions at the end. + consume(sessionA, queue, numMessages, "A"); + consume(sessionB, queue, numMessages, "B"); + consume(sessionC, queue, numMessages, "C"); + + return true; + } + finally + { + // Step 10. Be sure to close our resources! + + if (connectionA != null) + { + connectionA.close(); + } + if (connectionB != null) + { + connectionB.close(); + } + if (connectionC != null) + { + connectionC.close(); + } + + if (initialContext != null) + { + initialContext.close(); + } + } + } + + private void consume(Session session, Queue queue, int numMessages, String node) throws JMSException + { + MessageConsumer consumer = session.createConsumer(queue); + + for (int i = 0; i < numMessages; i++) + { + TextMessage message = (TextMessage)consumer.receive(2000); + System.out.println("Got message: " + message.getText() + " from node " + node); + } + + System.out.println("receive other message from node " + node + ": " + consumer.receive(2000)); + + } +} http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-configuration.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-configuration.xml new file mode 100644 index 0000000..9ecc814 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-configuration.xml @@ -0,0 +1,73 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd"> + + + <bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory> + + <!-- Connectors --> + + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5445"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5445"/> + </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> + <max-hops>0</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> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-jms.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-jms.xml new file mode 100644 index 0000000..227e0f1 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-jms.xml @@ -0,0 +1,17 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> + +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-users.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server0/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-configuration.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-configuration.xml new file mode 100644 index 0000000..c5b1451 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-configuration.xml @@ -0,0 +1,72 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd"> + + + + <bindings-directory>${build.directory}/server1/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server1/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server1/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server1/data/messaging/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5446"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5446"/> + </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> + <max-hops>0</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> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-jms.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-jms.xml new file mode 100644 index 0000000..227e0f1 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-jms.xml @@ -0,0 +1,17 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> + +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-users.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server1/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-configuration.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-configuration.xml new file mode 100644 index 0000000..c819564 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-configuration.xml @@ -0,0 +1,72 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd"> + + + + <bindings-directory>${build.directory}/server2/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server2/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server2/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server2/data/messaging/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5447"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5447"/> + </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> + <max-hops>0</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> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-jms.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-jms.xml new file mode 100644 index 0000000..227e0f1 --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-jms.xml @@ -0,0 +1,17 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> + +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-users.xml b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/client-side-load-balancing/src/main/resources/hornetq/server2/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/pom.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/pom.xml b/examples/jms/clustered-durable-subscription/pom.xml new file mode 100644 index 0000000..0575139 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/pom.xml @@ -0,0 +1,167 @@ +<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.hornetq.examples.jms</groupId> + <artifactId>jms-examples</artifactId> + <version>2.5.0-SNAPSHOT</version> + </parent> + + <artifactId>hornetq-jms-clustered-durable-subscription-example</artifactId> + <packaging>jar</packaging> + <name>HornetQ JMS Clustered Durable Subscription Example</name> + + <dependencies> + <dependency> + <groupId>org.hornetq.examples.jms</groupId> + <artifactId>hornetq-jms-examples-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.spec.javax.jms</groupId> + <artifactId>jboss-jms-api_2.0_spec</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-maven-plugin</artifactId> + <executions> + <execution> + <id>start0</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server0</hornetqConfigurationDir> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + <property> + <name>udp-address</name> + <value>${udp-address}</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>start1</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + <jndiPort>1199</jndiPort> + <jndiRmiPort>1198</jndiRmiPort> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server1</hornetqConfigurationDir> + <fork>true</fork> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + <property> + <name>udp-address</name> + <value>${udp-address}</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.hornetq.jms.example.ClusteredDurableSubscriptionExample</clientClass> + <args> + <param>jnp://localhost:1099</param> + <param>jnp://localhost:1199</param> + </args> + <systemProperties> + <property> + <name>exampleConfigDir</name> + <value>${basedir}/target/classes/hornetq</value> + </property> + </systemProperties> + </configuration> + </execution> + <execution> + <id>stop0</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server0</hornetqConfigurationDir> + </configuration> + </execution> + <execution> + <id>stop1</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <hornetqConfigurationDir>${basedir}/target/classes/hornetq/server1</hornetqConfigurationDir> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.hornetq.examples.jms</groupId> + <artifactId>hornetq-jms-clustered-durable-subscription-example</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-core-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-jms-client</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.hornetq</groupId> + <artifactId>hornetq-jms-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + <version>${netty.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.javaee</groupId> + <artifactId>jboss-jms-api</artifactId> + <version>1.1.0.GA</version> + </dependency> + <dependency> + <groupId>org.jboss.naming</groupId> + <artifactId>jnpserver</artifactId> + <version>5.0.3.GA</version> + </dependency> + </dependencies> + <configuration> + <waitOnStart>false</waitOnStart> + <systemProperties> + <property> + <name>build.directory</name> + <value>${basedir}/target/</value> + </property> + </systemProperties> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/readme.html ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/readme.html b/examples/jms/clustered-durable-subscription/readme.html new file mode 100644 index 0000000..e83bb33 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/readme.html @@ -0,0 +1,194 @@ +<html> + <head> + <title>HornetQ JMS Durable Subscription 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 Durable Subscription Example</h1> + + <p>This example demonstrates a clustered JMS durable subscription. + Normally durable subscriptions exist on a single node and can only have one subscriber at any one time, + however, with HornetQ it's possible to create durable subscription instances with the same name and client-id + on different nodes of the cluster, and consume from them simultaneously. + This allows the work of processing messages from a durable subscription to be spread across the cluster in + a similar way to how JMS Queues can be load balanced across the cluster + </p> + <p>In this example we first configure the two nodes to form a cluster, then we then create a durable subscriber + with the same name and client-id on both nodes, and we create a producer on only one of the nodes.</p> + <p>We then send some messages via the producer, and we verify that the messages are round robin'd between + the two subscription instances. Note that each durable subscription instance with the same name and client-id + <b>does not</b> receive its own copy of the messages. This is because the instances on different nodes form a + single "logical" durable subscription, in the same way multiple JMS Queue instances on different nodes + form a single "local" JMS Queue</p> + <p>This example uses JNDI to lookup the JMS Queue and ConnectionFactory objects. If you prefer not to use + JNDI, these could be instantiated directly. + <p>Here's the relevant snippet from the server configuration, which tells the server to form a cluster between the two nodes + and to load balance the messages between the nodes.</p> + <pre class="prettyprint"> + <code><cluster-connection name="my-cluster"> + <address>jms</address> + <retry-interval>500</retry-interval> + <use-duplicate-detection>true</use-duplicate-detection> + <forward-when-no-consumers>true</forward-when-no-consumers> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </code> + </pre> + <p>For more information on HornetQ load balancing, and clustering in general, please see the clustering + section of the user manual.</p> + + <h2>Example step-by-step</h2> + <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p> + + <ol> + <li> Get an initial context for looking up JNDI from server 0.</li> + <pre class="prettyprint"> + <code> + ic0 = getContext(0); + </code> + </pre> + + <li>Look-up the JMS Topic object from JNDI</li> + <pre class="prettyprint"> + <code>Topic topic = (Topic)ic0.lookup("/topic/exampleTopic");</code> + </pre> + + <li>Look-up a JMS Connection Factory object from JNDI on server 0</li> + <pre class="prettyprint"> + <code>ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");</code> + </pre> + + <li>Get an initial context for looking up JNDI from server 1.</li> + <pre class="prettyprint"> + <code>ic1 = getContext(1);</code> + </pre> + + <li>Look-up a JMS Connection Factory object from JNDI on server 1</li> + <pre class="prettyprint"> + <code>ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory"); + </code> + </pre> + + <li>We create a JMS Connection connection0 which is a connection to server 0 + and set the same client-id.</li> + <pre class="prettyprint"> + <code> + connection0 = cf0.createConnection(); + final String clientID = "my-client-id"; + connection0.setClientID(clientID); + </code> + </pre> + + <li>We create a JMS Connection connection1 which is a connection to server 1 + and set the same client-id.</li> + <pre class="prettyprint"> + <code> + connection1 = cf1.createConnection(); + connection1.setClientID(clientID); + </code> + </pre> + + <li>We create a JMS Session on server 0</li> + <pre class="prettyprint"> + <code> + Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE); + </code> + </pre> + + <li>We create a JMS Session on server 1</li> + <pre class="prettyprint"> + <code> + Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + </code> + </pre> + + <li>We start the connections to ensure delivery occurs on them</li> + <pre class="prettyprint"> + <code> + connection0.start(); + + connection1.start(); + </code> + </pre> + + <li>We create JMS durable subscriptions with the same name and client-id on both nodes + of the cluster + </li> + <pre class="prettyprint"> + <code> + final String subscriptionName = "my-subscription"; + + MessageConsumer subscriber0 = session0.createDurableSubscriber(topic, subscriptionName); + + MessageConsumer subscriber1 = session1.createDurableSubscriber(topic, subscriptionName); + </code> + </pre> + + <li>We create a JMS MessageProducer object on server 0.</li> + <pre class="prettyprint"> + <code> + MessageProducer producer = session0.createProducer(topic);</code> + </pre> + + <li>We send some messages to server 0.</li> + <pre class="prettyprint"> + <code> + final int numMessages = 10; + + for (int i = 0; i < numMessages; i++) + { + TextMessage message = session0.createTextMessage("This is text message " + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + </code> + </pre> + + <li> + We now consume those messages on *both* server 0 and server 1. + Note that the messages have been load-balanced between the two nodes, with some + messages on node 0 and others on node 1. + The "logical" subscription is distributed across the cluster an contains exactly one copy of all the messages sent. + </li> + <pre class="prettyprint"> + <code> + for (int i = 0; i < numMessages; i += 2) + { + TextMessage message0 = (TextMessage)consumer0.receive(5000); + + System.out.println("Got message: " + message0.getText() + " from node 0"); + + TextMessage message1 = (TextMessage)consumer1.receive(5000); + + System.out.println("Got message: " + message1.getText() + " from node 1"); + } + </code> + </pre> + + <li>And finally (no pun intended), <b>always</b> remember to close your JMS 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 + { + if (connection0 != null) + { + connection0.close(); + } + + if (connection1 != null) + { + connection1.close(); + } + } + </code> + </pre> + + </ol> + </body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/java/org/hornetq/jms/example/ClusteredDurableSubscriptionExample.java ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/java/org/hornetq/jms/example/ClusteredDurableSubscriptionExample.java b/examples/jms/clustered-durable-subscription/src/main/java/org/hornetq/jms/example/ClusteredDurableSubscriptionExample.java new file mode 100644 index 0000000..54ee927 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/java/org/hornetq/jms/example/ClusteredDurableSubscriptionExample.java @@ -0,0 +1,165 @@ +/* + * Copyright 2005-2014 Red Hat, Inc. + * Red Hat 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.hornetq.jms.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.naming.InitialContext; + +import org.hornetq.common.example.HornetQExample; + +/** + * A simple example that shows a JMS Durable Subscription across two nodes of a cluster. + * + * The same durable subscription can exist on more than one node of the cluster, and messages + * sent to the topic will be load-balanced in a round-robin fashion between the two nodes + * + * @author <a href="tim....@jboss.com>Tim Fox</a> + */ +public class ClusteredDurableSubscriptionExample extends HornetQExample +{ + public static void main(final String[] args) + { + new ClusteredDurableSubscriptionExample().run(args); + } + + @Override + public boolean runExample() throws Exception + { + Connection connection0 = null; + + Connection connection1 = null; + + InitialContext ic0 = null; + + InitialContext ic1 = null; + + try + { + // Step 1. Get an initial context for looking up JNDI from server 0 + ic0 = getContext(0); + + // Step 2. Look-up the JMS Topic object from JNDI + Topic topic = (Topic)ic0.lookup("/topic/exampleTopic"); + + // Step 3. Look-up a JMS Connection Factory object from JNDI on server 0 + ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory"); + + // Step 4. Get an initial context for looking up JNDI from server 1 + ic1 = getContext(1); + + // Step 5. Look-up a JMS Connection Factory object from JNDI on server 1 + ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory"); + + // Step 6. We create a JMS Connection connection0 which is a connection to server 0 + // and set the client-id + connection0 = cf0.createConnection(); + + final String clientID = "my-client-id"; + + connection0.setClientID(clientID); + + // Step 7. We create a JMS Connection connection1 which is a connection to server 1 + // and set the same client-id + connection1 = cf1.createConnection(); + + connection1.setClientID(clientID); + + // Step 8. We create a JMS Session on server 0 + Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 9. We create a JMS Session on server 1 + Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 10. We start the connections to ensure delivery occurs on them + connection0.start(); + + connection1.start(); + + // Step 11. We create JMS durable subscriptions with the same name and client-id on both nodes + // of the cluster + + final String subscriptionName = "my-subscription"; + + MessageConsumer subscriber0 = session0.createDurableSubscriber(topic, subscriptionName); + + MessageConsumer subscriber1 = session1.createDurableSubscriber(topic, subscriptionName); + + Thread.sleep(1000); + + // Step 12. We create a JMS MessageProducer object on server 0 + MessageProducer producer = session0.createProducer(topic); + + // Step 13. We send some messages to server 0 + + final int numMessages = 10; + + for (int i = 0; i < numMessages; i++) + { + TextMessage message = session0.createTextMessage("This is text message " + i); + + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + } + + // Step 14. We now consume those messages on *both* server 0 and server 1. + // Note that the messages have been load-balanced between the two nodes, with some + // messages on node 0 and others on node 1. + // The "logical" subscription is distributed across the cluster an contains exactly one copy of all the + // messages + + for (int i = 0; i < numMessages; i += 2) + { + TextMessage message0 = (TextMessage)subscriber0.receive(5000); + + System.out.println("Got message: " + message0.getText() + " from node 0"); + + TextMessage message1 = (TextMessage)subscriber1.receive(5000); + + System.out.println("Got message: " + message1.getText() + " from node 1"); + } + + return true; + } + finally + { + // Step 15. Be sure to close our JMS resources! + if (connection0 != null) + { + connection0.close(); + } + + if (connection1 != null) + { + connection1.close(); + } + + if (ic0 != null) + { + ic0.close(); + } + + if (ic1 != null) + { + ic1.close(); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-configuration.xml b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-configuration.xml new file mode 100644 index 0000000..a6eeb26 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-configuration.xml @@ -0,0 +1,75 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd"> + + <bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory> + + + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5445"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5445"/> + </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> + <forward-when-no-consumers>true</forward-when-no-consumers> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- other configuration --> + + <security-settings> + <!--security for example queue--> + <security-setting match="jms.topic.exampleTopic"> + <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> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-jms.xml b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-jms.xml new file mode 100644 index 0000000..f89d475 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-jms.xml @@ -0,0 +1,19 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty-connector"/> + </connectors> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the topic used by the example--> + <topic name="exampleTopic"> + <entry name="/topic/exampleTopic"/> + </topic> + +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-users.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-users.xml b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-users.xml new file mode 100644 index 0000000..934306c --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server0/hornetq-users.xml @@ -0,0 +1,7 @@ +<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd"> + <!-- the default user. this is used where username is null--> + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-configuration.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-configuration.xml b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-configuration.xml new file mode 100644 index 0000000..e949a05 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-configuration.xml @@ -0,0 +1,76 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd"> + + + + <bindings-directory>${build.directory}/server1/data/messaging/bindings</bindings-directory> + + <journal-directory>${build.directory}/server1/data/messaging/journal</journal-directory> + + <large-messages-directory>${build.directory}/server1/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${build.directory}/server1/data/messaging/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> + <param key="port" value="5446"/> + </connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor"> + <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> + <param key="port" value="5446"/> + </acceptor> + </acceptors> + + <!-- Clustering configuration --> + <broadcast-groups> + <broadcast-group name="my-broacast-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> + <forward-when-no-consumers>true</forward-when-no-consumers> + <max-hops>1</max-hops> + <discovery-group-ref discovery-group-name="my-discovery-group"/> + </cluster-connection> + </cluster-connections> + + <!-- other configuration --> + + <security-settings> + <!--security for example queue--> + <security-setting match="jms.topic.exampleTopic"> + <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> + + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-jms.xml ---------------------------------------------------------------------- diff --git a/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-jms.xml b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-jms.xml new file mode 100644 index 0000000..f89d475 --- /dev/null +++ b/examples/jms/clustered-durable-subscription/src/main/resources/hornetq/server1/hornetq-jms.xml @@ -0,0 +1,19 @@ +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty-connector"/> + </connectors> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the topic used by the example--> + <topic name="exampleTopic"> + <entry name="/topic/exampleTopic"/> + </topic> + +</configuration> \ No newline at end of file