From 114302a09387c14a890d17d5b2735640dae09564 Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Fri, 6 Jan 2023 17:25:06 -0600 Subject: [PATCH] ARTEMIS-4125 address can be removed inadvertently When the last non-durable subscriber on a JMS topic disconnects the corresponding queue representing the subscription is deleted as expected. However, the queue's address will also be deleted no matter what, which is *not* expected. --- .../core/server/impl/ServerSessionImpl.java | 17 +++++----- .../client/AutoDeleteJmsDestinationTest.java | 34 +++++++++++++++++++ .../client/TemporaryQueueTest.java | 16 +++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java index ab77a89f61..1128cd8a20 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java @@ -1126,16 +1126,15 @@ public class ServerSessionImpl implements ServerSession, FailureListener { private void run() { try { + Binding binding = server.getPostOffice().getBinding(bindingName); + if (binding == null) { + // the queue may have already been deleted + return; + } logger.debug("deleting temporary queue {}", bindingName); - - try { - server.destroyQueue(bindingName, null, false, false, true); - if (observer != null) { - observer.tempQueueDeleted(bindingName); - } - } catch (ActiveMQException e) { - // that's fine.. it can happen due to queue already been deleted - logger.debug(e.getMessage(), e); + server.destroyQueue(bindingName, null, false, false, server.getAddressInfo(binding.getAddress()).isTemporary()); + if (observer != null) { + observer.tempQueueDeleted(bindingName); } } catch (Exception e) { ActiveMQServerLogger.LOGGER.errorRemovingTempQueue(bindingName, e); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AutoDeleteJmsDestinationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AutoDeleteJmsDestinationTest.java index f05a3dc963..7c55b2d592 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AutoDeleteJmsDestinationTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AutoDeleteJmsDestinationTest.java @@ -22,6 +22,7 @@ import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; +import javax.jms.Topic; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; @@ -185,6 +186,39 @@ public class AutoDeleteJmsDestinationTest extends JMSTestBase { assertNull(server.getManagementService().getResource("jtest")); } + @Test + public void testAutoDeleteTopicNegative() throws Exception { + final int numMessages = 100; + final SimpleString addressName = new SimpleString("test"); + server.getAddressSettingsRepository().addMatch(addressName.toString(), new AddressSettings().setAutoDeleteAddresses(false)); + + Connection connection = cf.createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(addressName.toString()); + MessageConsumer messageConsumer = session.createConsumer(topic); + MessageProducer producer = session.createProducer(topic); + + for (int i = 0; i < numMessages; i++) { + TextMessage mess = session.createTextMessage("msg" + i); + producer.send(mess); + } + + producer.close(); + // ensure the address was created + assertNotNull(server.getAddressInfo(addressName)); + + connection.start(); + + for (int i = 0; i < numMessages; i++) { + Message m = messageConsumer.receive(5000); + Assert.assertNotNull(m); + } + + connection.close(); + // ensure the topic was not removed + assertFalse(Wait.waitFor(() -> server.getAddressInfo(addressName) == null, 2000, 100)); + } + @Test public void testAutoDeleteTopicDurableSubscriber() throws Exception { Connection connection = cf.createConnection(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/TemporaryQueueTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/TemporaryQueueTest.java index 1037230d52..b77269a57e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/TemporaryQueueTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/TemporaryQueueTest.java @@ -45,6 +45,7 @@ import org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImp import org.apache.activemq.artemis.core.remoting.CloseListener; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.ServerSession; +import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.core.server.impl.ServerSessionImpl; import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; @@ -198,6 +199,21 @@ public class TemporaryQueueTest extends SingleServerTestBase { session.close(); } + @Test + public void testPreserveNonTemporaryAddressAfterConnectionIsClosed() throws Exception { + SimpleString queue = RandomUtil.randomSimpleString(); + SimpleString address = RandomUtil.randomSimpleString(); + server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setAutoDeleteAddresses(false)); + + server.addAddressInfo(new AddressInfo(address).setTemporary(false).setAutoCreated(true)); + session.createQueue(new QueueConfiguration(queue).setAddress(address).setDurable(false).setTemporary(true)); + assertNotNull(server.getAddressInfo(address)); + session.close(); + sf.close(); + Wait.assertTrue(() -> server.locateQueue(queue) == null, 2000, 100); + assertFalse(Wait.waitFor(() -> server.getAddressInfo(address) == null, 2000, 100)); + } + @Test public void testQueueWithWildcard() throws Exception { session.createQueue(new QueueConfiguration("queue1").setAddress("a.b"));