You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by mi...@apache.org on 2020/06/23 10:19:58 UTC

[activemq-artemis] branch master updated: ARTEMIS-2797 - Reset queue properties by unsetting them in broker.xml

This is an automated email from the ASF dual-hosted git repository.

michaelpearce pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/master by this push:
     new 5070e7a  ARTEMIS-2797 - Reset queue properties by unsetting them in broker.xml
     new b9eca30  This closes #3172
5070e7a is described below

commit 5070e7a72c84552c342d1f2da84c35650469e82f
Author: Jan Å mucr <ja...@aimtec.cz>
AuthorDate: Tue Jun 9 07:03:53 2020 +0200

    ARTEMIS-2797 - Reset queue properties by unsetting them in broker.xml
    
    Now it is possible to reset queue parameters to their defaults by removing them
    from broker.xml and redeploying the configuration.
    
    Originally this PR covered the "filter" parameter only.
---
 .../core/postoffice/impl/PostOfficeImpl.java       | 100 ++++++++-----
 docs/user-manual/en/config-reload.md               |   4 +-
 docs/user-manual/en/versions.md                    |  11 ++
 .../tests/integration/jms/RedeployTest.java        | 161 +++++++++++++++++++++
 .../management/ActiveMQServerControlTest.java      |  47 ++++++
 .../test/resources/reload-queue-defaults-after.xml |  43 ++++++
 .../resources/reload-queue-defaults-before.xml     |  59 ++++++++
 .../test/resources/reload-queue-filter-removed.xml |  42 ++++++
 .../reload-queue-filter-updated-empty.xml          |  43 ++++++
 9 files changed, 469 insertions(+), 41 deletions(-)

diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
index 556362e..c50f421 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
@@ -16,22 +16,6 @@
  */
 package org.apache.activemq.artemis.core.postoffice.impl;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import org.apache.activemq.artemis.api.core.ActiveMQAddressDoesNotExistException;
 import org.apache.activemq.artemis.api.core.ActiveMQAddressFullException;
 import org.apache.activemq.artemis.api.core.ActiveMQDuplicateIdException;
@@ -79,6 +63,7 @@ import org.apache.activemq.artemis.core.server.RoutingContext;
 import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
 import org.apache.activemq.artemis.core.server.group.GroupingHandler;
 import org.apache.activemq.artemis.core.server.impl.AddressInfo;
+import org.apache.activemq.artemis.core.server.impl.QueueConfigurationUtils;
 import org.apache.activemq.artemis.core.server.impl.QueueManagerImpl;
 import org.apache.activemq.artemis.core.server.impl.RoutingContextImpl;
 import org.apache.activemq.artemis.core.server.management.ManagementService;
