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 3bfff0b4fd..06c26b8e35 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 @@ -53,9 +53,11 @@ public class HierarchicalObjectRepository implements HierarchicalRepository> matches = new HashMap<>(); + private final Map> wildcardMatches = new HashMap<>(); + private final Map> exactMatches = new HashMap<>(); /** * Certain values cannot be removed after installed. @@ -83,7 +85,8 @@ public class HierarchicalObjectRepository implements HierarchicalRepository - * We could have a race between the state of {@link #matches} and {@link #cache}: + * We could have a race between the state of {@link #wildcardMatches}, {@link #exactMatches}, + * and {@link #cache}: *

* Thread1: calls {@link #addMatch(String, T)}: i. cleans cache; ii. adds match to Map.
* Thread2: could add an (out-dated) entry to the cache between 'i. clean cache' and 'ii. add @@ -145,9 +148,13 @@ public class HierarchicalObjectRepository implements HierarchicalRepository values() { lock.readLock().lock(); try { - ArrayList values = new ArrayList<>(matches.size()); + ArrayList values = new ArrayList<>(wildcardMatches.size() + exactMatches.size()); - for (Match matchValue : matches.values()) { + for (Match matchValue : wildcardMatches.values()) { + values.add(matchValue.getValue()); + } + + for (Match matchValue : exactMatches.values()) { values.add(matchValue.getValue()); } @@ -172,14 +179,23 @@ public class HierarchicalObjectRepository implements HierarchicalRepository match1 = new Match<>(modifiedMatch, value, wildcardConfiguration); - matches.put(modifiedMatch, match1); + if (usesWildcards(modifiedMatch)) { + wildcardMatches.put(modifiedMatch, match1); + } else { + exactMatches.put(modifiedMatch, match1); + } } finally { lock.writeLock().unlock(); } @@ -190,6 +206,10 @@ public class HierarchicalObjectRepository implements HierarchicalRepository implements HierarchicalRepository implements HierarchicalRepository implements HierarchicalRepository entry : entries) { addMatch(entry.getKey(), entry.getValue(), true, false); } @@ -362,6 +386,11 @@ public class HierarchicalObjectRepository implements HierarchicalRepository implements HierarchicalRepository> getPossibleMatches(final String match) { HashMap> possibleMatches = new HashMap<>(); - for (Entry> entry : matches.entrySet()) { + if (exactMatches.containsKey(match)) { + possibleMatches.put(match, exactMatches.get(match)); + } + + for (Entry> entry : wildcardMatches.entrySet()) { Match entryMatch = entry.getValue(); if (entryMatch.getPattern().matcher(match).matches()) { possibleMatches.put(entry.getKey(), entryMatch); 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 bdcd493e98..7770472299 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 @@ -65,6 +65,18 @@ public class RepositoryTest extends ActiveMQTestBase { Assert.assertEquals("abd#", repo.getMatch("a.b.d")); } + @Test + public void testCacheWithWildcards() throws Throwable { + HierarchicalObjectRepository repo = new HierarchicalObjectRepository<>(); + + repo.addMatch("#", "root"); + Assert.assertEquals("root", repo.getMatch("b")); + + repo.addMatch("b", "leaf"); + Assert.assertEquals("leaf", repo.getMatch("b")); + } + + @Test public void testMatchingDocsCustomUnderscorDelimiter() throws Throwable { WildcardConfiguration wildcardConfiguration = new WildcardConfiguration();