// // Copyright 2010 Cinch Logic Pty Ltd. // // http://www.chililog.com // // Licensed 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.chililog.server.engine; import static org.junit.Assert.*; import java.util.Date; import java.util.regex.Pattern; import javax.management.MBeanServerInvocationHandler; import javax.management.ObjectName; import org.chililog.server.common.Log4JLogger; import org.chililog.server.data.MongoConnection; import org.chililog.server.data.UserBO; import org.chililog.server.data.UserController; import org.chililog.server.engine.MqService; import org.hornetq.api.core.HornetQException; import org.hornetq.api.core.Message; import org.hornetq.api.core.SimpleString; import org.hornetq.api.core.client.ClientConsumer; import org.hornetq.api.core.client.ClientMessage; import org.hornetq.api.core.client.ClientProducer; import org.hornetq.api.core.client.ClientSession; import org.hornetq.api.core.client.ClientSession.QueueQuery; import org.hornetq.api.core.management.ObjectNameBuilder; import org.hornetq.api.core.management.QueueControl; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; /** * More tests regarding MqManager and transactions */ public class MqServiceTest { private static Log4JLogger _logger = Log4JLogger.getLogger(MqServiceTest.class); private static DB _db; private static final String PUBLISHER_USERNAME = "MqManagerTest.publisher"; private static final String PUBLISHER_PASSWORD = "pw4publisher!"; private static final String PUBLISHER_ROLE = "publisher"; private static final String SUBSCRIBER_USERNAME = "MqManagerTest.subscriber"; private static final String SUBSCRIBER_PASSWORD = "pw4subscriber!"; private static final String SUBSCRIBER_ROLE = "subscriber"; @BeforeClass public static void classSetup() throws Exception { _db = MongoConnection.getInstance().getConnection(); // Clean up old test data if any exists DBCollection coll = _db.getCollection(UserController.MONGODB_COLLECTION_NAME); Pattern pattern = Pattern.compile("^MqManagerTest\\.[\\w]*$"); DBObject query = new BasicDBObject(); query.put("username", pattern); coll.remove(query); UserBO user = new UserBO(); user.setUsername(PUBLISHER_USERNAME); user.setPassword(PUBLISHER_PASSWORD, true); user.addRole(PUBLISHER_ROLE); UserController.getInstance().save(_db, user); user = new UserBO(); user.setUsername(SUBSCRIBER_USERNAME); user.setPassword(SUBSCRIBER_PASSWORD, true); user.addRole(SUBSCRIBER_ROLE); UserController.getInstance().save(_db, user); // Start Mq MqService.getInstance().start(); // Configure security MqService.getInstance().addSecuritySettings("MqManagerTest#", PUBLISHER_ROLE, SUBSCRIBER_ROLE); MqService.getInstance().getNativeServer().getConfiguration().setSecurityEnabled(true); } @AfterClass public static void classTeardown() throws Exception { MqService.getInstance().stop(); // Clean up old test data if any exists DBCollection coll = _db.getCollection(UserController.MONGODB_COLLECTION_NAME); Pattern pattern = Pattern.compile("^MqManagerTest\\.[\\w]*$"); DBObject query = new BasicDBObject(); query.put("username", pattern); coll.remove(query); } @Test public void testDeployDeleteQueue() throws Exception { ClientSession clientSession = MqService.getInstance().getNonTransactionalSystemClientSession(); QueueQuery q = clientSession.queueQuery(new SimpleString("queue1")); assertNotNull(q); assertFalse(q.isExists()); MqService.getInstance().deployQueue("queue1", "queue1", false); q = clientSession.queueQuery(new SimpleString("queue1")); assertNotNull(q); assertTrue(q.isExists()); // Delete it MqService.getInstance().destroyQueue("queue1"); q = clientSession.queueQuery(new SimpleString("queue1")); assertFalse(q.isExists()); clientSession.close(); } @Test public void testDeployQueueTwice() throws Exception { ClientSession clientSession = MqService.getInstance().getNonTransactionalSystemClientSession(); MqService.getInstance().deployQueue("queue2", "queue2", false); QueueQuery q = clientSession.queueQuery(new SimpleString("queue1")); assertNotNull(q); // What if we do it twice? // We use deploy() so it should be OK. There should not be an exception MqService.getInstance().deployQueue("queue2", "queue2", false); q = clientSession.queueQuery(new SimpleString("queue1")); assertNotNull(q); } @Test public void testGetQueueControl() throws Exception { MqService.getInstance().deployQueue("queue3", "queue3", false); QueueControl qc = MqService.getInstance().getQueueControl("queue3", "queue3"); assertNotNull(qc); assertFalse(qc.isDurable()); qc = MqService.getInstance().getQueueControl("xxx", "nonexistentqueue"); assertNull(qc); } @Test public void testNonTransactional() throws Exception { ClientSession systemSession = MqService.getInstance().getNonTransactionalSystemClientSession(); ClientSession producerSession = MqService.getInstance().getNonTransactionalClientSession(PUBLISHER_USERNAME, PUBLISHER_PASSWORD); assertTrue(producerSession.isAutoCommitSends()); assertTrue(producerSession.isAutoCommitAcks()); ClientSession consumerSession = MqService.getInstance().getNonTransactionalClientSession(SUBSCRIBER_USERNAME, SUBSCRIBER_PASSWORD); assertTrue(consumerSession.isAutoCommitSends()); assertTrue(consumerSession.isAutoCommitAcks()); String queueAddress = "MqManagerTest.NonTransactional"; String queueName = "MqManagerTest.NonTransactional"; // Create queue MqService.getInstance().deployQueue(queueAddress, queueName, false); // Write ClientProducer producer = producerSession.createProducer(queueAddress); ClientMessage message = producerSession.createMessage(Message.TEXT_TYPE, false); String msg = "Hello sent at " + new Date(); message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(msg)); ; producer.send(message); _logger.info("Sent TextMessage: " + msg); QueueQuery q = systemSession.queueQuery(new SimpleString(queueName)); assertNotNull(q); assertTrue(q.isExists()); assertEquals(1, q.getMessageCount()); // Read // Should be able to consume messages because we in the reader role ClientConsumer messageConsumer = consumerSession.createConsumer(queueName); consumerSession.start(); ClientMessage messageReceived = messageConsumer.receive(1000); String msg2 = messageReceived.getBodyBuffer().readNullableSimpleString().toString(); _logger.info("Received TextMessage: " + msg2); assertEquals(msg, msg2); messageReceived.acknowledge(); messageReceived = messageConsumer.receive(100); assertNull(messageReceived); // Need close() to force message acknowledgement because the acknowledgement is being batched. consumerSession.close(); q = systemSession.queueQuery(new SimpleString(queueName)); assertNotNull(q); assertTrue(q.isExists()); assertEquals(0, q.getMessageCount()); } @Test public void testTransactional() throws Exception { ClientSession systemSession = MqService.getInstance().getNonTransactionalSystemClientSession(); ClientSession producerSession = MqService.getInstance().getTransactionalClientSession(PUBLISHER_USERNAME, PUBLISHER_PASSWORD); assertFalse(producerSession.isAutoCommitSends()); assertFalse(producerSession.isAutoCommitAcks()); ClientSession consumerSession = MqService.getInstance().getTransactionalClientSession(SUBSCRIBER_USERNAME, SUBSCRIBER_PASSWORD); assertFalse(consumerSession.isAutoCommitSends()); assertFalse(consumerSession.isAutoCommitAcks()); String queueAddress = "MqManagerTest.Transactional"; String queueName = "MqManagerTest.Transactional"; // Create queue MqService.getInstance().deployQueue(queueAddress, queueName, false); // Write ClientProducer producer = producerSession.createProducer(queueAddress); ClientMessage message = producerSession.createMessage(Message.TEXT_TYPE, false); String msg = "Hello sent at " + new Date(); message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(msg)); producer.send(message); _logger.info("Sent TextMessage: " + msg); QueueQuery q = systemSession.queueQuery(new SimpleString(queueName)); assertNotNull(q); assertTrue(q.isExists()); assertEquals(0, q.getMessageCount()); producerSession.commit(); q = systemSession.queueQuery(new SimpleString(queueName)); assertNotNull(q); assertTrue(q.isExists()); assertEquals(1, q.getMessageCount()); // Read // Should be able to consume messages because we in the reader role ClientConsumer messageConsumer = consumerSession.createConsumer(queueName); consumerSession.start(); ClientMessage messageReceived = messageConsumer.receive(1000); String msg2 = messageReceived.getBodyBuffer().readNullableSimpleString().toString(); _logger.info("Received TextMessage: " + msg2); assertEquals(msg, msg2); messageReceived.acknowledge(); consumerSession.commit(); q = systemSession.queueQuery(new SimpleString(queueName)); assertNotNull(q); assertTrue(q.isExists()); assertEquals(0, q.getMessageCount()); messageReceived = messageConsumer.receive(100); assertNull(messageReceived); // Get count via management API (extract from HornetQ unit test case) ObjectName objectName = ObjectNameBuilder.DEFAULT.getQueueObjectName(new SimpleString(queueAddress), new SimpleString(queueName)); QueueControl qc = (QueueControl) MBeanServerInvocationHandler.newProxyInstance(MqService.getInstance() .getNativeServer().getMBeanServer(), objectName, QueueControl.class, false); assertEquals(0, qc.getMessageCount()); } @Test public void testBadPassword() throws Exception { try { MqService.getInstance().getTransactionalClientSession(PUBLISHER_USERNAME, "badpassword"); fail("Exception expected: message=Unable to validate user: MqManagerTest.publisher"); } catch (HornetQException ex) { assertEquals(105, ex.getCode()); assertTrue(ex.getMessage().contains("Unable to validate user")); } try { MqService.getInstance().getTransactionalClientSession(SUBSCRIBER_USERNAME, "badpassword"); fail("Exception expected: message=Unable to validate user: MqManagerTest.subscriber"); } catch (HornetQException ex) { assertEquals(105, ex.getCode()); assertTrue(ex.getMessage().contains("Unable to validate user")); } } }