@@ -97,6 +82,23 @@ import org.apache.activemq.artemis.utils.UUIDGenerator;
 import org.apache.activemq.artemis.utils.collections.TypedProperties;
 import org.jboss.logging.Logger;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 /**
  * This is the class that will make the routing to Queues and decide which consumer will get the messages
  * It's the queue component on distributing the messages * *
@@ -632,7 +634,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
             boolean changed = false;
 
             //validate update
-            if (queueConfiguration.getMaxConsumers() != null && queueConfiguration.getMaxConsumers().intValue() != Queue.MAX_CONSUMERS_UNLIMITED) {
+            if (queueConfiguration.getMaxConsumers() != null && queueConfiguration.getMaxConsumers() != Queue.MAX_CONSUMERS_UNLIMITED) {
                final int consumerCount = queue.getConsumerCount();
                if (consumerCount > queueConfiguration.getMaxConsumers()) {
                   throw ActiveMQMessageBundle.BUNDLE.invalidMaxConsumersUpdate(queueConfiguration.getName().toString(), queueConfiguration.getMaxConsumers(), consumerCount);
@@ -647,74 +649,94 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
                }
             }
 
-            //atomic update
-            if (queueConfiguration.getMaxConsumers() != null && queue.getMaxConsumers() != queueConfiguration.getMaxConsumers().intValue()) {
+            QueueConfigurationUtils.applyDynamicQueueDefaults(queueConfiguration, addressSettingsRepository.getMatch(queueConfiguration.getAddress().toString()));
+
+            // atomic update, reset to defaults if value == null
+            // maxConsumers
+            if (queue.getMaxConsumers() != queueConfiguration.getMaxConsumers()) {
                changed = true;
                queue.setMaxConsumer(queueConfiguration.getMaxConsumers());
             }
-            if (queueConfiguration.getRoutingType() != null && queue.getRoutingType() != queueConfiguration.getRoutingType()) {
+            // routingType
+            if (queue.getRoutingType() != queueConfiguration.getRoutingType()) {
                changed = true;
                queue.setRoutingType(queueConfiguration.getRoutingType());
             }
-            if (queueConfiguration.isPurgeOnNoConsumers() != null && queue.isPurgeOnNoConsumers() != queueConfiguration.isPurgeOnNoConsumers().booleanValue()) {
+            // purgeOnNoConsumers
+            if (queue.isPurgeOnNoConsumers() != queueConfiguration.isPurgeOnNoConsumers()) {
                changed = true;
                queue.setPurgeOnNoConsumers(queueConfiguration.isPurgeOnNoConsumers());
             }
-            if (queueConfiguration.isEnabled() != null && queue.isEnabled() != queueConfiguration.isEnabled().booleanValue()) {
+            // enabled
+            if (queue.isEnabled() != queueConfiguration.isEnabled()) {
                changed = true;
                queue.setEnabled(queueConfiguration.isEnabled());
             }
-            if (queueConfiguration.isExclusive() != null && queue.isExclusive() != queueConfiguration.isExclusive().booleanValue()) {
+            // exclusive
+            if (queue.isExclusive() != queueConfiguration.isExclusive()) {
                changed = true;
                queue.setExclusive(queueConfiguration.isExclusive());
             }
-            if (queueConfiguration.isGroupRebalance() != null && queue.isGroupRebalance() != queueConfiguration.isGroupRebalance().booleanValue()) {
+            // groupRebalance
+            if (queue.isGroupRebalance() != queueConfiguration.isGroupRebalance()) {
                changed = true;
                queue.setGroupRebalance(queueConfiguration.isGroupRebalance());
             }
-            if (queueConfiguration.getGroupBuckets() != null && queue.getGroupBuckets() != queueConfiguration.getGroupBuckets().intValue()) {
+            // groupBuckets
+            if (queue.getGroupBuckets() != queueConfiguration.getGroupBuckets()) {
                changed = true;
                queue.setGroupBuckets(queueConfiguration.getGroupBuckets());
             }
-            if (queueConfiguration.getGroupFirstKey() != null && !queueConfiguration.getGroupFirstKey().equals(queue.getGroupFirstKey())) {
+            // groupFirstKey
+            // Objects.equals() performs the null check for us
+            if (!Objects.equals(queue.getGroupFirstKey(), queueConfiguration.getGroupFirstKey())) {
                changed = true;
                queue.setGroupFirstKey(queueConfiguration.getGroupFirstKey());
             }
-            if (queueConfiguration.isNonDestructive() != null && queue.isNonDestructive() != queueConfiguration.isNonDestructive().booleanValue()) {
+            // nonDestructive
+            if (queue.isNonDestructive() != queueConfiguration.isNonDestructive()) {
                changed = true;
                queue.setNonDestructive(queueConfiguration.isNonDestructive());
             }
-            if (queueConfiguration.getConsumersBeforeDispatch() != null && !queueConfiguration.getConsumersBeforeDispatch().equals(queue.getConsumersBeforeDispatch())) {
+            // consumersBeforeDispatch
+            if (queue.getConsumersBeforeDispatch() != queueConfiguration.getConsumersBeforeDispatch()) {
                changed = true;
-               queue.setConsumersBeforeDispatch(queueConfiguration.getConsumersBeforeDispatch().intValue());
+               queue.setConsumersBeforeDispatch(queueConfiguration.getConsumersBeforeDispatch());
             }
-            if (queueConfiguration.getDelayBeforeDispatch() != null && !queueConfiguration.getDelayBeforeDispatch().equals(queue.getDelayBeforeDispatch())) {
+            // delayBeforeDispatch
+            if (queue.getDelayBeforeDispatch() != queueConfiguration.getDelayBeforeDispatch()) {
                changed = true;
-               queue.setDelayBeforeDispatch(queueConfiguration.getDelayBeforeDispatch().longValue());
+               queue.setDelayBeforeDispatch(queueConfiguration.getDelayBeforeDispatch());
             }
-            Filter filter = FilterImpl.createFilter(queueConfiguration.getFilterString());
-            if (filter != null && !filter.equals(queue.getFilter())) {
+            // filter
+            // There's no default ActiveMQDefaultConfiguration setting for a filter
+            final Filter newFilter = FilterImpl.createFilter(queueConfiguration.getFilterString());
+            if (!Objects.equals(queue.getFilter(), newFilter)) {
                changed = true;
-               queue.setFilter(filter);
+               queue.setFilter(newFilter);
             }
-            if (queueConfiguration.isConfigurationManaged() != null && !queueConfiguration.isConfigurationManaged().equals(queue.isConfigurationManaged())) {
-               changed = true;
+            // configurationManaged
+            if (queueConfiguration.isConfigurationManaged() != queue.isConfigurationManaged()) {
                queue.setConfigurationManaged(queueConfiguration.isConfigurationManaged());
+               changed = true;
             }
+            /* Why is this?
             if (logger.isDebugEnabled()) {
                if (queueConfiguration.getUser() == null && queue.getUser() != null) {
                   logger.debug("Ignoring updating Queue to a NULL user");
                }
             }
-            if (queueConfiguration.getUser() != null && !queueConfiguration.getUser().equals(queue.getUser())) {
+             */
+            // user
+            if (!Objects.equals(queue.getUser(), queueConfiguration.getUser())) {
                changed = true;
                queue.setUser(queueConfiguration.getUser());
             }
