/* * 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.jms.client; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSConsumer; import javax.jms.JMSContext; import javax.jms.JMSException; import javax.jms.JMSProducer; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import java.util.UUID; import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQMessage; import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.tests.util.JMSTestBase; import org.junit.Assume; import org.junit.Before; import org.junit.Test; /** * GroupingTest */ public class GroupingTest extends JMSTestBase { private Queue queue; @Override @Before public void setUp() throws Exception { super.setUp(); queue = createQueue("TestQueue"); } protected void setProperty(Message message) { ((ActiveMQMessage) message).getCoreMessage().putStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_GROUP_ID, new SimpleString("foo")); } protected ConnectionFactory getCF() throws Exception { return cf; } @Test public void testGrouping() throws Exception { ConnectionFactory fact = getCF(); Connection connection = fact.createConnection(); Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); MessageConsumer consumer1 = session.createConsumer(queue); MessageConsumer consumer2 = session.createConsumer(queue); MessageConsumer consumer3 = session.createConsumer(queue); connection.start(); String jmsxgroupID = null; for (int j = 0; j < 100; j++) { TextMessage message = session.createTextMessage(); message.setText("Message" + j); setProperty(message); producer.send(message); String prop = message.getStringProperty("JMSXGroupID"); assertNotNull(prop); if (jmsxgroupID != null) { assertEquals(jmsxgroupID, prop); } else { jmsxgroupID = prop; } } //All msgs should go to the first consumer for (int j = 0; j < 100; j++) { TextMessage tm = (TextMessage) consumer1.receive(10000); assertNotNull(tm); assertEquals("Message" + j, tm.getText()); assertEquals(tm.getStringProperty("JMSXGroupID"), jmsxgroupID); } connection.close(); } @Test public void testGroupingWithJMS2Producer() throws Exception { ConnectionFactory fact = getCF(); Assume.assumeFalse("only makes sense withOUT auto-group", ((ActiveMQConnectionFactory) fact).isAutoGroup()); Assume.assumeTrue("only makes sense withOUT explicit group-id", ((ActiveMQConnectionFactory) fact).getGroupID() == null); final String groupID = UUID.randomUUID().toString(); JMSContext ctx = addContext(getCF().createContext(JMSContext.SESSION_TRANSACTED)); JMSProducer producer = ctx.createProducer().setProperty("JMSXGroupID", groupID); JMSConsumer consumer1 = ctx.createConsumer(queue); JMSConsumer consumer2 = ctx.createConsumer(queue); JMSConsumer consumer3 = ctx.createConsumer(queue); ctx.start(); for (int j = 0; j < 100; j++) { TextMessage message = ctx.createTextMessage("Message" + j); producer.send(queue, message); String prop = message.getStringProperty("JMSXGroupID"); assertNotNull(prop); assertEquals(groupID, prop); } ctx.commit(); //All msgs should go to the first consumer for (int j = 0; j < 100; j++) { TextMessage tm = (TextMessage) consumer1.receive(10000); assertNotNull(tm); tm.acknowledge(); assertEquals("Message" + j, tm.getText()); assertEquals(tm.getStringProperty("JMSXGroupID"), groupID); tm = (TextMessage) consumer2.receiveNoWait(); assertNull(tm); tm = (TextMessage) consumer3.receiveNoWait(); assertNull(tm); } ctx.commit(); ctx.close(); } @Test public void testManyGroups() throws Exception { ConnectionFactory fact = getCF(); Assume.assumeFalse("only makes sense withOUT auto-group", ((ActiveMQConnectionFactory) fact).isAutoGroup()); Connection connection = fact.createConnection(); Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); MessageConsumer consumer1 = session.createConsumer(queue); MessageConsumer consumer2 = session.createConsumer(queue); MessageConsumer consumer3 = session.createConsumer(queue); connection.start(); for (int j = 0; j < 1000; j++) { TextMessage message = session.createTextMessage(); message.setText("Message" + j); message.setStringProperty("_AMQ_GROUP_ID", "" + (j % 10)); producer.send(message); String prop = message.getStringProperty("JMSXGroupID"); assertNotNull(prop); } int msg1 = flushMessages(consumer1); int msg2 = flushMessages(consumer2); int msg3 = flushMessages(consumer3); assertNotSame(0, msg1); assertNotSame(0, msg2); assertNotSame(0, msg2); consumer1.close(); consumer2.close(); consumer3.close(); connection.close(); } @Test public void testGroupingRollbackOnClose() throws Exception { ActiveMQConnectionFactory fact = (ActiveMQConnectionFactory) getCF(); fact.setConsumerWindowSize(1000); fact.setTransactionBatchSize(0); Connection connection = fact.createConnection(); RemotingConnection rc = server.getRemotingService().getConnections().iterator().next(); Connection connection2 = fact.createConnection(); Session session = connection.createSession(true, Session.SESSION_TRANSACTED); Session session2 = connection2.createSession(true, Session.SESSION_TRANSACTED); MessageProducer producer = session.createProducer(queue); MessageConsumer consumer1 = session.createConsumer(queue); MessageConsumer consumer2 = session2.createConsumer(queue); connection.start(); connection2.start(); String jmsxgroupID = null; for (int j = 0; j < 100; j++) { TextMessage message = session.createTextMessage(); message.setText("Message" + j); setProperty(message); producer.send(message); String prop = message.getStringProperty("JMSXGroupID"); assertNotNull(prop); if (jmsxgroupID != null) { assertEquals(jmsxgroupID, prop); } else { jmsxgroupID = prop; } } session.commit(); //consume 5 msgs from 1st first consumer for (int j = 0; j < 1; j++) { TextMessage tm = (TextMessage) consumer1.receive(10000); assertNotNull(tm); assertEquals("Message" + j, tm.getText()); assertEquals(tm.getStringProperty("JMSXGroupID"), jmsxgroupID); } Thread.sleep(2000); //session.rollback(); //session.close(); //consume all msgs from 2nd first consumer // ClientSession amqs = ((ActiveMQSession) session).getCoreSession(); // ((DelegatingSession) amqs).getChannel().close(); rc.fail(new ActiveMQNotConnectedException()); for (int j = 0; j < 10; j++) { TextMessage tm = (TextMessage) consumer2.receive(10000); assertNotNull(tm); long text = ((ActiveMQTextMessage) tm).getCoreMessage().getMessageID(); System.out.println(tm.getJMSMessageID() + " text = " + text); //assertEquals("Message" + j, text); assertEquals(tm.getStringProperty("JMSXGroupID"), jmsxgroupID); } connection.close(); connection2.close(); } private int flushMessages(MessageConsumer consumer) throws JMSException { int received = 0; while (true) { TextMessage msg = (TextMessage) consumer.receiveNoWait(); if (msg == null) { break; } msg.acknowledge(); received++; } return received; } }