/**
* 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.broker.policy;
import static org.junit.Assert.assertTrue;
import java.io.File;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.Lists;
/**
* This unit test is to test that setting the property "maxDestinations" on
* PolicyEntry works correctly. If this property is set, it will limit the
* number of destinations that can be created. Advisory topics will be ignored
* during calculations.
*
*/
public class MaxDestinationsPolicyTest {
BrokerService broker;
ConnectionFactory factory;
Connection connection;
Session session;
MessageProducer producer;
@Before
public void setUp() throws Exception {
broker = new BrokerService();
File testDataDir = new File("target/activemq-data/AMQ-5751");
broker.setDataDirectoryFile(testDataDir);
broker.setUseJmx(true);
broker.setDeleteAllMessagesOnStartup(true);
broker.getSystemUsage().getMemoryUsage().setLimit(1024l * 1024 * 64);
KahaDBPersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
persistenceAdapter.setDirectory(new File(testDataDir, "kahadb"));
broker.setPersistenceAdapter(persistenceAdapter);
broker.addConnector("tcp://localhost:0");
broker.start();
factory = new ActiveMQConnectionFactory(broker.getTransportConnectors()
.get(0).getConnectUri().toString());
connection = factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@After
public void tearDown() throws Exception {
session.close();
connection.stop();
connection.close();
broker.stop();
}
/**
* Test that 10 queues can be created when default policy allows it.
*/
@Test
public void testMaxDestinationDefaultPolicySuccess() throws Exception {
applyDefaultMaximumDestinationPolicy(10);
for (int i = 0; i < 10; i++) {
createQueue("queue." + i);
}
}
/**
* Test that default policy prevents going beyond max
*/
@Test(expected = javax.jms.IllegalStateException.class)
public void testMaxDestinationDefaultPolicyFail() throws Exception {
applyDefaultMaximumDestinationPolicy(10);
for (int i = 0; i < 11; i++) {
createQueue("queue." + i);
}
}
/**
* Test that a queue policy overrides the default policy
*/
@Test(expected = javax.jms.IllegalStateException.class)
public void testMaxDestinationOnQueuePolicy() throws Exception {
PolicyMap policyMap = applyDefaultMaximumDestinationPolicy(10);
applyMaximumDestinationPolicy(policyMap, new ActiveMQQueue("queue.>"),
5);
// This should fail even though the default policy is set to a limit of
// 10 because the
// queue policy overrides it
for (int i = 0; i < 6; i++) {
createQueue("queue." + i);
}
}
/**
* Test that 10 topics can be created when default policy allows it.
*/
@Test
public void testTopicMaxDestinationDefaultPolicySuccess() throws Exception {
applyDefaultMaximumDestinationPolicy(10);
for (int i = 0; i < 10; i++) {
createTopic("topic." + i);
}
}
/**
* Test that topic creation will faill when exceeding the limit
*/
@Test(expected = javax.jms.IllegalStateException.class)
public void testTopicMaxDestinationDefaultPolicyFail() throws Exception {
applyDefaultMaximumDestinationPolicy(20);
for (int i = 0; i < 21; i++) {
createTopic("topic." + i);
}
}
/**
* Test that no limit is enforced
*/
@Test
public void testTopicDefaultPolicyNoMaxDestinations() throws Exception {
// -1 is the default and signals no max destinations
applyDefaultMaximumDestinationPolicy(-1);
for (int i = 0; i < 100; i++) {
createTopic("topic." + i);
}
}
/**
* Test a mixture of queue and topic policies
*/
@Test
public void testComplexMaxDestinationPolicy() throws Exception {
PolicyMap policyMap = applyMaximumDestinationPolicy(new PolicyMap(),
new ActiveMQQueue("queue.>"), 5);
applyMaximumDestinationPolicy(policyMap, new ActiveMQTopic("topic.>"),
10);
for (int i = 0; i < 5; i++) {
createQueue("queue." + i);
}
for (int i = 0; i < 10; i++) {
createTopic("topic." + i);
}
// Make sure that adding one more of either a topic or a queue fails
boolean fail = false;
try {
createTopic("topic.test");
} catch (javax.jms.IllegalStateException e) {
fail = true;
}
assertTrue(fail);
fail = false;
try {
createQueue("queue.test");
} catch (javax.jms.IllegalStateException e) {
fail = true;
}
assertTrue(fail);
}
/**
* Test child destinations of a policy
*/
@Test
public void testMaxDestinationPolicyOnChildDests() throws Exception {
applyMaximumDestinationPolicy(new PolicyMap(), new ActiveMQTopic(
"topic.>"), 10);
for (int i = 0; i < 10; i++) {
createTopic("topic.test" + i);
}
// Make sure that adding one more fails
boolean fail = false;
try {
createTopic("topic.abc.test");
} catch (javax.jms.IllegalStateException e) {
fail = true;
}
assertTrue(fail);
}
/**
* Test a topic policy overrides the default
*/
@Test(expected = javax.jms.IllegalStateException.class)
public void testMaxDestinationOnTopicPolicy() throws Exception {
PolicyMap policyMap = applyDefaultMaximumDestinationPolicy(10);
applyMaximumDestinationPolicy(policyMap, new ActiveMQTopic("topic.>"),
5);
// This should fail even though the default policy is set to a limit of
// 10 because the
// queue policy overrides it
for (int i = 0; i < 6; i++) {
createTopic("topic." + i);
}
}
private PolicyMap applyMaximumDestinationPolicy(PolicyMap policyMap,
ActiveMQDestination destination, int maxDestinations) {
PolicyEntry entry = new PolicyEntry();
entry.setDestination(destination);
entry.setMaxDestinations(maxDestinations);
policyMap.setPolicyEntries(Lists.newArrayList(entry));
broker.setDestinationPolicy(policyMap);
return policyMap;
}
private PolicyMap applyDefaultMaximumDestinationPolicy(int maxDestinations) {
PolicyMap policyMap = new PolicyMap();
PolicyEntry defaultEntry = new PolicyEntry();
if (maxDestinations >= 0) {
defaultEntry.setMaxDestinations(maxDestinations);
}
policyMap.setDefaultEntry(defaultEntry);
broker.setDestinationPolicy(policyMap);
return policyMap;
}
private void createQueue(String queueName) throws Exception {
Queue queue = session.createQueue(queueName);
producer = session.createProducer(queue);
}
private void createTopic(String topicName) throws Exception {
Topic topic = session.createTopic(topicName);
producer = session.createProducer(topic);
}
}