use of org.apache.activemq.artemis.core.transaction.impl.XidImpl in project activemq-artemis by apache.
the class AMQPConnectionCallback method newTransaction.
public Binary newTransaction() {
XidImpl xid = newXID();
Binary binary = new Binary(xid.getGlobalTransactionId());
Transaction transaction = new ProtonTransactionImpl(xid, server.getStorageManager(), -1);
transactions.put(binary, transaction);
return binary;
}
use of org.apache.activemq.artemis.core.transaction.impl.XidImpl in project activemq-artemis by apache.
the class MessageGroupingTest method dotestMultipleGroupingXACommit.
private void dotestMultipleGroupingXACommit() throws Exception {
ServerLocator locator = createInVMNonHALocator();
ClientSessionFactory sessionFactory = createSessionFactory(locator);
ClientSession clientSession = sessionFactory.createSession(true, false, false);
ClientProducer clientProducer = this.clientSession.createProducer(qName);
ClientConsumer consumer = clientSession.createConsumer(qName);
ClientConsumer consumer2 = clientSession.createConsumer(qName);
clientSession.start();
Xid xid = new XidImpl("bq".getBytes(), 4, "gtid".getBytes());
clientSession.start(xid, XAResource.TMNOFLAGS);
SimpleString groupId = new SimpleString("grp1");
SimpleString groupId2 = new SimpleString("grp2");
int numMessages = 100;
for (int i = 0; i < numMessages; i++) {
ClientMessage message = createTextMessage(clientSession, "m" + i);
if (i % 2 == 0 || i == 0) {
message.putStringProperty(Message.HDR_GROUP_ID, groupId);
} else {
message.putStringProperty(Message.HDR_GROUP_ID, groupId2);
}
clientProducer.send(message);
}
CountDownLatch latch = new CountDownLatch(numMessages);
DummyMessageHandler dummyMessageHandler = new DummyMessageHandler(latch, true);
consumer.setMessageHandler(dummyMessageHandler);
DummyMessageHandler dummyMessageHandler2 = new DummyMessageHandler(latch, true);
consumer2.setMessageHandler(dummyMessageHandler2);
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
clientSession.commit(xid, false);
Assert.assertEquals(dummyMessageHandler.list.size(), 50);
int i = 0;
for (ClientMessage message : dummyMessageHandler.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
Assert.assertEquals(dummyMessageHandler2.list.size(), 50);
i = 1;
for (ClientMessage message : dummyMessageHandler2.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
consumer.close();
consumer2.close();
consumer = this.clientSession.createConsumer(qName);
Assert.assertNull(consumer.receiveImmediate());
clientSession.close();
locator.close();
}
use of org.apache.activemq.artemis.core.transaction.impl.XidImpl in project activemq-artemis by apache.
the class MessageGroupingTest method doTestMultipleGroupingXARollback.
private void doTestMultipleGroupingXARollback() throws Exception {
ServerLocator locator = createInVMNonHALocator();
locator.setBlockOnAcknowledge(true);
ClientSessionFactory sessionFactory = createSessionFactory(locator);
ClientSession clientSession = sessionFactory.createSession(true, false, false);
ClientProducer clientProducer = this.clientSession.createProducer(qName);
clientSession.start();
ClientConsumer consumer = clientSession.createConsumer(qName);
ClientConsumer consumer2 = clientSession.createConsumer(qName);
Xid xid = new XidImpl("bq".getBytes(), 4, "gtid".getBytes());
clientSession.start(xid, XAResource.TMNOFLAGS);
SimpleString groupId = new SimpleString("grp1");
SimpleString groupId2 = new SimpleString("grp2");
int numMessages = 100;
for (int i = 0; i < numMessages; i++) {
ClientMessage message = createTextMessage(clientSession, "m" + i);
if (i % 2 == 0 || i == 0) {
message.putStringProperty(Message.HDR_GROUP_ID, groupId);
} else {
message.putStringProperty(Message.HDR_GROUP_ID, groupId2);
}
clientProducer.send(message);
}
CountDownLatch latch = new CountDownLatch(numMessages);
DummyMessageHandler dummyMessageHandler = new DummyMessageHandler(latch, true);
consumer.setMessageHandler(dummyMessageHandler);
DummyMessageHandler dummyMessageHandler2 = new DummyMessageHandler(latch, true);
consumer2.setMessageHandler(dummyMessageHandler2);
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
clientSession.end(xid, XAResource.TMSUCCESS);
Assert.assertEquals(dummyMessageHandler.list.size(), 50);
int i = 0;
for (ClientMessage message : dummyMessageHandler.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
Assert.assertEquals(dummyMessageHandler2.list.size(), 50);
i = 1;
for (ClientMessage message : dummyMessageHandler2.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
latch = new CountDownLatch(numMessages);
dummyMessageHandler.reset(latch);
dummyMessageHandler2.reset(latch);
clientSession.rollback(xid);
clientSession.start(xid, XAResource.TMNOFLAGS);
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
clientSession.end(xid, XAResource.TMSUCCESS);
clientSession.prepare(xid);
clientSession.commit(xid, false);
Assert.assertEquals(dummyMessageHandler.list.size(), 50);
i = 0;
for (ClientMessage message : dummyMessageHandler.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
Assert.assertEquals(dummyMessageHandler2.list.size(), 50);
i = 1;
for (ClientMessage message : dummyMessageHandler2.list) {
Assert.assertEquals(message.getBodyBuffer().readString(), "m" + i);
i += 2;
}
consumer = this.clientSession.createConsumer(qName);
Assert.assertNull(consumer.receiveImmediate());
clientSession.close();
locator.close();
}
use of org.apache.activemq.artemis.core.transaction.impl.XidImpl in project activemq-artemis by apache.
the class BMFailoverTest method testFailoverOnCommit2.
@Test
@BMRules(rules = { @BMRule(name = "trace clientsessionimpl commit", targetClass = "org.apache.activemq.artemis.core.client.impl.ClientSessionImpl", targetMethod = "start(javax.transaction.xa.Xid, int)", targetLocation = "AT EXIT", action = "org.apache.activemq.artemis.tests.extras.byteman.BMFailoverTest.serverToStop.getServer().stop(true)") })
public void testFailoverOnCommit2() throws Exception {
serverToStop = liveServer;
locator = getServerLocator().setFailoverOnInitialConnection(true);
SimpleString inQueue = new SimpleString("inQueue");
SimpleString outQueue = new SimpleString("outQueue");
createSessionFactory();
createSessionFactory2();
// closeable will take care of closing it
try (ClientSession session = sf.createSession(false, true, true);
ClientProducer sendInitialProducer = session.createProducer()) {
session.createQueue(inQueue, inQueue, null, true);
session.createQueue(outQueue, outQueue, null, true);
sendInitialProducer.send(inQueue, createMessage(session, 0, true));
}
ClientSession xaSessionRec = addClientSession(sf.createSession(true, false, false));
ClientConsumer consumer = addClientConsumer(xaSessionRec.createConsumer(inQueue));
byte[] globalTransactionId = UUIDGenerator.getInstance().generateStringUUID().getBytes();
Xid xidRec = new XidImpl("xa2".getBytes(), 1, globalTransactionId);
xaSessionRec.start();
xaSessionRec.getXAResource().start(xidRec, XAResource.TMNOFLAGS);
// failover is now occurring, receive, ack and end will be called whilst this is happening.
ClientMessageImpl m = (ClientMessageImpl) consumer.receive(5000);
assertNotNull(m);
System.out.println("********************" + m.getIntProperty("counter"));
// the mdb would ack the message before calling onMessage()
m.acknowledge();
try {
// this may fail but thats ok, it depends on the race and when failover actually happens
xaSessionRec.end(xidRec, XAResource.TMSUCCESS);
} catch (XAException ignore) {
}
// we always reset the client on the RA
((ClientSessionInternal) xaSessionRec).resetIfNeeded();
// closeable will take care of closing it
try (ClientSession session = sf.createSession(false, true, true);
ClientProducer sendInitialProducer = session.createProducer()) {
sendInitialProducer.send(inQueue, createMessage(session, 0, true));
}
// now receive and send a message successfully
globalTransactionId = UUIDGenerator.getInstance().generateStringUUID().getBytes();
xidRec = new XidImpl("xa4".getBytes(), 1, globalTransactionId);
xaSessionRec.getXAResource().start(xidRec, XAResource.TMNOFLAGS);
Binding binding = backupServer.getServer().getPostOffice().getBinding(inQueue);
Queue inQ = (Queue) binding.getBindable();
m = (ClientMessageImpl) consumer.receive(5000);
assertNotNull(m);
// the mdb would ack the message before calling onMessage()
m.acknowledge();
System.out.println("********************" + m.getIntProperty("counter"));
xaSessionRec.getXAResource().end(xidRec, XAResource.TMSUCCESS);
xaSessionRec.getXAResource().prepare(xidRec);
xaSessionRec.getXAResource().commit(xidRec, false);
// let's close the consumer so anything pending is handled
consumer.close();
assertEquals(1, getMessageCount(inQ));
}
use of org.apache.activemq.artemis.core.transaction.impl.XidImpl in project activemq-artemis by apache.
the class ConcurrentDeliveryCancelTest method testConcurrentCancels.
@Test
@BMRules(rules = { @BMRule(name = "enterCancel-holdThere", targetClass = "org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl", targetMethod = "close", targetLocation = "ENTRY", action = "org.apache.activemq.artemis.tests.extras.byteman.ConcurrentDeliveryCancelTest.enterCancel();") })
public void testConcurrentCancels() throws Exception {
System.out.println(server.getConfiguration().getJournalLocation().toString());
server.getAddressSettingsRepository().clear();
AddressSettings settings = new AddressSettings();
settings.setMaxDeliveryAttempts(-1);
server.getAddressSettingsRepository().addMatch("#", settings);
ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory("tcp://localhost:61616", "test");
cf.setReconnectAttempts(0);
cf.setRetryInterval(10);
System.out.println(".....");
for (ServerSession srvSess : server.getSessions()) {
System.out.println(srvSess);
}
String queueName = RandomUtil.randomString();
Queue queue = createQueue(queueName);
int numberOfMessages = 10000;
{
Connection connection = cf.createConnection();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = session.createProducer(queue);
for (int i = 0; i < numberOfMessages; i++) {
TextMessage msg = session.createTextMessage("message " + i);
msg.setIntProperty("i", i);
producer.send(msg);
}
session.commit();
connection.close();
}
for (int i = 0; i < 100; i++) {
XAConnectionFactory xacf = ActiveMQJMSClient.createConnectionFactory("tcp://localhost:61616", "test");
final XAConnection connection = xacf.createXAConnection();
final XASession theSession = connection.createXASession();
((ActiveMQSession) theSession).getCoreSession().addMetaData("theSession", "true");
connection.start();
final MessageConsumer consumer = theSession.createConsumer(queue);
XidImpl xid = newXID();
theSession.getXAResource().start(xid, XAResource.TMNOFLAGS);
// I'm setting a small timeout just because I'm lazy to call end myself
theSession.getXAResource().setTransactionTimeout(1);
for (int msg = 0; msg < 11; msg++) {
Assert.assertNotNull(consumer.receiveNoWait());
}
System.out.println(".....");
final List<ServerSession> serverSessions = new LinkedList<>();
// We will force now the failure simultaneously from several places
for (ServerSession srvSess : server.getSessions()) {
if (srvSess.getMetaData("theSession") != null) {
System.out.println(srvSess);
serverSessions.add(srvSess);
}
}
// from Transactional reaper
resetLatches(2);
List<Thread> threads = new LinkedList<>();
threads.add(new Thread("ConsumerCloser") {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " closing consumer");
consumer.close();
System.out.println(Thread.currentThread().getName() + " closed consumer");
} catch (Exception e) {
e.printStackTrace();
}
}
});
threads.add(new Thread("SessionCloser") {
@Override
public void run() {
for (ServerSession sess : serverSessions) {
System.out.println("Thread " + Thread.currentThread().getName() + " starting");
try {
// A session.close could sneak in through failover or some other scenarios.
// a call to RemotingConnection.fail wasn't replicating the issue.
// I needed to call Session.close() directly to replicate what was happening in production
sess.close(true);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread " + Thread.currentThread().getName() + " done");
}
}
});
for (Thread t : threads) {
t.start();
}
Assert.assertTrue(latchEnter.await(10, TimeUnit.MINUTES));
latchFlag.countDown();
for (Thread t : threads) {
t.join(5000);
Assert.assertFalse(t.isAlive());
}
connection.close();
}
Connection connection = cf.createConnection();
try {
connection.setClientID("myID");
// I am too lazy to call end on all the transactions
Thread.sleep(5000);
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(queue);
HashMap<Integer, AtomicInteger> mapCount = new HashMap<>();
while (true) {
TextMessage message = (TextMessage) consumer.receiveNoWait();
if (message == null) {
break;
}
Integer value = message.getIntProperty("i");
AtomicInteger count = mapCount.get(value);
if (count == null) {
count = new AtomicInteger(0);
mapCount.put(message.getIntProperty("i"), count);
}
count.incrementAndGet();
}
boolean failed = false;
for (int i = 0; i < numberOfMessages; i++) {
AtomicInteger count = mapCount.get(i);
if (count == null) {
System.out.println("Message " + i + " not received");
failed = true;
} else if (count.get() > 1) {
System.out.println("Message " + i + " received " + count.get() + " times");
failed = true;
}
}
Assert.assertFalse("test failed, look at the system.out of the test for more information", failed);
} finally {
connection.close();
}
}
Aggregations