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 1d3fd65008 ARTEMIS-4270 Allow hierarchy of wildcard bindings
1d3fd65008 is described below

commit 1d3fd650086522bb6da2b3c387f87e300fbca2e5
Author: Nicolas Filotto <[email protected]>
AuthorDate: Thu Sep 14 18:40:00 2023 +0200

    ARTEMIS-4270 Allow hierarchy of wildcard bindings
    
    In case the bindings "news.#" and "news.europe.#" are registered, only the 
first one matches with the address "news.europe" while both are supposed to 
match. Those changes are meant to get rid of this limitation.
---
 .../core/postoffice/impl/AddressPartNode.java      | 17 +++----
 .../tests/integration/jms/client/MessageTest.java  | 38 ++++++++++++++++
 .../impl/WildcardAddressManagerUnitTest.java       | 53 ++++++++++++++++++++++
 3 files changed, 97 insertions(+), 11 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 122abc0210..4c2d2bdc9a 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
@@ -225,10 +225,9 @@ public final class AddressPartNode<T> {
 
    // non wildcard paths, match any expanded wildcards in the map
    public void visitMatchingWildcards(final String[] paths, final int 
startIndex, final AddressMapVisitor<T> collector) throws Exception {
-      boolean canVisitAnyDescendent = true;
       AddressPartNode<T> node = this;
-      AddressPartNode<T> anyDescendentNode = null;
-      AddressPartNode<T> anyChildNode = null;
+      AddressPartNode<T> anyDescendentNode;
+      AddressPartNode<T> anyChildNode;
       final int size = paths.length;
       for (int i = startIndex; i < size && node != null; i++) {
 
@@ -240,7 +239,6 @@ public final class AddressPartNode<T> {
             anyDescendentNode.visitValues(collector);
             // match tail with current path, such that ANY_DESCENDENT can 
match zero
             anyDescendentNode.visitPathTailMatch(paths, i, collector);
-            canVisitAnyDescendent = false;
          }
 
          anyChildNode = node.getChild(ANY_CHILD);
@@ -260,13 +258,10 @@ public final class AddressPartNode<T> {
 
          node.visitValues(collector);
 
-         if (canVisitAnyDescendent) {
-
-            // allow zero node any descendant at the end of path node
-            anyDescendentNode = node.getChild(ANY_DESCENDENT);
-            if (anyDescendentNode != null) {
-               anyDescendentNode.visitValues(collector);
-            }
+         // allow zero node any descendant at the end of path node
+         anyDescendentNode = node.getChild(ANY_DESCENDENT);
+         if (anyDescendentNode != null) {
+            anyDescendentNode.visitValues(collector);
          }
       }
    }
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/MessageTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/MessageTest.java
index 20595ca560..adcb9315b1 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/MessageTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/MessageTest.java
@@ -24,6 +24,8 @@ import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.Session;
 import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
 
 import java.lang.invoke.MethodHandles;
 
@@ -253,6 +255,42 @@ public class MessageTest extends JMSTestBase {
       }
    }
 
+   /**
+    * @see <a 
href="https://issues.apache.org/jira/browse/ARTEMIS-4270";>ARTEMIS-4270</a>
+    */
+   @Test
+   public void testWildcardRoutingHierarchyWithMultipleConsumers() throws 
Exception {
+      Topic parentTopic = createTopic(true, "a.#");
+      Topic childTopic = createTopic(true, "a.b.#");
+      try (Connection conn = cf.createConnection()) {
+         conn.start();
+
+         try (Session session = conn.createSession(false, 
Session.CLIENT_ACKNOWLEDGE)) {
+            MessageConsumer parentConsumer = 
session.createConsumer(parentTopic);
+            MessageConsumer childConsumer = session.createConsumer(childTopic);
+
+            MessageProducer producer = session.createProducer(null);
+
+            producer.send(session.createTopic("a.b.c"), 
session.createTextMessage("m1"));
+            producer.send(session.createTopic("a.b"), 
session.createTextMessage("m2"));
+
+            Message m = parentConsumer.receive(5_000);
+            assertTrue(m instanceof TextMessage);
+            assertEquals("m1", ((TextMessage) m).getText());
+            m = parentConsumer.receive(5_000);
+            assertTrue(m instanceof TextMessage);
+            assertEquals("m2", ((TextMessage) m).getText());
+
+            m = childConsumer.receive(5_000);
+            assertTrue(m instanceof TextMessage);
+            assertEquals("m1", ((TextMessage) m).getText());
+            m = childConsumer.receive(5_000);
+            assertTrue(m instanceof TextMessage);
+            assertEquals("m2", ((TextMessage) m).getText());
+         }
+      }
+   }
+
    // https://issues.jboss.org/browse/HORNETQ-988
    @Test
    public void testShouldNotThrowException() throws Exception {
diff --git 
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
 
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
index 58c0ddf30b..a2eace09f5 100644
--- 
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
+++ 
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/WildcardAddressManagerUnitTest.java
@@ -221,6 +221,59 @@ public class WildcardAddressManagerUnitTest extends 
ActiveMQTestBase {
 
    }
 
+   @Test
+   public void testSingleWordWildCardAddressBindingsForRouting() throws 
Exception {
+      WildcardAddressManager ad = new WildcardAddressManager(new 
BindingFactoryFake(), null, null);
+      ad.addAddressInfo(new AddressInfo(SimpleString.toSimpleString("news.*"), 
RoutingType.MULTICAST));
+      ad.addAddressInfo(new 
AddressInfo(SimpleString.toSimpleString("news.*.sport"), 
RoutingType.MULTICAST));
+      ad.addBinding(new BindingFake("news.*", "one"));
+      ad.addBinding(new BindingFake("news.*.sport", "two"));
+
+      Collection<Binding> bindings = 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe")).getBindings();
+      assertEquals(1, bindings.size());
+      assertEquals("one", 
bindings.iterator().next().getUniqueName().toString());
+      bindings = 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.usa")).getBindings();
+      assertEquals(1, bindings.size());
+      assertEquals("one", 
bindings.iterator().next().getUniqueName().toString());
+      bindings = 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.sport")).getBindings();
+      assertEquals(1, bindings.size());
+      assertEquals("two", 
bindings.iterator().next().getUniqueName().toString());
+      bindings = 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.usa.sport")).getBindings();
+      assertEquals(1, bindings.size());
+      assertEquals("two", 
bindings.iterator().next().getUniqueName().toString());
+      
assertNull(ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.fr.sport")));
+   }
+
+   @Test
+   public void testAnyWordsWildCardAddressBindingsForRouting() throws 
Exception {
+      WildcardAddressManager ad = new WildcardAddressManager(new 
BindingFactoryFake(), null, null);
+      ad.addAddressInfo(new 
AddressInfo(SimpleString.toSimpleString("news.europe.#"), 
RoutingType.MULTICAST));
+      ad.addBinding(new BindingFake("news.europe.#", "one"));
+
+      assertEquals(1, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe")).getBindings().size());
+      assertEquals(1, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.sport")).getBindings().size());
+      assertEquals(1, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.politics.fr")).getBindings().size());
+      
assertNull(ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.usa")));
+      
assertNull(ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("europe")));
+   }
+
+   @Test
+   public void testAnyWordsMultipleWildCardsAddressBindingsForRouting() throws 
Exception {
+      WildcardAddressManager ad = new WildcardAddressManager(new 
BindingFactoryFake(), null, null);
+      ad.addAddressInfo(new AddressInfo(SimpleString.toSimpleString("news.#"), 
RoutingType.MULTICAST));
+      ad.addAddressInfo(new 
AddressInfo(SimpleString.toSimpleString("news.europe.#"), 
RoutingType.MULTICAST));
+      ad.addBinding(new BindingFake("news.#", "one"));
+      ad.addBinding(new BindingFake("news.europe.#", "two"));
+
+      assertEquals(2, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe")).getBindings().size());
+      assertEquals(2, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.sport")).getBindings().size());
+      assertEquals(2, 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.europe.politics.fr")).getBindings().size());
+
+      Collection<Binding> bindings = 
ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("news.usa")).getBindings();
+      assertEquals(1, bindings.size());
+      assertEquals("one", 
bindings.iterator().next().getUniqueName().toString());
+      
assertNull(ad.getBindingsForRoutingAddress(SimpleString.toSimpleString("europe")));
+   }
 
    @Test
    public void testNumberOfBindingsThatMatch() throws Exception {

Reply via email to