Skip to content

Commit

Permalink
ARTEMIS-4270 Allow hierarchy of wildcard bindings
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
essobedo authored and jbertram committed Sep 18, 2023
1 parent 09cc76c commit 1d3fd65
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,9 @@ public void visitNonWildcard(final String[] paths, final int startIndex, final A

// 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++) {

Expand All @@ -240,7 +239,6 @@ public void visitMatchingWildcards(final String[] paths, final int startIndex, f
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);
Expand All @@ -260,13 +258,10 @@ public void visitMatchingWildcards(final String[] paths, final int startIndex, f

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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
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;

Expand Down Expand Up @@ -253,6 +255,42 @@ private void checkProperties(final Message message) throws Exception {
}
}

/**
* @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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,59 @@ public void testWildCardAddressDirectBindings() throws Exception {

}

@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 {
Expand Down

0 comments on commit 1d3fd65

Please sign in to comment.