This is an automated email from the ASF dual-hosted git repository.
jbertram pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/main by this push:
new b075cd6fc0 ARTEMIS-4537 Fix merge of multiple address setting matches
b075cd6fc0 is described below
commit b075cd6fc08e5e69fc4b887ff3af070c43ae6d6a
Author: Domenico Francesco Bruscino <[email protected]>
AuthorDate: Fri Dec 15 10:54:13 2023 +0100
ARTEMIS-4537 Fix merge of multiple address setting matches
Merge multiple address setting matches on a new instance to be idempotent.
---
.../activemq/artemis/core/settings/Mergeable.java | 4 +
.../core/settings/impl/AddressSettings.java | 262 +++------------------
.../impl/HierarchicalObjectRepository.java | 23 +-
.../artemis/core/settings/AddressSettingsTest.java | 57 ++++-
.../artemis/core/settings/RepositoryTest.java | 202 ++++++++++++----
.../integration/client/MessageExpirationTest.java | 9 +-
6 files changed, 250 insertions(+), 307 deletions(-)
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/Mergeable.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/Mergeable.java
index 0cfb344fad..6b855cafc8 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/Mergeable.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/Mergeable.java
@@ -21,5 +21,9 @@ package org.apache.activemq.artemis.core.settings;
*/
public interface Mergeable<T> {
+ // Merge two object instances in one instance
void merge(T merged);
+
+ // Merge two object instances in a new instance
+ T mergeCopy(T merged);
}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
index f1e50d62ea..bbbc74289d 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
@@ -531,6 +531,9 @@ public class AddressSettings implements
Mergeable<AddressSettings>, Serializable
}
private Integer idCacheSize = null;
+ static {
+ metaBean.add(Integer.class, "queuePrefetch", (t, p) -> t.queuePrefetch =
p, t -> t.queuePrefetch);
+ }
//from amq5
//make it transient
private transient Integer queuePrefetch = null;
@@ -1279,243 +1282,38 @@ public class AddressSettings implements
Mergeable<AddressSettings>, Serializable
}
/**
- * merge 2 objects in to 1
+ * Merge two AddressSettings instances in one instance
*
* @param merged
*/
@Override
public void merge(final AddressSettings merged) {
- if (maxDeliveryAttempts == null) {
- maxDeliveryAttempts = merged.maxDeliveryAttempts;
- }
- if (dropMessagesWhenFull == null) {
- dropMessagesWhenFull = merged.dropMessagesWhenFull;
- }
- if (maxSizeBytes == null) {
- maxSizeBytes = merged.maxSizeBytes;
- }
- if (maxSizeMessages == null) {
- maxSizeMessages = merged.maxSizeMessages;
- }
- if (maxReadPageBytes == null) {
- maxReadPageBytes = merged.maxReadPageBytes;
- }
- if (maxReadPageMessages == null) {
- maxReadPageMessages = merged.maxReadPageMessages;
- }
- if (pageCacheMaxSize == null) {
- pageCacheMaxSize = merged.pageCacheMaxSize;
- }
- if (pageSizeBytes == null) {
- pageSizeBytes = merged.pageSizeBytes;
- }
- if (messageCounterHistoryDayLimit == null) {
- messageCounterHistoryDayLimit = merged.messageCounterHistoryDayLimit;
- }
- if (redeliveryDelay == null) {
- redeliveryDelay = merged.redeliveryDelay;
- }
- if (redeliveryMultiplier == null) {
- redeliveryMultiplier = merged.redeliveryMultiplier;
- }
- if (redeliveryCollisionAvoidanceFactor == null) {
- redeliveryCollisionAvoidanceFactor =
merged.redeliveryCollisionAvoidanceFactor;
- }
- if (maxRedeliveryDelay == null) {
- maxRedeliveryDelay = merged.maxRedeliveryDelay;
- }
- if (deadLetterAddress == null) {
- deadLetterAddress = merged.deadLetterAddress;
- }
- if (expiryAddress == null) {
- expiryAddress = merged.expiryAddress;
- }
- if (expiryDelay == null) {
- expiryDelay = merged.expiryDelay;
- }
- if (minExpiryDelay == null) {
- minExpiryDelay = merged.minExpiryDelay;
- }
- if (maxExpiryDelay == null) {
- maxExpiryDelay = merged.maxExpiryDelay;
- }
- if (redistributionDelay == null) {
- redistributionDelay = merged.redistributionDelay;
- }
- if (sendToDLAOnNoRoute == null) {
- sendToDLAOnNoRoute = merged.sendToDLAOnNoRoute;
- }
- if (addressFullMessagePolicy == null) {
- addressFullMessagePolicy = merged.addressFullMessagePolicy;
- }
- if (slowConsumerThreshold == null) {
- slowConsumerThreshold = merged.slowConsumerThreshold;
- }
- if (slowConsumerThresholdMeasurementUnit == null) {
- slowConsumerThresholdMeasurementUnit =
merged.slowConsumerThresholdMeasurementUnit;
- }
- if (slowConsumerCheckPeriod == null) {
- slowConsumerCheckPeriod = merged.slowConsumerCheckPeriod;
- }
- if (slowConsumerPolicy == null) {
- slowConsumerPolicy = merged.slowConsumerPolicy;
- }
- if (autoCreateJmsQueues == null) {
- autoCreateJmsQueues = merged.autoCreateJmsQueues;
- }
- if (autoDeleteJmsQueues == null) {
- autoDeleteJmsQueues = merged.autoDeleteJmsQueues;
- }
- if (autoCreateJmsTopics == null) {
- autoCreateJmsTopics = merged.autoCreateJmsTopics;
- }
- if (autoDeleteJmsTopics == null) {
- autoDeleteJmsTopics = merged.autoDeleteJmsTopics;
- }
- if (autoCreateQueues == null) {
- autoCreateQueues = merged.autoCreateQueues;
- }
- if (autoDeleteQueues == null) {
- autoDeleteQueues = merged.autoDeleteQueues;
- }
- if (autoDeleteCreatedQueues == null) {
- autoDeleteCreatedQueues = merged.autoDeleteCreatedQueues;
- }
- if (autoDeleteQueuesDelay == null) {
- autoDeleteQueuesDelay = merged.autoDeleteQueuesDelay;
- }
- if (autoDeleteQueuesSkipUsageCheck == null) {
- autoDeleteQueuesSkipUsageCheck =
merged.autoDeleteQueuesSkipUsageCheck;
- }
- if (autoDeleteQueuesMessageCount == null) {
- autoDeleteQueuesMessageCount = merged.autoDeleteQueuesMessageCount;
- }
- if (configDeleteQueues == null) {
- configDeleteQueues = merged.configDeleteQueues;
- }
- if (autoCreateAddresses == null) {
- autoCreateAddresses = merged.autoCreateAddresses;
- }
- if (autoDeleteAddresses == null) {
- autoDeleteAddresses = merged.autoDeleteAddresses;
- }
- if (autoDeleteAddressesDelay == null) {
- autoDeleteAddressesDelay = merged.autoDeleteAddressesDelay;
- }
- if (autoDeleteAddressesSkipUsageCheck == null) {
- autoDeleteAddressesSkipUsageCheck =
merged.autoDeleteAddressesSkipUsageCheck;
- }
- if (configDeleteAddresses == null) {
- configDeleteAddresses = merged.configDeleteAddresses;
- }
- if (configDeleteDiverts == null) {
- configDeleteDiverts = merged.configDeleteDiverts;
- }
- if (managementBrowsePageSize == null) {
- managementBrowsePageSize = merged.managementBrowsePageSize;
- }
- if (managementMessageAttributeSizeLimit == null) {
- managementMessageAttributeSizeLimit =
merged.managementMessageAttributeSizeLimit;
- }
- if (queuePrefetch == null) {
- queuePrefetch = merged.queuePrefetch;
- }
- if (maxSizeBytesRejectThreshold == null) {
- maxSizeBytesRejectThreshold = merged.maxSizeBytesRejectThreshold;
- }
- if (defaultMaxConsumers == null) {
- defaultMaxConsumers = merged.defaultMaxConsumers;
- }
- if (defaultPurgeOnNoConsumers == null) {
- defaultPurgeOnNoConsumers = merged.defaultPurgeOnNoConsumers;
- }
- if (defaultQueueRoutingType == null) {
- defaultQueueRoutingType = merged.defaultQueueRoutingType;
- }
- if (defaultAddressRoutingType == null) {
- defaultAddressRoutingType = merged.defaultAddressRoutingType;
- }
- if (defaultExclusiveQueue == null) {
- defaultExclusiveQueue = merged.defaultExclusiveQueue;
- }
- if (defaultConsumerWindowSize == null) {
- defaultConsumerWindowSize = merged.defaultConsumerWindowSize;
- }
- if (defaultLastValueQueue == null) {
- defaultLastValueQueue = merged.defaultLastValueQueue;
- }
- if (defaultLastValueKey == null) {
- defaultLastValueKey = merged.defaultLastValueKey;
- }
- if (defaultNonDestructive == null) {
- defaultNonDestructive = merged.defaultNonDestructive;
- }
- if (defaultConsumersBeforeDispatch == null) {
- defaultConsumersBeforeDispatch =
merged.defaultConsumersBeforeDispatch;
- }
- if (defaultDelayBeforeDispatch == null) {
- defaultDelayBeforeDispatch = merged.defaultDelayBeforeDispatch;
- }
- if (defaultGroupRebalance == null) {
- defaultGroupRebalance = merged.defaultGroupRebalance;
- }
- if (defaultGroupRebalancePauseDispatch == null) {
- defaultGroupRebalancePauseDispatch =
merged.defaultGroupRebalancePauseDispatch;
- }
- if (defaultGroupBuckets == null) {
- defaultGroupBuckets = merged.defaultGroupBuckets;
- }
- if (defaultGroupFirstKey == null) {
- defaultGroupFirstKey = merged.defaultGroupFirstKey;
- }
- if (defaultRingSize == null) {
- defaultRingSize = merged.defaultRingSize;
- }
- if (retroactiveMessageCount == null) {
- retroactiveMessageCount = merged.retroactiveMessageCount;
- }
- if (autoCreateDeadLetterResources == null) {
- autoCreateDeadLetterResources = merged.autoCreateDeadLetterResources;
- }
- if (deadLetterQueuePrefix == null) {
- deadLetterQueuePrefix = merged.deadLetterQueuePrefix;
- }
- if (deadLetterQueueSuffix == null) {
- deadLetterQueueSuffix = merged.deadLetterQueueSuffix;
- }
- if (autoCreateExpiryResources == null) {
- autoCreateExpiryResources = merged.autoCreateExpiryResources;
- }
- if (expiryQueuePrefix == null) {
- expiryQueuePrefix = merged.expiryQueuePrefix;
- }
- if (expiryQueueSuffix == null) {
- expiryQueueSuffix = merged.expiryQueueSuffix;
- }
- if (enableMetrics == null) {
- enableMetrics = merged.enableMetrics;
- }
- if (enableIngressTimestamp == null) {
- enableIngressTimestamp = merged.enableIngressTimestamp;
- }
- if (pageFullMessagePolicy == null) {
- pageFullMessagePolicy = merged.pageFullMessagePolicy;
- }
- if (pageLimitBytes == null) {
- pageLimitBytes = merged.pageLimitBytes;
- }
- if (pageLimitMessages == null) {
- pageLimitMessages = merged.pageLimitMessages;
- }
- if (idCacheSize == null) {
- idCacheSize = merged.idCacheSize;
- }
- if (prefetchPageMessages == null) {
- prefetchPageMessages = merged.prefetchPageMessages;
- }
- if (prefetchPageBytes == null) {
- prefetchPageBytes = merged.prefetchPageBytes;
- }
+ metaBean.forEach((type, name, setter, getter, gate) -> {
+ if (getter.apply(AddressSettings.this) == null) {
+ setter.accept(this, getter.apply(merged));
+ }
+ });
+ }
+
+ /**
+ * Merge two AddressSettings instances in a new instance
+ *
+ * @param merged
+ */
+ @Override
+ public AddressSettings mergeCopy(final AddressSettings merged) {
+ AddressSettings target = new AddressSettings();
+
+ metaBean.forEach((type, name, setter, getter, gate) -> {
+ Object sourceValue = getter.apply(AddressSettings.this);
+ if (sourceValue != null) {
+ setter.accept(target, sourceValue);
+ } else {
+ setter.accept(target, getter.apply(merged));
+ }
+ });
+
+ return target;
}
@Override
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/HierarchicalObjectRepository.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/HierarchicalObjectRepository.java
index d63a1a9172..cf568deff4 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/HierarchicalObjectRepository.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/HierarchicalObjectRepository.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -288,21 +289,23 @@ public class HierarchicalObjectRepository<T> implements
HierarchicalRepository<T
* @return
*/
private T merge(final Collection<Match<T>> orderedMatches) {
- T actualMatch = null;
- for (Match<T> match : orderedMatches) {
- if (actualMatch == null ||
!Mergeable.class.isAssignableFrom(actualMatch.getClass())) {
- actualMatch = match.getValue();
- if (!Mergeable.class.isAssignableFrom(actualMatch.getClass())) {
- break;
- }
- } else {
- ((Mergeable) actualMatch).merge(match.getValue());
+ Iterator<Match<T>> matchIterator = orderedMatches.iterator();
+
+ T result = null;
+ if (matchIterator.hasNext()) {
+ Match<T> match = matchIterator.next();
+ result = match.getValue();
+
+ while (matchIterator.hasNext() &&
Mergeable.class.isAssignableFrom(result.getClass())) {
+ match = matchIterator.next();
+ result = ((Mergeable<T>)result).mergeCopy(match.getValue());
if (match.isLiteral()) {
break;
}
}
}
- return actualMatch;
+
+ return result;
}
/**
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/AddressSettingsTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/AddressSettingsTest.java
index 0614f97376..30b4fe388c 100644
---
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/AddressSettingsTest.java
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/AddressSettingsTest.java
@@ -62,6 +62,15 @@ public class AddressSettingsTest extends ActiveMQTestBase {
@Test
public void testSingleMerge() {
+ testSingleMerge(false);
+ }
+
+ @Test
+ public void testSingleMergeCopy() {
+ testSingleMerge(true);
+ }
+
+ private void testSingleMerge(boolean copy) {
AddressSettings addressSettings = new AddressSettings();
AddressSettings addressSettingsToMerge = new AddressSettings();
SimpleString DLQ = new SimpleString("testDLQ");
@@ -82,7 +91,11 @@ public class AddressSettingsTest extends ActiveMQTestBase {
addressSettingsToMerge.setMaxExpiryDelay(777L);
addressSettingsToMerge.setIDCacheSize(5);
- addressSettings.merge(addressSettingsToMerge);
+ if (copy) {
+ addressSettings = addressSettings.mergeCopy(addressSettingsToMerge);
+ } else {
+ addressSettings.merge(addressSettingsToMerge);
+ }
Assert.assertEquals(addressSettings.getDeadLetterAddress(), DLQ);
Assert.assertEquals(addressSettings.getExpiryAddress(), exp);
Assert.assertEquals(addressSettings.getMaxDeliveryAttempts(), 1000);
@@ -102,6 +115,15 @@ public class AddressSettingsTest extends ActiveMQTestBase {
@Test
public void testMultipleMerge() {
+ testMultipleMerge(false);
+ }
+
+ @Test
+ public void testMultipleMergeCopy() {
+ testSingleMerge(true);
+ }
+
+ private void testMultipleMerge(boolean copy) {
AddressSettings addressSettings = new AddressSettings();
AddressSettings addressSettingsToMerge = new AddressSettings();
SimpleString DLQ = new SimpleString("testDLQ");
@@ -113,7 +135,11 @@ public class AddressSettingsTest extends ActiveMQTestBase {
addressSettingsToMerge.setMessageCounterHistoryDayLimit(1002);
addressSettingsToMerge.setAddressFullMessagePolicy(AddressFullMessagePolicy.DROP);
addressSettingsToMerge.setMaxSizeBytesRejectThreshold(10 * 1024);
- addressSettings.merge(addressSettingsToMerge);
+ if (copy) {
+ addressSettings = addressSettings.mergeCopy(addressSettingsToMerge);
+ } else {
+ addressSettings.merge(addressSettingsToMerge);
+ }
AddressSettings addressSettingsToMerge2 = new AddressSettings();
SimpleString exp2 = new SimpleString("testExpiryQueue2");
@@ -121,7 +147,11 @@ public class AddressSettingsTest extends ActiveMQTestBase {
addressSettingsToMerge2.setMaxSizeBytes(2001);
addressSettingsToMerge2.setRedeliveryDelay(2003);
addressSettingsToMerge2.setRedeliveryMultiplier(2.5);
- addressSettings.merge(addressSettingsToMerge2);
+ if (copy) {
+ addressSettings = addressSettings.mergeCopy(addressSettingsToMerge2);
+ } else {
+ addressSettings.merge(addressSettingsToMerge2);
+ }
Assert.assertEquals(addressSettings.getDeadLetterAddress(), DLQ);
Assert.assertEquals(addressSettings.getExpiryAddress(), exp);
@@ -136,6 +166,15 @@ public class AddressSettingsTest extends ActiveMQTestBase {
@Test
public void testMultipleMergeAll() {
+ testMultipleMergeAll(false);
+ }
+
+ @Test
+ public void testMultipleMergeAllCopy() {
+ testMultipleMergeAll(true);
+ }
+
+ private void testMultipleMergeAll(boolean copy) {
AddressSettings addressSettings = new AddressSettings();
AddressSettings addressSettingsToMerge = new AddressSettings();
SimpleString DLQ = new SimpleString("testDLQ");
@@ -146,7 +185,11 @@ public class AddressSettingsTest extends ActiveMQTestBase {
addressSettingsToMerge.setRedeliveryDelay(1003);
addressSettingsToMerge.setRedeliveryMultiplier(1.0);
addressSettingsToMerge.setAddressFullMessagePolicy(AddressFullMessagePolicy.DROP);
- addressSettings.merge(addressSettingsToMerge);
+ if (copy) {
+ addressSettings = addressSettings.mergeCopy(addressSettingsToMerge);
+ } else {
+ addressSettings.merge(addressSettingsToMerge);
+ }
AddressSettings addressSettingsToMerge2 = new AddressSettings();
SimpleString exp2 = new SimpleString("testExpiryQueue2");
@@ -160,7 +203,11 @@ public class AddressSettingsTest extends ActiveMQTestBase {
addressSettingsToMerge2.setRedeliveryMultiplier(2.0);
addressSettingsToMerge2.setMaxRedeliveryDelay(5000);
addressSettingsToMerge.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
- addressSettings.merge(addressSettingsToMerge2);
+ if (copy) {
+ addressSettings = addressSettings.mergeCopy(addressSettingsToMerge2);
+ } else {
+ addressSettings.merge(addressSettingsToMerge2);
+ }
Assert.assertEquals(addressSettings.getDeadLetterAddress(), DLQ);
Assert.assertEquals(addressSettings.getExpiryAddress(), exp);
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/RepositoryTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/RepositoryTest.java
index e4389748b8..bc9cba1476 100644
---
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/RepositoryTest.java
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/RepositoryTest.java
@@ -17,14 +17,17 @@
package org.apache.activemq.artemis.core.settings;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import
org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -41,14 +44,6 @@ public class RepositoryTest extends ActiveMQTestBase {
securityRepository = new HierarchicalObjectRepository<>();
}
- @Override
- @After
- public void tearDown() throws Exception {
- super.tearDown();
-
- DummyMergeable.reset();
- }
-
@Test
public void testDefault() {
securityRepository.setDefault(new HashSet<Role>());
@@ -86,18 +81,16 @@ public class RepositoryTest extends ActiveMQTestBase {
repo.addMatch("a.#", new DummyMergeable(2));
repo.addMatch("a.b", new DummyMergeable(3));
- repo.getMatch("a.b");
- assertTrue(DummyMergeable.contains(0));
- assertFalse(DummyMergeable.contains(1));
- assertTrue(DummyMergeable.contains(2));
- assertTrue(DummyMergeable.contains(3));
-
- DummyMergeable.reset();
- repo.getMatch("a.#");
- assertTrue(DummyMergeable.contains(0));
- assertTrue(DummyMergeable.contains(1));
- assertFalse(DummyMergeable.contains(2));
- assertFalse(DummyMergeable.contains(3));
+ DummyMergeable abDummyMatch = repo.getMatch("a.b");
+ Assert.assertEquals(2, abDummyMatch.getMergedItems().size());
+ Assert.assertEquals(3, abDummyMatch.getId());
+ Assert.assertEquals(2, abDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(0, abDummyMatch.getMergedItems().get(1).getId());
+
+ DummyMergeable aDummyMatch = repo.getMatch("a.#");
+ Assert.assertEquals(1, aDummyMatch.getMergedItems().size());
+ Assert.assertEquals(1, aDummyMatch.getId());
+ Assert.assertEquals(0, aDummyMatch.getMergedItems().get(0).getId());
}
@Test
@@ -263,23 +256,23 @@ public class RepositoryTest extends ActiveMQTestBase {
repository.addMatch("a.b.c.#", new DummyMergeable(6));
repository.addMatch("a.b.*.d", new DummyMergeable(7));
repository.addMatch("a.b.c.*", new DummyMergeable(8));
- repository.getMatch("a.b.c.d");
- Assert.assertEquals(5, DummyMergeable.timesMerged);
- Assert.assertTrue(DummyMergeable.contains(1));
- Assert.assertTrue(DummyMergeable.contains(2));
- Assert.assertTrue(DummyMergeable.contains(4));
- Assert.assertTrue(DummyMergeable.contains(7));
- Assert.assertTrue(DummyMergeable.contains(8));
- DummyMergeable.reset();
- repository.getMatch("a.b.c");
- Assert.assertEquals(3, DummyMergeable.timesMerged);
- Assert.assertTrue(DummyMergeable.contains(1));
- Assert.assertTrue(DummyMergeable.contains(2));
- Assert.assertTrue(DummyMergeable.contains(4));
- DummyMergeable.reset();
- repository.getMatch("z");
- Assert.assertEquals(0, DummyMergeable.timesMerged);
- DummyMergeable.reset();
+ DummyMergeable abcdDummyMatch = repository.getMatch("a.b.c.d");
+ Assert.assertEquals(5, abcdDummyMatch.getMergedItems().size());
+ Assert.assertEquals(8, abcdDummyMatch.getId());
+ Assert.assertEquals(7, abcdDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(6, abcdDummyMatch.getMergedItems().get(1).getId());
+ Assert.assertEquals(4, abcdDummyMatch.getMergedItems().get(2).getId());
+ Assert.assertEquals(2, abcdDummyMatch.getMergedItems().get(3).getId());
+ Assert.assertEquals(1, abcdDummyMatch.getMergedItems().get(4).getId());
+ DummyMergeable abcDummyMatch = repository.getMatch("a.b.c");
+ Assert.assertEquals(3, abcDummyMatch.getMergedItems().size());
+ Assert.assertEquals(6, abcDummyMatch.getId());
+ Assert.assertEquals(4, abcDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(2, abcDummyMatch.getMergedItems().get(1).getId());
+ Assert.assertEquals(1, abcDummyMatch.getMergedItems().get(2).getId());
+ DummyMergeable zDummyMatch = repository.getMatch("z");
+ Assert.assertEquals(0, zDummyMatch.getMergedItems().size());
+ Assert.assertEquals(1, zDummyMatch.getId());
}
@Test
@@ -340,32 +333,137 @@ public class RepositoryTest extends ActiveMQTestBase {
}
}
- static class DummyMergeable implements Mergeable {
+ @Test
+ public void testMatchMergeIdempotence() {
+ HierarchicalRepository<DummyMergeable> repository = new
HierarchicalObjectRepository<>();
+ repository.addMatch("foo.*", new DummyMergeable(0, Map.of("s0", "x")));
+ repository.addMatch("foo.0.#", new DummyMergeable(1, Map.of("so", "a",
"s1", "a")));
+ repository.addMatch("foo.1.#", new DummyMergeable(2, Map.of("so", "b",
"s1", "b")));
+
+ DummyMergeable fooxMatch = repository.getMatch("foo.x");
+ Assert.assertEquals(0, fooxMatch.getId());
+ Assert.assertEquals(0, fooxMatch.getMergedItems().size());
+ Assert.assertEquals("x", fooxMatch.getSettings().get("s0"));
+ Assert.assertNull(fooxMatch.getSettings().get("s1"));
+
+ DummyMergeable foo1Match = repository.getMatch("foo.0");
+ Assert.assertEquals(0, foo1Match.getId());
+ Assert.assertEquals(1, foo1Match.getMergedItems().size());
+ Assert.assertEquals("x", fooxMatch.getSettings().get("s0"));
+ Assert.assertEquals("a", foo1Match.getSettings().get("s1"));
+
+ DummyMergeable foo2Match = repository.getMatch("foo.1");
+ Assert.assertEquals(0, foo2Match.getId());
+ Assert.assertEquals(1, foo2Match.getMergedItems().size());
+ Assert.assertEquals("x", fooxMatch.getSettings().get("s0"));
+ Assert.assertEquals("b", foo2Match.getSettings().get("s1"));
+
+ DummyMergeable fooxBisMatch = repository.getMatch("foo.x");
+ Assert.assertEquals(0, fooxBisMatch.getId());
+ Assert.assertEquals(0, fooxBisMatch.getMergedItems().size());
+ Assert.assertEquals("x", fooxBisMatch.getSettings().get("s0"));
+ Assert.assertNull(fooxBisMatch.getSettings().get("s1"));
+
+ DummyMergeable foo1BisMatch = repository.getMatch("foo.0");
+ Assert.assertEquals(0, foo1BisMatch.getId());
+ Assert.assertEquals(1, foo1BisMatch.getMergedItems().size());
+ Assert.assertEquals("x", foo1BisMatch.getSettings().get("s0"));
+ Assert.assertEquals("a", foo1BisMatch.getSettings().get("s1"));
+
+ DummyMergeable foo2BisMatch = repository.getMatch("foo.1");
+ Assert.assertEquals(0, foo2BisMatch.getId());
+ Assert.assertEquals(1, foo2BisMatch.getMergedItems().size());
+ Assert.assertEquals("x", foo2BisMatch.getSettings().get("s0"));
+ Assert.assertEquals("b", foo2BisMatch.getSettings().get("s1"));
+ }
- static int timesMerged = 0;
+ @Test
+ public void testAddressSettingsMergeIdempotence() {
+ AddressSettings foox = new
AddressSettings().setMaxRedeliveryDelay(10000);
+ AddressSettings foo0 = new
AddressSettings().setMaxRedeliveryDelay(20000).setMaxExpiryDelay(20000L);
+ AddressSettings foo1 = new
AddressSettings().setMaxRedeliveryDelay(30000).setMaxExpiryDelay(30000L);
+
+ HierarchicalRepository<AddressSettings> repository = new
HierarchicalObjectRepository<>();
+ repository.addMatch("foo.*", foox);
+ repository.addMatch("foo.0.#", foo0);
+ repository.addMatch("foo.1.#", foo1);
+
+ AddressSettings fooxMatch = repository.getMatch("foo.x");
+ Assert.assertEquals(10000, fooxMatch.getMaxRedeliveryDelay());
+
Assert.assertEquals(Long.valueOf(AddressSettings.DEFAULT_MAX_EXPIRY_DELAY),
fooxMatch.getMaxExpiryDelay());
+
+ AddressSettings foo0Match = repository.getMatch("foo.0");
+ Assert.assertEquals(10000, foo0Match.getMaxRedeliveryDelay());
+ Assert.assertEquals(Long.valueOf(20000), foo0Match.getMaxExpiryDelay());
+
+ AddressSettings foo1Match = repository.getMatch("foo.1");
+ Assert.assertEquals(10000, foo1Match.getMaxRedeliveryDelay());
+ Assert.assertEquals(Long.valueOf(30000), foo1Match.getMaxExpiryDelay());
+
+ AddressSettings fooxBisMatch = repository.getMatch("foo.x");
+ Assert.assertEquals(10000, fooxBisMatch.getMaxRedeliveryDelay());
+
Assert.assertEquals(Long.valueOf(AddressSettings.DEFAULT_MAX_EXPIRY_DELAY),
fooxBisMatch.getMaxExpiryDelay());
+
+ AddressSettings foo0BisMatch = repository.getMatch("foo.0");
+ Assert.assertEquals(10000, foo0BisMatch.getMaxRedeliveryDelay());
+ Assert.assertEquals(Long.valueOf(20000),
foo0BisMatch.getMaxExpiryDelay());
+
+ AddressSettings foo1BisMatch = repository.getMatch("foo.1");
+ Assert.assertEquals(10000, foo1BisMatch.getMaxRedeliveryDelay());
+ Assert.assertEquals(Long.valueOf(30000),
foo1BisMatch.getMaxExpiryDelay());
+ }
- static ArrayList<Integer> merged = new ArrayList<>();
+ static class DummyMergeable implements Mergeable<DummyMergeable> {
+ private final int id;
+ private final Map<String,String> settings;
+ private final List<DummyMergeable> mergedItems;
- private final Integer id;
+ public int getId() {
+ return id;
+ }
- static void reset() {
- DummyMergeable.timesMerged = 0;
- DummyMergeable.merged = new ArrayList<>();
+ public Map<String, String> getSettings() {
+ return settings;
}
- static boolean contains(final Integer i) {
- return DummyMergeable.merged.contains(i);
+ public List<DummyMergeable> getMergedItems() {
+ return mergedItems;
}
- DummyMergeable(final Integer id) {
+ DummyMergeable(final int id) {
this.id = id;
+ this.settings = new HashMap<>();
+ this.mergedItems = new ArrayList<>();
+ }
+
+ DummyMergeable(final int id, final Map<String,String> settings) {
+ this.id = id;
+ this.settings = settings;
+ this.mergedItems = new ArrayList<>();
+ }
+
+ DummyMergeable(DummyMergeable item) {
+ this.id = item.id;
+ this.settings = new HashMap<>(item.settings);
+ this.mergedItems = new ArrayList<>(item.mergedItems);
}
@Override
- public void merge(final Object merged) {
- DummyMergeable.timesMerged++;
- DummyMergeable.merged.add(id);
- DummyMergeable.merged.add(((DummyMergeable) merged).id);
+ public void merge(final DummyMergeable merged) {
+ for (Map.Entry<String, String> entry : merged.settings.entrySet()) {
+ this.settings.putIfAbsent(entry.getKey(), entry.getValue());
+ }
+ this.mergedItems.add(merged);
+ }
+
+ @Override
+ public DummyMergeable mergeCopy(DummyMergeable merged) {
+ DummyMergeable target = new DummyMergeable(this);
+ for (Map.Entry<String, String> entry : merged.settings.entrySet()) {
+ target.settings.putIfAbsent(entry.getKey(), entry.getValue());
+ }
+ target.mergedItems.add(merged);
+ return target;
}
}
}
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MessageExpirationTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MessageExpirationTest.java
index fb3be03d54..2aefb8c1a5 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MessageExpirationTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MessageExpirationTest.java
@@ -242,14 +242,7 @@ public class MessageExpirationTest extends
ActiveMQTestBase {
final SimpleString expiryAddress = RandomUtil.randomSimpleString();
SimpleString expiryQueue = RandomUtil.randomSimpleString();
- server.getAddressSettingsRepository().addMatch(address.toString(), new
AddressSettings() {
- private static final long serialVersionUID = -6476053400596299130L;
-
- @Override
- public SimpleString getExpiryAddress() {
- return expiryAddress;
- }
- });
+ server.getAddressSettingsRepository().addMatch(address.toString(), new
AddressSettings().setExpiryAddress(expiryAddress));
session.createQueue(new
QueueConfiguration(queue).setAddress(address).setDurable(false));
session.createQueue(new
QueueConfiguration(expiryQueue).setAddress(expiryAddress).setDurable(false));