blob: eab8ad3e2e4a11a9b8ac06b2dee2d94d4c4ae58a [file] [log] [blame]
/*
*
* 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.qpid.server.queue;
import junit.framework.TestCase;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentBody;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.RequiredDeliveryException;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactory;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.txn.TransactionalContext;
import org.apache.qpid.server.txn.NonTransactionalContext;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.mina.common.ByteBuffer;
import javax.management.JMException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Collections;
/**
* Test class to test AMQQueueMBean attribtues and operations
*/
public class AMQQueueMBeanTest extends TestCase
{
private static long MESSAGE_SIZE = 1000;
private AMQQueue _queue;
private AMQQueueMBean _queueMBean;
private MessageStore _messageStore;
private StoreContext _storeContext = new StoreContext();
private TransactionalContext _transactionalContext;
private VirtualHost _virtualHost;
private AMQProtocolSession _protocolSession;
private static final SubscriptionFactoryImpl SUBSCRIPTION_FACTORY = SubscriptionFactoryImpl.INSTANCE;
public void testMessageCountTransient() throws Exception
{
int messageCount = 10;
sendMessages(messageCount, false);
assertTrue(_queueMBean.getMessageCount() == messageCount);
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
long queueDepth = (messageCount * MESSAGE_SIZE) >> 10;
assertTrue(_queueMBean.getQueueDepth() == queueDepth);
_queueMBean.deleteMessageFromTop();
assertTrue(_queueMBean.getMessageCount() == (messageCount - 1));
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
_queueMBean.clearQueue();
assertEquals(0,(int)_queueMBean.getMessageCount());
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
//Ensure that the data has been removed from the Store
verifyBrokerState();
}
public void testMessageCountPersistent() throws Exception
{
int messageCount = 10;
sendMessages(messageCount, true);
assertEquals("", messageCount, _queueMBean.getMessageCount().intValue());
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
long queueDepth = (messageCount * MESSAGE_SIZE) >> 10;
assertTrue(_queueMBean.getQueueDepth() == queueDepth);
_queueMBean.deleteMessageFromTop();
assertTrue(_queueMBean.getMessageCount() == (messageCount - 1));
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
_queueMBean.clearQueue();
assertTrue(_queueMBean.getMessageCount() == 0);
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
//Ensure that the data has been removed from the Store
verifyBrokerState();
}
// todo: collect to a general testing class -duplicated from Systest/MessageReturntest
private void verifyBrokerState()
{
TestableMemoryMessageStore store = new TestableMemoryMessageStore((MemoryMessageStore) _virtualHost.getMessageStore());
// Unlike MessageReturnTest there is no need for a delay as there this thread does the clean up.
assertNotNull("ContentBodyMap should not be null", store.getContentBodyMap());
assertEquals("Expected the store to have no content:" + store.getContentBodyMap(), 0, store.getContentBodyMap().size());
assertNotNull("MessageMetaDataMap should not be null", store.getMessageMetaDataMap());
assertEquals("Expected the store to have no metadata:" + store.getMessageMetaDataMap(), 0, store.getMessageMetaDataMap().size());
}
public void testConsumerCount() throws AMQException
{
assertTrue(_queue.getActiveConsumerCount() == 0);
assertTrue(_queueMBean.getActiveConsumerCount() == 0);
InternalTestProtocolSession protocolSession = new InternalTestProtocolSession();
AMQChannel channel = new AMQChannel(protocolSession, 1, _messageStore);
protocolSession.addChannel(channel);
Subscription subscription =
SUBSCRIPTION_FACTORY.createSubscription(channel.getChannelId(), protocolSession, new AMQShortString("test"), false, null, false, channel.getCreditManager());
_queue.registerSubscription(subscription, false);
assertEquals(1,(int)_queueMBean.getActiveConsumerCount());
SubscriptionFactory subscriptionFactory = SUBSCRIPTION_FACTORY;
Subscription s1 = subscriptionFactory.createSubscription(channel.getChannelId(),
protocolSession,
new AMQShortString("S1"),
false,
null,
true,
channel.getCreditManager());
Subscription s2 = subscriptionFactory.createSubscription(channel.getChannelId(),
protocolSession,
new AMQShortString("S2"),
false,
null,
true,
channel.getCreditManager());
_queue.registerSubscription(s1,false);
_queue.registerSubscription(s2,false);
assertTrue(_queueMBean.getActiveConsumerCount() == 3);
assertTrue(_queueMBean.getConsumerCount() == 3);
s1.close();
assertEquals(2, (int) _queueMBean.getActiveConsumerCount());
assertTrue(_queueMBean.getConsumerCount() == 3);
}
public void testGeneralProperties()
{
long maxQueueDepth = 1000; // in bytes
_queueMBean.setMaximumMessageCount(50000l);
_queueMBean.setMaximumMessageSize(2000l);
_queueMBean.setMaximumQueueDepth(maxQueueDepth);
assertTrue(_queueMBean.getMaximumMessageCount() == 50000);
assertTrue(_queueMBean.getMaximumMessageSize() == 2000);
assertTrue(_queueMBean.getMaximumQueueDepth() == (maxQueueDepth >> 10));
assertTrue(_queueMBean.getName().equals("testQueue"));
assertTrue(_queueMBean.getOwner().equals("AMQueueMBeanTest"));
assertFalse(_queueMBean.isAutoDelete());
assertFalse(_queueMBean.isDurable());
}
public void testExceptions() throws Exception
{
try
{
_queueMBean.viewMessages(0, 3);
fail();
}
catch (JMException ex)
{
}
try
{
_queueMBean.viewMessages(2, 1);
fail();
}
catch (JMException ex)
{
}
try
{
_queueMBean.viewMessages(-1, 1);
fail();
}
catch (JMException ex)
{
}
IncomingMessage msg = message(false, false);
long id = msg.getMessageId();
_queue.clearQueue(_storeContext);
ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
qs.add(_queue);
msg.enqueue(qs);
msg.routingComplete(_messageStore, new MessageHandleFactory());
msg.addContentBodyFrame(new ContentChunk()
{
ByteBuffer _data = ByteBuffer.allocate((int)MESSAGE_SIZE);
public int getSize()
{
return (int) MESSAGE_SIZE;
}
public ByteBuffer getData()
{
return _data;
}
public void reduceToFit()
{
}
});
msg.deliverToQueues();
// _queue.process(_storeContext, new QueueEntry(_queue, msg), false);
_queueMBean.viewMessageContent(id);
try
{
_queueMBean.viewMessageContent(id + 1);
fail();
}
catch (JMException ex)
{
}
}
private IncomingMessage message(final boolean immediate, boolean persistent) throws AMQException
{
MessagePublishInfo publish = new MessagePublishInfo()
{
public AMQShortString getExchange()
{
return null;
}
public void setExchange(AMQShortString exchange)
{
//To change body of implemented methods use File | Settings | File Templates.
}
public boolean isImmediate()
{
return immediate;
}
public boolean isMandatory()
{
return false;
}
public AMQShortString getRoutingKey()
{
return null;
}
};
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
contentHeaderBody.bodySize = MESSAGE_SIZE; // in bytes
contentHeaderBody.properties = new BasicContentHeaderProperties();
((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) (persistent ? 2 : 1));
IncomingMessage msg = new IncomingMessage(_messageStore.getNewMessageId(), publish, _transactionalContext, _protocolSession);
msg.setContentHeaderBody(contentHeaderBody);
return msg;
}
@Override
protected void setUp() throws Exception
{
super.setUp();
IApplicationRegistry applicationRegistry = ApplicationRegistry.getInstance(1);
_virtualHost = applicationRegistry.getVirtualHostRegistry().getVirtualHost("test");
_messageStore = _virtualHost.getMessageStore();
_transactionalContext = new NonTransactionalContext(_messageStore, _storeContext,
null,
new LinkedList<RequiredDeliveryException>()
);
_queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue"), false, new AMQShortString("AMQueueMBeanTest"), false, _virtualHost,
null);
_queueMBean = new AMQQueueMBean(_queue);
_protocolSession = new InternalTestProtocolSession();
}
public void tearDown()
{
ApplicationRegistry.remove(1);
}
private void sendMessages(int messageCount, boolean persistent) throws AMQException
{
for (int i = 0; i < messageCount; i++)
{
IncomingMessage currentMessage = message(false, persistent);
ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
qs.add(_queue);
currentMessage.enqueue(qs);
// route header
currentMessage.routingComplete(_messageStore, new MessageHandleFactory());
// Add the body so we have somthing to test later
currentMessage.addContentBodyFrame(
_protocolSession.getMethodRegistry()
.getProtocolVersionMethodConverter()
.convertToContentChunk(
new ContentBody(ByteBuffer.allocate((int) MESSAGE_SIZE),
MESSAGE_SIZE)));
currentMessage.deliverToQueues();
}
}
}