This is an automated email from the ASF dual-hosted git repository.
brusdev 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 0b51bcfa52 ARTEMIS-4488 Merge settings with wildcards after literal
matches
0b51bcfa52 is described below
commit 0b51bcfa52fde03e8e7ac8f56c3169083c62b473
Author: Domenico Francesco Bruscino <[email protected]>
AuthorDate: Tue Dec 19 18:28:24 2023 +0100
ARTEMIS-4488 Merge settings with wildcards after literal matches
---
.../impl/HierarchicalObjectRepository.java | 57 +++++++---------------
.../artemis/core/settings/RepositoryTest.java | 14 ++++--
docs/user-manual/address-settings.adoc | 2 +-
.../integration/client/AddressSettingsTest.java | 21 +++++---
4 files changed, 41 insertions(+), 53 deletions(-)
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 cf568deff4..98245da7b6 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
@@ -20,14 +20,12 @@ import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
-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;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -258,10 +256,9 @@ public class HierarchicalObjectRepository<T> implements
HierarchicalRepository<T
}
lock.readLock().lock();
try {
- T actualMatch;
- Map<String, Match<T>> possibleMatches =
getPossibleMatches(modifiedMatch);
- Collection<Match<T>> orderedMatches = sort(possibleMatches);
- actualMatch = merge(orderedMatches);
+ List<Match<T>> matches =
+ getMatches(modifiedMatch);
+ T actualMatch = merge(matches);
T value = actualMatch != null ? actualMatch : defaultmatch;
if (value != null) {
cache.put(modifiedMatch, value);
@@ -299,32 +296,12 @@ public class HierarchicalObjectRepository<T> implements
HierarchicalRepository<T
while (matchIterator.hasNext() &&
Mergeable.class.isAssignableFrom(result.getClass())) {
match = matchIterator.next();
result = ((Mergeable<T>)result).mergeCopy(match.getValue());
- if (match.isLiteral()) {
- break;
- }
}
}
return result;
}
- /**
- * Sort the matches according to their precedence (that is, according to
the precedence of their
- * keys).
- *
- * @param possibleMatches
- * @return
- */
- private List<Match<T>> sort(final Map<String, Match<T>> possibleMatches) {
- List<String> keys = new ArrayList<>(possibleMatches.keySet());
- Collections.sort(keys, matchComparator);
- List<Match<T>> matches1 = new ArrayList<>(possibleMatches.size());
- for (String key : keys) {
- matches1.add(possibleMatches.get(key));
- }
- return matches1;
- }
-
/**
* remove a match from the repository
*
@@ -463,30 +440,30 @@ public class HierarchicalObjectRepository<T> implements
HierarchicalRepository<T
}
/**
- * return any possible matches
+ * return matches
*
* @param match
* @return
*/
- private Map<String, Match<T>> getPossibleMatches(final String match) {
- HashMap<String, Match<T>> possibleMatches = new HashMap<>();
+ private List<Match<T>> getMatches(final String match) {
+ List<Match<T>> matches = new ArrayList<>();
- if (exactMatches.containsKey(match)) {
- possibleMatches.put(match, exactMatches.get(match));
+ Match exactMatch = exactMatches.get(match);
+ if (exactMatch != null) {
+ matches.add(exactMatch);
}
- for (Entry<String, Match<T>> entry : wildcardMatches.entrySet()) {
- Match<T> entryMatch = entry.getValue();
- if (entryMatch.getPattern().matcher(match).matches()) {
- possibleMatches.put(entry.getKey(), entryMatch);
- }
+ Match literalMatch = literalMatches.get(match);
+ if (literalMatch != null) {
+ matches.add(literalMatch);
}
- if (literalMatches.containsKey(match)) {
- possibleMatches.put(match, literalMatches.get(match));
- }
+ wildcardMatches.values().stream().
+ filter(m -> m.getPattern().matcher(match).matches()).
+ sorted((m1, m2) -> matchComparator.compare(m1.getMatch(),
m2.getMatch())).
+ forEach(m -> matches.add(m));
- return possibleMatches;
+ return matches;
}
/**
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 bc9cba1476..a161a5f81d 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
@@ -80,17 +80,21 @@ public class RepositoryTest extends ActiveMQTestBase {
repo.addMatch("(a.#)", new DummyMergeable(1));
repo.addMatch("a.#", new DummyMergeable(2));
repo.addMatch("a.b", new DummyMergeable(3));
+ repo.addMatch("a.*", new DummyMergeable(4));
DummyMergeable abDummyMatch = repo.getMatch("a.b");
- Assert.assertEquals(2, abDummyMatch.getMergedItems().size());
+ Assert.assertEquals(3, abDummyMatch.getMergedItems().size());
Assert.assertEquals(3, abDummyMatch.getId());
- Assert.assertEquals(2, abDummyMatch.getMergedItems().get(0).getId());
- Assert.assertEquals(0, abDummyMatch.getMergedItems().get(1).getId());
+ Assert.assertEquals(4, abDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(2, abDummyMatch.getMergedItems().get(1).getId());
+ Assert.assertEquals(0, abDummyMatch.getMergedItems().get(2).getId());
DummyMergeable aDummyMatch = repo.getMatch("a.#");
- Assert.assertEquals(1, aDummyMatch.getMergedItems().size());
+ Assert.assertEquals(3, aDummyMatch.getMergedItems().size());
Assert.assertEquals(1, aDummyMatch.getId());
- Assert.assertEquals(0, aDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(4, aDummyMatch.getMergedItems().get(0).getId());
+ Assert.assertEquals(2, aDummyMatch.getMergedItems().get(1).getId());
+ Assert.assertEquals(0, aDummyMatch.getMergedItems().get(2).getId());
}
@Test
diff --git a/docs/user-manual/address-settings.adoc
b/docs/user-manual/address-settings.adoc
index 17de2ba614..b810e519f6 100644
--- a/docs/user-manual/address-settings.adoc
+++ b/docs/user-manual/address-settings.adoc
@@ -13,7 +13,7 @@ A match on the any-words delimiter (`#` by default) is
considered less specific
A match with a single word delimiter (`*` by default) is considered less
specific than a match on an exact queue name.
In this way settings can be "layered" so that configuration details don't need
to be repeated.
-Address setting matches can also be "literal" which can be used to interrupt
the hierarchy in useful ways.
+Address setting matches can also be "literal" which can be used to match
wildcards literally, for further details see <<literal-matches,literal
matches>>.
The meaning of the specific settings are explained fully throughout the user
manual, however here is a brief description with a link to the appropriate
chapter if available.
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AddressSettingsTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AddressSettingsTest.java
index b8d8b14e25..ea5612398b 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AddressSettingsTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/AddressSettingsTest.java
@@ -117,22 +117,29 @@ public class AddressSettingsTest extends ActiveMQTestBase
{
@Test
public void testLiteralMatch() throws Exception {
- final SimpleString literal = RandomUtil.randomSimpleString();
- final SimpleString nonLiteral = RandomUtil.randomSimpleString();
+ final SimpleString defaultDLA = RandomUtil.randomSimpleString();
+ final SimpleString defaultEA = RandomUtil.randomSimpleString();
+ final SimpleString fooDefaultDLA = RandomUtil.randomSimpleString();
+ final SimpleString fooChildrenDLA = RandomUtil.randomSimpleString();
+ final SimpleString fooLiteralDLA = RandomUtil.randomSimpleString();
Configuration configuration = createDefaultConfig(false);
configuration.setLiteralMatchMarkers("()");
ActiveMQServer server = createServer(false, configuration);
server.start();
HierarchicalRepository<AddressSettings> repo =
server.getAddressSettingsRepository();
- repo.addMatch("(foo.#)", new
AddressSettings().setDeadLetterAddress(literal));
- repo.addMatch("foo.#", new
AddressSettings().setDeadLetterAddress(nonLiteral));
+ repo.addMatch("#", new
AddressSettings().setDeadLetterAddress(defaultDLA).setExpiryAddress(defaultEA));
+ repo.addMatch("foo.#", new
AddressSettings().setDeadLetterAddress(fooDefaultDLA));
+ repo.addMatch("foo.*", new
AddressSettings().setDeadLetterAddress(fooChildrenDLA));
+ repo.addMatch("(foo.#)", new
AddressSettings().setDeadLetterAddress(fooLiteralDLA));
// should be the DLA from foo.# - the literal match
- Assert.assertEquals(literal,
repo.getMatch("foo.#").getDeadLetterAddress());
-
- Assert.assertEquals(nonLiteral,
repo.getMatch("foo.bar").getDeadLetterAddress());
+ Assert.assertEquals(fooLiteralDLA,
repo.getMatch("foo.#").getDeadLetterAddress());
+ Assert.assertEquals(defaultEA,
repo.getMatch("foo.#").getExpiryAddress());
+ Assert.assertEquals(fooChildrenDLA,
repo.getMatch("foo.bar").getDeadLetterAddress());
+ Assert.assertEquals(fooDefaultDLA,
repo.getMatch("foo.bar.too").getDeadLetterAddress());
+ Assert.assertEquals(defaultDLA,
repo.getMatch("too.#").getDeadLetterAddress());
}
@Test