[jboss-cvs] JBoss Messaging SVN: r6431 - in trunk: examples/jms and 21 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Apr 15 08:27:48 EDT 2009
Author: timfox
Date: 2009-04-15 08:27:47 -0400 (Wed, 15 Apr 2009)
New Revision: 6431
Added:
trunk/examples/jms/reconnect-same-node/
trunk/examples/jms/reconnect-same-node/build.xml
trunk/examples/jms/reconnect-same-node/readme.html
trunk/examples/jms/reconnect-same-node/server0/
trunk/examples/jms/reconnect-same-node/server0/client-jndi.properties
trunk/examples/jms/reconnect-same-node/server0/jbm-configuration.xml
trunk/examples/jms/reconnect-same-node/server0/jbm-jms.xml
trunk/examples/jms/reconnect-same-node/server0/jbm-queues.xml
trunk/examples/jms/reconnect-same-node/server0/jbm-security.xml
trunk/examples/jms/reconnect-same-node/server0/jbm-standalone-beans.xml
trunk/examples/jms/reconnect-same-node/src/
trunk/examples/jms/reconnect-same-node/src/org/
trunk/examples/jms/reconnect-same-node/src/org/jboss/
trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/
trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/example/
trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/example/ReconnectSameNodeExample.java
Modified:
trunk/.classpath
trunk/examples/jms/clustered-durable-subscription/src/org/jboss/jms/example/ClusteredDurableSubscriptionExample.java
trunk/examples/jms/clustered-queue/src/org/jboss/jms/example/ClusteredQueueExample.java
trunk/examples/jms/clustered-topic/src/org/jboss/jms/example/ClusteredTopicExample.java
trunk/examples/jms/common/src/org/jboss/jms/example/JMSExample.java
trunk/examples/jms/queue/src/org/jboss/jms/example/QueueExample.java
trunk/src/main/org/jboss/messaging/core/client/impl/ConnectionManagerImpl.java
trunk/src/main/org/jboss/messaging/core/deployers/impl/AddressSettingsDeployer.java
trunk/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java
trunk/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java
trunk/src/main/org/jboss/messaging/integration/transports/netty/NettyAcceptor.java
trunk/src/main/org/jboss/messaging/jms/server/impl/JMSServerDeployer.java
trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSManagementHelper.java
trunk/src/schemas/jbm-configuration.xsd
trunk/src/schemas/jbm-jms.xsd
trunk/tests/src/org/jboss/messaging/tests/integration/cluster/failover/ReconnectTest.java
Log:
reconnect example
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/.classpath 2009-04-15 12:27:47 UTC (rev 6431)
@@ -26,6 +26,7 @@
<classpathentry kind="src" path="examples/jms/clustered-durable-subscription/src"/>
<classpathentry kind="src" path="examples/jms/queue-message-redistribution/src"/>
<classpathentry kind="src" path="examples/jms/client-side-load-balancing/src"/>
+ <classpathentry kind="src" path="examples/jms/reconnect-same-node/src"/>
<classpathentry kind="src" path="examples/jms/browser/src"/>
<classpathentry kind="src" path="examples/jms/durable-subscription/src"/>
<classpathentry kind="src" path="examples/jms/common/src"/>
Modified: trunk/examples/jms/clustered-durable-subscription/src/org/jboss/jms/example/ClusteredDurableSubscriptionExample.java
===================================================================
--- trunk/examples/jms/clustered-durable-subscription/src/org/jboss/jms/example/ClusteredDurableSubscriptionExample.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/examples/jms/clustered-durable-subscription/src/org/jboss/jms/example/ClusteredDurableSubscriptionExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -36,6 +36,7 @@
* 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.fox at jboss.com>Tim Fox</a>
*/
public class ClusteredDurableSubscriptionExample extends JMSExample
{
Modified: trunk/examples/jms/clustered-queue/src/org/jboss/jms/example/ClusteredQueueExample.java
===================================================================
--- trunk/examples/jms/clustered-queue/src/org/jboss/jms/example/ClusteredQueueExample.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/examples/jms/clustered-queue/src/org/jboss/jms/example/ClusteredQueueExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -23,7 +23,6 @@
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
-import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
Modified: trunk/examples/jms/clustered-topic/src/org/jboss/jms/example/ClusteredTopicExample.java
===================================================================
--- trunk/examples/jms/clustered-topic/src/org/jboss/jms/example/ClusteredTopicExample.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/examples/jms/clustered-topic/src/org/jboss/jms/example/ClusteredTopicExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -34,6 +34,7 @@
* A simple example that shows a JMS Topic clustered across two nodes of a cluster.
* Messages are sent on one node and received by consumers on both nodes.
*
+ * @author <a href="tim.fox at jboss.com>Tim Fox</a>
*/
public class ClusteredTopicExample extends JMSExample
{
Modified: trunk/examples/jms/common/src/org/jboss/jms/example/JMSExample.java
===================================================================
--- trunk/examples/jms/common/src/org/jboss/jms/example/JMSExample.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/examples/jms/common/src/org/jboss/jms/example/JMSExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -23,8 +23,6 @@
import java.io.File;
import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
@@ -48,20 +46,38 @@
private boolean failure = false;
public abstract boolean runExample() throws Exception;
-
- protected void run(String[] serverVMArgs, String[] args)
+
+ private boolean logServerOutput;
+
+ private String[] allVMArgs;
+
+ private String[] configs;
+
+ protected void run(String[] serverVMArgs, String[] configs)
{
String runServerProp = System.getProperty("jbm.example.runServer");
String logServerOutputProp = System.getProperty("jbm.example.logserveroutput");
boolean runServer = runServerProp == null ? true : Boolean.valueOf(runServerProp);
- boolean logServerOutput = logServerOutputProp == null?false:Boolean.valueOf(logServerOutputProp);
+ logServerOutput = logServerOutputProp == null?false:Boolean.valueOf(logServerOutputProp);
log.info("jbm.example.runServer is " + runServer);
+
+ allVMArgs = new String[serverVMArgs == null ? 1 : serverVMArgs.length + 1];
+ if (serverVMArgs != null)
+ {
+ System.arraycopy(serverVMArgs, 0, allVMArgs, 0, serverVMArgs.length);
+ }
+ String logProps = System.getProperty("java.util.logging.config.file");
+ allVMArgs[allVMArgs.length - 1] = "-Djava.util.logging.config.file=" + logProps;
+
+ this.configs = configs;
+
try
{
if (runServer)
{
- startServers(serverVMArgs, args, logServerOutput);
+ startServers();
}
+
if (!runExample())
{
failure = true;
@@ -89,7 +105,7 @@
{
try
{
- stopServer();
+ stopServers();
}
catch (Throwable throwable)
{
@@ -117,6 +133,13 @@
file.createNewFile();
}
+ protected void stopServer(int id) throws Exception
+ {
+ System.out.println("Stopping server " + id);
+
+ stopServer(servers[id]);
+ }
+
protected InitialContext getContext(int serverId) throws Exception
{
String jndiFilename = "server" + serverId + "/client-jndi.properties";
@@ -138,52 +161,52 @@
}
return new InitialContext(props);
}
-
- private void startServers(String[] vmArgs, String[] args, boolean logServerOutput) throws Throwable
+
+ protected void startServer(int index) throws Exception
{
- List<String> allVMArgsList = new ArrayList<String>();
- if (vmArgs != null)
+ String config = configs[index];
+ log.info("starting server with config '" + config + "' " + "logServerOutput " + logServerOutput);
+ servers[index] = SpawnedVMSupport.spawnVM(
+ SpawnedJMSServer.class.getName(),
+ allVMArgs,
+ logServerOutput,
+ "STARTED::",
+ "FAILED::",
+ config,
+ "jbm-standalone-beans.xml");
+ }
+
+ private void startServers() throws Exception
+ {
+ servers = new Process[configs.length];
+ for (int i = 0; i < configs.length; i++)
{
- for (String arg : vmArgs)
- {
- allVMArgsList.add(arg);
- }
- }
- String logProps = System.getProperty("java.util.logging.config.file");
- allVMArgsList.add("-Djava.util.logging.config.file=" + logProps);
- String[] allVMArgs = (String[])allVMArgsList.toArray(new String[allVMArgsList.size()]);
-
- servers = new Process[args.length];
- for (int i = 0; i < args.length; i++)
- {
- log.info("starting server with config '" + args[i] + "' " + "logServerOutput " + logServerOutput);
- servers[i] = SpawnedVMSupport.spawnVM(
- SpawnedJMSServer.class.getName(),
- allVMArgs,
- logServerOutput,
- "STARTED::",
- "FAILED::",
- args[i],
- "jbm-standalone-beans.xml");
+ startServer(i);
}
}
-
- private void stopServer() throws Throwable
+
+ private void stopServers() throws Exception
{
for (Process server : servers)
{
- if (server.getInputStream() != null)
- {
- server.getInputStream().close();
- }
- if (server.getErrorStream() != null)
- {
- server.getErrorStream().close();
- }
- server.destroy();
+ stopServer(server);
}
}
+ private void stopServer(Process server) throws Exception
+ {
+ if (server.getInputStream() != null)
+ {
+ server.getInputStream().close();
+ }
+ if (server.getErrorStream() != null)
+ {
+ server.getErrorStream().close();
+ }
+ server.destroy();
+ }
+
+
private void reportResultAndExit()
{
if (failure)
Modified: trunk/examples/jms/queue/src/org/jboss/jms/example/QueueExample.java
===================================================================
--- trunk/examples/jms/queue/src/org/jboss/jms/example/QueueExample.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/examples/jms/queue/src/org/jboss/jms/example/QueueExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -85,8 +85,6 @@
System.out.println("Received message: " + messageReceived.getText());
- initialContext.close();
-
return true;
}
finally
Added: trunk/examples/jms/reconnect-same-node/build.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/build.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/build.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE project [
+ <!ENTITY libraries SYSTEM "../../../thirdparty/libraries.ent">
+ ]>
+
+<!-- =========================================================================================== -->
+<!-- -->
+<!-- JBoss, Home of Professional Open Source -->
+<!-- Copyright 2005, JBoss Inc., and individual contributors as indicated -->
+<!-- by the @authors tag. See the copyright.txt in the distribution for a -->
+<!-- full listing of individual contributors. -->
+<!-- -->
+<!-- This is free software; you can redistribute it and/or modify it -->
+<!-- under the terms of the GNU Lesser General Public License as -->
+<!-- published by the Free Software Foundation; either version 2.1 of -->
+<!-- the License, or (at your option) any later version. -->
+<!-- -->
+<!-- This software is distributed in the hope that it will be useful, -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -->
+<!-- Lesser General Public License for more details. -->
+<!-- -->
+<!-- You should have received a copy of the GNU Lesser General Public -->
+<!-- License along with this software; if not, write to the Free -->
+<!-- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -->
+<!-- 02110-1301 USA, or see the FSF site: http://www.fsf.org. -->
+<!-- -->
+<!-- =========================================================================================== -->
+
+
+<project default="run" name="JBoss Messaging Reconnect Same Node Example">
+
+ <import file="../common/build.xml"/>
+
+ <target name="run">
+ <antcall target="runExample">
+ <param name="example.classname" value="org.jboss.jms.example.ReconnectSameNodeExample"/>
+ </antcall>
+ </target>
+
+ <target name="runRemote">
+ <antcall target="runExample">
+ <param name="example.classname" value="org.jboss.jms.example.ReconnectSameNodeExample"/>
+ <param name="jbm.example.runServer" value="false"/>
+ </antcall>
+ </target>
+
+</project>
\ No newline at end of file
Added: trunk/examples/jms/reconnect-same-node/readme.html
===================================================================
--- trunk/examples/jms/reconnect-same-node/readme.html (rev 0)
+++ trunk/examples/jms/reconnect-same-node/readme.html 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,134 @@
+<html>
+ <head>
+ <title>JBoss Messaging JMS Automatic Reconnect Same Server Example</title>
+ <link rel="stylesheet" type="text/css" href="../common/common.css">
+ </head>
+ <body>
+ <h1>JBoss Messaging JMS Reconnect Same Server Example</h1>
+ <br>
+ <p>This example demonstrates how JBoss Messaging connections can be configured to be resilient to
+ temporary network failures.</p>
+ <p>In the case of a network failure being detected, either as a result of a failure to read/write to the connection,
+ or the failure of a pong to arrive back from the server in good time after a ping is sent, instead of
+ failing the connection immediately and notifying any user ExceptionListener objects, JBoss Messaging
+ can be configured to automatically retry the connection, and reconnect to the server when it becomes
+ available again across the network.</p>
+ <p>In the case that the server didn't actually crash, i.e. the network was temporarily unavailable, the client will
+ be able to resume all its sessions and connections where it left off, 100% transparently.</p>
+ <p>This is very similar to automatic failover, the difference being with automatic failover the reconnection
+ is to a different server, but in this cases the reconnection is to the <b>same</b> server</p>
+ <p>In the case that the server <b>did</b> crash and was restarted, on reconnection the server session
+ clearly won't still exist, so the session will be unable to continue transparently, and any registered
+ ExceptionListener will be called, to allow any application layer reconnect logic to be called.</p>
+ <p>This example starts a single server, connects to it and performs some JMS operations. We then
+ simulate failure of the network connection by temporarily stopping the network acceptor on the server.
+ (This is done by sending management messages, but that is not central to the purpose of the example).</p>
+ <p>We then wait a few seconds, then restart the acceptor. The client reconnects and the session resumes
+ as if nothing happened.</p>
+ <p>The JMS Connection Factory is configured to reconnect automatically by specifying the various reconnect
+ related attributes in the <code>jbm-jms.xml</code> file.</p>
+
+ <p>For more details on how to configure this and for clustering in general
+ please consult the JBoss Messaging user manual.</p>
+
+ <br>
+ <h2>Example step-by-step</h2>
+ <p><i>To run the example, simply type <code>ant</code> from this directory</i></p>
+ <br>
+ <ol>
+ <li>Create an initial context to perform the JNDI lookup.</li>
+ <pre>
+ <code>initialContext = getContext(0);</code>
+ </pre>
+
+ <li>Perform a lookup on the queue</li>
+ <pre>
+ <code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code>
+ </pre>
+
+ <li>Perform a lookup on the Connection Factory</li>
+ <pre>
+ <code>ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code>
+ </pre>
+
+ <li>We create a JMS connection</li>
+ <pre>
+ <code>connection = cf.createConnection();</code>
+ </pre>
+
+ <li>We create a JMS session. </li>
+ <pre>
+ <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code>
+ </pre>
+
+ <li>We create a JMS message producer.</li>
+ <pre>
+ <code>MessageProducer messageProducer = session.createProducer(topic);</code>
+ </pre>
+
+ <li>We create a JMS text message that we are going to send.</li>
+ <pre>
+ <code>TextMessage message = session.createTextMessage("This is a text message");</code>
+ </pre>
+
+ <li>We send message to the queue</li>
+ <pre>
+ <code>messageProducer.send(message);</code>
+ </pre>
+
+ <li>We create a JMS Message Consumer to receive the message.</li>
+ <pre>
+ <code>MessageConsumer messageConsumer = session.createConsumer(queue);</code>
+ </pre>
+
+ <li>We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started</li>
+ <pre>
+ <code>connection.start();</code>
+ </pre>
+
+ <li>To simulate a temporary problem on the network, we stop the remoting acceptor on the
+ server which will casue all client connections to fail.</li>
+ <pre>
+ <code>stopAcceptor(initialContext);</code>
+ </pre>
+
+ <li>We wait 10 seconds, before restarting the acceptor. During this period the client will be retrying
+ to connect. When the acceptor is restarted it will be successful in reconnecting.</li>
+
+ <pre>
+ <code>
+ Thread.sleep(10000);
+
+ startAcceptor(initialContext);
+ </code>
+ </pre>
+
+ <li>We receive the message after reconnection! Note that no exceptions were received by the client.</li>
+
+ <pre>
+ <code>
+ TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
+ </code>
+ </pre>
+
+ <li>And finally, <b>always</b> remember to close your JMS connections and 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>
+ <code>finally
+ {
+ if (initialContext != null)
+ {
+ initialContext.close();
+ }
+ if (connection != null)
+ {
+ connection.close();
+ }
+ }</code>
+ </pre>
+
+
+
+ </ol>
+ </body>
+</html>
\ No newline at end of file
Added: trunk/examples/jms/reconnect-same-node/server0/client-jndi.properties
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/client-jndi.properties (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/client-jndi.properties 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,3 @@
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.provider.url=jnp://localhost:1099
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
Added: trunk/examples/jms/reconnect-same-node/server0/jbm-configuration.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/jbm-configuration.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/jbm-configuration.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,40 @@
+<deployment xmlns="urn:jboss:messaging"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:messaging ../schemas/jbm-configuration.xsd">
+ <configuration>
+
+ <!-- Connectors -->
+
+ <connector name="netty-connector">
+ <factory-class>org.jboss.messaging.integration.transports.netty.NettyConnectorFactory</factory-class>
+ <param key="jbm.remoting.netty.port" value="5445" type="Integer"/>
+ </connector>
+
+ <!-- We just use this connector so we can send management operations while the other acceptor
+ is stopped -->
+ <connector name="netty-connector2">
+ <factory-class>org.jboss.messaging.integration.transports.netty.NettyConnectorFactory</factory-class>
+ <param key="jbm.remoting.netty.port" value="5446" type="Integer"/>
+ </connector>
+
+ <!-- Acceptors -->
+
+ <acceptor name="netty-acceptor">
+ <factory-class>org.jboss.messaging.integration.transports.netty.NettyAcceptorFactory</factory-class>
+ <param key="jbm.remoting.netty.port" value="5445" type="Integer"/>
+ </acceptor>
+
+ <!-- We just use this acceptor so we can send management operations while the other acceptor
+ is stopped -->
+ <acceptor name="netty-acceptor2">
+ <factory-class>org.jboss.messaging.integration.transports.netty.NettyAcceptorFactory</factory-class>
+ <param key="jbm.remoting.netty.port" value="5446" type="Integer"/>
+ </acceptor>
+
+ <!-- Other config -->
+
+ <journal-min-files>2</journal-min-files>
+
+ </configuration>
+
+</deployment>
Added: trunk/examples/jms/reconnect-same-node/server0/jbm-jms.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/jbm-jms.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/jbm-jms.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,40 @@
+<deployment xmlns="urn:jboss:messaging"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:messaging ../schemas/jbm-jms.xsd ">
+ <!--the connection factory used by the example-->
+ <connection-factory name="ConnectionFactory">
+ <connector-ref connector-name="netty-connector"/>
+ <entry name="ConnectionFactory"/>
+ <entry name="XAConnectionFactory"/>
+ <entry name="java:/ConnectionFactory"/>
+ <entry name="java:/XAConnectionFactory"/>
+
+ <!-- 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>
+
+ <!-- When the server is cleanly shutdown we don't want to give up, we want to continue
+ to try to reconnect -->
+ <failover-on-server-shutdown>true</failover-on-server-shutdown>
+
+ </connection-factory>
+
+ <!-- This is used by the example to send the management operations, it's not central to the example -->
+ <connection-factory name="ConnectionFactory2">
+ <connector-ref connector-name="netty-connector2"/>
+ <entry name="ConnectionFactory2"/>
+ </connection-factory>
+
+ <!--the queue used by the example-->
+ <queue name="exampleQueue">
+ <entry name="/queue/exampleQueue"/>
+ </queue>
+
+</deployment>
\ No newline at end of file
Added: trunk/examples/jms/reconnect-same-node/server0/jbm-queues.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/jbm-queues.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/jbm-queues.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,22 @@
+<settings xmlns="urn:jboss:messaging"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:messaging ../schemas/jbm-queues.xsd ">
+
+ <!--security for example queue-->
+ <security match="jms.queue.exampleQueue">
+ <permission type="createDurableQueue" roles="guest"/>
+ <permission type="deleteDurableQueue" roles="guest"/>
+ <permission type="createTempQueue" roles="guest"/>
+ <permission type="deleteTempQueue" roles="guest"/>
+ <permission type="consume" roles="guest"/>
+ <permission type="send" roles="guest"/>
+ </security>
+
+ <security match="jbm.management">
+ <!-- only the admin role can interact with the management address -->
+ <permission type="consume" roles="admin"/>
+ <permission type="send" roles="admin"/>
+ <permission type="manage" roles="admin"/>
+ </security>
+
+</settings>
Added: trunk/examples/jms/reconnect-same-node/server0/jbm-security.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/jbm-security.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/jbm-security.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,11 @@
+<deployment xmlns="urn:jboss:messaging" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:messaging ../schemas/jbm-security.xsd ">
+ <!-- the default user. this is used where username is null-->
+ <defaultuser name="guest" password="guest">
+ <role name="guest"/>
+
+ <!-- We give guest the admin role so it can do management operations for the example -
+ you don't want to do this in real life -->
+ <role name="admin"/>
+ </defaultuser>
+</deployment>
\ No newline at end of file
Added: trunk/examples/jms/reconnect-same-node/server0/jbm-standalone-beans.xml
===================================================================
--- trunk/examples/jms/reconnect-same-node/server0/jbm-standalone-beans.xml (rev 0)
+++ trunk/examples/jms/reconnect-same-node/server0/jbm-standalone-beans.xml 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+
+ <bean name="Naming" class="org.jnp.server.NamingBeanImpl"/>
+
+ <!-- JNDI server. Disable this if you don't want JNDI -->
+ <bean name="JNDIServer" class="org.jnp.server.Main">
+ <property name="namingInfo">
+ <inject bean="Naming"/>
+ </property>
+ <property name="port">1099</property>
+ <property name="bindAddress">localhost</property>
+ <property name="rmiPort">1098</property>
+ <property name="rmiBindAddress">localhost</property>
+ </bean>
+
+ <!-- MBean server -->
+ <bean name="MBeanServer" class="javax.management.MBeanServer">
+ <constructor factoryClass="java.lang.management.ManagementFactory"
+ factoryMethod="getPlatformMBeanServer"/>
+ </bean>
+
+ <!-- The core configuration -->
+ <bean name="Configuration" class="org.jboss.messaging.core.config.impl.FileConfiguration"/>
+
+ <!-- The security manager -->
+ <bean name="JBMSecurityManager" class="org.jboss.messaging.core.security.impl.JBMSecurityManagerImpl">
+ <start ignored="true"/>
+ <stop ignored="true"/>
+ </bean>
+
+ <!-- The core server -->
+ <bean name="MessagingServer" class="org.jboss.messaging.core.server.impl.MessagingServerImpl">
+ <constructor>
+ <parameter>
+ <inject bean="Configuration"/>
+ </parameter>
+ <parameter>
+ <inject bean="MBeanServer"/>
+ </parameter>
+ <parameter>
+ <inject bean="JBMSecurityManager"/>
+ </parameter>
+ </constructor>
+ </bean>
+
+ <!-- The JMS server -->
+ <bean name="JMSServerManager" class="org.jboss.messaging.jms.server.impl.JMSServerManagerImpl">
+ <constructor>
+ <parameter>
+ <inject bean="MessagingServer"/>
+ </parameter>
+ </constructor>
+ </bean>
+
+</deployment>
Added: trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/example/ReconnectSameNodeExample.java
===================================================================
--- trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/example/ReconnectSameNodeExample.java (rev 0)
+++ trunk/examples/jms/reconnect-same-node/src/org/jboss/jms/example/ReconnectSameNodeExample.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+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.jboss.messaging.jms.JBossQueue;
+import org.jboss.messaging.jms.server.management.impl.JMSManagementHelper;
+
+/**
+ * This examples demonstrates a connection created to a server. Failure of the network connection is then simulated
+ *
+ * The network is brought back up and the client reconnects and resumes transparently.
+ *
+ * @author <a href="tim.fox at jboss.com>Tim Fox</a>
+ */
+public class ReconnectSameNodeExample extends JMSExample
+{
+ public static void main(String[] args)
+ {
+ new ReconnectSameNodeExample().run(args);
+ }
+
+ public boolean runExample() throws Exception
+ {
+ Connection connection = null;
+ InitialContext initialContext = null;
+
+ try
+ {
+ // Step 1. Create an initial context to perform the JNDI lookup.
+ initialContext = getContext(0);
+
+ // Step 2. Perform a lookup on the queue
+ Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
+
+ // Step 3. Perform a lookup on the Connection Factory
+ ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
+
+ // Step 4. Create a JMS Connection
+ connection = cf.createConnection();
+
+ // Step 5. Create a JMS Session
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // Step 6. Create a JMS Message Producer
+ MessageProducer producer = session.createProducer(queue);
+
+ // Step 7. Create a Text Message
+ TextMessage message = session.createTextMessage("This is a text message");
+
+ System.out.println("Sent message: " + message.getText());
+
+ // Step 8. Send the Message
+ producer.send(message);
+
+ // Step 9. Create a JMS Message Consumer
+ MessageConsumer messageConsumer = session.createConsumer(queue);
+
+ // Step 10. Start the Connection
+ connection.start();
+
+ // Step 11. To simulate a temporary problem on the network, we stop the remoting acceptor on the
+ // server which will close all connections
+ stopAcceptor(initialContext);
+
+ System.out.println("Acceptor now stopped, will wait for 10 seconds. This simulates the network connection failing for a while");
+
+ // Step 12. Wait a while then restart the acceptor
+ Thread.sleep(10000);
+
+ System.out.println("Re-starting acceptor");
+
+ startAcceptor(initialContext);
+
+ System.out.println("Restarted acceptor. The client will now reconnect.");
+
+ // Step 13. We receive the message
+ TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
+
+ System.out.println("Received message: " + messageReceived.getText());
+
+ return true;
+ }
+ finally
+ {
+ // Step 14. Be sure to close our JMS resources!
+ if (initialContext != null)
+ {
+ initialContext.close();
+ }
+
+ if (connection != null)
+ {
+ connection.close();
+ }
+ }
+ }
+
+ private void stopAcceptor(InitialContext ic) throws Exception
+ {
+ this.stopStartAcceptor(ic, true);
+ }
+
+ private void startAcceptor(InitialContext ic) throws Exception
+ {
+ this.stopStartAcceptor(ic, false);
+ }
+
+ // To do this we send a management message to close the acceptor, we do this on a different
+ // connection factory which uses a different remoting connection so we can still send messages
+ // when the main connection has been stopped
+ private void stopStartAcceptor(InitialContext initialContext, boolean stop) throws Exception
+ {
+ ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory2");
+
+ Connection connection = null;
+ try
+ {
+ connection = cf.createConnection();
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Queue managementQueue = new JBossQueue("jbm.management", "jbm.management");
+
+ MessageProducer producer = session.createProducer(managementQueue);
+
+ connection.start();
+
+ Message m = session.createMessage();
+
+ String oper = stop ? "stop" : "start";
+
+ JMSManagementHelper.putOperationInvocation(m, "core.acceptor.netty-acceptor", oper);
+
+ producer.send(m);
+ }
+ finally
+ {
+ if (connection != null)
+ {
+ connection.close();
+ }
+ }
+ }
+
+}
Modified: trunk/src/main/org/jboss/messaging/core/client/impl/ConnectionManagerImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/client/impl/ConnectionManagerImpl.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/core/client/impl/ConnectionManagerImpl.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -150,8 +150,6 @@
private boolean inFailoverOrReconnect;
- private volatile boolean failureSignalled;
-
// debug
private static Map<TransportConfiguration, Set<RemotingConnection>> debugConns;
@@ -278,21 +276,9 @@
if (connection == null)
{
- if (!failureSignalled)
- {
- // This can happen if the connection manager gets closed - e.g. the server gets shut down
+ // This can happen if the connection manager gets closed - e.g. the server gets shut down
- throw new MessagingException(MessagingException.NOT_CONNECTED, "Unable to connect to server");
- }
- else
- {
- // This means an async failure came in while getConnectionForCreateSession was executing, we
- // need
- // to allow the failover/reconnection to occur and let the create session retry after
- retry = true;
-
- continue;
- }
+ throw new MessagingException(MessagingException.NOT_CONNECTED, "Unable to connect to server");
}
channel1 = connection.getChannel(1, -1, false);
@@ -468,10 +454,8 @@
// --------------------------------------------------------------------------------------
private boolean handleConnectionFailure(final MessagingException me, final Object connectionID)
- {
- boolean callNext = !failoverOrReconnect(me, connectionID);
-
- return callNext;
+ {
+ return !failoverOrReconnect(me, connectionID);
}
private boolean failoverOrReconnect(final MessagingException me, final Object connectionID)
@@ -482,23 +466,17 @@
return false;
}
- if (connectionID != null && !connections.containsKey(connectionID))
- {
- // We already failed over/reconnected - probably the first failure came in, all the connections were failed
- // over then a async connection exception or disconnect
- // came in for one of the already closed connections, so we return true - we don't want to call the
- // listeners again
-
- return true;
- }
-
- failureSignalled = true;
-
synchronized (failoverLock)
{
- failureSignalled = false;
+ if (connectionID != null && !connections.containsKey(connectionID))
+ {
+ // We already failed over/reconnected - probably the first failure came in, all the connections were failed
+ // over then a async connection exception or disconnect
+ // came in for one of the already closed connections, so we return true - we don't want to call the
+ // listeners again
- inFailoverOrReconnect = true;
+ return true;
+ }
// Now get locks on all channel 1s, whilst holding the failoverLock - this makes sure
// There are either no threads executing in createSession, or one is blocking on a createSession
@@ -599,10 +577,12 @@
done = reattachSessions(reconnectAttempts == -1 ? -1 : reconnectAttempts + 1);
}
else if (reconnectAttempts != 0)
- {
+ {
done = reattachSessions(reconnectAttempts);
}
+ inFailoverOrReconnect = true;
+
if (done)
{
// Destroy the old connections
@@ -728,7 +708,7 @@
while (true)
{
- if (closed || failureSignalled)
+ if (closed)
{
return null;
}
Modified: trunk/src/main/org/jboss/messaging/core/deployers/impl/AddressSettingsDeployer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/deployers/impl/AddressSettingsDeployer.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/core/deployers/impl/AddressSettingsDeployer.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -98,8 +98,7 @@
* @throws Exception .
*/
public void deploy(Node node) throws Exception
- {
- log.info("** address setings deployer, deploying");
+ {
String match = node.getAttributes().getNamedItem(getKeyAttribute()).getNodeValue();
NodeList children = node.getChildNodes();
Modified: trunk/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -426,6 +426,7 @@
{
return;
}
+
synchronized (mbeanServer)
{
unregisterFromJMX(objectName);
@@ -436,6 +437,7 @@
public synchronized void registerInRegistry(final String resourceName, final Object managedResource)
{
unregisterFromRegistry(resourceName);
+
registry.put(resourceName, managedResource);
}
@@ -643,6 +645,12 @@
try
{
Object resource = registry.get(resourceName);
+
+ if (resource == null)
+ {
+ throw new IllegalArgumentException("Cannot find resource with name " + resourceName);
+ }
+
Method method = null;
try
@@ -671,6 +679,12 @@
private Object invokeOperation(final String resourceName, final String operation, final List<Object> params) throws Exception
{
Object resource = registry.get(resourceName);
+
+ if (resource == null)
+ {
+ throw new IllegalArgumentException("Cannot find resource with name " + resourceName);
+ }
+
Method method = null;
Method[] methods = resource.getClass().getMethods();
Modified: trunk/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -1655,9 +1655,7 @@
{
// Error - didn't get pong back
final MessagingException me = new MessagingException(MessagingException.NOT_CONNECTED,
- "Did not receive pong from server, active " + createdActive +
- " client " +
- client);
+ "Did not receive pong from server");
future.cancel(true);
Modified: trunk/src/main/org/jboss/messaging/integration/transports/netty/NettyAcceptor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/integration/transports/netty/NettyAcceptor.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/integration/transports/netty/NettyAcceptor.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -213,10 +213,10 @@
}
public synchronized void start() throws Exception
- {
+ {
if (channelFactory != null)
{
- // Already started
+ // Already started
return;
}
bossExecutor = Executors.newCachedThreadPool(new org.jboss.messaging.utils.JBMThreadFactory("jbm-netty-acceptor-boss-threads"));
Modified: trunk/src/main/org/jboss/messaging/jms/server/impl/JMSServerDeployer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/impl/JMSServerDeployer.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/jms/server/impl/JMSServerDeployer.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -77,7 +77,7 @@
private static final String RETRY_INTERVAL_MULTIPLIER = "retry-interval-multiplier";
- private static final String CONNECT_ATTEMPTS = "reconnect-attempts";
+ private static final String RECONNECT_ATTEMPTS = "reconnect-attempts";
private static final String FAILOVER_ON_NODE_SHUTDOWN = "failover-on-server-shutdown";
@@ -256,7 +256,7 @@
{
retryIntervalMultiplier = org.jboss.messaging.utils.XMLUtil.parseDouble(child);
}
- else if (CONNECT_ATTEMPTS.equals(child.getNodeName()))
+ else if (RECONNECT_ATTEMPTS.equals(child.getNodeName()))
{
reconnectAttempts = org.jboss.messaging.utils.XMLUtil.parseInt(child);;
}
Modified: trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSManagementHelper.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSManagementHelper.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/main/org/jboss/messaging/jms/server/management/impl/JMSManagementHelper.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -50,6 +50,13 @@
message.setStringProperty(HDR_RESOURCE_NAME.toString(), resourceName);
message.setStringProperty(HDR_ATTRIBUTE.toString(), attribute);
}
+
+ public static void putOperationInvocation(final Message message,
+ final String resourceName,
+ final String operationName) throws JMSException
+ {
+ putOperationInvocation(message, resourceName, operationName, (Object[])null);
+ }
public static void putOperationInvocation(final Message message,
final String resourceName,
@@ -60,13 +67,16 @@
message.setStringProperty(HDR_RESOURCE_NAME.toString(), resourceName);
message.setStringProperty(HDR_OPERATION_NAME.toString(), operationName);
// ... and all the parameters (preserving their types)
- for (int i = 0; i < parameters.length; i++)
+ if (parameters != null)
{
- Object parameter = parameters[i];
- // use a zero-filled 2-padded index:
- // if there is more than 10 parameters, order is preserved (e.g. 02 will be before 10)
- String key = String.format("%s%02d", HDR_OPERATION_PREFIX, i);
- storeTypedProperty(message, key, parameter);
+ for (int i = 0; i < parameters.length; i++)
+ {
+ Object parameter = parameters[i];
+ // use a zero-filled 2-padded index:
+ // if there is more than 10 parameters, order is preserved (e.g. 02 will be before 10)
+ String key = String.format("%s%02d", HDR_OPERATION_PREFIX, i);
+ storeTypedProperty(message, key, parameter);
+ }
}
}
Modified: trunk/src/schemas/jbm-configuration.xsd
===================================================================
--- trunk/src/schemas/jbm-configuration.xsd 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/schemas/jbm-configuration.xsd 2009-04-15 12:27:47 UTC (rev 6431)
@@ -41,7 +41,7 @@
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="security-invalidation-interval"
- type="period" maxOccurs="1" minOccurs="0">
+ type="xsd:unsignedLong" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="wild-card-routing-enabled"
type="xsd:boolean" maxOccurs="1" minOccurs="0">
@@ -56,7 +56,7 @@
type="xsd:string" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="management-request-timeout"
- type="period" maxOccurs="1" minOccurs="0">
+ type="xsd:unsignedLong" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="jmx-management-enabled"
type="xsd:boolean" maxOccurs="1" minOccurs="0">
@@ -65,19 +65,19 @@
type="xsd:boolean" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="connection-scan-period"
- type="period" maxOccurs="1" minOccurs="0">
+ type="xsd:unsignedLong" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="connection-ttl-override"
type="xsd:long" maxOccurs="1" minOccurs="0">
</xsd:element>
- <xsd:element name="transaction-timeout" type="period"
+ <xsd:element name="transaction-timeout" type="xsd:unsignedLong"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="transaction-timeout-scan-period"
- type="period" maxOccurs="1" minOccurs="0">
+ type="xsd:unsignedLong" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="message-expiry-scan-period"
- type="period" maxOccurs="1" minOccurs="0">
+ type="xsd:unsignedLong" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="message-expiry-thread-priority"
type="xsd:positiveInteger" maxOccurs="1" minOccurs="0">
@@ -197,7 +197,7 @@
<xsd:element name="group-port" type="portRange"></xsd:element>
- <xsd:element name="broadcast-period" type="period"></xsd:element>
+ <xsd:element name="broadcast-period" type="xsd:unsignedLong"></xsd:element>
<xsd:element name="connector-ref" type="connector-refType">
</xsd:element>
@@ -225,7 +225,7 @@
</xsd:complexType>
</xsd:element>
- <xsd:element name="refresh-timeout" type="period"></xsd:element>
+ <xsd:element name="refresh-timeout" type="xsd:unsignedLong"></xsd:element>
<xsd:element name="discovery-group">
<xsd:complexType>
@@ -326,14 +326,14 @@
<xsd:element name="transformer-class-name" type="xsd:string"
maxOccurs="1" minOccurs="0">
</xsd:element>
- <xsd:element name="retry-interval" type="period"
+ <xsd:element name="retry-interval" type="xsd:unsignedLong"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="retry-interval-multiplier"
type="xsd:double" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="reconnect-attempts"
- type="xsd:nonNegativeInteger" maxOccurs="1" minOccurs="0">
+ type="minusOneOrMoreInteger" maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="failover-on-server-shutdown"
type="xsd:boolean" maxOccurs="1" minOccurs="0">
@@ -363,7 +363,7 @@
<xsd:element name="address" type="xsd:string"
maxOccurs="1" minOccurs="1">
</xsd:element>
- <xsd:element name="retry-interval" type="period"
+ <xsd:element name="retry-interval" type="xsd:unsignedLong"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="use-duplicate-detection"
@@ -434,14 +434,16 @@
<xsd:attribute name="string" type="xsd:string" use="required"></xsd:attribute>
</xsd:complexType>
-
<xsd:simpleType name="portRange">
<xsd:restriction base="xsd:int">
<xsd:minExclusive value="1024"></xsd:minExclusive>
</xsd:restriction>
</xsd:simpleType>
+
+ <xsd:simpleType name="minusOneOrMoreInteger">
+ <xsd:restriction base="xsd:int">
+ <xsd:minInclusive value="-1"></xsd:minInclusive>
+ </xsd:restriction>
+ </xsd:simpleType>
- <xsd:simpleType name="period">
- <xsd:restriction base="xsd:unsignedLong"></xsd:restriction>
- </xsd:simpleType>
</xsd:schema>
Modified: trunk/src/schemas/jbm-jms.xsd
===================================================================
--- trunk/src/schemas/jbm-jms.xsd 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/src/schemas/jbm-jms.xsd 2009-04-15 12:27:47 UTC (rev 6431)
@@ -92,7 +92,7 @@
<xsd:element name="retry-interval-multiplier" type="xsd:float"
maxOccurs="1" minOccurs="0">
</xsd:element>
- <xsd:element name="connect-attempts" type="xsd:positiveInteger"
+ <xsd:element name="reconnect-attempts" type="minusOneOrMoreInteger"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="failover-on-server-shutdown" type="xsd:boolean"
@@ -135,4 +135,10 @@
<xsd:element name="topic" type="destinationType"></xsd:element>
+ <xsd:simpleType name="minusOneOrMoreInteger">
+ <xsd:restriction base="xsd:int">
+ <xsd:minInclusive value="-1"></xsd:minInclusive>
+ </xsd:restriction>
+ </xsd:simpleType>
+
</xsd:schema>
Modified: trunk/tests/src/org/jboss/messaging/tests/integration/cluster/failover/ReconnectTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/cluster/failover/ReconnectTest.java 2009-04-15 07:38:07 UTC (rev 6430)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/cluster/failover/ReconnectTest.java 2009-04-15 12:27:47 UTC (rev 6431)
@@ -34,6 +34,7 @@
import org.jboss.messaging.core.config.impl.ConfigurationImpl;
import org.jboss.messaging.core.exception.MessagingException;
import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.remoting.FailureListener;
import org.jboss.messaging.core.remoting.RemotingConnection;
import org.jboss.messaging.core.remoting.impl.invm.InVMConnector;
import org.jboss.messaging.core.remoting.impl.invm.InVMRegistry;
@@ -80,7 +81,7 @@
final double retryMultiplier = 1d;
- final int reconnectAttempts = 1;
+ final int reconnectAttempts = 1;
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
@@ -90,15 +91,15 @@
ClientSession session = sf.createSession(false, true, true);
session.createQueue(ADDRESS, ADDRESS, null, false);
-
+
final int numIterations = 100;
-
+
for (int j = 0; j < numIterations; j++)
- {
+ {
ClientProducer producer = session.createProducer(ADDRESS);
-
+
final int numMessages = 1000;
-
+
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
@@ -112,40 +113,40 @@
}
ClientConsumer consumer = session.createConsumer(ADDRESS);
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
+
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
-
+
session.start();
-
+
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = consumer.receive(500);
-
+
assertNotNull(message);
-
+
assertEquals("aardvarks", message.getBody().readString());
-
+
assertEquals(i, message.getProperty(new SimpleString("count")));
-
+
message.acknowledge();
}
-
+
ClientMessage message = consumer.receiveImmediate();
-
+
assertNull(message);
-
+
producer.close();
-
+
consumer.close();
}
-
+
session.close();
-
+
sf.close();
}
-
+
/*
* Test failure on connection, simulate failure to create connection for a while, then
* allow connection to be recreated
@@ -157,10 +158,10 @@
final double retryMultiplier = 1d;
final int reconnectAttempts = -1;
-
+
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
- retryMultiplier,
+ retryMultiplier,
reconnectAttempts);
ClientSession session = sf.createSession(false, true, true);
@@ -186,9 +187,9 @@
ClientConsumer consumer = session.createConsumer(ADDRESS);
InVMConnector.failOnCreateConnection = true;
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
+
Thread t = new Thread()
{
public void run()
@@ -198,13 +199,13 @@
Thread.sleep(retryInterval * 3);
}
catch (InterruptedException ignore)
- {
+ {
}
-
+
InVMConnector.failOnCreateConnection = false;
}
};
-
+
t.start();
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
@@ -227,21 +228,145 @@
ClientMessage message = consumer.receiveImmediate();
assertNull(message);
+
+ session.close();
+
+ sf.close();
+
+ t.join();
+ }
+
+ // Test an async (e.g. pinger) failure coming in while a connection manager is already reconnecting
+ public void testAsyncFailureWhileReconnecting() throws Exception
+ {
+ final long retryInterval = 500;
+
+ final double retryMultiplier = 1d;
+
+ final int reconnectAttempts = -1;
+
+ final long asyncFailDelay = 2000;
+
+ ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
+ retryInterval,
+ retryMultiplier,
+ reconnectAttempts);
+
+ ClientSession session = sf.createSession(false, true, true);
+
+ ClientSession session2 = sf.createSession(false, true, true);
+ class MyFailureListener implements FailureListener
+ {
+ volatile boolean failed;
+
+ public boolean connectionFailed(MessagingException me)
+ {
+ failed = true;
+
+ return true;
+ }
+ }
+
+ MyFailureListener listener = new MyFailureListener();
+
+ session2.addFailureListener(listener);
+
+ session.createQueue(ADDRESS, ADDRESS, null, false);
+
+ ClientProducer producer = session.createProducer(ADDRESS);
+
+ final int numMessages = 1000;
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
+ false,
+ 0,
+ System.currentTimeMillis(),
+ (byte)1);
+ message.putIntProperty(new SimpleString("count"), i);
+ message.getBody().writeString("aardvarks");
+ producer.send(message);
+ }
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ InVMConnector.numberOfFailures = 10;
+ InVMConnector.failOnCreateConnection = true;
+
+ //We need to fail on different connections.
+
+ //We fail on one connection then the connection manager tries to reconnect all connections
+ //Then we fail the other, and the connection manager is then called while the reconnection is occurring
+ //We can't use the same connection since RemotingConnectionImpl only allows one fail to be in process
+ //at same time
+
+ final RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
+
+ final RemotingConnection conn2 = ((ClientSessionImpl)session2).getConnection();
+
+ assertTrue(conn != conn2);
+
+ Thread t = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ Thread.sleep(asyncFailDelay);
+ }
+ catch (InterruptedException ignore)
+ {
+ }
+
+ log.info("calling fail async");
+
+ conn2.fail(new MessagingException(MessagingException.NOT_CONNECTED, "Did not receive pong from server"));
+ }
+ };
+
+ t.start();
+
+ conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
+
+ assertFalse(listener.failed);
+
+ session.start();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = consumer.receive(500);
+
+ assertNotNull(message);
+
+ assertEquals("aardvarks", message.getBody().readString());
+
+ assertEquals(i, message.getProperty(new SimpleString("count")));
+
+ message.acknowledge();
+ }
+
+ ClientMessage message = consumer.receiveImmediate();
+
+ assertNull(message);
+
session.close();
+ session2.close();
+
sf.close();
-
+
t.join();
}
-
+
public void testReconnectAttemptsFailsToReconnect() throws Exception
{
final long retryInterval = 500;
final double retryMultiplier = 1d;
- final int reconnectAttempts = 3;
+ final int reconnectAttempts = 3;
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
@@ -271,11 +396,11 @@
ClientConsumer consumer = session.createConsumer(ADDRESS);
InVMConnector.failOnCreateConnection = true;
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
- //Sleep for longer than max retries so should fail to reconnect
-
+
+ // Sleep for longer than max retries so should fail to reconnect
+
Thread t = new Thread()
{
public void run()
@@ -285,42 +410,42 @@
Thread.sleep(retryInterval * (reconnectAttempts + 1));
}
catch (InterruptedException ignore)
- {
+ {
}
-
+
InVMConnector.failOnCreateConnection = false;
}
};
-
+
t.start();
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
session.start();
- //Should be null since failed to reconnect
+ // Should be null since failed to reconnect
ClientMessage message = consumer.receive(500);
assertNull(message);
-
+
session.close();
-
+
sf.close();
-
+
t.join();
}
-
+
public void testReconnectAttemptsSucceedsInReconnecting() throws Exception
{
final long retryInterval = 500;
final double retryMultiplier = 1d;
- final int reconnectAttempts = 10;
+ final int reconnectAttempts = 10;
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
- retryMultiplier,
+ retryMultiplier,
reconnectAttempts);
ClientSession session = sf.createSession(false, true, true);
@@ -347,11 +472,11 @@
InVMConnector.failOnCreateConnection = true;
InVMConnector.numberOfFailures = reconnectAttempts - 1;
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
+
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
-
+
session.start();
for (int i = 0; i < numMessages; i++)
@@ -370,23 +495,23 @@
ClientMessage message = consumer.receiveImmediate();
assertNull(message);
-
+
session.close();
-
+
sf.close();
}
-
+
public void testRetryInterval() throws Exception
{
final long retryInterval = 500;
final double retryMultiplier = 1d;
- final int reconnectAttempts = -1;
+ final int reconnectAttempts = -1;
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
- retryMultiplier,
+ retryMultiplier,
reconnectAttempts);
ClientSession session = sf.createSession(false, true, true);
@@ -412,11 +537,11 @@
ClientConsumer consumer = session.createConsumer(ADDRESS);
InVMConnector.failOnCreateConnection = true;
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
+
long start = System.currentTimeMillis();
-
+
Thread t = new Thread()
{
public void run()
@@ -426,16 +551,16 @@
Thread.sleep(retryInterval / 2);
}
catch (InterruptedException ignore)
- {
+ {
}
InVMConnector.failOnCreateConnection = false;
}
};
-
+
t.start();
-
+
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
-
+
session.start();
for (int i = 0; i < numMessages; i++)
@@ -454,29 +579,29 @@
ClientMessage message = consumer.receiveImmediate();
assertNull(message);
-
+
long end = System.currentTimeMillis();
-
+
assertTrue((end - start) >= retryInterval);
-
+
session.close();
-
+
sf.close();
-
+
t.join();
}
-
+
public void testExponentialBackoff() throws Exception
{
final long retryInterval = 500;
final double retryMultiplier = 4d;
- final int reconnectAttempts = -1;
+ final int reconnectAttempts = -1;
ClientSessionFactoryInternal sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
retryInterval,
- retryMultiplier,
+ retryMultiplier,
reconnectAttempts);
ClientSession session = sf.createSession(false, true, true);
@@ -502,11 +627,11 @@
ClientConsumer consumer = session.createConsumer(ADDRESS);
InVMConnector.failOnCreateConnection = true;
-
+
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
-
+
long start = System.currentTimeMillis();
-
+
Thread t = new Thread()
{
public void run()
@@ -516,17 +641,17 @@
Thread.sleep(retryInterval * 2);
}
catch (InterruptedException ignore)
- {
+ {
}
-
+
InVMConnector.failOnCreateConnection = false;
}
};
-
+
t.start();
-
+
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
-
+
session.start();
for (int i = 0; i < numMessages; i++)
@@ -545,15 +670,15 @@
ClientMessage message = consumer.receiveImmediate();
assertNull(message);
-
+
long end = System.currentTimeMillis();
-
+
assertTrue((end - start) >= retryInterval * (1 + retryMultiplier));
-
+
session.close();
-
+
sf.close();
-
+
t.join();
}
@@ -565,7 +690,7 @@
protected void setUp() throws Exception
{
super.setUp();
-
+
Configuration liveConf = new ConfigurationImpl();
liveConf.setSecurityEnabled(false);
liveConf.getAcceptorConfigurations()
@@ -578,11 +703,11 @@
protected void tearDown() throws Exception
{
InVMConnector.resetFailures();
-
+
service.stop();
assertEquals(0, InVMRegistry.instance.size());
-
+
super.tearDown();
}
More information about the jboss-cvs-commits
mailing list