/* * Stress a queue with transational, non transactional and 2pc senders sending both persistent * and non persistent messages * Transactional senders go through a cycle of sending and rolling back * */ @Test public void testQueueMultipleSenders() throws Exception { Connection conn1 = cf.createConnection(); Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess2 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess3 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess4 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess5 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess6 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess7 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess8 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE); Session sess9 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess10 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess11 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess12 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess13 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess14 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess15 = conn1.createSession(true, Session.SESSION_TRANSACTED); Session sess16 = conn1.createSession(true, Session.SESSION_TRANSACTED); XASession xaSess1 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess1); XASession xaSess2 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess2); XASession xaSess3 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess3); XASession xaSess4 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess4); XASession xaSess5 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess5); XASession xaSess6 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess6); XASession xaSess7 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess7); XASession xaSess8 = ((XAConnection) conn1).createXASession(); tweakXASession(xaSess8); Session sess17 = xaSess1.getSession(); Session sess18 = xaSess2.getSession(); Session sess19 = xaSess3.getSession(); Session sess20 = xaSess4.getSession(); Session sess21 = xaSess5.getSession(); Session sess22 = xaSess6.getSession(); Session sess23 = xaSess7.getSession(); Session sess24 = xaSess8.getSession(); MessageProducer prod1 = sess1.createProducer(destinationQueue1); prod1.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod2 = sess2.createProducer(destinationQueue1); prod2.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod3 = sess3.createProducer(destinationQueue1); prod3.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod4 = sess4.createProducer(destinationQueue1); prod4.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod5 = sess5.createProducer(destinationQueue1); prod5.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod6 = sess6.createProducer(destinationQueue1); prod6.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod7 = sess7.createProducer(destinationQueue1); prod7.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod8 = sess8.createProducer(destinationQueue1); prod8.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod9 = sess9.createProducer(destinationQueue1); prod9.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod10 = sess10.createProducer(destinationQueue1); prod10.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod11 = sess11.createProducer(destinationQueue1); prod11.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod12 = sess12.createProducer(destinationQueue1); prod12.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod13 = sess13.createProducer(destinationQueue1); prod13.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod14 = sess14.createProducer(destinationQueue1); prod14.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod15 = sess15.createProducer(destinationQueue1); prod15.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod16 = sess16.createProducer(destinationQueue1); prod16.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod17 = sess17.createProducer(destinationQueue1); prod17.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod18 = sess18.createProducer(destinationQueue1); prod18.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod19 = sess19.createProducer(destinationQueue1); prod19.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod20 = sess20.createProducer(destinationQueue1); prod20.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod21 = sess21.createProducer(destinationQueue1); prod21.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod22 = sess22.createProducer(destinationQueue1); prod22.setDeliveryMode(DeliveryMode.PERSISTENT); MessageProducer prod23 = sess23.createProducer(destinationQueue1); prod23.setDeliveryMode(DeliveryMode.NON_PERSISTENT); MessageProducer prod24 = sess24.createProducer(destinationQueue1); prod24.setDeliveryMode(DeliveryMode.PERSISTENT); Connection conn2 = cf.createConnection(); conn2.start(); Session sessReceive = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer cons = sessReceive.createConsumer(destinationQueue1); Runner[] runners = new Runner[] { new Sender("prod1", sess1, prod1, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES), new Sender("prod2", sess2, prod2, JMSStressTestBase.NUM_PERSISTENT_MESSAGES), new Sender("prod3", sess3, prod3, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES), new Sender("prod4", sess4, prod4, JMSStressTestBase.NUM_PERSISTENT_MESSAGES), new Sender("prod5", sess5, prod5, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES), new Sender("prod6", sess6, prod6, JMSStressTestBase.NUM_PERSISTENT_MESSAGES), new Sender("prod7", sess7, prod7, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES), new Sender("prod8", sess8, prod8, JMSStressTestBase.NUM_PERSISTENT_MESSAGES), new TransactionalSender( "prod9", sess9, prod9, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 1, 1), new TransactionalSender( "prod10", sess10, prod10, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 1, 1), new TransactionalSender( "prod11", sess11, prod11, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 10, 7), new TransactionalSender( "prod12", sess12, prod12, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 10, 7), new TransactionalSender( "prod13", sess13, prod13, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 50, 21), new TransactionalSender( "prod14", sess14, prod14, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 50, 21), new TransactionalSender( "prod15", sess15, prod15, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 100, 67), new TransactionalSender( "prod16", sess16, prod16, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 100, 67), new Transactional2PCSender( "prod17", xaSess1, prod17, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 1, 1), new Transactional2PCSender( "prod18", xaSess2, prod18, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 1, 1), new Transactional2PCSender( "prod19", xaSess3, prod19, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 10, 7), new Transactional2PCSender( "prod20", xaSess4, prod20, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 10, 7), new Transactional2PCSender( "prod21", xaSess5, prod21, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 50, 21), new Transactional2PCSender( "prod22", xaSess6, prod22, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 50, 21), new Transactional2PCSender( "prod23", xaSess7, prod23, JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES, 100, 67), new Transactional2PCSender( "prod24", xaSess8, prod24, JMSStressTestBase.NUM_PERSISTENT_MESSAGES, 100, 67), new Receiver( sessReceive, cons, 12 * JMSStressTestBase.NUM_NON_PERSISTENT_MESSAGES + 12 * JMSStressTestBase.NUM_PERSISTENT_MESSAGES, false) }; runRunners(runners); conn1.close(); conn2.close(); }
/** * Create a one time MessageProducer for this JMS OutTransport information. For simplicity and * best compatibility, this method uses only JMS 1.0.2b API. Please be cautious when making any * changes * * @return a JMSSender based on one-time use resources * @throws JMSException on errors, to be handled and logged by the caller */ public JMSMessageSender createJMSSender(MessageContext msgCtx) throws JMSException { // digest the targetAddress and locate CF from the EPR loadConnectionFactoryFromProperties(); // create a one time connection and session to be used String user = properties != null ? properties.get(JMSConstants.PARAM_JMS_USERNAME) : null; String pass = properties != null ? properties.get(JMSConstants.PARAM_JMS_PASSWORD) : null; QueueConnectionFactory qConFac = null; TopicConnectionFactory tConFac = null; int destType = -1; // TODO: there is something missing here for destination type generic if (JMSConstants.DESTINATION_TYPE_QUEUE.equals(destinationType)) { destType = JMSConstants.QUEUE; qConFac = (QueueConnectionFactory) connectionFactory; } else if (JMSConstants.DESTINATION_TYPE_TOPIC.equals(destinationType)) { destType = JMSConstants.TOPIC; tConFac = (TopicConnectionFactory) connectionFactory; } else { // treat jmsdestination type=queue(default is queue) destType = JMSConstants.QUEUE; qConFac = (QueueConnectionFactory) connectionFactory; } if (msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER) != null) { XAConnection connection = null; if (user != null && pass != null) { if (qConFac != null) { connection = ((XAConnectionFactory) qConFac).createXAConnection(user, pass); } else if (tConFac != null) { connection = ((XAConnectionFactory) tConFac).createXAConnection(user, pass); } } else { if (qConFac != null) { connection = ((XAConnectionFactory) qConFac).createXAConnection(); } else if (tConFac != null) { connection = ((XAConnectionFactory) tConFac).createXAConnection(); } } if (connection == null) { connection = ((XAConnectionFactory) qConFac).createXAConnection(); } XASession session = null; MessageProducer producer = null; if (connection != null) { if (destType == JMSConstants.QUEUE) { session = connection.createXASession(); producer = session.createProducer(destination); } else { session = connection.createXASession(); producer = session.createProducer(destination); } } XAResource xaResource = session.getXAResource(); TransactionManager tx = null; Xid xid1 = null; Transaction transaction = null; java.util.UUID uuid = java.util.UUID.randomUUID(); try { tx = (TransactionManager) msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER); transaction = tx.getTransaction(); msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER, tx); msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION, transaction); xid1 = new JMSXid( JMSConstants.JMS_XA_TRANSACTION_PREFIX.getBytes(StandardCharsets.UTF_8), 1, uuid.toString().getBytes()); msgCtx.setProperty("XID", xid1); xaResource.start(xid1, XAResource.TMNOFLAGS); } catch (SystemException e) { handleException("Error Occurred during starting getting Transaction.", e); } catch (XAException e) { handleException("Error Occurred during starting XA resource.", e); } return new JMSMessageSender( connection, session, producer, destination, jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(), jmsSpecVersion, destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE, transaction, xid1, xaResource); } else { Connection connection = null; if (user != null && pass != null) { if (qConFac != null) { connection = qConFac.createQueueConnection(user, pass); } else if (tConFac != null) { connection = tConFac.createTopicConnection(user, pass); } } else { if (qConFac != null) { connection = qConFac.createQueueConnection(); } else if (tConFac != null) { connection = tConFac.createTopicConnection(); } } if (connection == null) { connection = jmsConnectionFactory != null ? jmsConnectionFactory.getConnection() : null; } Session session = null; MessageProducer producer = null; if (connection != null) { if (destType == JMSConstants.QUEUE) { session = ((QueueConnection) connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE); producer = ((QueueSession) session).createSender((Queue) destination); } else { session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE); producer = ((TopicSession) session).createPublisher((Topic) destination); } } return new JMSMessageSender( connection, session, producer, destination, jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(), jmsSpecVersion, destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE); } }
@Override public boolean runExample() throws Exception { XAConnection connection = null; InitialContext initialContext = null; try { // Step 1. Create an initial context to perform the JNDI lookup. initialContext = getContext(0); // Step 2. Lookup on the queue Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue"); // Step 3. Perform a lookup on the XA Connection Factory XAConnectionFactory cf = (XAConnectionFactory) initialContext.lookup("/XAConnectionFactory"); // Step 4.Create a JMS XAConnection connection = cf.createXAConnection(); // Step 5. Start the connection connection.start(); // Step 6. Create a JMS XASession XASession xaSession = connection.createXASession(); // Step 7. Create a normal session Session normalSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Step 8. Create a normal Message Consumer MessageConsumer normalConsumer = normalSession.createConsumer(queue); normalConsumer.setMessageListener(new SimpleMessageListener()); // Step 9. Get the JMS Session Session session = xaSession.getSession(); // Step 10. Create a message producer MessageProducer producer = session.createProducer(queue); // Step 11. Create two Text Messages TextMessage helloMessage = session.createTextMessage("hello"); TextMessage worldMessage = session.createTextMessage("world"); // Step 12. create a transaction Xid xid1 = new DummyXid( "xa-example1".getBytes(CharsetUtil.UTF_8), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); // Step 13. Get the JMS XAResource XAResource xaRes = xaSession.getXAResource(); // Step 14. Begin the Transaction work xaRes.start(xid1, XAResource.TMNOFLAGS); // Step 15. do work, sending two messages. producer.send(helloMessage); producer.send(worldMessage); Thread.sleep(2000); // Step 16. Check the result, it should receive none! checkNoMessageReceived(); // Step 17. Stop the work xaRes.end(xid1, XAResource.TMSUCCESS); // Step 18. Prepare xaRes.prepare(xid1); // Step 19. Roll back the transaction xaRes.rollback(xid1); // Step 20. No messages should be received! checkNoMessageReceived(); // Step 21. Create another transaction Xid xid2 = new DummyXid( "xa-example2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes()); // Step 22. Start the transaction xaRes.start(xid2, XAResource.TMNOFLAGS); // Step 23. Re-send those messages producer.send(helloMessage); producer.send(worldMessage); // Step 24. Stop the work xaRes.end(xid2, XAResource.TMSUCCESS); // Step 25. Prepare xaRes.prepare(xid2); // Step 26. No messages should be received at this moment checkNoMessageReceived(); // Step 27. Commit! xaRes.commit(xid2, false); Thread.sleep(2000); // Step 28. Check the result, all message received checkAllMessageReceived(); return result; } finally { // Step 29. Be sure to close our JMS resources! if (initialContext != null) { initialContext.close(); } if (connection != null) { connection.close(); } } }