-            if (queueConfiguration.getRingSize() != null && !queueConfiguration.getRingSize().equals(queue.getRingSize())) {
+            // ringSize
+            if (queue.getRingSize() != queueConfiguration.getRingSize()) {
                changed = true;
                queue.setRingSize(queueConfiguration.getRingSize());
             }
-
             if (changed) {
                final long txID = storageManager.generateID();
                try {
diff --git a/docs/user-manual/en/config-reload.md b/docs/user-manual/en/config-reload.md
index 0f639b5..fdda05b 100644
--- a/docs/user-manual/en/config-reload.md
+++ b/docs/user-manual/en/config-reload.md
@@ -244,8 +244,8 @@ attribute `name` | N/A | X | A queue with new name will be deployed and the queu
 attribute `max-consumers` | If max-consumers > current consumers max-consumers will update on reload | max-consumers will be set back to the default `-1` | If max-consumers > current consumers max-consumers will update on reload
 attribute `purge-on-no-consumers` | On reload purge-on-no-consumers will be updated | Will be set back to the default `false` | On reload purge-on-no-consumers will be updated
 attribute `address` | N/A | No effect unless starting broker | No effect unless starting broker
-attribute `filter` | N/A | No effect unless starting broker | No effect unless starting broker
-attribute `durable` | N/A | No effect unless starting broker | No effect unless starting broker
+attribute `filter` | The filter will be added after reloading | The filter will be removed after reloading | The filter will be updated after reloading
+attribute `durable` | The queue durability will be set to the given value after reloading | The queue durability will be set to the default `true` after reloading | The queue durability will be set to the new value after reloading
 
 ### `<jms>` *(Deprecated)*
 
diff --git a/docs/user-manual/en/versions.md b/docs/user-manual/en/versions.md
index fb4154e..324b830 100644
--- a/docs/user-manual/en/versions.md
+++ b/docs/user-manual/en/versions.md
@@ -8,6 +8,17 @@ This chapter provides the following information for each release:
   - **Note:** Follow the general upgrade procedure outlined in the [Upgrading the Broker](upgrading.md) 
     chapter in addition to any version-specific upgrade instructions outlined here.
 
+## 2.14.0
+
+[Full release notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12315920&version=12348290).
+
+Highlights:
+- Removing `broker.xml` queue parameters now causes these to be reset to their default values.
+
+#### Upgrading from older versions
+
+Make sure the existing queues have their parameters set according to the `broker.xml` values before upgrading.
+
 ## 2.11.0
 
 [Full release notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12315920&version=12346258).
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
index f63a408..ebfc220 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/RedeployTest.java
@@ -37,10 +37,13 @@ import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.Session;
 import javax.jms.TextMessage;
+
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.api.core.RoutingType;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.core.postoffice.Binding;
 import org.apache.activemq.artemis.core.postoffice.QueueBinding;
+import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
 import org.apache.activemq.artemis.core.security.Role;
 import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
 import org.apache.activemq.artemis.core.server.cluster.impl.RemoteQueueBindingImpl;
@@ -287,6 +290,164 @@ public class RedeployTest extends ActiveMQTestBase {
       }
    }
 
+   private void deployBrokerConfig(EmbeddedActiveMQ server, URL configFile) throws Exception {
+
+      Path brokerXML = getTestDirfile().toPath().resolve("broker.xml");
+      Files.copy(configFile.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING);
+
+      final ReusableLatch latch = new ReusableLatch(1);
+      Runnable tick = latch::countDown;
+      server.getActiveMQServer().getReloadManager().setTick(tick);
+
+      latch.await(10, TimeUnit.SECONDS);
+   }
+
+   private void doTestRemoveFilter(URL testConfiguration) throws Exception {
+
+      Path brokerXML = getTestDirfile().toPath().resolve("broker.xml");
+
+      URL baseConfig = RedeployTest.class.getClassLoader().getResource("reload-queue-filter.xml");
+
+      Files.copy(baseConfig.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING);
+
+      EmbeddedActiveMQ embeddedActiveMQ = new EmbeddedActiveMQ();
+      embeddedActiveMQ.setConfigResourcePath(brokerXML.toUri().toString());
+      embeddedActiveMQ.start();
+
+      deployBrokerConfig(embeddedActiveMQ, baseConfig);
+
+      try {
+
+         try (ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
+              Connection connection = factory.createConnection();
+              Session session = connection.createSession(Session.AUTO_ACKNOWLEDGE)) {
+
+            connection.start();
+            Queue queue = session.createQueue("myFilterQueue");
+
+            // Test that the original filter has been set up
+            LocalQueueBinding queueBinding = (LocalQueueBinding) embeddedActiveMQ.getActiveMQServer().getPostOffice()
+                    .getBinding(new SimpleString("myFilterQueue"));
+            // The "x = 'x'" value is found in "reload-queue-filter.xml"
+            assertEquals("x = 'x'", queueBinding.getFilter().getFilterString().toString());
+
+            MessageProducer producer = session.createProducer(queue);
+
+            // Test that the original filter affects the flow
+            Message passingMessage = session.createMessage();
+            passingMessage.setStringProperty("x", "x");
+            producer.send(passingMessage);
+
+            Message filteredMessage = session.createMessage();
+            filteredMessage.setStringProperty("x", "y");
+            producer.send(filteredMessage);
+
+            MessageConsumer consumer = session.createConsumer(queue);
+            Message receivedMessage = consumer.receive(2000);
+            assertNotNull(receivedMessage);
+            assertEquals("x", receivedMessage.getStringProperty("x"));
+
+            assertNull(consumer.receive(2000));
+
+            consumer.close();
+         }
+
+         deployBrokerConfig(embeddedActiveMQ, testConfiguration);
+
+         try (ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
+              Connection connection = factory.createConnection();
+              Session session = connection.createSession(Session.AUTO_ACKNOWLEDGE)) {
+
+            connection.start();
+            Queue queue = session.createQueue("myFilterQueue");
+
+            // Test that the filter has been removed
+            LocalQueueBinding queueBinding = (LocalQueueBinding) embeddedActiveMQ.getActiveMQServer().getPostOffice()
+                    .getBinding(new SimpleString("myFilterQueue"));
+            assertNull(queueBinding.getFilter());
+
+            MessageProducer producer = session.createProducer(queue);
+
+            // Test that the original filter no longer affects the flow
+            Message message1 = session.createMessage();
+            message1.setStringProperty("x", "x");
+            producer.send(message1);
+
+            Message message2 = session.createMessage();
+            message2.setStringProperty("x", "y");
+            producer.send(message2);
+
+            MessageConsumer consumer = session.createConsumer(queue);
+            assertNotNull(consumer.receive(2000));
+            assertNotNull(consumer.receive(2000));
+
+            consumer.close();
+         }
+
+      } finally {
+         embeddedActiveMQ.stop();
+      }
+   }
+
+   @Test
+   public void testRedeployRemoveFilter() throws Exception {
+      doTestRemoveFilter(RedeployTest.class.getClassLoader().getResource("reload-queue-filter-updated-empty.xml"));
+      doTestRemoveFilter(RedeployTest.class.getClassLoader().getResource("reload-queue-filter-removed.xml"));
+   }
+
+   @Test
+   public void testRedeployQueueDefaults() throws Exception {
+
+      Path brokerXML = getTestDirfile().toPath().resolve("broker.xml");
+      URL baseConfig = RedeployTest.class.getClassLoader().getResource("reload-queue-defaults-before.xml");
+      URL newConfig = RedeployTest.class.getClassLoader().getResource("reload-queue-defaults-after.xml");
+      Files.copy(baseConfig.openStream(), brokerXML, StandardCopyOption.REPLACE_EXISTING);
+      EmbeddedActiveMQ embeddedActiveMQ = new EmbeddedActiveMQ();
+      embeddedActiveMQ.setConfigResourcePath(brokerXML.toUri().toString());
+      embeddedActiveMQ.start();
+
+      try {
+         LocalQueueBinding queueBinding = (LocalQueueBinding) embeddedActiveMQ.getActiveMQServer().getPostOffice()
+                 .getBinding(new SimpleString("myQueue"));
+         org.apache.activemq.artemis.core.server.Queue queue = queueBinding.getQueue();
+
+         assertNotEquals(queue.getMaxConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+         assertNotEquals(queue.getRoutingType(), RoutingType.MULTICAST);
+         assertNotEquals(queue.isPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers());
+         assertNotEquals(queue.isEnabled(), ActiveMQDefaultConfiguration.getDefaultEnabled());
+         assertNotEquals(queue.isExclusive(), ActiveMQDefaultConfiguration.getDefaultExclusive());
+         assertNotEquals(queue.isGroupRebalance(), ActiveMQDefaultConfiguration.getDefaultGroupRebalance());
+         assertNotEquals(queue.getGroupBuckets(), ActiveMQDefaultConfiguration.getDefaultGroupBuckets());
+         assertNotEquals(queue.getGroupFirstKey(), ActiveMQDefaultConfiguration.getDefaultGroupFirstKey());
+         assertNotEquals(queue.isNonDestructive(), ActiveMQDefaultConfiguration.getDefaultNonDestructive());
+         assertNotEquals(queue.getConsumersBeforeDispatch(), ActiveMQDefaultConfiguration.getDefaultConsumersBeforeDispatch());
+         assertNotEquals(queue.getDelayBeforeDispatch(), ActiveMQDefaultConfiguration.getDefaultDelayBeforeDispatch());
+         assertNotEquals(queue.getFilter(), null);
+         assertNotEquals(queue.getUser(), "jdoe");
+         assertNotEquals(queue.getRingSize(), ActiveMQDefaultConfiguration.getDefaultRingSize());
+
+         deployBrokerConfig(embeddedActiveMQ, newConfig);
+
+         assertEquals(queue.getMaxConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+         assertEquals(queue.getRoutingType(), RoutingType.MULTICAST);
+         assertEquals(queue.isPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers());
+         assertEquals(queue.isEnabled(), ActiveMQDefaultConfiguration.getDefaultEnabled());
+         assertEquals(queue.isExclusive(), ActiveMQDefaultConfiguration.getDefaultExclusive());
+         assertEquals(queue.isGroupRebalance(), ActiveMQDefaultConfiguration.getDefaultGroupRebalance());
+         assertEquals(queue.getGroupBuckets(), ActiveMQDefaultConfiguration.getDefaultGroupBuckets());
+         assertEquals(queue.getGroupFirstKey(), ActiveMQDefaultConfiguration.getDefaultGroupFirstKey());
+         assertEquals(queue.isNonDestructive(), ActiveMQDefaultConfiguration.getDefaultNonDestructive());
+         assertEquals(queue.getConsumersBeforeDispatch(), ActiveMQDefaultConfiguration.getDefaultConsumersBeforeDispatch());
+         assertEquals(queue.getDelayBeforeDispatch(), ActiveMQDefaultConfiguration.getDefaultDelayBeforeDispatch());
+         assertEquals(queue.getFilter(), null);
+         assertEquals(queue.getUser(), null);
+         assertEquals(queue.getRingSize(), ActiveMQDefaultConfiguration.getDefaultRingSize());
+
+      } finally {
+         embeddedActiveMQ.stop();
+      }
+   }
+
    @Test
    public void testRedeployWithFailover() throws Exception {
       Set<Role> original = new HashSet<>();
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
index a0656f3..0431c7d 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
@@ -472,6 +472,53 @@ public class ActiveMQServerControlTest extends ManagementTestBase {
    }
 
    @Test
+   public void testRemoveQueueFilter() throws Exception {
+
+      String address = RandomUtil.randomString();
+      QueueConfiguration queue1 = new QueueConfiguration("q1")
+              .setAddress(address)
+              .setFilterString("hello='world'");
+
+      QueueConfiguration queue2 = new QueueConfiguration("q2")
+              .setAddress(address)
+              .setFilterString("hello='darling'");
+
+      ActiveMQServerControl serverControl = createManagementControl();
+      serverControl.createAddress(address, "MULTICAST");
+
+      if (legacyCreateQueue) {
+         serverControl.createQueue(address, queue1.getName().toString(), queue1.getFilterString().toString(), queue1.isDurable());
+         serverControl.createQueue(address, queue2.getName().toString(), queue2.getFilterString().toString(), queue2.isDurable());
+      } else {
+         serverControl.createQueue(queue1.toJSON());
+         serverControl.createQueue(queue2.toJSON());
+      }
+
+      ServerLocator loc = createInVMNonHALocator();
+      ClientSessionFactory csf = createSessionFactory(loc);
+      ClientSession session = csf.createSession();
+      session.start();
+
+      ClientProducer producer = session.createProducer(address);
+      ClientConsumer consumer1 = session.createConsumer("q1");
+      ClientConsumer consumer2 = session.createConsumer("q2");
+
+      ClientMessage m = session.createMessage(true);
+      m.putStringProperty("hello", "world");
+      producer.send(m);
+
+      assertNotNull(consumer1.receiveImmediate());
+      assertNull(consumer2.receiveImmediate());
+
+      serverControl.updateQueue(queue2.setFilterString((String) null).toJSON());
+
+      producer.send(m);
+
+      assertNotNull(consumer1.receiveImmediate());
+      assertNotNull(consumer2.receiveImmediate());
+   }
+
+   @Test
    public void testCreateAndDestroyQueueClosingConsumers() throws Exception {
       SimpleString address = RandomUtil.randomSimpleString();
       SimpleString name = RandomUtil.randomSimpleString();
diff --git a/tests/integration-tests/src/test/resources/reload-queue-defaults-after.xml b/tests/integration-tests/src/test/resources/reload-queue-defaults-after.xml
new file mode 100644
index 0000000..ecc4ecd
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-queue-defaults-after.xml
@@ -0,0 +1,43 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core">
+      <security-enabled>false</security-enabled>
+      <persistence-enabled>false</persistence-enabled>
+
+      <acceptors>
+         <acceptor name="artemis">tcp://0.0.0.0:61616</acceptor>
+      </acceptors>
+
+      <addresses>
+         <address name="myQueue">
+            <multicast>
+               <!-- Shoud reset queue according to org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration -->
+               <!-- some values cannot be changed: last-value -->
+               <queue name="myQueue" />
+            </multicast>
+         </address>
+      </addresses>
+   </core>
+</configuration>
diff --git a/tests/integration-tests/src/test/resources/reload-queue-defaults-before.xml b/tests/integration-tests/src/test/resources/reload-queue-defaults-before.xml
new file mode 100644
index 0000000..8a7521d
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-queue-defaults-before.xml
@@ -0,0 +1,59 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core">
+      <security-enabled>false</security-enabled>
+      <persistence-enabled>false</persistence-enabled>
+
+      <acceptors>
+         <acceptor name="artemis">tcp://0.0.0.0:61616</acceptor>
+      </acceptors>
+
+      <addresses>
+         <address name="myQueue">
+            <anycast>
+               <!-- non-default values based on org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration -->
+               <!-- some values cannot be changed: last-value -->
+               <queue name="myQueue"
+                      max-consumers="10"
+                      purge-on-no-consumers="true"
+                      exclusive="true"
+                      group-rebalance="true"
+                      group-buckets="10"
+                      group-first-key="foo"
+                      non-destructive="true"
+                      consumers-before-dispatch="10"
+                      delay-before-dispatch="10"
+                      ring-size="10"
+                      enabled="false"
+               >
+                  <durable>false</durable>
+                  <filter string="x = 'x'"/>
+                  <user>jdoe</user>
+               </queue>
+            </anycast>
+         </address>
+      </addresses>
+   </core>
+</configuration>
diff --git a/tests/integration-tests/src/test/resources/reload-queue-filter-removed.xml b/tests/integration-tests/src/test/resources/reload-queue-filter-removed.xml
new file mode 100644
index 0000000..150316c
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-queue-filter-removed.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core">
+      <security-enabled>false</security-enabled>
+      <persistence-enabled>false</persistence-enabled>
+
+      <acceptors>
+         <acceptor name="artemis">tcp://0.0.0.0:61616</acceptor>
+      </acceptors>
+
+      <addresses>
+         <address name="myFilterQueue">
+            <anycast>
+               <queue name="myFilterQueue">
+               </queue>
+            </anycast>
+         </address>
+      </addresses>
+   </core>
+</configuration>
diff --git a/tests/integration-tests/src/test/resources/reload-queue-filter-updated-empty.xml b/tests/integration-tests/src/test/resources/reload-queue-filter-updated-empty.xml
new file mode 100644
index 0000000..c998aab
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/reload-queue-filter-updated-empty.xml
@@ -0,0 +1,43 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core">
+      <security-enabled>false</security-enabled>
+      <persistence-enabled>false</persistence-enabled>
+
+      <acceptors>
+         <acceptor name="artemis">tcp://0.0.0.0:61616</acceptor>
+      </acceptors>
+
+      <addresses>
+         <address name="myFilterQueue">
+            <anycast>
+               <queue name="myFilterQueue">
+                  <filter string=""/>
+               </queue>
+            </anycast>
+         </address>
+      </addresses>
+   </core>
+</configuration>