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

gtully 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 052bd60  ARTEMIS-3180 - fix multiple path match case in wildcard 
address map
052bd60 is described below

commit 052bd60da4292eabecc58582c0e4195396f4494e
Author: gtully <[email protected]>
AuthorDate: Mon Mar 15 14:30:39 2021 +0000

    ARTEMIS-3180 - fix multiple path match case in wildcard address map
---
 .../core/postoffice/impl/AddressPartNode.java      | 23 ++++++--
 .../core/postoffice/impl/AddressMapUnitTest.java   | 67 +++++++++++++++++++++-
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/AddressPartNode.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/AddressPartNode.java
index cc300cf..122abc0 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/AddressPartNode.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/AddressPartNode.java
@@ -17,6 +17,7 @@
 
 package org.apache.activemq.artemis.core.postoffice.impl;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -137,23 +138,33 @@ public final class AddressPartNode<T> {
       }
 
       // look for a path match after 0-N skips among immediate children
-      AddressPartNode<T> match = null;
+      ArrayList<AddressPartNode> visitedSet = new ArrayList<>(paths.length);
       for (int i = startIndex; i < paths.length; i++) {
-         match = getChild(paths[i]);
+         final AddressPartNode<T> match = getChild(paths[i]);
          if (match != null) {
             match.visitMatchingWildcards(paths, i + 1, collector);
-            break;
+            visitedSet.add(match);
          }
       }
 
       // walk the rest of the sub tree to find a tail path match
       for (AddressPartNode<T> child : childNodes.values()) {
-         // instance equality arranged in node creation
-         if (child != match && ANY_DESCENDENT != child.getPath()) {
+         if (alreadyVisited(child, visitedSet)) {
+            continue;
+         }
+         child.visitPathTailMatch(paths, startIndex, collector);
+      }
+   }
 
-            child.visitPathTailMatch(paths, startIndex, collector);
+   private boolean alreadyVisited(final AddressPartNode<T> child, final 
ArrayList<AddressPartNode> matches) {
+      if (!matches.isEmpty()) {
+         for (AddressPartNode alreadyMatched : matches) {
+            if (child == alreadyMatched) {
+               return true;
+            }
          }
       }
+      return false;
    }
 
    // wildcards in the paths, ignore wildcard expansions in the map
diff --git 
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/AddressMapUnitTest.java
 
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/AddressMapUnitTest.java
index cabdc17..7b74942 100644
--- 
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/AddressMapUnitTest.java
+++ 
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/AddressMapUnitTest.java
@@ -638,7 +638,7 @@ public class AddressMapUnitTest {
       assertFalse(aABCA.matches(aHashA));
       assertFalse(aHashA.matches(aABCA));
 
-      assertEquals(0, countMatchingWildcards(abcaS));
+      assertEquals(1, countMatchingWildcards(abcaS));
 
       assertEquals(0, countMatchingWildcards(new SimpleString("a.b")));
 
@@ -650,7 +650,7 @@ public class AddressMapUnitTest {
       SimpleString AHashA = new SimpleString("a.#.a");
       underTest.put(AHashA, AHashA);
 
-      assertEquals(1, countMatchingWildcards(new SimpleString("a.b.c.a")));
+      assertEquals(2, countMatchingWildcards(new SimpleString("a.b.c.a")));
 
       assertEquals(0, countNonWildcardMatching(new SimpleString("a.b.c.a")));
 
@@ -772,6 +772,67 @@ public class AddressMapUnitTest {
    }
 
    @Test
+   public void testHashAandHashB() throws Exception {
+
+      SimpleString hashAhash = new SimpleString("test.#.aaa.#");
+      underTest.put(hashAhash, hashAhash);
+
+      SimpleString hashBhash = new SimpleString("test.#.bbb.#");
+      underTest.put(hashBhash, hashBhash);
+
+      assertEquals(2, 
countMatchingWildcards(SimpleString.toSimpleString("test.aaa.bbb")));
+      assertEquals(2, 
countMatchingWildcards(SimpleString.toSimpleString("test.bbb.aaa")));
+
+      assertEquals(2, 
countMatchingWildcards(SimpleString.toSimpleString("test.bbb.aaa.ccc")));
+      assertEquals(2, 
countMatchingWildcards(SimpleString.toSimpleString("test.aaa.bbb.ccc")));
+   }
+
+   @Test
+   public void testHashNoHashNo() throws Exception {
+
+      SimpleString hashAhash = new SimpleString("test.#.0.#.168");
+      underTest.put(hashAhash, hashAhash);
+
+      assertEquals(1, 
countMatchingWildcards(SimpleString.toSimpleString("test.0.168")));
+   }
+
+   @Test
+   public void testHashNoHashHashNo() throws Exception {
+
+      SimpleString v = new SimpleString("test.#.0.#.168");
+      underTest.put(v, v);
+
+      v = new SimpleString("test.#.0.#");
+      underTest.put(v, v);
+
+      v = new SimpleString("test.0.#");
+      underTest.put(v, v);
+
+      assertEquals(3, 
countMatchingWildcards(SimpleString.toSimpleString("test.0.168")));
+   }
+
+   @Test
+   public void testHashNoHashNoWithNMatch() throws Exception {
+
+      for (String s : new String[] {"t.#.0.#", "t.#.1.#", "t.#.2.#", 
"t.#.3.#", "t.#.1.2.3", "t.0.1.2.3"}) {
+         SimpleString v = new SimpleString(s);
+         underTest.put(v, v);
+      }
+      assertEquals(6, 
countMatchingWildcards(SimpleString.toSimpleString("t.0.1.2.3")));
+   }
+
+   @Test
+   public void testSomeMoreHashPlacement() throws Exception {
+
+      for (String s : new String[] {"t.#.0.#", "t.0.1.#", "t.0.1.2.#", 
"t.0.1.#.2.3", "t.*.#.1.2.3"}) {
+         SimpleString v = new SimpleString(s);
+         underTest.put(v, v);
+      }
+      assertEquals(5, 
countMatchingWildcards(SimpleString.toSimpleString("t.0.1.2.3")));
+      assertEquals(3, 
countMatchingWildcards(SimpleString.toSimpleString("t.0.1.2.3.4")));
+   }
+
+   @Test
    public void testManyEntries() throws Exception {
 
       for (int i = 0; i < 10; i++) {
@@ -875,7 +936,7 @@ public class AddressMapUnitTest {
       underTest.put(new SimpleString("#.a"), new SimpleString("#.a"));
 
       assertEquals(3, countMatchingWildcards(new SimpleString("test.a")));
-      assertEquals(1, countMatchingWildcards(new SimpleString("test.a.a")));
+      assertEquals(3, countMatchingWildcards(new SimpleString("test.a.a")));
    }
 
 }
\ No newline at end of file

Reply via email to