ARTEMIS-2199 PagingStore leak when deleting queue

When deleting a queue the JMSPostQueueDeletionCallback#callback will
invoke PostOfficeImpl#getBindingsForAddress which will *create* a
Bindings instance if one doesn't exist. This will trigger the creation
of a PagingStore instance which will be stored by the PagingManager
and may never be deleted. This is particularly problematic for use-cases
involving temporary JMS queues.

This change uses the lookupBindingsForAddress instead of
getBindingsForAddress which doesn't implicitly create a Bindings
instance.

This problem doesn't exist on the master branch as the
JMSPostQueueDeletionCallback no longer exists there.
This commit is contained in:
Justin Bertram 2018-12-10 12:13:37 -06:00
parent 11ce7f864e
commit 0a7757b2cd
2 changed files with 26 additions and 2 deletions

View File

@ -51,6 +51,7 @@ import org.apache.activemq.artemis.api.jms.JMSFactoryType;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.postoffice.Binding;
import org.apache.activemq.artemis.core.postoffice.BindingType;
import org.apache.activemq.artemis.core.postoffice.Bindings;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
import org.apache.activemq.artemis.core.security.Role;
@ -1719,11 +1720,11 @@ public class JMSServerManagerImpl implements JMSServerManager, ActivateCallback
@Override
public void callback(SimpleString address, SimpleString queueName) throws Exception {
Queue queue = server.locateQueue(address);
Collection<Binding> bindings = server.getPostOffice().getBindingsForAddress(address).getBindings();
Bindings bindings = server.getPostOffice().lookupBindingsForAddress(address);
AddressSettings settings = server.getAddressSettingsRepository().getMatch(address.toString());
if (address.toString().startsWith(ActiveMQDestination.JMS_TOPIC_ADDRESS_PREFIX) && settings.isAutoDeleteJmsTopics() && bindings.size() == 1 && queue != null && queue.isAutoCreated()) {
if (address.toString().startsWith(ActiveMQDestination.JMS_TOPIC_ADDRESS_PREFIX) && settings.isAutoDeleteJmsTopics() && bindings != null && bindings.getBindings().size() == 1 && queue != null && queue.isAutoCreated()) {
try {
destroyTopic(address.toString().substring(ActiveMQDestination.JMS_TOPIC_ADDRESS_PREFIX.length()));
} catch (IllegalStateException e) {

View File

@ -26,7 +26,9 @@ import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic;
import javax.jms.TextMessage;
import javax.naming.NamingException;
import java.util.Arrays;
import org.apache.activemq.artemis.jms.client.ActiveMQTemporaryQueue;
import org.apache.activemq.artemis.jms.tests.util.ProxyAssertSupport;
import org.junit.Test;
@ -126,6 +128,27 @@ public class TemporaryDestinationTest extends JMSTestCase {
}
}
@Test
public void testTemporaryQueuePagingStoreLeak() throws Exception {
Connection conn = null;
try {
conn = createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue tempQueue = session.createTemporaryQueue();
tempQueue.delete();
ProxyAssertSupport.assertFalse(Arrays.asList(servers.get(0).getActiveMQServer().getPagingManager().getStoreNames()).contains(((ActiveMQTemporaryQueue)tempQueue).getSimpleAddress()));
} finally {
if (conn != null) {
conn.close();
}
}
}
/**
* http://jira.jboss.com/jira/browse/JBMESSAGING-93
*/