/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.integration.xa;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.api.core.management.QueueControl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.StoreConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
import org.apache.activemq.artemis.jms.client.ActiveMQBytesMessage;
import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.integration.management.ManagementControlHelper;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class BasicXaRecoveryTest extends ActiveMQTestBase {
private static IntegrationTestLogger log = IntegrationTestLogger.LOGGER;
private final Map<String, AddressSettings> addressSettings = new HashMap<>();
private ActiveMQServer server;
private ClientSession clientSession;
private ClientProducer clientProducer;
private ClientConsumer clientConsumer;
private ClientSessionFactory sessionFactory;
private Configuration configuration;
private final SimpleString atestq = new SimpleString("atestq");
private ServerLocator locator;
private MBeanServer mbeanServer;
protected StoreConfiguration.StoreType storeType;
public BasicXaRecoveryTest(StoreConfiguration.StoreType storeType) {
this.storeType = storeType;
}
@Parameterized.Parameters(name = "storeType={0}")
public static Collection<Object[]> data() {
Object[][] params = new Object[][]{{StoreConfiguration.StoreType.FILE}, {StoreConfiguration.StoreType.DATABASE}};
return Arrays.asList(params);
}
@Override
@Before
public void setUp() throws Exception {
super.setUp();
if (storeType == StoreConfiguration.StoreType.DATABASE) {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
}
addressSettings.clear();
if (storeType == StoreConfiguration.StoreType.DATABASE) {
configuration = createDefaultJDBCConfig(true).setJMXManagementEnabled(true);
} else {
configuration = createDefaultInVMConfig().setJMXManagementEnabled(true);
}
mbeanServer = MBeanServerFactory.createMBeanServer();
server = createServer(true, configuration, -1, -1, addressSettings);
server.setMBeanServer(mbeanServer);
// start the server
server.start();
// then we create a client as normal
createClients(true, false);
}
@Override
@After
public void tearDown() throws Exception {
MBeanServerFactory.releaseMBeanServer(mbeanServer);
super.tearDown();
if (storeType == StoreConfiguration.StoreType.DATABASE) {
destroyTables(Arrays.asList("BINDINGS", "LARGE_MESSAGE", "MESSAGE"));
}
}
@Test
public void testBasicSendWithCommit() throws Exception {
testBasicSendWithCommit(false);
}
@Test
public void testBasicSendWithCommitWithServerStopped() throws Exception {
testBasicSendWithCommit(true);
}
@Test
public void testBasicSendWithRollback() throws Exception {
testBasicSendWithRollback(false);
}
@Test
public void testBasicSendWithRollbackWithServerStopped() throws Exception {
testBasicSendWithRollback(true);
}
@Test
public void testMultipleBeforeSendWithCommit() throws Exception {
testMultipleBeforeSendWithCommit(false);
}
@Test
public void testMultipleBeforeSendWithCommitWithServerStopped() throws Exception {
testMultipleBeforeSendWithCommit(true);
}
@Test
public void testMultipleTxSendWithCommit() throws Exception {
testMultipleTxSendWithCommit(false);
}
@Test
public void testMultipleTxSendWithCommitWithServerStopped() throws Exception {
testMultipleTxSendWithCommit(true);
}
@Test
public void testMultipleTxSendWithRollback() throws Exception {
testMultipleTxSendWithRollback(false);
}
@Test
public void testMultipleTxSendWithRollbackWithServerStopped() throws Exception {
testMultipleTxSendWithRollback(true);
}
@Test
public void testMultipleTxSendWithCommitAndRollback() throws Exception {
testMultipleTxSendWithCommitAndRollback(false);
}
@Test
public void testMultipleTxSendWithCommitAndRollbackWithServerStopped() throws Exception {
testMultipleTxSendWithCommitAndRollback(true);
}
@Test
public void testMultipleTxSameXidSendWithCommit() throws Exception {
testMultipleTxSameXidSendWithCommit(false);
}
@Test
public void testMultipleTxSameXidSendWithCommitWithServerStopped() throws Exception {
testMultipleTxSameXidSendWithCommit(true);
}
@Test
public void testBasicReceiveWithCommit() throws Exception {
testBasicReceiveWithCommit(false);
}
@Test
public void testBasicReceiveWithCommitWithServerStopped() throws Exception {
testBasicReceiveWithCommit(true);
}
@Test
public void testBasicReceiveWithRollback() throws Exception {
testBasicReceiveWithRollback(false);
}
@Test
public void testBasicReceiveWithRollbackWithServerStopped() throws Exception {
testBasicReceiveWithRollback(true);
}
@Test
public void testMultipleTxReceiveWithCommit() throws Exception {
testMultipleTxReceiveWithCommit(false);
}
@Test
public void testMultipleTxReceiveWithCommitWithServerStopped() throws Exception {
testMultipleTxReceiveWithCommit(true);
}
@Test
public void testMultipleTxReceiveWithRollback() throws Exception {
testMultipleTxReceiveWithRollback(false);
}
@Test
public void testMultipleTxReceiveWithRollbackWithServerStopped() throws Exception {
testMultipleTxReceiveWithRollback(true);
}
@Test
public void testPagingServerRestarted() throws Exception {
if (storeType == StoreConfiguration.StoreType.DATABASE)
return;
verifyPaging(true);
}
@Test
public void testPaging() throws Exception {
if (storeType == StoreConfiguration.StoreType.DATABASE)
return;
verifyPaging(false);
}
public void verifyPaging(final boolean restartServer) throws Exception {
if (storeType == StoreConfiguration.StoreType.DATABASE)
return;
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
SimpleString pageQueue = new SimpleString("pagequeue");
AddressSettings pageAddressSettings = new AddressSettings().setMaxSizeBytes(100 * 1024).setPageSizeBytes(10 * 1024);
addressSettings.put(pageQueue.toString(), pageAddressSettings);
addSettings();
clientSession.createQueue(pageQueue, pageQueue, null, true);
clientSession.start(xid, XAResource.TMNOFLAGS);
ClientProducer pageProducer = clientSession.createProducer(pageQueue);
for (int i = 0; i < 1000; i++) {
ClientMessage m = createBytesMessage(new byte[512], true);
pageProducer.send(m);
}
pageProducer.close();
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
BasicXaRecoveryTest.log.info("*** stopping and restarting");
if (restartServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
clientSession.commit(xid, false);
clientSession.close();
clientSession = sessionFactory.createSession(false, false, false);
clientSession.start();
ClientConsumer pageConsumer = clientSession.createConsumer(pageQueue);
for (int i = 0; i < 1000; i++) {
ClientMessage m = pageConsumer.receive(10000);
Assert.assertNotNull(m);
m.acknowledge();
clientSession.commit();
}
Assert.assertNull(pageConsumer.receiveImmediate());
}
@Test
public void testRollbackPaging() throws Exception {
if (storeType == StoreConfiguration.StoreType.DATABASE)
return;
testRollbackPaging(false);
}
@Test
public void testRollbackPagingServerRestarted() throws Exception {
if (storeType == StoreConfiguration.StoreType.DATABASE)
return;
testRollbackPaging(true);
}
public void testRollbackPaging(final boolean restartServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
SimpleString pageQueue = new SimpleString("pagequeue");
AddressSettings pageAddressSettings = new AddressSettings().setMaxSizeBytes(100 * 1024).setPageSizeBytes(10 * 1024);
addressSettings.put(pageQueue.toString(), pageAddressSettings);
addSettings();
clientSession.createQueue(pageQueue, pageQueue, null, true);
clientSession.start(xid, XAResource.TMNOFLAGS);
ClientProducer pageProducer = clientSession.createProducer(pageQueue);
for (int i = 0; i < 1000; i++) {
ClientMessage m = createBytesMessage(new byte[512], true);
pageProducer.send(m);
}
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (restartServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(1, xids.length);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
clientSession.rollback(xid);
clientSession.start();
ClientConsumer pageConsumer = clientSession.createConsumer(pageQueue);
Assert.assertNull(pageConsumer.receiveImmediate());
// Management message (from createQueue) will not be taken into account again as it is nonPersistent
}
@Test
public void testNonPersistent() throws Exception {
testNonPersistent(true);
testNonPersistent(false);
}
public void testNonPersistent(final boolean commit) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1", false);
ClientMessage m2 = createTextMessage("m2", false);
ClientMessage m3 = createTextMessage("m3", false);
ClientMessage m4 = createTextMessage("m4", false);
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m1);
clientProducer.send(m2);
clientProducer.send(m3);
clientProducer.send(m4);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
stopAndRestartServer();
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
if (commit) {
clientSession.commit(xid, false);
} else {
clientSession.rollback(xid);
}
xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 0);
}
@Test
public void testNonPersistentMultipleIDs() throws Exception {
for (int i = 0; i < 10; i++) {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1", false);
ClientMessage m2 = createTextMessage("m2", false);
ClientMessage m3 = createTextMessage("m3", false);
ClientMessage m4 = createTextMessage("m4", false);
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m1);
clientProducer.send(m2);
clientProducer.send(m3);
clientProducer.send(m4);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (i == 2) {
clientSession.commit(xid, false);
}
recreateClients();
}
stopAndRestartServer();
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(9, xids.length);
}
public void testBasicSendWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m1);
clientProducer.send(m2);
clientProducer.send(m3);
clientProducer.send(m4);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
}
public void testBasicSendWithRollback(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m1);
clientProducer.send(m2);
clientProducer.send(m3);
clientProducer.send(m4);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
BasicXaRecoveryTest.log.info("shutting down server");
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
BasicXaRecoveryTest.log.info("restarted");
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.rollback(xid);
clientSession.start();
ClientMessage m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
}
public void testMultipleBeforeSendWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(false, false, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m5);
clientProducer.send(m6);
clientProducer.send(m7);
clientProducer.send(m8);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m5");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m6");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m7");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m8");
}
public void testMultipleTxSendWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(true, false, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientSession2.start(xid2, XAResource.TMNOFLAGS);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.end(xid2, XAResource.TMSUCCESS);
clientSession2.prepare(xid2);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m5);
clientProducer.send(m6);
clientProducer.send(m7);
clientProducer.send(m8);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 2);
assertEqualXids(xids, xid, xid2);
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.commit(xid2, false);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m5");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m6");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m7");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m8");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
}
public void testMultipleTxSendWithRollback(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(true, false, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientSession2.start(xid2, XAResource.TMNOFLAGS);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.end(xid2, XAResource.TMSUCCESS);
clientSession2.prepare(xid2);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m5);
clientProducer.send(m6);
clientProducer.send(m7);
clientProducer.send(m8);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 2);
assertEqualXids(xids, xid, xid2);
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.rollback(xid);
clientSession.rollback(xid2);
clientSession.start();
ClientMessage m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
}
public void testMultipleTxSendWithCommitAndRollback(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(true, false, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientSession2.start(xid2, XAResource.TMNOFLAGS);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.end(xid2, XAResource.TMSUCCESS);
clientSession2.prepare(xid2);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientProducer.send(m5);
clientProducer.send(m6);
clientProducer.send(m7);
clientProducer.send(m8);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 2);
assertEqualXids(xids, xid, xid2);
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.rollback(xid);
clientSession.commit(xid2, false);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
}
public void testMultipleTxSameXidSendWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(true, false, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientSession2.start(xid, XAResource.TMNOFLAGS);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.end(xid, XAResource.TMSUCCESS);
clientSession2.close();
clientSession.start(xid, XAResource.TMJOIN);
clientProducer.send(m5);
clientProducer.send(m6);
clientProducer.send(m7);
clientProducer.send(m8);
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m5");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m6");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m7");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m8");
}
public void testBasicReceiveWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientSession clientSession2 = sessionFactory.createSession(false, true, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
clientSession.end(xid, XAResource.TMSUCCESS);
Assert.assertEquals("Expected XA_OK", XAResource.XA_OK, clientSession.prepare(xid));
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(xids.length, 1);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.start();
m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
//check deliveringCount Zero
checkQueueDeliveryCount(atestq, 0);
}
private void checkQueueDeliveryCount(SimpleString thequeue, int expectedCount) throws Exception {
QueueControl queueControl = ManagementControlHelper.createQueueControl(thequeue, thequeue, mbeanServer);
int actualCount = queueControl.getDeliveringCount();
assertEquals(expectedCount, actualCount);
}
public void testBasicReceiveWithRollback(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientSession clientSession2 = sessionFactory.createSession(false, true, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientSession2.close();
clientSession.start(xid, XAResource.TMNOFLAGS);
clientSession.start();
ClientMessage m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
BasicXaRecoveryTest.log.info("stopping and restarting");
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
BasicXaRecoveryTest.log.info("Restarted");
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
Assert.assertEquals(1, xids.length);
Assert.assertEquals(xids[0].getFormatId(), xid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getBranchQualifier(), xid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xids[0].getGlobalTransactionId(), xid.getGlobalTransactionId());
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.rollback(xid);
clientSession.start();
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
}
public void testMultipleTxReceiveWithCommit(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(false, true, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
SimpleString anewtestq = new SimpleString("anewtestq");
clientSession.createQueue(anewtestq, anewtestq, null, true);
ClientProducer clientProducer3 = clientSession2.createProducer(anewtestq);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientProducer3.send(m5);
clientProducer3.send(m6);
clientProducer3.send(m7);
clientProducer3.send(m8);
clientSession2.close();
clientSession2 = sessionFactory.createSession(true, false, false);
ClientConsumer clientConsumer2 = clientSession2.createConsumer(anewtestq);
clientSession2.start(xid2, XAResource.TMNOFLAGS);
clientSession2.start();
ClientMessage m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m5");
m = clientConsumer2.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m6");
m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m7");
m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m8");
clientSession2.end(xid2, XAResource.TMSUCCESS);
clientSession2.prepare(xid2);
clientSession2.close();
clientSession2 = null;
clientSession.start(xid, XAResource.TMNOFLAGS);
clientSession.start();
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
assertEqualXids(xids, xid, xid2);
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.commit(xid, false);
clientSession.start();
m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
}
public void testMultipleTxReceiveWithRollback(final boolean stopServer) throws Exception {
Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
Xid xid2 = new XidImpl("xa2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
ClientMessage m1 = createTextMessage("m1");
ClientMessage m2 = createTextMessage("m2");
ClientMessage m3 = createTextMessage("m3");
ClientMessage m4 = createTextMessage("m4");
ClientMessage m5 = createTextMessage("m5");
ClientMessage m6 = createTextMessage("m6");
ClientMessage m7 = createTextMessage("m7");
ClientMessage m8 = createTextMessage("m8");
ClientSession clientSession2 = sessionFactory.createSession(false, true, true);
ClientProducer clientProducer2 = clientSession2.createProducer(atestq);
SimpleString anewtestq = new SimpleString("anewtestq");
clientSession.createQueue(anewtestq, anewtestq, null, true);
ClientProducer clientProducer3 = clientSession2.createProducer(anewtestq);
clientProducer2.send(m1);
clientProducer2.send(m2);
clientProducer2.send(m3);
clientProducer2.send(m4);
clientProducer3.send(m5);
clientProducer3.send(m6);
clientProducer3.send(m7);
clientProducer3.send(m8);
clientSession2.close();
clientSession2 = sessionFactory.createSession(true, false, false);
ClientConsumer clientConsumer2 = clientSession2.createConsumer(anewtestq);
clientSession2.start(xid2, XAResource.TMNOFLAGS);
clientSession2.start();
ClientMessage m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m5");
m = clientConsumer2.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m6");
m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m7");
m = clientConsumer2.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m8");
clientSession2.end(xid2, XAResource.TMSUCCESS);
clientSession2.prepare(xid2);
clientSession2.close();
clientSession2 = null;
clientSession.start(xid, XAResource.TMNOFLAGS);
clientSession.start();
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
if (stopServer) {
stopAndRestartServer();
} else {
recreateClients();
}
Xid[] xids = clientSession.recover(XAResource.TMSTARTRSCAN);
assertEqualXids(xids, xid, xid2);
xids = clientSession.recover(XAResource.TMENDRSCAN);
Assert.assertEquals(xids.length, 0);
clientSession.rollback(xid);
clientSession.start();
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
m = clientConsumer.receive(1000);
Assert.assertNotNull(m);
m.acknowledge();
Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
m = clientConsumer.receive(1000);
m.acknowledge();
Assert.assertNotNull(m);
Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
}
protected void stopAndRestartServer() throws Exception {
// now stop and start the server
clientSession.close();
clientSession = null;
server.stop();
server = null;
server = createServer(true, configuration, -1, -1, addressSettings);
server.setMBeanServer(mbeanServer);
server.start();
createClients();
}
private void addSettings() {
for (Map.Entry<String, AddressSettings> setting : addressSettings.entrySet()) {
server.getAddressSettingsRepository().addMatch(setting.getKey(), setting.getValue());
}
}
protected void recreateClients() throws Exception {
clientSession.close();
clientSession = null;
createClients();
}
private ClientMessage createTextMessage(final String s) {
return createTextMessage(s, true);
}
private ClientMessage createTextMessage(final String s, final boolean durable) {
ClientMessage message = clientSession.createMessage(ActiveMQTextMessage.TYPE, durable, 0, System.currentTimeMillis(), (byte) 1);
message.getBodyBuffer().writeString(s);
return message;
}
private ClientMessage createBytesMessage(final byte[] b, final boolean durable) {
ClientMessage message = clientSession.createMessage(ActiveMQBytesMessage.TYPE, durable, 0, System.currentTimeMillis(), (byte) 1);
message.getBodyBuffer().writeBytes(b);
return message;
}
private void createClients() throws Exception {
createClients(false, true);
}
private void createClients(final boolean createQueue, final boolean commitACKs) throws Exception {
locator = createInVMNonHALocator();
sessionFactory = createSessionFactory(locator);
clientSession = sessionFactory.createSession(true, false, commitACKs);
if (createQueue) {
clientSession.createQueue(atestq, atestq, null, true);
}
clientProducer = clientSession.createProducer(atestq);
clientConsumer = clientSession.createConsumer(atestq);
}
private void assertEqualXids(final Xid[] xids, final Xid... origXids) {
Assert.assertEquals(xids.length, origXids.length);
for (Xid xid : xids) {
boolean found = false;
for (Xid origXid : origXids) {
found = Arrays.equals(origXid.getBranchQualifier(), xid.getBranchQualifier());
if (found) {
Assert.assertEquals(xid.getFormatId(), origXid.getFormatId());
ActiveMQTestBase.assertEqualsByteArrays(xid.getBranchQualifier(), origXid.getBranchQualifier());
ActiveMQTestBase.assertEqualsByteArrays(xid.getGlobalTransactionId(), origXid.getGlobalTransactionId());
break;
}
}
if (!found) {
Assert.fail("correct xid not found: " + xid);
}
}
}
}