[jboss-cvs] JBoss Messaging SVN: r1970 - in trunk: src/etc/server/default/deploy and 19 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Jan 16 15:59:22 EST 2007
Author: timfox
Date: 2007-01-16 15:58:56 -0500 (Tue, 16 Jan 2007)
New Revision: 1970
Added:
trunk/src/etc/server/default/deploy/bridge-service.xml
trunk/src/etc/xmdesc/Bridge-xmbean.xml
trunk/src/main/org/jboss/jms/recovery/BridgeXAResourceRecovery.java
trunk/src/main/org/jboss/jms/server/bridge/BridgeMBean.java
trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java
trunk/tests/etc/bridge-recovery.properties
trunk/tests/etc/jbossjta-properties.xml
trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeMBeanTest.java
trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTestBase.java
trunk/tests/src/org/jboss/test/messaging/jms/bridge/ReconnectTest.java
Removed:
trunk/lib/jbossts/
trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java
trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java
Modified:
trunk/src/etc/server/default/deploy/remoting-service.xml
trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java
trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java
trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java
trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java
trunk/src/main/org/jboss/jms/server/ServerPeer.java
trunk/src/main/org/jboss/jms/server/bridge/Bridge.java
trunk/src/main/org/jboss/jms/server/bridge/JNDIConnectionFactoryFactory.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
trunk/tests/bin/runtest
trunk/tests/bin/start-rmi-server
trunk/tests/etc/log4j.xml
trunk/tests/etc/poison.xml
trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTest.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java
trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
trunk/tests/src/org/jboss/test/messaging/tools/aop/PoisonInterceptor.java
trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java
trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
Log:
More bridge work
Added: trunk/src/etc/server/default/deploy/bridge-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/bridge-service.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/etc/server/default/deploy/bridge-service.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Example Message Bridge configurations
+
+ $Id: destinations-service.xml 1930 2007-01-09 18:16:04Z timfox $
+ -->
+
+<server>
+
+ <mbean code="org.jboss.jms.server.bridge.BridgeService"
+ name="jboss.messaging:service=Bridge,name=exampleBridge"
+ xmbean-dd="xmdesc/Bridge-xmbean.xml">
+
+ <attribute name="SourceConnectionFactoryLookup">/ConnectionFactory</attribute>
+
+ <attribute name="TargetConnectionFactoryLookup">/ConnectionFactory</attribute>
+
+ <attribute name="SourceDestinationLookup">/topic/sourceTopic</attribute>
+
+ <attribute name="TargetDestinationLookup">/queue/targetQueue</attribute>
+
+ <attribute name="SourceUsername">bob</attribute>
+
+ <attribute name="SourcePassword">pwd1</attribute>
+
+ <attribute name="TargetUsername">jane</attribute>
+
+ <attribute name="TargetPassword">pwd2</attribute>
+
+ <attribute name="QualityOfServiceMode">2</attribute>
+
+ <attribute name="Selector">vegetable='marrow'</attribute>
+
+ <attribute name="MaxBatchSize">100</attribute>
+
+ <attribute name="MaxBatchTime">5000</attribute>
+
+ <attribute name="SubName">mySubscription</attribute>
+
+ <attribute name="ClientID">clientid-123</attribute>
+
+ <attribute name="FailureRetryInterval">5000</attribute>
+
+ <attribute name="MaxRetries">-1</attribute>
+
+ <attribute name="SourceJNDIProperties"><![CDATA[
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.provider.url=jnp://server1:1099
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+ ]]>
+ </attribute>
+
+ <attribute name="TargetJNDIProperties"><![CDATA[
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.provider.url=jnp://server2:1099
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+ ]]>
+ </attribute>
+ </mbean>
+
+
+</server>
\ No newline at end of file
Modified: trunk/src/etc/server/default/deploy/remoting-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/remoting-service.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/etc/server/default/deploy/remoting-service.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -27,6 +27,8 @@
<attribute name="callbackStore">org.jboss.remoting.callback.CallbackStore</attribute>
<attribute name="clientSocketClass" isParam="true">org.jboss.jms.client.remoting.ClientSocketWrapper</attribute>
<attribute name="serverSocketClass">org.jboss.jms.server.remoting.ServerSocketWrapper</attribute>
+ <attribute name="NumberOfRetries">1</attribute>
+ <attribute name="NumberOfCallRetries">1</attribute>
</invoker>
<handlers>
<handler subsystem="JMS">org.jboss.jms.server.remoting.JMSServerInvocationHandler</handler>
Added: trunk/src/etc/xmdesc/Bridge-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Bridge-xmbean.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/etc/xmdesc/Bridge-xmbean.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE mbean PUBLIC
+ "-//JBoss//DTD JBOSS XMBEAN 1.2//EN"
+ "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_2.dtd">
+
+<mbean>
+ <description>A JMS Message Bridge</description>
+ <class>org.jboss.server.bridge.BridgeService</class>
+
+ <!-- Managed constructors -->
+
+ <!-- Managed attributes -->
+
+ <attribute access="read-only" getMethod="getInstance">
+ <description>Gets the underlying instance</description>
+ <name>Instance</name>
+ <type>org.jboss.messaging.core.plugin.contract.MessagingComponent</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSourceConnectionFactoryLookup"
+ setMethod="setSourceConnectionFactoryLookup">
+ <description>The source connection factory lookup</description>
+ <name>SourceConnectionFactoryLookup</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getDestConnectionFactoryLookup"
+ setMethod="setDestConnectionFactoryLookup">
+ <description>The destination connection factory lookup</description>
+ <name>DestConnectionFactoryLookup</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSourceUsername"
+ setMethod="setSourceUsername">
+ <description>The source username</description>
+ <name>SourceUsername</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSourcePassword"
+ setMethod="setSourcePassword">
+ <description>The source username</description>
+ <name>SourcePassword</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getDestUsername"
+ setMethod="setDestUsername">
+ <description>The destination username</description>
+ <name>DestUsername</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getQualityOfServiceMode"
+ setMethod="setQualityOfServiceMode">
+ <description>The quality of service mode. 0 = at most once. 1 = duplicates ok, 2 = once and only once</description>
+ <name>QualitOfServiceMode</name>
+ <type>int</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSelector"
+ setMethod="setSelector">
+ <description>The JMS selector to use when consuming messages from the source destination</description>
+ <name>Selector</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getMaxBatchSize"
+ setMethod="setMaxBatchSize">
+ <description>The maximum number of messages to forward at a time, must be >= 1</description>
+ <name>MaxBatchSize</name>
+ <type>int</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getMaxBatchTime"
+ setMethod="setMaxBatchTime">
+ <description>Number of milliseconds to wait after no messages arrive to forward batch of messages</description>
+ <name>MaxBatchTime</name>
+ <type>int</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSubName"
+ setMethod="setSubName">
+ <description>If consuming from a durable subscription, this is the name of the durable subscrition</description>
+ <name>SubName</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getClientID"
+ setMethod="setClientID">
+ <description>If consuming from a durable subscription, this is the client id to use</description>
+ <name>ClientID</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getFailureRetryInterval"
+ setMethod="setFailureRetryInterval">
+ <description>The amount of time to wait in milliseconds before retrying connection creation, after connection failure is detected, or -1 if no retries will be attempted</description>
+ <name>FailureRetryInterval</name>
+ <type>long</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getMaxRetries"
+ setMethod="setMaxRetries">
+ <description>The maximum number of attempts to retry connection creation after connection failure is detected</description>
+ <name>MaxRetries</name>
+ <type>int</type>
+ </attribute>
+
+ <attribute access="read-only" getMethod="isFailed">
+ <description>Has the bridge failed?</description>
+ <name>Failed</name>
+ <type>boolean</type>
+ </attribute>
+
+ <attribute access="read-only" getMethod="isPaused">
+ <description>Is the bridge paused?</description>
+ <name>Paused</name>
+ <type>boolean</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSourceJNDIProperties" setMethod="setSourceJNDIProperties>
+ <description>The JNDI properties to use to lookup the source destination, or null if a local JNDI initial context should be used</description>
+ <name>SourceJNDIProperties</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getDestNDIProperties" setMethod="setDestJNDIProperties>
+ <description>The JNDI properties to use to lookup the destination destination, or null if a local JNDI initial context should be used</description>
+ <name>DestJNDIProperties</name>
+ <type>java.lang.String</type>
+ </attribute>
+
+ <!-- Managed operations -->
+
+ <operation>
+ <description>JBoss Service lifecycle operation</description>
+ <name>create</name>
+ </operation>
+
+ <operation>
+ <description>JBoss Service lifecycle operation</description>
+ <name>start</name>
+ </operation>
+
+ <operation>
+ <description>JBoss Service lifecycle operation</description>
+ <name>stop</name>
+ </operation>
+
+ <operation>
+ <description>JBoss Service lifecycle operation</description>
+ <name>destroy</name>
+ </operation>
+
+</mbean>
\ No newline at end of file
Modified: trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -298,7 +298,7 @@
catch (Throwable ignored)
{
// Add a log interceptor to the child if you want the error
- ignored.printStackTrace();
+ // ignored.printStackTrace();
}
}
Modified: trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -73,7 +73,7 @@
catch(JMSException e)
{
// JMSException should not be logged unless trace is on
- if (trace) { log.trace("Caught JMSException", e); }
+ // if (trace) { log.trace("Caught JMSException", e); }
throw e;
}
catch (Throwable t)
Modified: trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -90,7 +90,6 @@
log.debug("checked out MessageIdGenerator for " + serverId +
", reference count is " + h.refCount);
-
return h.generator;
}
Added: trunk/src/main/org/jboss/jms/recovery/BridgeXAResourceRecovery.java
===================================================================
--- trunk/src/main/org/jboss/jms/recovery/BridgeXAResourceRecovery.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/recovery/BridgeXAResourceRecovery.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,230 @@
+/*
+ * 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.
+ */
+package org.jboss.jms.recovery;
+
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import javax.jms.XAConnection;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XASession;
+import javax.naming.InitialContext;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+
+import com.arjuna.ats.jta.recovery.XAResourceRecovery;
+
+/**
+ * A BridgeXAResourceRecovery
+ *
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class BridgeXAResourceRecovery implements XAResourceRecovery
+{
+ private static final Logger log = Logger.getLogger(BridgeXAResourceRecovery.class);
+
+ private Hashtable jndiProperties;
+
+ private String connectionFactoryLookup;
+
+ private boolean returnedXAResource;
+
+ private XAConnection conn;
+
+ public synchronized XAResource getXAResource() throws SQLException
+ {
+ InitialContext ic = null;
+
+ if (log.isTraceEnabled()) { log.trace(this + " getting XAResource"); }
+
+ try
+ {
+ if (jndiProperties.isEmpty())
+ {
+ //Local initial context
+
+ ic = new InitialContext();
+ }
+ else
+ {
+ ic = new InitialContext(jndiProperties);
+ }
+
+ XAConnectionFactory cf = (XAConnectionFactory)ic.lookup(connectionFactoryLookup);
+
+ conn = cf.createXAConnection();
+
+ XASession sess = conn.createXASession();
+
+ XAResource res = sess.getXAResource();
+
+ returnedXAResource = true;
+
+ if (log.isTraceEnabled()) { log.trace(this + " returning " + res); }
+
+ return res;
+ }
+ catch (Exception e)
+ {
+ log.warn("Failed to get XAResource", e);
+
+ return null;
+ }
+ finally
+ {
+ if (ic != null)
+ {
+ try
+ {
+ ic.close();
+ }
+ catch (Exception ignore)
+ {
+ //Ignore
+ }
+ }
+ }
+
+ }
+
+ public synchronized boolean hasMoreResources()
+ {
+ return !returnedXAResource;
+ }
+
+ public synchronized boolean initialise(String config)
+ {
+ if (log.isTraceEnabled()) { log.trace(this + " intialise: " + config); }
+
+ StringTokenizer tok = new StringTokenizer(config, ",");
+
+ if (tok.countTokens() != 2)
+ {
+ log.error("Invalid config: " + config);
+ return false;
+ }
+
+ String provider = tok.nextToken();
+
+ String propsFile = tok.nextToken();
+
+ try
+ {
+ //The config should point to a properties file on the classpath that holds the actual config
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propsFile);
+
+ Properties props = new Properties();
+
+ props.load(is);
+
+ /*
+ * provider1.jndi.prop1=xxxx
+ * provider1.jndi.prop2=yyyy
+ * provider1.jndi.prop3=zzzz
+ *
+ * provider1.xaconnectionfactorylookup=xyz
+ *
+ * provider2.jndi.prop1=xxxx
+ * provider2.jndi.prop2=yyyy
+ * provider2.jndi.prop3=zzzz
+ *
+ * provider2.xaconnectionfactorylookup=xyz
+ *
+ */
+
+ Iterator iter = props.entrySet().iterator();
+
+ String jndiPrefix = provider + ".jndi.";
+
+ String cfKey = provider + ".xaconnectionfactorylookup";
+
+ jndiProperties = new Hashtable();
+
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+
+ String key = (String)entry.getKey();
+ String value = (String)entry.getValue();
+
+ if (key.startsWith(jndiPrefix))
+ {
+ String actualKey = key.substring(jndiPrefix.length());
+
+ jndiProperties.put(actualKey, value);
+ }
+ else if (key.equals(cfKey))
+ {
+ connectionFactoryLookup = value;
+ }
+ }
+
+ if (connectionFactoryLookup == null)
+ {
+ log.error("Key " + cfKey + " does not exist in config");
+ return false;
+ }
+
+ if (log.isTraceEnabled()) { log.trace(this + " initialised"); }
+
+ return true;
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to load config file: " + config, e);
+
+ return false;
+ }
+ }
+
+ protected void finalize()
+ {
+ if (log.isTraceEnabled()) { log.trace(this + " finalizing"); }
+
+ //I'd rather have some lifecycle method that gets called on this class by the recovery manager
+ //but there doesn't seem to be one.
+ //Therefore the only place I can close the connection is in the finalizer
+ if (conn != null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (Exception ignore)
+ {
+ //Ignore
+ }
+ }
+ }
+
+}
Modified: trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java
===================================================================
--- trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -29,6 +29,10 @@
/**
* JMS Provider Adapter based recovery.
+ *
+ * This should be done when recovery is being driven from a transaction manager deployed with JBoss AS
+ * since it relies on JMSProviderLoader instances being deployed that correspond to the JMS providers
+ * to recover for.
*
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @author <a href="juha at jboss.com">Juha Lindfors</a>
Deleted: trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java
===================================================================
--- trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -1,152 +0,0 @@
-package org.jboss.jms.recovery;
-
-import java.sql.SQLException;
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.transaction.xa.XAResource;
-
-import org.jboss.logging.Logger;
-
-import com.arjuna.ats.jta.recovery.XAResourceRecovery;
-
-/**
- *
- * A MessagingXAResourceRecovery
- *
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class MessagingXAResourceRecovery implements XAResourceRecovery
-{
- private boolean trace = log.isTraceEnabled();
-
- private static final Logger log = Logger.getLogger(MessagingXAResourceRecovery.class);
-
- private boolean working = false;
-
- private XAResource xaRes = null;
-
- private String xaConnFactory = null;
-
- public MessagingXAResourceRecovery()
- {
- }
-
- public XAResource getXAResource() throws SQLException
- {
- if (trace) { log.trace("returning the xaresource " + xaRes); }
- return xaRes;
- }
-
- /**
- * This method returns the Messaging XAResource reference.
- * You have to pass the jndi name of the XAConnectionFactory
- * via the JBossTS RecoveryManager's properties
- * @return
- */
- public XAResource initXAResource()
- {
- if(trace)
- {
- log.trace("Initialising xaresource..");
- }
- try
- {
- Context ctx = new InitialContext();
-
- XAConnectionFactory cf = (XAConnectionFactory) ctx
- .lookup(xaConnFactory);
-
- XAConnection xaConn = cf.createXAConnection();
-
- XASession session = xaConn.createXASession();
- xaRes = session.getXAResource();
-
- if(trace)
- log.trace("Found the xares: "+xaRes);
-
- }
- catch (Exception e)
- {
- // You may get this exception when the messaging server
- // is not fully booted up. Nothing to worry, it'll keep
- // trying until successful.
- log.warn("XAConnectionFactory is not found. \n" +
- "The messaging server is not yet initialized.\n" +
- "we'll try again once server is fully back");
-
- }
-
- return xaRes;
- }
-
- /**
- * This method is used to pass any
- * intialisation parameters to this
- * class
- * @param param
- * @return
- * @throws SQLException
- */
- public boolean initialise(String param) throws SQLException
- {
- if(trace) { log.trace("Passed in parameter: " + param); }
-
- if (param != null)
- {
- // param is in the form of name=value
- String value = param.substring(param.indexOf("=") + 1);
-
- if(trace) { log.trace("The connection factory is " + value); }
-
- xaConnFactory = value;
- }
- else
- {
- log.debug("The XA connection factory parameter is null. " +
- "Using the default 'XAConnectionFactory'");
-
- xaConnFactory = "XAConnectionFactory";
- }
- return true;
- }
-
- /**
- * This method checks whether there's an xa resource available
- *
- * @return
- */
- public boolean hasMoreResources()
- {
- if (working)
- {
- return false;
- }
-
- if (xaRes == null)
- {
- xaRes = initXAResource();
- }
-
- // test the resource
- try
- {
-
- xaRes.getTransactionTimeout();
-
- working = true;
- }
- catch (Exception ignored)
- {
-
- // ignore this exception
- }
-
- return working;
- }
-}
Modified: trunk/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeer.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/ServerPeer.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -185,6 +185,8 @@
{
throw new IllegalArgumentException("ID cannot be negative");
}
+
+ log.info(this + " creating serverpeer with id " + serverPeerID);
this.serverPeerID = serverPeerID;
this.defaultQueueJNDIContext = defaultQueueJNDIContext;
Modified: trunk/src/main/org/jboss/jms/server/bridge/Bridge.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/Bridge.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/bridge/Bridge.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -42,6 +42,7 @@
import org.jboss.logging.Logger;
import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.tm.TxManager;
/**
*
@@ -128,9 +129,9 @@
private String sourcePassword;
- private String destUsername;
+ private String targetUsername;
- private String destPassword;
+ private String targetPassword;
private TransactionManager tm;
@@ -156,21 +157,21 @@
private Object lock;
- private ConnectionFactoryFactory sourceCfFactory;
+ private ConnectionFactoryFactory sourceCff;
- private ConnectionFactoryFactory destCfFactory;
+ private ConnectionFactoryFactory targetCff;
- private Connection connSource;
+ private Connection sourceConn;
- private Connection connDest;
+ private Connection targetConn;
- private Destination destSource;
+ private Destination sourceDestination;
- private Destination destDest;
+ private Destination targetDestination;
- private Session sessSource;
+ private Session sourceSession;
- private Session sessDest;
+ private Session targetSession;
private MessageConsumer consumer;
@@ -186,79 +187,47 @@
private Transaction tx;
- private boolean manualAck;
+ private boolean failed;
- private boolean manualCommit;
-
+ private boolean usingXA;
+
+
/*
+ * Constructor for MBean
+ */
+ public Bridge()
+ {
+ }
+
+
+ /*
* This constructor is used when source and destination are on different servers
*/
- public Bridge(ConnectionFactoryFactory sourceCfFactory, ConnectionFactoryFactory destCfFactory,
- Destination destSource, Destination destDest,
+ public Bridge(ConnectionFactoryFactory sourceCff, ConnectionFactoryFactory destCff,
+ Destination sourceDestination, Destination targetDestination,
String sourceUsername, String sourcePassword,
- String destUsername, String destPassword,
+ String targetUsername, String targetPassword,
String selector, long failureRetryInterval,
int maxRetries,
int qosMode,
int maxBatchSize, long maxBatchTime,
String subName, String clientID)
- {
- if (sourceCfFactory == null)
- {
- throw new IllegalArgumentException("sourceCfFactory cannot be null");
- }
- if (destCfFactory == null)
- {
- throw new IllegalArgumentException("destCfFactory cannot be null");
- }
- if (destSource == null)
- {
- throw new IllegalArgumentException("destSource cannot be null");
- }
- if (destDest == null)
- {
- throw new IllegalArgumentException("destDest cannot be null");
- }
- if (failureRetryInterval < 0 && failureRetryInterval != -1)
- {
- throw new IllegalArgumentException("failureRetryInterval must be > 0 or -1 to represent no retry");
- }
- if (maxRetries < 0)
- {
- throw new IllegalArgumentException("maxRetries must be >= 0");
- }
- if (failureRetryInterval == -1 && maxRetries > 0)
- {
- throw new IllegalArgumentException("If failureRetryInterval == -1 maxRetries must be 0");
- }
- if (maxBatchSize < 1)
- {
- throw new IllegalArgumentException("maxBatchSize must be >= 1");
- }
- if (maxBatchTime < 1 && maxBatchTime != -1)
- {
- throw new IllegalArgumentException("maxBatchTime must be >= 1 or -1 to represent unlimited batch time");
- }
- if (qosMode != QOS_AT_MOST_ONCE && qosMode != QOS_DUPLICATES_OK && qosMode != QOS_ONCE_AND_ONLY_ONCE)
- {
- throw new IllegalArgumentException("Invalid QoS mode " + qosMode);
- }
+ {
+ this.sourceCff = sourceCff;
- this.sourceCfFactory = sourceCfFactory;
+ this.targetCff = destCff;
- this.destCfFactory = destCfFactory;
+ this.sourceDestination = sourceDestination;
- this.destSource = destSource;
+ this.targetDestination = targetDestination;
- this.destDest = destDest;
-
this.sourceUsername = sourceUsername;
this.sourcePassword = sourcePassword;
- this.destUsername = destUsername;
+ this.targetUsername = targetUsername;
- this.destPassword = destPassword;
+ this.targetPassword = targetPassword;
this.selector = selector;
@@ -275,6 +244,8 @@
this.subName = subName;
this.clientID = clientID;
+
+ checkParams();
this.messages = new LinkedList();
@@ -325,6 +296,8 @@
else
{
log.warn("Failed to start bridge");
+
+ failed = true;
}
}
@@ -359,9 +332,12 @@
if (trace) { log.trace("Checker thread has finished"); }
}
- connSource.close();
+ sourceConn.close();
- connDest.close();
+ if (targetConn != null)
+ {
+ targetConn.close();
+ }
if (tx != null)
{
@@ -386,7 +362,7 @@
{
paused = true;
- connSource.stop();
+ sourceConn.stop();
}
if (trace) { log.trace("Paused " + this); }
@@ -400,23 +376,328 @@
{
paused = false;
- connSource.start();
+ sourceConn.start();
}
if (trace) { log.trace("Resumed " + this); }
}
+ public Destination getSourceDestination()
+ {
+ return sourceDestination;
+ }
+
+ public void setSourceDestination(Destination dest)
+ {
+ if (started)
+ {
+ log.warn("Cannot set SourceDestination while bridge is started");
+ return;
+ }
+ this.sourceDestination = dest;
+ checkParams();
+ }
+
+ public Destination getTargetDestination()
+ {
+ return targetDestination;
+ }
+
+ public void setTargetDestination(Destination dest)
+ {
+ if (started)
+ {
+ log.warn("Cannot set TargetDestination while bridge is started");
+ return;
+ }
+ this.targetDestination = dest;
+ checkParams();
+ }
+
+ public String getSourceUsername()
+ {
+ return sourceUsername;
+ }
+
+ public synchronized void setSourceUserName(String name)
+ {
+ if (started)
+ {
+ log.warn("Cannot set SourceUsername while bridge is started");
+ return;
+ }
+ sourceUsername = name;
+ checkParams();
+ }
+
+ public synchronized String getSourcePassword()
+ {
+ return sourcePassword;
+ }
+
+ public synchronized void setSourcePassword(String pwd)
+ {
+ if (started)
+ {
+ log.warn("Cannot set SourcePassword while bridge is started");
+ return;
+ }
+ sourcePassword = pwd;
+ checkParams();
+ }
+
+ public synchronized String getDestUsername()
+ {
+ return targetUsername;
+ }
+
+ public synchronized void setDestUserName(String name)
+ {
+ if (started)
+ {
+ log.warn("Cannot set DestUserName while bridge is started");
+ return;
+ }
+ this.targetUsername = name;
+ checkParams();
+ }
+
+ public synchronized String getDestPassword()
+ {
+ return this.targetPassword;
+ }
+
+ public synchronized void setDestPassword(String pwd)
+ {
+ if (started)
+ {
+ log.warn("Cannot set DestPassword while bridge is started");
+ return;
+ }
+ this.targetPassword = pwd;
+ checkParams();
+ }
+
+ public synchronized String getSelector()
+ {
+ return selector;
+ }
+
+ public synchronized void setSelector(String selector)
+ {
+ if (started)
+ {
+ log.warn("Cannot set Selector while bridge is started");
+ return;
+ }
+ this.selector = selector;
+ checkParams();
+ }
+
+ public synchronized long getFailureRetryInterval()
+ {
+ return failureRetryInterval;
+ }
+
+ public synchronized void setFailureRetryInterval(long interval)
+ {
+ if (started)
+ {
+ log.warn("Cannot set FailureRetryInterval while bridge is started");
+ return;
+ }
+
+ this.failureRetryInterval = interval;
+ checkParams();
+ }
+
+ public synchronized int getMaxRetries()
+ {
+ return maxRetries;
+ }
+
+ public synchronized void setMaxRetries(int retries)
+ {
+ if (started)
+ {
+ log.warn("Cannot set MaxRetries while bridge is started");
+ return;
+ }
+
+ this.maxRetries = retries;
+ checkParams();
+ }
+
+ public synchronized int getQualityOfServiceMode()
+ {
+ return qualityOfServiceMode;
+ }
+
+ public synchronized void setQualityOfServiceMode(int mode)
+ {
+ if (started)
+ {
+ log.warn("Cannot set QualityOfServiceMode while bridge is started");
+ return;
+ }
+
+ qualityOfServiceMode = mode;
+ checkParams();
+ }
+
+ public synchronized int getMaxBatchSize()
+ {
+ return maxBatchSize;
+ }
+
+ public synchronized void setMaxBatchSize(int size)
+ {
+ if (started)
+ {
+ log.warn("Cannot set MaxBatchSize while bridge is started");
+ return;
+ }
+
+ maxBatchSize = size;
+ checkParams();
+ }
+
+ public synchronized long getMaxBatchTime()
+ {
+ return maxBatchTime;
+ }
+
+ public synchronized void setMaxBatchTime(long time)
+ {
+ if (started)
+ {
+ log.warn("Cannot set MaxBatchTime while bridge is started");
+ return;
+ }
+
+ maxBatchTime = time;
+ checkParams();
+ }
+
+ public synchronized String getSubName()
+ {
+ return this.subName;
+ }
+
+ public synchronized void setSubName(String subname)
+ {
+ if (started)
+ {
+ log.warn("Cannot set SubName while bridge is started");
+ return;
+ }
+
+ this.subName = subname;
+ checkParams();
+ }
+
+ public synchronized String getClientID()
+ {
+ return clientID;
+ }
+
+ public synchronized void setClientID(String clientID)
+ {
+ if (started)
+ {
+ log.warn("Cannot set ClientID while bridge is started");
+ return;
+ }
+
+ this.clientID = clientID;
+ checkParams();
+ }
+
+ public synchronized boolean isPaused()
+ {
+ return paused;
+ }
+
+ public synchronized boolean isFailed()
+ {
+ return failed;
+ }
+
+ public synchronized void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff)
+ {
+ if (started)
+ {
+ log.warn("Cannot set SourceConnectionFactoryFactory while bridge is started");
+ return;
+ }
+ this.sourceCff = cff;
+ }
+
+ public synchronized void setDestConnectionFactoryFactory(ConnectionFactoryFactory cff)
+ {
+ if (started)
+ {
+ log.warn("Cannot set DestConnectionFactoryFactory while bridge is started");
+ return;
+ }
+ this.targetCff = cff;
+ }
+
// Private -------------------------------------------------------------------
+ private void checkParams()
+ {
+ if (sourceCff == null)
+ {
+ throw new IllegalArgumentException("sourceCfFactory cannot be null");
+ }
+ if (targetCff == null)
+ {
+ throw new IllegalArgumentException("destCfFactory cannot be null");
+ }
+ if (sourceDestination == null)
+ {
+ throw new IllegalArgumentException("destSource cannot be null");
+ }
+ if (targetDestination == null)
+ {
+ throw new IllegalArgumentException("destDest cannot be null");
+ }
+ if (failureRetryInterval < 0 && failureRetryInterval != -1)
+ {
+ throw new IllegalArgumentException("failureRetryInterval must be > 0 or -1 to represent no retry");
+ }
+ if (maxRetries < 0 && maxRetries != -1)
+ {
+ throw new IllegalArgumentException("maxRetries must be >= 0 or -1 to represent infinite retries");
+ }
+ if (failureRetryInterval == -1 && maxRetries > 0)
+ {
+ throw new IllegalArgumentException("If failureRetryInterval == -1 maxRetries must be 0");
+ }
+ if (maxBatchSize < 1)
+ {
+ throw new IllegalArgumentException("maxBatchSize must be >= 1");
+ }
+ if (maxBatchTime < 1 && maxBatchTime != -1)
+ {
+ throw new IllegalArgumentException("maxBatchTime must be >= 1 or -1 to represent unlimited batch time");
+ }
+ if (this.qualityOfServiceMode != QOS_AT_MOST_ONCE && qualityOfServiceMode != QOS_DUPLICATES_OK && qualityOfServiceMode != QOS_ONCE_AND_ONLY_ONCE)
+ {
+ throw new IllegalArgumentException("Invalid quality of service mode " + qualityOfServiceMode);
+ }
+ }
+
private void enlistResources(Transaction tx) throws Exception
{
if (trace) { log.trace("Enlisting resources in tx"); }
- XAResource resSource = ((XASession)sessSource).getXAResource();
+ XAResource resSource = ((XASession)sourceSession).getXAResource();
tx.enlistResource(resSource);
- XAResource resDest = ((XASession)sessDest).getXAResource();
+ XAResource resDest = ((XASession)targetSession).getXAResource();
tx.enlistResource(resDest);
@@ -427,11 +708,11 @@
{
if (trace) { log.trace("Delisting resources from tx"); }
- XAResource resSource = ((XASession)sessSource).getXAResource();
+ XAResource resSource = ((XASession)sourceSession).getXAResource();
tx.delistResource(resSource, XAResource.TMSUCCESS);
- XAResource resDest = ((XASession)sessDest).getXAResource();
+ XAResource resDest = ((XASession)targetSession).getXAResource();
tx.delistResource(resDest, XAResource.TMSUCCESS);
@@ -462,14 +743,22 @@
{
if (tm == null)
{
-// tm = TransactionManagerLocator.getInstance().locate();
-//
-// if (tm == null)
-// {
-// throw new IllegalStateException("Cannot locate a transaction manager");
-// }
+ //tm = TransactionManagerLocator.getInstance().locate();
tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+ if (tm == null)
+ {
+ throw new IllegalStateException("Cannot locate a transaction manager");
+ }
+
+ //Sanity check
+ if (tm instanceof TxManager)
+ {
+ log.warn("WARNING! The old JBoss transaction manager is being used. " +
+ "This does not have XA transaction recovery functionality. " +
+ "For XA transaction recovery please deploy the JBoss Transactions JTA/JTS implementation.");
+ }
}
return tm;
@@ -516,73 +805,128 @@
}
return conn;
}
-
+
+ /*
+ * Source and target on same server
+ * --------------------------------
+ * If the source and target destinations are on the same server (same resource manager) then,
+ * in order to get QOS_ONCE_AND_ONLY_ONCE, we simply need to consuming and send in a single
+ * local JMS transaction.
+ *
+ * We actually use a single local transacted session for the other QoS modes too since this
+ * is more performant than using DUPS_OK_ACKNOWLEDGE or AUTO_ACKNOWLEDGE session ack modes, so effectively
+ * the QoS is upgraded.
+ *
+ * Source and target on different server
+ * -------------------------------------
+ * If the source and target destinations are on a different servers (different resource managers) then:
+ *
+ * If desired QoS is QOS_ONCE_AND_ONLY_ONCE, then we start a JTA transaction and enlist the consuming and sending
+ * XAResources in that.
+ *
+ * If desired QoS is QOS_DUPLICATES_OK then, we use CLIENT_ACKNOWLEDGE for the consuming session and
+ * AUTO_ACKNOWLEDGE (this is ignored) for the sending session if the maxBatchSize == 1, otherwise we
+ * use a local transacted session for the sending session where maxBatchSize > 1, since this is more performant
+ * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
+ * *after* the batch has been sent
+ *
+ * If desired QoS is QOS_AT_MOST_ONCE then, if maxBatchSize == 1, we use AUTO_ACKNOWLEDGE for the consuming session,
+ * and AUTO_ACKNOWLEDGE for the sending session.
+ * If maxBatchSize > 1, we use CLIENT_ACKNOWLEDGE for the consuming session and a local transacted session for the
+ * sending session.
+ *
+ * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
+ * *before* the batch has been sent
+ *
+ */
private boolean setupJMSObjects()
{
try
- {
- connSource = createConnection(sourceUsername, sourcePassword, sourceCfFactory);
+ {
+ //Are source and target destinations on the server? If so we can get once and only once
+ //just using a local transacted session
+ boolean sourceAndTargetSameServer = sourceCff == targetCff;
- connDest = createConnection(destUsername, destPassword, destCfFactory);
+ sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff);
+ if (!sourceAndTargetSameServer)
+ {
+ targetConn = createConnection(targetUsername, targetPassword, targetCff);
+ }
+
if (clientID != null)
{
- connSource.setClientID(clientID);
+ sourceConn.setClientID(clientID);
}
Session sess;
- if (qualityOfServiceMode == QOS_ONCE_AND_ONLY_ONCE)
+ if (sourceAndTargetSameServer)
{
- //Create an XASession for consuming from the source
- if (trace) { log.trace("Creating XA source session"); }
- sessSource = ((XAConnection)connSource).createXASession();
+ //We simply use a single local transacted session for consuming and sending
- sess = ((XASession)sessSource).getSession();
+ sourceSession = sourceConn.createSession(true, Session.SESSION_TRANSACTED);
+
+ sess = sourceSession;
}
else
{
- if (trace) { log.trace("Creating non XA source session"); }
+ //Source and destination are on different resource managers
- //Create a standard session for consuming from the source
-
- //If the QoS is at_most_once, and max batch size is 1 then we use AUTO_ACKNOWLEDGE
- //If the QoS is at_most_once, and max batch size > 1 or -1, then we use CLIENT_ACKNOWLEDGE
- //We could use CLIENT_ACKNOWLEDGE for both the above but AUTO_ACKNOWLEGE may be slightly more
- //performant in some implementations that manually acking every time but it really depends
- //on the implementation.
- //We could also use local transacted for both the above but don't for the same reasons.
-
- //If the QoS is duplicates_ok, we use CLIENT_ACKNOWLEDGE
- //We could use local transacted, whether one is faster than the other probably depends on the
- //messaging implementation but there's probably not much in it
-
- int ackMode;
- if (qualityOfServiceMode == QOS_AT_MOST_ONCE && maxBatchSize == 1)
+ if (qualityOfServiceMode == QOS_ONCE_AND_ONLY_ONCE)
{
- ackMode = Session.AUTO_ACKNOWLEDGE;
+ //Create an XASession for consuming from the source
+ if (trace) { log.trace("Creating XA source session"); }
+
+ sourceSession = ((XAConnection)sourceConn).createXASession();
+
+ sess = ((XASession)sourceSession).getSession();
+
+ usingXA = true;
}
else
{
- ackMode = Session.CLIENT_ACKNOWLEDGE;
+ if (trace) { log.trace("Creating non XA source session"); }
- manualAck = true;
+ //Create a standard session for consuming from the source
+
+ //If the QoS is at_most_once, and max batch size is 1 then we use AUTO_ACKNOWLEDGE
+ //If the QoS is at_most_once, and max batch size > 1 or -1, then we use CLIENT_ACKNOWLEDGE
+ //We could use CLIENT_ACKNOWLEDGE for both the above but AUTO_ACKNOWLEGE may be slightly more
+ //performant in some implementations that manually acking every time but it really depends
+ //on the implementation.
+ //We could also use local transacted for both the above but don't for the same reasons.
+
+ //If the QoS is duplicates_ok, we use CLIENT_ACKNOWLEDGE
+ //We could use local transacted, whether one is faster than the other probably depends on the
+ //messaging implementation but there's probably not much in it
+
+ int ackMode;
+ if (qualityOfServiceMode == QOS_AT_MOST_ONCE && maxBatchSize == 1)
+ {
+ ackMode = Session.AUTO_ACKNOWLEDGE;
+ }
+ else
+ {
+ ackMode = Session.CLIENT_ACKNOWLEDGE;
+
+ }
+
+ sourceSession = sourceConn.createSession(false, ackMode);
+
+ sess = sourceSession;
}
-
- sessSource = connSource.createSession(false, ackMode);
-
- sess = sessSource;
}
if (subName == null)
{
if (selector == null)
{
- consumer = sess.createConsumer(destSource);
+ consumer = sess.createConsumer(sourceDestination);
}
else
{
- consumer = sess.createConsumer(destSource, selector, false);
+ consumer = sess.createConsumer(sourceDestination, selector, false);
}
}
else
@@ -590,42 +934,47 @@
//Durable subscription
if (selector == null)
{
- consumer = sess.createDurableSubscriber((Topic)destSource, subName);
+ consumer = sess.createDurableSubscriber((Topic)sourceDestination, subName);
}
else
{
- consumer = sess.createDurableSubscriber((Topic)destSource, subName, selector, false);
+ consumer = sess.createDurableSubscriber((Topic)sourceDestination, subName, selector, false);
}
}
- if (qualityOfServiceMode == QOS_ONCE_AND_ONLY_ONCE)
- {
- if (trace) { log.trace("Creating XA dest session"); }
-
- //Create an XA sesion for sending to the destination
-
- sessDest = ((XAConnection)connDest).createXASession();
-
- sess = ((XASession)sessDest).getSession();
+ //Now the sending session
+
+ if (!sourceAndTargetSameServer)
+ {
+ if (usingXA)
+ {
+ if (trace) { log.trace("Creating XA dest session"); }
+
+ //Create an XA sesion for sending to the destination
+
+ targetSession = ((XAConnection)targetConn).createXASession();
+
+ sess = ((XASession)targetSession).getSession();
+ }
+ else
+ {
+ if (trace) { log.trace("Creating non XA dest session"); }
+
+ //Create a standard session for sending to the destination
+
+ //If maxBatchSize == 1 we just create a non transacted session, otherwise we
+ //create a transacted session for the send, since sending the batch in a transaction
+ //is likely to be more efficient than sending messages individually
+
+ boolean manualCommit = maxBatchSize == 1;
+
+ targetSession = targetConn.createSession(manualCommit, manualCommit ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
+
+ sess = targetSession;
+ }
}
- else
- {
- if (trace) { log.trace("Creating non XA dest session"); }
-
- //Create a standard session for sending to the destination
-
- //If maxBatchSize == 1 we just create a non transacted session, otherwise we
- //create a transacted session for the send, since sending the batch in a transaction
- //is likely to be more efficient than sending messages individually
-
- manualCommit = maxBatchSize == 1;
-
- sessDest = connDest.createSession(manualCommit, manualCommit ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
-
- sess = sessDest;
- }
- if (qualityOfServiceMode == QOS_ONCE_AND_ONLY_ONCE)
+ if (usingXA)
{
if (trace) { log.trace("Starting JTA transaction"); }
@@ -634,11 +983,11 @@
enlistResources(tx);
}
- producer = sess.createProducer(destDest);
+ producer = sess.createProducer(targetDestination);
consumer.setMessageListener(new SourceListener());
- connSource.start();
+ sourceConn.start();
return true;
}
@@ -678,14 +1027,17 @@
//Close the old objects
try
{
- connSource.close();
+ sourceConn.close();
}
catch (Throwable ignore)
{
}
try
{
- connDest.close();
+ if (targetConn != null)
+ {
+ targetConn.close();
+ }
}
catch (Throwable ignore)
{
@@ -746,138 +1098,161 @@
{
if (trace) { log.trace("Sending batch of " + messages.size() + " messages"); }
- synchronized (lock)
+ if (paused)
{
- try
+ //Don't send now
+ if (trace) { log.trace("Paused, so not sending now"); }
+
+ return;
+ }
+
+ try
+ {
+ if (qualityOfServiceMode == QOS_AT_MOST_ONCE)
{
- if (paused)
+ //We ack *before* we send
+ if (sourceSession.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
{
- //Don't send now
- if (trace) { log.trace("Paused, so not sending now"); }
-
- return;
+ //Ack on the last message
+ ((Message)messages.getLast()).acknowledge();
}
+ }
+
+ //Now send the message(s)
- if (qualityOfServiceMode == QOS_AT_MOST_ONCE)
- {
- //We ack before we send
- if (manualAck)
- {
- //Ack on the last message
- ((Message)messages.getLast()).acknowledge();
- }
- }
+ Iterator iter = messages.iterator();
+
+ Message msg = null;
+
+ while (iter.hasNext())
+ {
+ msg = (Message)iter.next();
- //Now send the message(s)
-
- Iterator iter = messages.iterator();
+ if (trace) { log.trace("Sending message " + msg); }
- Message msg = null;
+ producer.send(msg);
- while (iter.hasNext())
- {
- msg = (Message)iter.next();
-
- if (trace) { log.trace("Sending message " + msg); }
-
- producer.send(msg);
-
- if (trace) { log.trace("Sent message " + msg); }
- }
+ if (trace) { log.trace("Sent message " + msg); }
+ }
+
+ if (qualityOfServiceMode == QOS_DUPLICATES_OK)
+ {
+ //We ack the source message(s) after sending
- if (qualityOfServiceMode == QOS_DUPLICATES_OK)
- {
- //We ack the source message(s) after sending
-
- if (manualAck)
- {
- //Ack on the last message
- ((Message)messages.getLast()).acknowledge();
- }
- }
+ if (sourceSession.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ //Ack on the last message
+ ((Message)messages.getLast()).acknowledge();
+ }
+ }
+
+ //Now we commit the sending session if necessary
+ if (targetSession != null && targetSession.getTransacted() && !usingXA)
+ {
+ if (trace) { log.trace("Committing target session"); }
- //Now we commit the sending session if necessary
- if (manualCommit)
- {
- sessDest.commit();
- }
+ targetSession.commit();
- if (qualityOfServiceMode == QOS_ONCE_AND_ONLY_ONCE)
- {
- //Commit the JTA transaction and start another
-
- delistResources(tx);
-
- if (trace) { log.trace("Committing JTA transaction"); }
+ if (trace) { log.trace("Committed target session"); }
+ }
+
+ //And commit the consuming session if necessary
+ if (sourceSession.getTransacted() && !usingXA)
+ {
+ if (trace) { log.trace("Committing source session"); }
+
+ sourceSession.commit();
+
+ if (trace) { log.trace("Committed source session"); }
+ }
+
+ if (usingXA)
+ {
+ //Commit the JTA transaction and start another
+
+ delistResources(tx);
- tx.commit();
-
- if (trace) { log.trace("Committed JTA transaction"); }
-
- tx = startTx();
-
- enlistResources(tx);
- }
+ if (trace) { log.trace("Committing JTA transaction"); }
- //Clear the messages
- messages.clear();
+ tx.commit();
+
+ if (trace) { log.trace("Committed JTA transaction"); }
+
+ tx = startTx();
+
+ enlistResources(tx);
}
- catch (Exception e)
+
+ //Clear the messages
+ messages.clear();
+ }
+ catch (Exception e)
+ {
+ log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
+
+ handleFailure();
+ }
+ }
+
+ private void handleFailure()
+ {
+ failed = true;
+
+ //Failure must be handled on a separate thread to the onMessage thread since we can't close the connection
+ //from inside the onMessage method since it will block waiting for onMessage to complete
+ Thread t = new Thread(new FailureHandler());
+
+ t.start();
+ }
+
+ // Inner classes ---------------------------------------------------------------
+
+ private class FailureHandler implements Runnable
+ {
+ public void run()
+ {
+ // Clear the messages
+ messages.clear();
+
+ cleanup();
+
+ boolean ok = false;
+
+ if (maxRetries > 0 || maxRetries == -1)
{
- log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
+ log.warn( "Will retry after a pause of " + failureRetryInterval);
- /*
- * If an Exception occurs in attempting to send / ack the batch, this might be due
- * to a network problem on either the source or destination connection.
- * If it was on the source connection then the server has probably NACKed the unacked
- * messages back to the destination anyway.
- * If the failure occurred during 2PC commit protocol then the participants may or may not
- * have reached the prepared state, if they do then the tx will commit at some time during
- * recovery.
- *
- * So we can safely close the dead connections, without fear of stepping outside our
- * QoS guarantee.
- *
- *
- */
+ pause(failureRetryInterval);
- //Clear the messages
- messages.clear();
-
- cleanup();
+ //Now we try
+ ok = setupJMSObjectsWithRetry();
+ }
+
+ if (!ok)
+ {
+ //We haven't managed to recreate connections or maxRetries = 0
+ log.warn("Unable to set up connections, bridge will be stopped");
- boolean ok = false;
-
- if (maxRetries > 0 || maxRetries == -1)
- {
- log.warn("Will try and re-set up connections after a pause of " + failureRetryInterval);
-
- pause(this.failureRetryInterval);
-
- //Now we try
- ok = setupJMSObjectsWithRetry();
+ try
+ {
+ stop();
}
+ catch (Exception ignore)
+ {
+ }
+ }
+ else
+ {
+ log.info("Succeeded in reconnecting to servers");
- if (!ok)
+ synchronized (lock)
{
- //We haven't managed to recreate connections or maxRetries = 0
- log.warn("Unable to set up connections, bridge will be stopped");
-
- try
- {
- stop();
- }
- catch (Exception ignore)
- {
- }
+ failed = false;
}
-
- }
+ }
}
}
- // Inner classes ---------------------------------------------------------------
-
private class BatchTimeChecker implements Runnable
{
public void run()
@@ -894,13 +1269,16 @@
{
if (trace) { log.trace(this + " waited enough"); }
- if (!messages.isEmpty())
- {
- if (trace) { log.trace(this + " got some messages so sending batch"); }
-
- sendBatch();
-
- if (trace) { log.trace(this + " sent batch"); }
+ synchronized (lock)
+ {
+ if (!failed && !messages.isEmpty())
+ {
+ if (trace) { log.trace(this + " got some messages so sending batch"); }
+
+ sendBatch();
+
+ if (trace) { log.trace(this + " sent batch"); }
+ }
}
batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
@@ -933,6 +1311,14 @@
{
synchronized (lock)
{
+ if (failed)
+ {
+ //Ignore the message
+ if (trace) { log.trace("Bridge has failed so ignoring message"); }
+
+ return;
+ }
+
if (trace) { log.trace(this + " received message " + msg); }
messages.add(msg);
Added: trunk/src/main/org/jboss/jms/server/bridge/BridgeMBean.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/BridgeMBean.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/bridge/BridgeMBean.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+package org.jboss.jms.server.bridge;
+
+
+/**
+ * A BridgeMBean
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface BridgeMBean
+{
+ String getSourceDestinationLookup();
+
+ void setSourceDestinationLookup(String lookup);
+
+ String getTargetDestinationLookup();
+
+ void setTargetDestinationLookup(String lookup);
+
+ String getSourceUsername();
+
+ void setSourceUserName(String name);
+
+ String getSourcePassword();
+
+ void setSourcePassword(String pwd);
+
+ String getTargetUsername();
+
+ void setTargetUsername(String name);
+
+ String getTargetPassword();
+
+ void setTargetPassword(String pwd);
+
+ String getSelector();
+
+ void setSelector(String selector);
+
+ long getFailureRetryInterval();
+
+ void setFailureRetryInterval(long interval);
+
+ int getMaxRetries();
+
+ void setMaxRetries(int retries);
+
+ int getQualityOfServiceMode();
+
+ void setQualityOfServiceMode(int mode);
+
+ int getMaxBatchSize();
+
+ void setMaxBatchSize(int size);
+
+ long getMaxBatchTime();
+
+ void setMaxBatchTime(long time);
+
+ String getSubName();
+
+ void setSubName(String subname);
+
+ String getClientID();
+
+ void setClientID(String id);
+
+ boolean isPaused();
+
+ boolean isFailed();
+
+ void setSourceJNDIProperties(String props);
+
+ void setTargetJNDIProperties(String props);
+
+ String getSourceJNDIProperties();
+
+ String getTargetJNDIProperties();
+
+ void pause() throws Exception;
+
+ void resume() throws Exception;
+}
Added: trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/bridge/BridgeService.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,395 @@
+/*
+ * 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.
+ */
+package org.jboss.jms.server.bridge;
+
+import java.io.ByteArrayInputStream;
+import java.util.Properties;
+
+import javax.jms.Destination;
+import javax.naming.InitialContext;
+
+import org.jboss.messaging.core.plugin.contract.MessagingComponent;
+import org.jboss.messaging.core.plugin.contract.ServerPlugin;
+import org.jboss.system.ServiceMBeanSupport;
+
+/**
+ * A BridgeService
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class BridgeService extends ServiceMBeanSupport
+ implements ServerPlugin, BridgeMBean
+{
+ private Bridge bridge;
+
+ private String sourceJNDIProperties;
+
+ private String targetJNDIProperties;
+
+ private String sourceConnectionFactoryLookup;
+
+ private String targetConnectionFactoryLookup;
+
+ private String sourceDestinationLookup;
+
+ private String targetDestinationLookup;
+
+
+ public BridgeService()
+ {
+ bridge = new Bridge();
+ }
+
+ // JMX attributes ----------------------------------------------------------------
+
+ public synchronized String getSourceConnectionFactoryLookup()
+ {
+ return this.sourceConnectionFactoryLookup;
+ }
+
+ public synchronized String getTargetConnectionFactoryLookup()
+ {
+ return this.targetConnectionFactoryLookup;
+ }
+
+ public synchronized void setSourceConnectionFactoryLookup(String lookup)
+ {
+ if (getState() != STOPPED)
+ {
+ log.warn("Cannot set SourceConnectionFactoryLookup when bridge is started");
+ return;
+ }
+ this.sourceConnectionFactoryLookup = lookup;
+ }
+
+ public synchronized void setTargetConnectionFactoryLookup(String lookup)
+ {
+ if (getState() != STOPPED)
+ {
+ log.warn("Cannot set DestConnectionFactoryLookup when bridge is started");
+ return;
+ }
+ this.targetConnectionFactoryLookup = lookup;
+ }
+
+ public String getSourceDestinationLookup()
+ {
+ return sourceDestinationLookup;
+ }
+
+ public String getTargetDestinationLookup()
+ {
+ return targetDestinationLookup;
+ }
+
+ public void setSourceDestinationLookup(String lookup)
+ {
+ if (getState() != STOPPED)
+ {
+ log.warn("Cannot set SourceDestinationLookup when bridge is started");
+ return;
+ }
+ this.sourceDestinationLookup = lookup;
+ }
+
+ public void setTargetDestinationLookup(String lookup)
+ {
+ if (getState() != STOPPED)
+ {
+ log.warn("Cannot set TargetDestinationLookup when bridge is started");
+ return;
+ }
+ this.targetDestinationLookup = lookup;
+ }
+
+ public String getSourceUsername()
+ {
+ return bridge.getSourceUsername();
+ }
+
+ public String getSourcePassword()
+ {
+ return bridge.getSourcePassword();
+ }
+
+ public void setSourceUserName(String name)
+ {
+ bridge.setSourceUserName(name);
+ }
+
+ public void setSourcePassword(String pwd)
+ {
+ bridge.setSourcePassword(pwd);
+ }
+
+ public String getTargetUsername()
+ {
+ return bridge.getDestUsername();
+ }
+
+ public String getTargetPassword()
+ {
+ return bridge.getDestPassword();
+ }
+
+ public void setTargetUsername(String name)
+ {
+ bridge.setDestUserName(name);
+ }
+
+ public void setTargetPassword(String pwd)
+ {
+ bridge.setDestPassword(pwd);
+ }
+
+ public int getQualityOfServiceMode()
+ {
+ return bridge.getQualityOfServiceMode();
+ }
+
+ public void setQualityOfServiceMode(int mode)
+ {
+ bridge.setQualityOfServiceMode(mode);
+ }
+
+ public String getSelector()
+ {
+ return bridge.getSelector();
+ }
+
+ public void setSelector(String selector)
+ {
+ bridge.setSelector(selector);
+ }
+
+ public int getMaxBatchSize()
+ {
+ return bridge.getMaxBatchSize();
+ }
+
+ public void setMaxBatchSize(int size)
+ {
+ bridge.setMaxBatchSize(size);
+ }
+
+ public long getMaxBatchTime()
+ {
+ return bridge.getMaxBatchTime();
+ }
+
+ public void setMaxBatchTime(long time)
+ {
+ bridge.setMaxBatchTime(time);
+ }
+
+ public String getSubName()
+ {
+ return bridge.getSubName();
+ }
+
+ public void setSubName(String subname)
+ {
+ bridge.setSubName(subname);
+ }
+
+ public String getClientID()
+ {
+ return bridge.getClientID();
+ }
+
+ public void setClientID(String clientID)
+ {
+ bridge.setClientID(clientID);
+ }
+
+ public long getFailureRetryInterval()
+ {
+ return bridge.getFailureRetryInterval();
+ }
+
+ public void setFailureRetryInterval(long interval)
+ {
+ bridge.setFailureRetryInterval(interval);
+ }
+
+ public int getMaxRetries()
+ {
+ return bridge.getMaxRetries();
+ }
+
+ public void setMaxRetries(int retries)
+ {
+ bridge.setMaxRetries(retries);
+ }
+
+ public boolean isFailed()
+ {
+ return bridge.isFailed();
+ }
+
+ public boolean isPaused()
+ {
+ return bridge.isPaused();
+ }
+
+ public synchronized String getSourceJNDIProperties()
+ {
+ return sourceJNDIProperties;
+ }
+
+ public synchronized void setSourceJNDIProperties(String props)
+ {
+ if (props != null)
+ {
+ props = props.trim();
+ if ("".equals(props))
+ {
+ props = null;
+ }
+ }
+ this.sourceJNDIProperties = props;
+ }
+
+ public synchronized String getTargetJNDIProperties()
+ {
+ return targetJNDIProperties;
+ }
+
+ public synchronized void setTargetJNDIProperties(String props)
+ {
+ if (props != null)
+ {
+ props = props.trim();
+ if ("".equals(props))
+ {
+ props = null;
+ }
+ }
+ this.targetJNDIProperties = props;
+ }
+
+ public MessagingComponent getInstance()
+ {
+ return bridge;
+ }
+
+ // JMX operations ----------------------------------------------------------------
+
+ public void pause() throws Exception
+ {
+ bridge.pause();
+ }
+
+ public void resume() throws Exception
+ {
+ bridge.resume();
+ }
+
+ // ServiceMBeanSupport overrides --------------------------------------------------
+
+ protected void startService() throws Exception
+ {
+ super.startService();
+
+ Properties sourceProps = null;
+
+ if (sourceJNDIProperties != null)
+ {
+ sourceProps = createProps(sourceJNDIProperties);
+ }
+
+ Properties targetProps = null;
+
+ if (targetJNDIProperties != null)
+ {
+ targetProps = createProps(targetJNDIProperties);
+ }
+
+ InitialContext icSource = null;
+
+ if (sourceProps == null)
+ {
+ icSource = new InitialContext();
+ }
+ else
+ {
+ icSource = new InitialContext(sourceProps);
+ }
+
+ Destination sourceDest = (Destination)icSource.lookup(sourceDestinationLookup);
+
+ InitialContext icDest = null;
+
+ if (targetProps == null)
+ {
+ icDest = new InitialContext();
+ }
+ else
+ {
+ icDest = new InitialContext(sourceProps);
+ }
+
+ Destination targetDest = (Destination)icDest.lookup(targetDestinationLookup);
+
+ ConnectionFactoryFactory sourceCff =
+ new JNDIConnectionFactoryFactory(sourceProps, sourceConnectionFactoryLookup);
+
+ ConnectionFactoryFactory destCff =
+ new JNDIConnectionFactoryFactory(targetProps, targetConnectionFactoryLookup);
+
+ bridge.setSourceDestination(sourceDest);
+
+ bridge.setTargetDestination(targetDest);
+
+ bridge.setSourceConnectionFactoryFactory(sourceCff);
+
+ bridge.setDestConnectionFactoryFactory(destCff);
+
+ bridge.start();
+ }
+
+
+ protected void stopService() throws Exception
+ {
+ bridge.stop();
+ }
+
+ // Private ---------------------------------------------------------------------------------
+
+ private Properties createProps(String propsString) throws Exception
+ {
+ ByteArrayInputStream is = new ByteArrayInputStream(propsString.getBytes());
+
+ Properties props = new Properties();
+
+ props.load(is);
+
+ return props;
+ }
+
+
+
+}
Modified: trunk/src/main/org/jboss/jms/server/bridge/JNDIConnectionFactoryFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/bridge/JNDIConnectionFactoryFactory.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/bridge/JNDIConnectionFactoryFactory.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -56,7 +56,14 @@
try
{
- ic = new InitialContext(jndiProperties);
+ if (jndiProperties == null)
+ {
+ ic = new InitialContext();
+ }
+ else
+ {
+ ic = new InitialContext(jndiProperties);
+ }
cf = (ConnectionFactory)ic.lookup(lookup);
}
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -500,8 +500,11 @@
this.usingVersion = version;
}
-
-
+ public ServerPeer getServerPeer()
+ {
+ return serverPeer;
+ }
+
public String toString()
{
return "ConnectionEndpoint[" + id + "]";
@@ -584,11 +587,6 @@
}
}
- ServerPeer getServerPeer()
- {
- return serverPeer;
- }
-
String getRemotingClientSessionId()
{
return remotingClientSessionId;
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -48,6 +48,7 @@
import org.jboss.messaging.core.Queue;
import org.jboss.messaging.core.local.PagingFilteredQueue;
import org.jboss.messaging.core.plugin.JDBCSupport;
+import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
import org.jboss.messaging.core.plugin.contract.Condition;
import org.jboss.messaging.core.plugin.contract.ConditionFactory;
import org.jboss.messaging.core.plugin.contract.MessageStore;
@@ -519,13 +520,22 @@
Condition condition = conditionFactory.createCondition(conditionText);
- Binding binding = createBinding(nodeID, condition, queueName, channelID,
- selector, true, failed, failedNodeID);
-
- log.debug(this + " loaded from database " + binding);
-
- binding.getQueue().deactivate();
- addBinding(binding);
+ //Temp hack
+ //For non clustered po don't want to load other nodes bindings!
+ if (!(this instanceof ClusteredPostOffice) && (nodeID != this.currentNodeId))
+ {
+ //Don't load other nodes binding
+ }
+ else
+ {
+ Binding binding = createBinding(nodeID, condition, queueName, channelID,
+ selector, true, failed, failedNodeID);
+
+ log.debug(this + " loaded from database " + binding);
+
+ binding.getQueue().deactivate();
+ addBinding(binding);
+ }
}
}
finally
Modified: trunk/tests/bin/runtest
===================================================================
--- trunk/tests/bin/runtest 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/bin/runtest 2007-01-16 20:58:56 UTC (rev 1970)
@@ -158,27 +158,9 @@
fi
fi
-if [ "$isRemote" = "true" ]; then
- export TEST_DATABASE TEST_SERIALIZATION TEST_CLUSTERED TEST_REMOTING
- $reldir/start-rmi-server $REMOTE_DEBUG_FLAG_0 -use-existent-test-classpath-file -index 0
- if [ "$TEST_CLUSTERED" = "true" ]; then
-
- # start the second remote server
- $reldir/start-rmi-server $REMOTE_DEBUG_FLAG_1 -use-existent-test-classpath-file -index 1
-
- # start the third remote server
- $reldir/start-rmi-server $REMOTE_DEBUG_FLAG_2 -use-existent-test-classpath-file -index 2
-
- # start the fourth remote server
- $reldir/start-rmi-server $REMOTE_DEBUG_FLAG_3 -use-existent-test-classpath-file -index 3
-
- fi
-fi
-
-
$JAVA_HOME/bin/java $JAVA_OPTS -cp "$CLASSPATH" \
org.jboss.test.messaging.tools.junit.SelectiveTestRunner $TARGET_CLASS $TARGET_TEST
Modified: trunk/tests/bin/start-rmi-server
===================================================================
--- trunk/tests/bin/start-rmi-server 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/bin/start-rmi-server 2007-01-16 20:58:56 UTC (rev 1970)
@@ -58,8 +58,9 @@
JAVA_OPTS="$JAVA_OPTS -Dtest.serialization=$TEST_SERIALIZATION"
fi
+# We need to append the index even if non clustered since we may have many non clustered servers
if [ "$TEST_REMOTING" != "" ]; then
- JAVA_OPTS="$JAVA_OPTS -Dtest.remoting=$TEST_REMOTING -Dtest.logfile.suffix=remote-server"
+ JAVA_OPTS="$JAVA_OPTS -Dtest.remoting=$TEST_REMOTING -Dtest.logfile.suffix=remote-server$index"
fi
if [ "$TEST_CLUSTERED" != "" ]; then
Added: trunk/tests/etc/bridge-recovery.properties
===================================================================
--- trunk/tests/etc/bridge-recovery.properties 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/etc/bridge-recovery.properties 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,9 @@
+#Only valid for testing the bridge recovery from within the test suite
+
+server0.jndi.java.naming.factory.initial=org.jboss.test.messaging.tools.jndi.RemoteInitialContextFactory
+server0.jndi.jboss.messaging.test.server.index=0
+server0.xaconnectionfactorylookup=/XAConnectionFactory
+
+server1.jndi.java.naming.factory.initial=org.jboss.test.messaging.tools.jndi.RemoteInitialContextFactory
+server1.jndi.jboss.messaging.test.server.index=1
+server1.xaconnectionfactorylookup=/XAConnectionFactory
Added: trunk/tests/etc/jbossjta-properties.xml
===================================================================
--- trunk/tests/etc/jbossjta-properties.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/etc/jbossjta-properties.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Arjuna JTA config for JBoss Messaging test suite
+This config has some quicker settings (lik recovery period) than you would
+probably have in a real production config, this is so the tests don't take aeons to run -->
+
+<transaction-service>
+
+ <properties depends="common" name="arjuna">
+ <!--
+ Transaction Reaper Timeout (default is 120000 microseconds).
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.coordinator.txReaperTimeout" value="120000"/>
+ <!--
+ Transaction Reaper Mode, can be: NORMAL or DYNAMIC (default is NORMAL).
+ -->
+ <property name="com.arjuna.ats.arjuna.coordinator.txReaperMode" value="NORMAL"/>
+ <!--
+ (default is NO)
+ -->
+ <property name="com.arjuna.ats.arjuna.coordinator.asyncCommit" value="NO"/>
+ <!--
+ (default is NO)
+ -->
+ <property name="com.arjuna.ats.arjuna.coordinator.asyncPrepare" value="NO"/>
+ <!--
+ (default is YES)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.coordinator.commitOnePhase" value="YES"/>
+ <!--
+ (default is defaultStore)
+ -->
+ <property name="com.arjuna.ats.arjuna.objectstore.localOSRoot" value="defaultStore"/>
+ <!--
+ default is under user.home - must be writeable!)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.objectstore.objectStoreDir" value="ObjectStore"/>
+ <!--
+ (default is ON)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.objectstore.objectStoreSync" value="ON"/>
+ <!--
+ (default is ShadowNoFileLockStore)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.objectstore.objectStoreType" value="ShadowNoFileLockStore"/>
+ <!--
+ (default is 255)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.objectstore.hashedDirectories" value="255"/>
+ <!--
+ (default is ON)
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.objectstore.transactionSync" value="ON"/>
+ <!--
+ (Must be unique across all Arjuna instances.)
+ -->
+ <property name="com.arjuna.ats.arjuna.xa.nodeIdentifier" value="node0"/>
+ <!-- property
+ name="com.arjuna.ats.arjuna.coordinator.actionStore"
+ value="HashedActionStore"
+ value="JDBCActionStore"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.jdbcTxDbAccess"
+ value="JDBCAccess"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.objectStoreType"
+ value="ShadowNoFileLockStore"
+ value="JDBCStore"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.jdbcUserDbAccess"
+ value="JDBCAccess"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeInitial"
+ value="1"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeMaximum"
+ value="1"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.objectstore.jdbcPoolPutConnections"
+ value="false"
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.internal.arjuna.objectstore.cacheStore.size"
+ value=""
+ -->
+ <!-- property
+ name="com.arjuna.ats.arjuna.internal.arjuna.objectstore.cacheStore.period"
+ value=""
+ -->
+ <!--
+ The location for creating temporary files, e.g., Uids.
+ Default is under user.home.
+ IMPORTANT: make sure the directory is lockable, e.g., /tmp on Unix
+ may not be!
+ -->
+ <!--
+ <property
+ name="com.arjuna.ats.arjuna.common.varDir"
+ value="var"/>
+ -->
+ </properties>
+ <properties depends="arjuna" name="recoverymanager">
+ <!--
+ Properties used only by the RecoveryManager.
+ -->
+ <!--
+ Periodic recovery settings.
+ Time values in this section are in seconds.
+ -->
+ <!--
+ Interval in seconds between initiating the periodic recovery modules.
+ Default is 120 seconds.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.periodicRecoveryPeriod" value="10"/>
+ <!--
+ Interval in seconds between first and second pass of periodic recovery.
+ Default is 10 seconds.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryBackoffPeriod" value="2"/>
+
+ <!--
+ Expired entry removal
+ -->
+ <!--
+ Expiry scanners to use (order of invocation is random).
+ Names must begin with "com.arjuna.ats.arjuna.recovery.expiryScanner"
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.expiryScannerTransactionStatusManager" value="com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"/>
+ <!--
+ Interval, in hours, between running the expiry scanners.
+ This can be quite long. The absolute value determines the interval -
+ if the value is negative, the scan will NOT be run until after one
+ interval has elapsed. If positive the first scan will be immediately
+ after startup. Zero will prevent any scanning.
+ Default = 12 = run immediately, then every 12 hours.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.expiryScanInterval" value="12"/>
+ <!--
+ Age, in hours, for removal of transaction status manager item.
+ This should be longer than any ts-using process will remain running.
+ Zero = Never removed. Default is 12.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerExpiryTime" value="12"/>
+ <!--
+ Use this to fix the port on which the TransactionStatusManager listens,
+ The default behaviour is to use any free port.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort" value="0"/>
+ <!--
+ Properties used only by the RecoveryManager.
+ -->
+ <!--
+ Periodic recovery modules to use. Invoked in sort-order of names.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryExtension1" value="com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule"/>
+ </properties>
+ <properties name="common">
+ <!-- CLF 2.0 properties -->
+ <property name="com.arjuna.common.util.logging.DebugLevel"
+ type="System" value="0x00000000"/>
+ <property name="com.arjuna.common.util.logging.FacilityLevel"
+ type="System" value="0xffffffff"/>
+ <property name="com.arjuna.common.util.logging.VisibilityLevel"
+ type="System" value="0xffffffff"/>
+ <property name="com.arjuna.common.util.logger" type="System" value="log4j"/>
+ </properties>
+ <properties depends="arjuna" name="txoj">
+ <!--
+ (default is LockStore of installation - must be writeable!)
+ -->
+ <!--
+ <property
+ name="com.arjuna.ats.txoj.lockstore.lockStoreDir"
+ value="LockStore"/>
+ -->
+ <!--
+ (default is BasicLockStore)
+ -->
+ <property name="com.arjuna.ats.txoj.lockstore.lockStoreType" value="BasicLockStore"/>
+ <!--
+ (default is NO)
+ -->
+ <property name="com.arjuna.ats.txoj.lockstore.multipleLockStore" value="NO"/>
+ <!--
+ (default is YES)
+ -->
+ <property name="com.arjuna.ats.txoj.lockstore.singleLockStore" value="YES"/>
+ <!--
+ (default is YES)
+ -->
+ <property
+ name="com.arjuna.ats.txoj.lockstore.allowNestedLocking" value="YES"/>
+ </properties>
+ <properties depends="arjuna" name="jta">
+
+
+ <!-- This used when deployed in the app server and we want to do a recovery of a JMS provider, the string after the semi colon
+ must match the JMS provider name from the JMSProviderAdapter -->
+
+ <!--
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING" value="org.jboss.jms.recovery.JMSProviderXAResourceRecovery;DefaultJMSProvider"/>
+-->
+
+ <!-- This is used for recovery using the message bridge, in which case JMSProviderAdapters aren't deployed so the string after the semi-colon
+ is first the provider name, then a comma, then the name of a properties file available on the classpath which has the server connection information, e.g:
+ provider1.jndi.prop1=xxxx
+ provider1.jndi.prop2=yyyy
+ provider1.jndi.prop3=zzzz
+ provider1.xaconnectionfactorylookup=xyz
+ provider2.jndi.prop1=xxxx
+ provider2.jndi.prop2=yyyy
+ provider2.jndi.prop3=zzzz
+ provider2.xaconnectionfactorylookup=xyz
+ -->
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGINGBRIDGE_SERVER0" value="org.jboss.jms.recovery.BridgeXAResourceRecovery;server0,bridge-recovery.properties"/>
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGINGBRIDGE_SERVER1" value="org.jboss.jms.recovery.BridgeXAResourceRecovery;server1,bridge-recovery.properties"/>
+
+ <!--
+ Support subtransactions in the JTA layer?
+ Default is NO.
+ -->
+ <property name="com.arjuna.ats.jta.supportSubtransactions" value="NO"/>
+ <property name="com.arjuna.ats.jta.jtaTMImplementation" value="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"/>
+ <!--
+ com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple
+ -->
+ <property name="com.arjuna.ats.jta.jtaUTImplementation" value="com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple"/>
+ <!--
+ com.arjuna.ats.internal.jta.transaction.jts.UserTransactionImple
+ -->
+ </properties>
+ <properties depends="jta" name="jdbc">
+ <!--
+ property name="com.arjuna.ats.jdbc.isolationLevel" value="TRANSACTION_SERIALIZABLE"/>
+ -->
+ </properties>
+</transaction-service>
Modified: trunk/tests/etc/log4j.xml
===================================================================
--- trunk/tests/etc/log4j.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/etc/log4j.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -38,6 +38,10 @@
</layout>
</appender>
+ <category name="com.arjuna">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+
<category name="org.apache">
<priority value="INFO"/>
</category>
Modified: trunk/tests/etc/poison.xml
===================================================================
--- trunk/tests/etc/poison.xml 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/etc/poison.xml 2007-01-16 20:58:56 UTC (rev 1970)
@@ -6,7 +6,7 @@
<interceptor class="org.jboss.test.messaging.tools.aop.PoisonInterceptor" scope="PER_VM"/>
- <bind pointcut="execution(* org.jboss.jms.server.endpoint.advised.ConnectionAdvised->createSessionDelegate(..))">
+ <bind pointcut="execution(* org.jboss.jms.server.endpoint.advised.ConnectionAdvised->*(..))">
<interceptor-ref name="org.jboss.test.messaging.tools.aop.PoisonInterceptor"/>
</bind>
Modified: trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -37,6 +37,7 @@
import junit.framework.TestCase;
+import org.jboss.jms.message.MessageIdGeneratorFactory;
import org.jboss.logging.Logger;
import org.jboss.test.messaging.tools.ServerManagement;
import org.jboss.tm.TransactionManagerService;
@@ -93,6 +94,8 @@
// log the test start in the remote log, this will make hunting through logs so much easier
ServerManagement.log(ServerManagement.INFO, banner);
}
+
+ MessageIdGeneratorFactory.instance.clear();
}
protected void tearDown() throws Exception
Modified: trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XATest.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XATest.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -41,8 +41,8 @@
import org.jboss.jms.client.JBossConnectionFactory;
import org.jboss.jms.tx.MessagingXAResource;
import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.util.TransactionManagerLocator;
import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
import org.jboss.tm.TxUtils;
/**
@@ -84,15 +84,15 @@
public void setUp() throws Exception
{
super.setUp();
- ServerManagement.start("all");
+ ServerManagement.start("all,-transaction,jbossjta");
initialContext = new InitialContext();
initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
if (!ServerManagement.isRemote())
- {
- tm = TransactionManagerLocator.getInstance().locate();
+ {
+ tm = (TransactionManager)initialContext.lookup(ServiceContainer.TRANSACTION_MANAGER_JNDI_NAME);
}
ServerManagement.undeployQueue("Queue");
Added: trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeMBeanTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeMBeanTest.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeMBeanTest.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+package org.jboss.test.messaging.jms.bridge;
+
+import javax.management.ObjectName;
+
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+
+/**
+ * A BridgeMBeanTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class BridgeMBeanTest extends MessagingTestCase
+{
+
+ public BridgeMBeanTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ /*
+
+ Example config
+
+ String config =
+ "<mbean code=org.jboss.jms.server.bridge.BridgeService " +
+ "name=jboss.messaging:service=Bridge,name=exampleBridge" +
+ "xmbean-dd=\"xmdesc/Bridge-xmbean.xml\">" +
+ "<attribute name=\"SourceConnectionFactoryLookup\">/ConnectionFactory</attribute>"+
+ "<attribute name=\"TargetConnectionFactoryLookup\">/ConnectionFactory</attribute>"+
+ "<attribute name=\"SourceDestinationLookup\">/topic/sourceTopic</attribute>"+
+ "<attribute name=\"TargetDestinationLookup\">/queue/targetQueue</attribute>"+
+ "<attribute name=\"SourceUsername\">bob</attribute>"+
+ "<attribute name=\"SourcePassword\">pwd1</attribute>"+
+ "<attribute name=\"TargetUsername\">jane</attribute>"+
+ "<attribute name=\"TargetPassword\">pwd2</attribute>"+
+ "<attribute name=\"QualityOfServiceMode\">2</attribute>"+
+ "<attribute name=\"Selector\">vegetable='marrow'</attribute>"+
+ "<attribute name=\"MaxBatchSize\">100</attribute>"+
+ "<attribute name=\"MaxBatchTime\">5000</attribute>"+
+ "<attribute name=\"SubName\">mySubscription</attribute>"+
+ "<attribute name=\"ClientID\">clientid-123</attribute>"+
+ "<attribute name=\"FailureRetryInterval\">5000</attribute>"+
+ "<attribute name=\"MaxRetries\">-1</attribute>"+
+ "<attribute name=\"SourceJNDIProperties\"><![CDATA["+
+"java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory\n"+
+"java.naming.provider.url=jnp://server1:1099\n"+
+"java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces\n"+
+"]]>"+
+ "</attribute>";
+ "<attribute name=\"TargetJNDIProperties\"><![CDATA["+
+"java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory\n"+
+"java.naming.provider.url=jnp://server1:1099\n"+
+"java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces\n"+
+"]]>"+
+ "</attribute>"+
+ "</mbean>";
+
+
+ */
+
+
+ private ObjectName deployBridge(String bridgeName, String sourceCFLookup, String targetCFLookup,
+ String sourceDestLookup, String targetDestLookup,
+ String sourceUsername, String sourcePassword,
+ String targetUsername, String targetPassword,
+ int qos, String selector, int maxBatchSize,
+ long maxBatchTime, String subName, String clientID,
+ long failureRetryInterval, int maxRetries,
+ String sourceJNDIProperties,
+ String targetJNDIProperties) throws Exception
+ {
+ String config =
+ "<mbean code=org.jboss.jms.server.bridge.BridgeService " +
+ "name=jboss.messaging:service=Bridge,name=" + bridgeName +
+ "xmbean-dd=\"xmdesc/Bridge-xmbean.xml\">" +
+ "<attribute name=\"SourceConnectionFactoryLookup\">" + sourceCFLookup + "/attribute>"+
+ "<attribute name=\"TargetConnectionFactoryLookup\">" + targetCFLookup + "</attribute>"+
+ "<attribute name=\"SourceDestinationLookup\">" + sourceDestLookup + "</attribute>"+
+ "<attribute name=\"TargetDestinationLookup\">" + targetDestLookup + "</attribute>"+
+ sourceUsername == null ? "" :
+ "<attribute name=\"SourceUsername\">" + sourceUsername + "</attribute>"+
+ sourcePassword == null ? "" :
+ "<attribute name=\"SourcePassword\">" + sourcePassword +"</attribute>"+
+ targetUsername == null ? "" :
+ "<attribute name=\"TargetUsername\">" + targetUsername +"</attribute>"+
+ targetPassword == null ? "" :
+ "<attribute name=\"TargetPassword\">" + targetPassword + "</attribute>"+
+ "<attribute name=\"QualityOfServiceMode\">" + qos +"</attribute>"+
+ selector == null ? "" :
+ "<attribute name=\"Selector\">" + selector + "</attribute>"+
+ "<attribute name=\"MaxBatchSize\">" + maxBatchSize + "</attribute>"+
+ "<attribute name=\"MaxBatchTime\">" + maxBatchTime +"</attribute>"+
+ subName == null ? "" :
+ "<attribute name=\"SubName\">" + subName + "</attribute>"+
+ clientID == null ? "" :
+ "<attribute name=\"ClientID\">" + clientID + "</attribute>"+
+ "<attribute name=\"FailureRetryInterval\">" + failureRetryInterval + "</attribute>"+
+ "<attribute name=\"MaxRetries\">" + maxRetries +"</attribute>"+
+ sourceJNDIProperties == null ? "" :
+ "<attribute name=\"SourceJNDIProperties\"><![CDATA["+
+ sourceJNDIProperties +
+ "]]>"+
+ "</attribute>"+
+ targetJNDIProperties == null ? "" :
+ "<attribute name=\"TargetJNDIProperties\"><![CDATA["+
+ targetJNDIProperties +
+ "]]>"+
+ "</attribute>"+
+ "</mbean>";
+
+ log.info(config);
+
+ return ServerManagement.deploy(config);
+ }
+
+}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTest.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTest.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -38,7 +38,6 @@
import org.jboss.jms.server.bridge.ConnectionFactoryFactory;
import org.jboss.jms.server.bridge.JNDIConnectionFactoryFactory;
import org.jboss.logging.Logger;
-import org.jboss.test.messaging.MessagingTestCase;
import org.jboss.test.messaging.tools.ServerManagement;
/**
@@ -50,10 +49,12 @@
* $Id$
*
*/
-public class BridgeTest extends MessagingTestCase
+public class BridgeTest extends BridgeTestBase
{
private static final Logger log = Logger.getLogger(BridgeTest.class);
+ private static final int NODE_COUNT = 2;
+
public BridgeTest(String name)
{
super(name);
@@ -61,12 +62,12 @@
protected void setUp() throws Exception
{
- super.setUp();
+ super.setUp();
}
protected void tearDown() throws Exception
- {
- super.tearDown();
+ {
+ super.tearDown();
}
// MaxBatchSize but no MaxBatchTime
@@ -125,7 +126,65 @@
testNoMaxBatchTime(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
}
+ //Same server
+ // MaxBatchSize but no MaxBatchTime
+
+ public void testNoMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_AT_MOST_ONCE, true);
+ }
+
+ public void testNoMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_DUPLICATES_OK, true);
+ }
+
+ public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
+ }
+
+ public void testNoMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_AT_MOST_ONCE, false);
+ }
+
+ public void testNoMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_DUPLICATES_OK, false);
+ }
+
+ public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testNoMaxBatchTimeSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
+ }
+
+
// MaxBatchTime but no MaxBatchSize
public void testMaxBatchTime_AtMostOnce_P() throws Exception
@@ -182,98 +241,901 @@
testMaxBatchTime(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
}
+ // Same server
- // Stress
+ // MaxBatchTime but no MaxBatchSize
- public void testStress_AtMostOnce_P() throws Exception
+ public void testMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_AT_MOST_ONCE, true);
+ this.testMaxBatchTimeSameServer(Bridge.QOS_AT_MOST_ONCE, true);
}
- public void testStress_DuplicatesOk_P() throws Exception
+ public void testMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_DUPLICATES_OK, true);
+ this.testMaxBatchTimeSameServer(Bridge.QOS_DUPLICATES_OK, true);
}
- public void testStress_OnceAndOnlyOnce_P() throws Exception
+ public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
+ testMaxBatchTimeSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
}
- public void testStress_AtMostOnce_NP() throws Exception
+ public void testMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_AT_MOST_ONCE, false);
+ this.testMaxBatchTimeSameServer(Bridge.QOS_AT_MOST_ONCE, false);
}
- public void testStress_DuplicatesOk_NP() throws Exception
+ public void testMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_DUPLICATES_OK, false);
+ this.testMaxBatchTimeSameServer(Bridge.QOS_DUPLICATES_OK, false);
}
- public void testStress_OnceAndOnlyOnce_NP() throws Exception
+ public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
{
if (!ServerManagement.isRemote())
{
return;
}
- testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
+ testMaxBatchTimeSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
}
+ // Stress with batch size of 50
+ public void testStress_AtMostOnce_P_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_AT_MOST_ONCE, true, 50);
+ }
- private static class Sender implements Runnable
+ public void testStress_DuplicatesOk_P_50() throws Exception
{
- int numMessages;
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_DUPLICATES_OK, true, 50);
+ }
+
+ public void testStress_OnceAndOnlyOnce_P_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, true, 50);
+ }
+
+ public void testStress_AtMostOnce_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_AT_MOST_ONCE, false, 50);
+ }
+
+ public void testStress_DuplicatesOk_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_DUPLICATES_OK, false, 50);
+ }
+
+ public void testStress_OnceAndOnlyOnce_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, false, 50);
+ }
+
+ // Stress with batch size of 1
+
+ public void testStress_AtMostOnce_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_AT_MOST_ONCE, true, 1);
+ }
+
+ public void testStress_DuplicatesOk_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_DUPLICATES_OK, true, 1);
+ }
+
+ public void testStress_OnceAndOnlyOnce_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, true, 1);
+ }
+
+ public void testStress_AtMostOnce_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_AT_MOST_ONCE, false, 1);
+ }
+
+ public void testStress_DuplicatesOk_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_DUPLICATES_OK, false, 1);
+ }
+
+ public void testStress_OnceAndOnlyOnce_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, false, 1);
+ }
+
+ // Stress on same server
+
+ // Stress with batch size of 50
+
+ public void testStressSameServer_AtMostOnce_P_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_AT_MOST_ONCE, true, 50);
+ }
+
+ public void testStressSameServer_DuplicatesOk_P_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_DUPLICATES_OK, true, 50);
+ }
+
+ public void testStressSameServer_OnceAndOnlyOnce_P_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStress(Bridge.QOS_ONCE_AND_ONLY_ONCE, true, 50);
+ }
+
+ public void testStressSameServer_AtMostOnce_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_AT_MOST_ONCE, false, 50);
+ }
+
+ public void testStressSameServer_DuplicatesOk_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_DUPLICATES_OK, false, 50);
+ }
+
+ public void testStressSameServer_OnceAndOnlyOnce_NP_50() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, false, 50);
+ }
+
+ // Stress with batch size of 1
+
+ public void testStressSameServer_AtMostOnce_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_AT_MOST_ONCE, true, 1);
+ }
+
+ public void testStressSameServer_DuplicatesOk_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_DUPLICATES_OK, true, 1);
+ }
+
+ public void testStressSameServer_OnceAndOnlyOnce_P_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, true, 1);
+ }
+
+ public void testStressSameServer_AtMostOnce_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_AT_MOST_ONCE, false, 1);
+ }
+
+ public void testStressSameServer_DuplicatesOk_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_DUPLICATES_OK, false, 1);
+ }
+
+ public void testStressSameServer_OnceAndOnlyOnce_NP_1() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testStressSameServer(Bridge.QOS_ONCE_AND_ONLY_ONCE, false, 1);
+ }
+
+ public void testParams() throws Exception
+ {
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ Bridge bridge;
+
+ int qosMode = Bridge.QOS_AT_MOST_ONCE;
+
+ int batchSize = 10;
+
+ int maxBatchTime = -1;
+
+ String sourceUsername = null;
+
+ String sourcePassword = null;
+
+ String destUsername = null;
+
+ String destPassword = null;
+
+ String selector = null;
+
+ long failureRetryInterval = 5000;
+
+ int maxRetries = 10;
+
+ String subName = null;
+
+ String clientID = null;
+
+ try
+ {
+ bridge= new Bridge(null, cff1, sourceQueue, destQueue,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, null, sourceQueue, destQueue,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, null, destQueue,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, null,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, destQueue,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, -2, maxRetries, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, destQueue,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, -1, 10, qosMode,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, null,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, -2,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, null,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, 3,
+ batchSize, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, null,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, 3,
+ 0, maxBatchTime,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+
+ try
+ {
+ bridge= new Bridge(cff0, cff1, sourceQueue, null,
+ sourceUsername, sourcePassword, destUsername, destPassword,
+ selector, failureRetryInterval, maxRetries, 3,
+ batchSize, -2,
+ subName, clientID);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //Ok
+ }
+ }
+ finally
+ {
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+ public void testSelector() throws Exception
+ {
+ Connection connSource = null;
- Session sess;
+ Connection connDest = null;
- MessageProducer prod;
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ final int BATCH_SIZE = 10;
+
+ String selector = "vegetable='radish'";
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ selector, 5000, 10, Bridge.QOS_AT_MOST_ONCE,
+ 1, -1,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ //Send half the messges
+
+ for (int i = 0; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ if (i >= BATCH_SIZE / 2)
+ {
+ tm.setStringProperty("vegetable", "radish");
+ }
+ else
+ {
+ tm.setStringProperty("vegetable", "cauliflower");
+ }
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ for (int i = BATCH_SIZE / 2 ; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+ public void testNonDurableSubscriber() throws Exception
+ {
+ Connection connSource = null;
- Exception ex;
+ Connection connDest = null;
- public void run()
+ Bridge bridge = null;
+
+ try
{
+ ServerManagement.deployTopic("sourceTopic", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ final int BATCH_SIZE = 10;
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 5000, 10, Bridge.QOS_AT_MOST_ONCE,
+ 1, -1,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ for (int i = 0; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ for (int i = 0 ; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
try
{
- for (int i = 0; i < numMessages; i++)
+ ServerManagement.undeployTopic("sourceTopic", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+ public void testDurableSubscriber() throws Exception
+ {
+ Connection connSource = null;
+
+ Connection connDest = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployTopic("sourceTopic", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ final int BATCH_SIZE = 10;
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 5000, 10, Bridge.QOS_AT_MOST_ONCE,
+ 1, -1,
+ "subTest", "clientid123");
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ for (int i = 0; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ for (int i = 0 ; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
{
- TextMessage tm = sess.createTextMessage("message" + i);
-
- prod.send(tm);
-
- log.trace("Sent message " + i);
+ connSource.close();
}
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
}
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ try
+ {
+ ServerManagement.undeployTopic("sourceTopic", 0);
+ }
catch (Exception e)
{
- log.error("Failed to send", e);
- ex = e;
- }
- }
-
- }
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
- private void testStress(int qosMode, boolean persistent) throws Exception
+
+ // Private -------------------------------------------------------------------------------
+
+
+
+ private void testStress(int qosMode, boolean persistent, int batchSize) throws Exception
{
Connection connSource = null;
@@ -285,10 +1147,6 @@
try
{
- ServerManagement.start(0, "all", null, true);
-
- ServerManagement.start(1, "all", null, false);
-
ServerManagement.deployQueue("sourceQueue", 0);
ServerManagement.deployQueue("destQueue", 1);
@@ -312,13 +1170,11 @@
Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
-
- final int BATCH_SIZE = 50;
-
+
bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
null, null, null, null,
null, 5000, 10, qosMode,
- BATCH_SIZE, -1,
+ batchSize, -1,
null, null);
bridge.start();
@@ -333,7 +1189,7 @@
final int NUM_MESSAGES = 2000;
- Sender sender = new Sender();
+ StressSender sender = new StressSender();
sender.sess = sessSend;
sender.prod = prod;
sender.numMessages = NUM_MESSAGES;
@@ -424,10 +1280,131 @@
{
log.error("Failed to undeploy", e);
}
+ }
+ }
+
+ //Both source and destination on same rm
+ private void testStressSameServer(int qosMode, boolean persistent, int batchSize) throws Exception
+ {
+ Connection connSource = null;
+
+ Bridge bridge = null;
+
+ Thread t = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
- ServerManagement.stop(0);
+ ServerManagement.deployQueue("destQueue", 0);
- ServerManagement.stop(1);
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic0.lookup("/queue/destQueue");
+
+ bridge = new Bridge(cff0, cff0, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 5000, 10, qosMode,
+ batchSize, -1,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ final int NUM_MESSAGES = 2000;
+
+ StressSender sender = new StressSender();
+ sender.sess = sessSend;
+ sender.prod = prod;
+ sender.numMessages = NUM_MESSAGES;
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ Session sessRec = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connSource.start();
+
+ t = new Thread(sender);
+
+ t.start();
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(5000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ t.join();
+
+ if (sender.ex != null)
+ {
+ //An error occurred during the send
+ throw sender.ex;
+ }
+
+ }
+ finally
+ {
+ if (t != null)
+ {
+ t.join(10000);
+ }
+
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
}
}
@@ -442,10 +1419,6 @@
try
{
- ServerManagement.start(0, "all", null, true);
-
- ServerManagement.start(1, "all", null, false);
-
ServerManagement.deployQueue("sourceQueue", 0);
ServerManagement.deployQueue("destQueue", 1);
@@ -646,10 +1619,195 @@
{
log.error("Failed to undeploy", e);
}
+ }
+ }
+
+ private void testNoMaxBatchTimeSameServer(int qosMode, boolean persistent) throws Exception
+ {
+ Connection connSource = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
- ServerManagement.stop(0);
+ ServerManagement.deployQueue("destQueue", 0);
- ServerManagement.stop(1);
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic0.lookup("/queue/destQueue");
+
+ final int BATCH_SIZE = 10;
+
+ bridge = new Bridge(cff0, cff0, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 5000, 10, qosMode,
+ BATCH_SIZE, -1,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ //Send half the messges
+
+ for (int i = 0; i < BATCH_SIZE / 2; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connSource.start();
+
+ //Verify none are received
+
+ Message m = cons.receive(2000);
+
+ assertNull(m);
+
+ //Send the other half
+
+ for (int i = BATCH_SIZE / 2; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ //This should now be receivable
+
+ for (int i = 0; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+ //Send another batch with one more than batch size
+
+ for (int i = 0; i < BATCH_SIZE + 1; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ //Make sure only batch size are received
+
+ for (int i = 0; i < BATCH_SIZE; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(2000);
+
+ assertNull(m);
+
+ //Final batch
+
+ for (int i = 0; i < BATCH_SIZE - 1; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + BATCH_SIZE, tm.getText());
+
+ for (int i = 0; i < BATCH_SIZE - 1; i++)
+ {
+ tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+
+ //Make sure no messages are left in the source dest
+
+ MessageConsumer cons2 = sessSend.createConsumer(sourceQueue);
+
+ connSource.start();
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
}
}
@@ -663,10 +1821,6 @@
try
{
- ServerManagement.start(0, "all", null, true);
-
- ServerManagement.start(1, "all", null, false);
-
ServerManagement.deployQueue("sourceQueue", 0);
ServerManagement.deployQueue("destQueue", 1);
@@ -808,16 +1962,185 @@
try
{
- ServerManagement.undeployQueue("destQueue", 1);
+ ServerManagement.undeployQueue("destQueue", 0);
}
catch (Exception e)
{
log.error("Failed to undeploy", e);
}
+ }
+ }
+
+ private void testMaxBatchTimeSameServer(int qosMode, boolean persistent) throws Exception
+ {
+ Connection connSource = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
- ServerManagement.stop(0);
+ ServerManagement.deployQueue("destQueue", 0);
- ServerManagement.stop(1);
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic0.lookup("/queue/destQueue");
+
+ final long MAX_BATCH_TIME = 3000;
+
+ final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
+
+ bridge = new Bridge(cff0, cff0, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 5000, 10, qosMode,
+ MAX_BATCH_SIZE, MAX_BATCH_TIME,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ final int NUM_MESSAGES = 10;
+
+ //Send some message
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connSource.start();
+
+ //Verify none are received
+
+ Message m = cons.receive(2000);
+
+ assertNull(m);
+
+ //Wait a bit longer
+
+ Thread.sleep(1500);
+
+ //Messages should now be receivable
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+ //Make sure no messages are left in the source dest
+
+ MessageConsumer cons2 = sessSend.createConsumer(sourceQueue);
+
+ connSource.start();
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
}
}
+
+
+ // Inner classes -------------------------------------------------------------------
+
+ private static class StressSender implements Runnable
+ {
+ int numMessages;
+
+ Session sess;
+
+ MessageProducer prod;
+
+ Exception ex;
+
+ public void run()
+ {
+ try
+ {
+ for (int i = 0; i < numMessages; i++)
+ {
+ TextMessage tm = sess.createTextMessage("message" + i);
+
+ prod.send(tm);
+
+ log.trace("Sent message " + i);
+ }
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to send", e);
+ ex = e;
+ }
+ }
+
+ }
}
Added: trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTestBase.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/bridge/BridgeTestBase.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+package org.jboss.test.messaging.jms.bridge;
+
+import org.jboss.logging.Logger;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+
+/**
+ *
+ * A BridgeTestBase
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class BridgeTestBase extends MessagingTestCase
+{
+ private static final Logger log = Logger.getLogger(BridgeTest.class);
+
+ private static final int NODE_COUNT = 2;
+
+ public BridgeTestBase(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ if (ServerManagement.isRemote())
+ {
+ for (int i = 0; i < NODE_COUNT; i++)
+ {
+ // make sure all servers are created and started; make sure that database is zapped
+ // ONLY for the first server, the others rely on values they expect to find in shared
+ // tables; don't clear the database for those.
+ ServerManagement.start(i, "all,-transaction,jbossjta", i == 0);
+ }
+ }
+
+ }
+
+ protected void tearDown() throws Exception
+ {
+ if (ServerManagement.isRemote())
+ {
+ for (int i = 0; i < NODE_COUNT; i++)
+ {
+ try
+ {
+ if (ServerManagement.isStarted(i))
+ {
+ ServerManagement.log(ServerManagement.INFO, "Undeploying Server " + i, i);
+
+ ServerManagement.stop(i);
+ }
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to stop server", e);
+ }
+ }
+
+ for (int i = 1; i < NODE_COUNT; i++)
+ {
+ try
+ {
+ ServerManagement.kill(i);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to kill server", e);
+ }
+ }
+ }
+
+ super.tearDown();
+
+ }
+
+
+ // Inner classes -------------------------------------------------------------------
+
+}
+
Added: trunk/tests/src/org/jboss/test/messaging/jms/bridge/ReconnectTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/bridge/ReconnectTest.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/bridge/ReconnectTest.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -0,0 +1,798 @@
+/*
+ * 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.
+ */
+package org.jboss.test.messaging.jms.bridge;
+
+import java.util.Hashtable;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.DeliveryMode;
+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.jms.server.bridge.Bridge;
+import org.jboss.jms.server.bridge.ConnectionFactoryFactory;
+import org.jboss.jms.server.bridge.JNDIConnectionFactoryFactory;
+import org.jboss.logging.Logger;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+
+/**
+ *
+ * A ReconnectTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class ReconnectTest extends BridgeTestBase
+{
+ private static final Logger log = Logger.getLogger(ReconnectTest.class);
+
+ private static final int NODE_COUNT = 2;
+
+ public ReconnectTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ // Crash and reconnect
+
+ public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestBasic(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
+ }
+
+ public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestBasic(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
+ }
+
+
+ public void testCrashAndReconnectDestCrashBeforePrepare_OnceAndOnlyOnce_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestCrashBeforePrepare(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
+ }
+
+ public void testCrashAndReconnectDestCrashBeforePrepare_OnceAndOnlyOnce_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestCrashBeforePrepare(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
+ }
+
+
+
+ public void testCrashAndReconnectDestCrashOnCommit_OnceAndOnlyOnce_P() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestCrashOnCommit(Bridge.QOS_ONCE_AND_ONLY_ONCE, true);
+ }
+
+ public void testCrashAndReconnectDestCrashOnCommit_OnceAndOnlyOnce_NP() throws Exception
+ {
+ if (!ServerManagement.isRemote())
+ {
+ return;
+ }
+ testCrashAndReconnectDestCrashOnCommit(Bridge.QOS_ONCE_AND_ONLY_ONCE, false);
+ }
+
+
+ /*
+ * Send some messages
+ * Crash the destination server
+ * Bring the destination server back up
+ * Send some more messages
+ * Verify all messages are received
+ */
+ private void testCrashAndReconnectDestBasic(int qosMode, boolean persistent) throws Exception
+ {
+ Connection connSource = null;
+
+ Connection connDest = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 1000, -1, qosMode,
+ 10, -1,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ final int NUM_MESSAGES = 10;
+
+ for (int i = 0; i < NUM_MESSAGES / 2; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Verify none are received
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ connDest.close();
+
+ ic1.close();
+
+ //Now crash the dest server
+
+ log.info("About to crash server");
+
+ ServerManagement.kill(1);
+
+ //Wait a while before starting up to simulate the dest being down for a while
+ log.info("Waiting 15 secs before bringing server back up");
+ Thread.sleep(15000);
+ log.info("Done wait");
+
+ //Restart the server
+
+ ServerManagement.start(1, "all", false);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ ic1 = new InitialContext(props1);
+
+ cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ connDest = cf1.createConnection();
+
+ sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Send some more messages
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ //Messages should now be receivable
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(10000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+ //Make sure no messages are left in the source dest
+
+ MessageConsumer cons2 = sessSend.createConsumer(sourceQueue);
+
+ connSource.start();
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ log.info("Got here");
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+
+ if (bridge != null)
+ {
+ try
+ {
+ bridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to stop bridge", e);
+ }
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+
+ /*
+ * Send some messages
+ * Crash the destination server
+ * Set the max batch time such that it will attempt to send the batch while the dest server is down
+ * Bring up the destination server
+ * Send some more messages
+ * Verify all messages are received
+ */
+ private void testCrashAndReconnectDestCrashBeforePrepare(int qosMode, boolean persistent) throws Exception
+ {
+ Connection connSource = null;
+
+ Connection connDest = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 1000, -1, qosMode,
+ 10, 5000,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ final int NUM_MESSAGES = 10;
+
+ for (int i = 0; i < NUM_MESSAGES / 2; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Verify none are received
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ connDest.close();
+
+ ic1.close();
+
+ //Now crash the dest server
+
+ log.info("About to crash server");
+
+ ServerManagement.kill(1);
+
+ //Wait a while before starting up to simulate the dest being down for a while
+ log.info("Waiting 15 secs before bringing server back up");
+ Thread.sleep(15000);
+ log.info("Done wait");
+
+ //Restart the server
+
+ ServerManagement.start(1, "all", false);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ ic1 = new InitialContext(props1);
+
+ cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ connDest = cf1.createConnection();
+
+ sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Send some more messages
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ //Messages should now be receivable
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(10000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+ //Make sure no messages are left in the source dest
+
+ MessageConsumer cons2 = sessSend.createConsumer(sourceQueue);
+
+ connSource.start();
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ log.info("Got here");
+
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+
+ if (bridge != null)
+ {
+ try
+ {
+ bridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to stop bridge", e);
+ }
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+ /*
+ * Send some messages
+ * Crash the server after prepare but on commit
+ * Bring up the destination server
+ * Send some more messages
+ * Verify all messages are received
+ */
+ private void testCrashAndReconnectDestCrashOnCommit(int qosMode, boolean persistent) throws Exception
+ {
+ Connection connSource = null;
+
+ Connection connDest = null;
+
+ Bridge bridge = null;
+
+ try
+ {
+ ServerManagement.deployQueue("sourceQueue", 0);
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ Hashtable props0 = ServerManagement.getJNDIEnvironment(0);
+
+ Hashtable props1 = ServerManagement.getJNDIEnvironment(1);
+
+ ConnectionFactoryFactory cff0 = new JNDIConnectionFactoryFactory(props0, "/ConnectionFactory");
+
+ ConnectionFactoryFactory cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ InitialContext ic0 = new InitialContext(props0);
+
+ InitialContext ic1 = new InitialContext(props1);
+
+ ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");
+
+ ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ Queue sourceQueue = (Queue)ic0.lookup("/queue/sourceQueue");
+
+ Queue destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ final int NUM_MESSAGES = 10;
+
+ bridge = new Bridge(cff0, cff1, sourceQueue, destQueue,
+ null, null, null, null,
+ null, 1000, -1, qosMode,
+ NUM_MESSAGES, 5000,
+ null, null);
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ connDest = cf1.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ for (int i = 0; i < NUM_MESSAGES / 2; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ Session sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Verify none are received
+
+ Message m = cons.receive(1000);
+
+ assertNull(m);
+
+ connDest.close();
+
+ ic1.close();
+
+ //Poison server 1 so it crashes on commit of dest but after prepare
+
+ //This means the transaction branch on source will get commmitted
+ //but the branch on dest won't be - it will remain prepared
+ //This corresponds to a HeuristicMixedException
+
+ ServerManagement.poisonTheServer(1);
+
+ ServerManagement.nullServer(1);
+
+
+ //Wait for maxBatchTime to kick in so a batch is sent
+ //This should cause the server to crash after prepare but before commit
+
+ Thread.sleep(20000);
+
+ //Restart the server
+
+ log.info("Restarting server");
+
+ ServerManagement.start(1, "all", false);
+
+ log.info("Restarted server");
+
+ ServerManagement.deployQueue("destQueue", 1);
+
+ log.info("Deployed queue");
+
+
+ log.info("Now sleeping");
+
+ Thread.sleep(120000);
+
+ log.info("Slept");
+
+ cff1 = new JNDIConnectionFactoryFactory(props1, "/ConnectionFactory");
+
+ ic1 = new InitialContext(props1);
+
+ cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
+
+ destQueue = (Queue)ic1.lookup("/queue/destQueue");
+
+ connDest = cf1.createConnection();
+
+ sessRec = connDest.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ cons = sessRec.createConsumer(destQueue);
+
+ connDest.start();
+
+ //Send some more messages
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+
+ //Messages should now be receivable
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(10000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons.receive(1000);
+
+ assertNull(m);
+
+ //Make sure no messages are left in the source dest
+
+ MessageConsumer cons2 = sessSend.createConsumer(sourceQueue);
+
+ connSource.start();
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ log.info("Got here");
+
+ }
+ finally
+ {
+ log.info("In finally");
+
+ if (connSource != null)
+ {
+ try
+ {
+ connSource.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+ if (connDest != null)
+ {
+ try
+ {
+ connDest.close();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close connection", e);
+ }
+ }
+
+
+ if (bridge != null)
+ {
+ try
+ {
+ bridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to stop bridge", e);
+ }
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("sourceQueue", 0);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+
+ try
+ {
+ ServerManagement.undeployQueue("destQueue", 1);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to undeploy", e);
+ }
+ }
+ }
+
+ // Inner classes -------------------------------------------------------------------
+
+}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/base/ClusteringTestBase.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -89,7 +89,7 @@
queue = new Queue[nodeCount];
topic = new Topic[nodeCount];
- for(int i = 0; i < nodeCount; i++)
+ for (int i = 0; i < nodeCount; i++)
{
// make sure all servers are created and started; make sure that database is zapped
// ONLY for the first server, the others rely on values they expect to find in shared
Modified: trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -192,8 +192,6 @@
{
Server s = create(i);
- MessageIdGeneratorFactory.instance.clear();
-
log.info("starting server " + i);
s.start(config, attrOverrides, clearDatabase);
@@ -265,6 +263,12 @@
servers[i] = null;
}
}
+
+ //Need to do this after a poison otherwise this will think the server is still alive
+ public static synchronized void nullServer(int i)
+ {
+ servers[i] = null;
+ }
/**
* Kills the server and waits keep trying any dumb communication until the server is effectively
@@ -334,11 +338,11 @@
*/
private static synchronized Server spawn(final int i) throws Exception
{
- if(isLocal())
+ if (isLocal())
{
return null;
}
-
+
StringBuffer sb = new StringBuffer();
sb.append("java").append(' ');
@@ -399,12 +403,12 @@
testLogfileSuffix = testLogfileSuffix.substring(0, pos) + "server";
}
- if (clustered != null)
- {
- testLogfileSuffix += i;
- }
+ //We need to add the i even in the non clustered case since we can have multiple
+ //non clustered servers
+ testLogfileSuffix += i;
+
}
-
+
sb.append("-Dtest.logfile.suffix=").append(testLogfileSuffix).append(' ');
String classPath = System.getProperty("java.class.path");
@@ -1027,11 +1031,11 @@
String name =
"//localhost:" + RMITestServer.DEFAULT_REGISTRY_PORT + "/" +
RMITestServer.RMI_SERVER_PREFIX + index;
-
+
Server s = null;
int retries = initialRetries;
- while(s == null && retries > 0)
+ while (s == null && retries > 0)
{
int attempt = initialRetries - retries + 1;
try
Modified: trunk/tests/src/org/jboss/test/messaging/tools/aop/PoisonInterceptor.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/aop/PoisonInterceptor.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/tools/aop/PoisonInterceptor.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -6,10 +6,17 @@
*/
package org.jboss.test.messaging.tools.aop;
-import org.jboss.logging.Logger;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.jms.server.endpoint.ServerConnectionEndpoint;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.tx.TransactionRequest;
+import org.jboss.logging.Logger;
+import org.jboss.test.messaging.tools.jmx.rmi.RMITestServer;
/**
* Used to force a "poisoned" server to do all sorts of bad things. Used for testing.
@@ -46,18 +53,25 @@
{
// Used by the failover tests to kill server in the middle of an invocation.
- log.info("#####");
- log.info("#####");
- log.info("##### Halting the server!");
- log.info("#####");
- log.info("#####");
-
- Runtime.getRuntime().halt(1);
-
+ crash(invocation.getTargetObject());
}
+ else if ("sendTransaction".equals(methodName))
+ {
+ TransactionRequest request = (TransactionRequest)mi.getArguments()[0];
+
+ if (request.getRequestType() == TransactionRequest.TWO_PHASE_COMMIT_REQUEST)
+ {
+ //Crash on 2pc commit - used in message bridge tests
+
+ log.info("##### Crashing on 2PC commit!!");
+
+ crash(invocation.getTargetObject());
+ }
+ }
return invocation.invokeNext();
}
+
// Public ---------------------------------------------------------------------------------------
@@ -66,7 +80,35 @@
// Protected ------------------------------------------------------------------------------------
// Private --------------------------------------------------------------------------------------
+
+ private void crash(Object target) throws Exception
+ {
+ ConnectionAdvised advised = (ConnectionAdvised)target;
+
+ ServerConnectionEndpoint endpoint = (ServerConnectionEndpoint)advised.getEndpoint();
+
+ int serverId = endpoint.getServerPeer().getServerPeerID();
+
+ //First unregister from the RMI registry
+ Registry registry = LocateRegistry.getRegistry(RMITestServer.DEFAULT_REGISTRY_PORT);
+ String name = RMITestServer.RMI_SERVER_PREFIX + serverId;
+ registry.unbind(name);
+ log.info("unregistered " + name + " from registry");
+
+ name = RMITestServer.NAMING_SERVER_PREFIX + serverId;
+ registry.unbind(name);
+ log.info("unregistered " + name + " from registry");
+
+ log.info("#####");
+ log.info("#####");
+ log.info("##### Halting the server!");
+ log.info("#####");
+ log.info("#####");
+
+ Runtime.getRuntime().halt(1);
+ }
+
// Inner classes --------------------------------------------------------------------------------
}
Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/ServiceContainer.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -38,14 +38,15 @@
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
+
import javax.management.Attribute;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
+import javax.management.NotificationListener;
import javax.management.ObjectName;
-import javax.management.NotificationListener;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
@@ -53,6 +54,7 @@
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
+
import org.hsqldb.Server;
import org.hsqldb.persist.HsqlProperties;
import org.jboss.jms.jndi.JNDIProviderAdapter;
@@ -81,8 +83,8 @@
import org.jboss.test.messaging.tools.jndi.Constants;
import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactory;
import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactoryBuilder;
-import org.jboss.tm.TransactionManagerLocator;
import org.jboss.tm.TransactionManagerService;
+import org.jboss.tm.TxManager;
import org.jboss.tm.usertx.client.ServerVMClientUserTransaction;
@@ -182,6 +184,7 @@
private Server hsqldbServer;
private boolean transaction;
+ private boolean jbossjta; //To use the ex-Arjuna tx mgr
private boolean database;
private boolean jca;
private boolean remoting;
@@ -361,8 +364,8 @@
startServiceController();
registerClassLoader();
-
- if (transaction)
+
+ if (transaction || jbossjta)
{
startTransactionManager();
}
@@ -385,6 +388,12 @@
DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME);
startWrapperDataSourceService();
}
+ if (database && (transaction || jbossjta) && jca && cleanDatabase)
+ {
+ // We make sure the database is clean (only if we have all dependencies the database,
+ // othewise we'll get an access error)
+ deleteAllData();
+ }
if (remoting)
{
@@ -396,13 +405,6 @@
startSecurityManager();
}
- if (database && transaction && jca && cleanDatabase)
- {
- // We make sure the database is clean (only if we have all dependencies the database,
- // othewise we'll get an access error)
- deleteAllData();
- }
-
loadJNDIContexts();
// aways install multiplexer as this is a cheap operation. The actual JChannels are started
@@ -988,7 +990,16 @@
{
if (tm == null)
{
- tm = TransactionManagerLocator.getInstance().locate();
+ if (jbossjta)
+ {
+ log.info("Starting arjuna tx mgr");
+ tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+ }
+ else
+ {
+ log.info("Starting non arjuna tx mgr");
+ tm = TxManager.getInstance();
+ }
}
TransactionManagerJMXWrapper mbean = new TransactionManagerJMXWrapper(tm);
@@ -1179,7 +1190,8 @@
"clientLeasePeriod=" + clientLeasePeriod + "&" +
"callbackStore=org.jboss.remoting.callback.BlockingCallbackStore&" +
"clientSocketClass=org.jboss.jms.client.remoting.ClientSocketWrapper&" +
- "serverSocketClass=org.jboss.jms.server.remoting.ServerSocketWrapper";
+ "serverSocketClass=org.jboss.jms.server.remoting.ServerSocketWrapper&" +
+ "NumberOfRetries=1&NumberOfCallRetries=1";
// specific parameters per transport
@@ -1391,6 +1403,20 @@
transaction = false;
}
}
+ else if ("jbossjta".equals(tok))
+ {
+ if (transaction)
+ {
+ throw new IllegalArgumentException("Cannot have the old JBoss transaction manager AND the JBoss Transactions transaction manager");
+ }
+
+ //Use the JBoss Transactions (ex Arjuna) JTA
+ jbossjta = true;
+ if (minus)
+ {
+ jbossjta = false;
+ }
+ }
else if ("database".equals(tok))
{
database = true;
Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -295,8 +295,6 @@
{
try
{
- log.info(" Server peer ID ........... " + serverPeerID);
-
log.debug("creating ServerPeer instance");
// we are using the "default" service deployment descriptors available in
Deleted: trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java 2007-01-16 14:25:37 UTC (rev 1969)
+++ trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java 2007-01-16 20:58:56 UTC (rev 1970)
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-package org.jboss.test.messaging.util;
-
-import javax.transaction.TransactionManager;
-
-
-/**
- * Mimics the JBossTM locator API with creation of JBossTS implementation.
- *
- * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
- *
- * @version $Revision: $
- */
-public class TransactionManagerLocator
-{
- private static TransactionManagerLocator instance = new TransactionManagerLocator();
-
- private TransactionManager tm;
-
-
- private TransactionManagerLocator()
- {}
-
-
- public static TransactionManagerLocator getInstance()
- {
- return instance;
- }
-
- public synchronized TransactionManager locate()
- {
- if (tm != null)
- return tm;
-
- tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
-
- return tm;
- }
-
-
-}
More information about the jboss-cvs-commits
mailing list