/*
* JBoss, Home of Professional Open Source Copyright 2005-2008, Red Hat
* Middleware LLC, and individual contributors by the @authors tag. See the
* copyright.txt in the distribution for a full listing of individual
* contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.jboss.messaging.tests.integration.cluster;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
import org.jboss.messaging.core.client.ClientConsumer;
import org.jboss.messaging.core.client.ClientMessage;
import org.jboss.messaging.core.client.ClientProducer;
import org.jboss.messaging.core.client.ClientSession;
import org.jboss.messaging.core.client.ClientSessionFactory;
import org.jboss.messaging.core.client.impl.ClientSessionFactoryImpl;
import org.jboss.messaging.core.client.impl.ClientSessionImpl;
import org.jboss.messaging.core.config.Configuration;
import org.jboss.messaging.core.config.TransportConfiguration;
import org.jboss.messaging.core.config.impl.ConfigurationImpl;
import org.jboss.messaging.core.exception.MessagingException;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.remoting.FailureListener;
import org.jboss.messaging.core.remoting.RemotingConnection;
import org.jboss.messaging.core.remoting.impl.ConnectionRegistryImpl;
import org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory;
import org.jboss.messaging.core.remoting.impl.invm.InVMRegistry;
import org.jboss.messaging.core.remoting.impl.invm.TransportConstants;
import org.jboss.messaging.core.server.MessagingService;
import org.jboss.messaging.core.server.impl.MessagingServiceImpl;
import org.jboss.messaging.jms.client.JBossTextMessage;
import org.jboss.messaging.util.SimpleString;
/**
*
* A SimpleAutomaticFailoverTest
*
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
*
*/
public class SimpleAutomaticFailoverTest extends TestCase
{
private static final Logger log = Logger.getLogger(SimpleAutomaticFailoverTest.class);
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
private static final SimpleString ADDRESS = new SimpleString("FailoverTestAddress");
private MessagingService liveService;
private MessagingService backupService;
private final Map<String, Object> backupParams = new HashMap<String, Object>();
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
public void testReplication() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 100;
log.info("Sending messages");
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
log.info("sent messages");
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
// log.info("Got message " + message2);
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
//ClientMessage message3 = consumer.receive(250);
//assertNull(message3);
session.close();
}
public void testFailoverSameConnectionFactory() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages / 2; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
session.close();
session = sf.createSession(false, true, true, false);
consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = numMessages / 2; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
ClientMessage message3 = consumer.receive(250);
session.close();
assertNull(message3);
}
public void testFailoverChangeConnectionFactory() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages / 2; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
session.close();
sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
session = sf.createSession(false, true, true, false);
consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = numMessages / 2; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
ClientMessage message3 = consumer.receive(250);
assertNull(message3);
session.close();
}
public void testNoMessagesLeftAfterFailoverNewSession() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
session.close();
sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
session = sf.createSession(false, true, true, false);
consumer = session.createConsumer(ADDRESS);
ClientMessage message3 = consumer.receive(250);
assertNull(message3);
session.close();
}
public void testCreateMoreSessionsAfterFailover() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session1 = sf.createSession(false, true, true, false);
ClientSession session2 = sf.createSession(false, true, true, false);
ClientSession session3 = sf.createSession(false, true, true, false);
session.close();
session1.close();
session2.close();
session3.close();
}
public void testFailureListenerCalledOnFailure() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
final CountDownLatch latch = new CountDownLatch(1);
class MyListener implements FailureListener
{
public void connectionFailed(final MessagingException me)
{
latch.countDown();
}
}
conn.addFailureListener(new MyListener());
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
boolean ok = latch.await(1000, TimeUnit.MILLISECONDS);
assertTrue(ok);
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < numMessages; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
session.close();
sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
session = sf.createSession(false, true, true, false);
consumer = session.createConsumer(ADDRESS);
ClientMessage message3 = consumer.receive(250);
assertNull(message3);
session.close();
}
public void testFailoverMultipleSessions() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
final int numSessions = 10;
List<ClientSession> sessions = new ArrayList<ClientSession>();
List<ClientConsumer> consumers = new ArrayList<ClientConsumer>();
for (int i = 0; i < numSessions; i++)
{
ClientSession sess = sf.createSession(false, true, true, false);
SimpleString queueName = new SimpleString("subscription" + i);
sess.createQueue(ADDRESS, queueName, null, false, false);
ClientConsumer consumer = sess.createConsumer(queueName);
sess.start();
sessions.add(sess);
consumers.add(consumer);
}
ClientSession session = sf.createSession(false, true, true, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 100;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
for (int i = 0; i < numSessions; i++)
{
ClientConsumer cons = consumers.get(i);
for (int j = 0; j < numMessages; j++)
{
ClientMessage message2 = cons.receive();
assertEquals("aardvarks", message2.getBody().getString());
// log.info("actually got message " + message2.getMessageID());
assertEquals(j, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
ClientMessage message3 = cons.receive(250);
assertNull(message3);
}
session.close();
for (int i = 0; i < numSessions; i++)
{
ClientSession sess = sessions.get(i);
sess.close();
}
}
public void testCantSetConnectorsAfterCreateSession() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
sf.setConnectorFactory(new InVMConnectorFactory());
sf.setTransportParams(new HashMap<String, Object>());
sf.setBackupConnectorFactory(new InVMConnectorFactory());
sf.setBackupTransportParams(new HashMap<String, Object>());
ClientSession sess = null;
try
{
sess = sf.createSession(false, true, true, false);
try
{
sf.setConnectorFactory(new InVMConnectorFactory());
fail("Should throw exception");
}
catch (IllegalStateException e)
{
// Ok
}
try
{
sf.setTransportParams(new HashMap<String, Object>());
fail("Should throw exception");
}
catch (IllegalStateException e)
{
// Ok
}
try
{
sf.setBackupConnectorFactory(new InVMConnectorFactory());
fail("Should throw exception");
}
catch (IllegalStateException e)
{
// Ok
}
try
{
sf.setBackupTransportParams(new HashMap<String, Object>());
fail("Should throw exception");
}
catch (IllegalStateException e)
{
// Ok
}
}
finally
{
sess.close();
}
sf.setConnectorFactory(new InVMConnectorFactory());
sf.setTransportParams(new HashMap<String, Object>());
sf.setBackupConnectorFactory(new InVMConnectorFactory());
sf.setBackupTransportParams(new HashMap<String, Object>());
}
public void testFailureAfterFailover() throws Exception
{
ClientSessionFactory sf = new ClientSessionFactoryImpl(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory"),
new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
ClientSession session = sf.createSession(false, true, true, false);
session.createQueue(ADDRESS, ADDRESS, null, false, false);
ClientProducer producer = session.createProducer(ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createClientMessage(JBossTextMessage.TYPE,
false,
0,
System.currentTimeMillis(),
(byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBody().putString("aardvarks");
message.getBody().flip();
producer.send(message);
}
RemotingConnection conn = ((ClientSessionImpl)session).getConnection();
// Simulate failure on connection
conn.fail(new MessagingException(MessagingException.NOT_CONNECTED));
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
// Consume half of them
for (int i = 0; i < numMessages / 2; i++)
{
ClientMessage message2 = consumer.receive();
assertEquals("aardvarks", message2.getBody().getString());
assertEquals(i, message2.getProperty(new SimpleString("count")));
message2.acknowledge();
}
RemotingConnection conn2 = ((ClientSessionImpl)session).getConnection();
final CountDownLatch latch = new CountDownLatch(1);
class MyListener implements FailureListener
{
public void connectionFailed(final MessagingException me)
{
latch.countDown();
}
}
conn2.addFailureListener(new MyListener());
assertFalse(conn == conn2);
conn2.fail(new MessagingException(MessagingException.NOT_CONNECTED));
boolean ok = latch.await(1000, TimeUnit.MILLISECONDS);
assertTrue(ok);
try
{
session.createQueue(new SimpleString("blah"), new SimpleString("blah"), null, false, false);
fail("Should throw exception");
}
catch (MessagingException me)
{
assertEquals(MessagingException.NOT_CONNECTED, me.getCode());
}
session.close();
}
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
@Override
protected void setUp() throws Exception
{
Configuration backupConf = new ConfigurationImpl();
backupConf.setSecurityEnabled(false);
backupConf.setPacketConfirmationBatchSize(10);
backupParams.put(TransportConstants.SERVER_ID_PROP_NAME, 1);
backupConf.getAcceptorConfigurations()
.add(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMAcceptorFactory",
backupParams));
backupConf.setBackup(true);
backupService = MessagingServiceImpl.newNullStorageMessagingServer(backupConf);
backupService.start();
Configuration liveConf = new ConfigurationImpl();
liveConf.setSecurityEnabled(false);
liveConf.setPacketConfirmationBatchSize(10);
liveConf.getAcceptorConfigurations()
.add(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMAcceptorFactory"));
liveConf.setBackupConnectorConfiguration(new TransportConfiguration("org.jboss.messaging.core.remoting.impl.invm.InVMConnectorFactory",
backupParams));
liveService = MessagingServiceImpl.newNullStorageMessagingServer(liveConf);
liveService.start();
}
@Override
protected void tearDown() throws Exception
{
assertEquals(0, ConnectionRegistryImpl.instance.size());
assertEquals(0, backupService.getServer().getRemotingService().getConnections().size());
backupService.stop();
assertEquals(0, liveService.getServer().getRemotingService().getConnections().size());
liveService.stop();
assertEquals(0, InVMRegistry.instance.size());
}
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}