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

tabish 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 4db1ac7d08 ARTEMIS-5739 allow $ for any-words wildcard char
4db1ac7d08 is described below

commit 4db1ac7d081fb07d08d8c19772afc790b803be04
Author: Justin Bertram <[email protected]>
AuthorDate: Mon Nov 3 14:27:02 2025 -0600

    ARTEMIS-5739 allow $ for any-words wildcard char
---
 .../artemis/core/config/WildcardConfiguration.java       | 11 +++++++++++
 .../activemq/artemis/core/settings/impl/Match.java       | 16 ++++++++++------
 .../artemis/core/config/WildcardConfigurationTest.java   | 14 ++++++++++++++
 .../activemq/artemis/core/settings/impl/MatchTest.java   | 13 +++++++++++--
 docs/user-manual/configuration-index.adoc                |  2 +-
 docs/user-manual/wildcard-syntax.adoc                    | 14 +++++++++++++-
 6 files changed, 60 insertions(+), 10 deletions(-)

diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/WildcardConfiguration.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/WildcardConfiguration.java
index 80fbea34b2..cfbb91ea0f 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/WildcardConfiguration.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/WildcardConfiguration.java
@@ -240,4 +240,15 @@ public class WildcardConfiguration implements Serializable 
{
          }
       }
    }
+
+   /**
+    * Checks whether the specified character matches any of the configured 
wildcard characters: single word, any words,
+    * or delimiter.
+    *
+    * @param input the character to be checked
+    * @return true if the input character matches one of the wildcard 
characters; false otherwise
+    */
+   public boolean contains(char input) {
+      return input == getSingleWord() || input == getAnyWords() || input == 
getDelimiter();
+   }
 }
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/Match.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/Match.java
index 3909b18342..91e32a074c 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/Match.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/Match.java
@@ -37,9 +37,11 @@ public class Match<T> {
 
    private static final String DOT_REPLACEMENT = "\\.";
 
-   private static final String DOLLAR = "$";
+   private static final char DOLLAR_CHAR = '$';
 
-   private static final String DOLLAR_REPLACEMENT = "\\$";
+   private static final String DOLLAR = String.valueOf(DOLLAR_CHAR);
+
+   private static final String DOLLAR_REPLACEMENT = "\\" + DOLLAR;
 
    private final String match;
 
@@ -60,19 +62,21 @@ public class Match<T> {
 
       if (wildcardConfiguration.getAnyWordsString().equals(match)) {
          // replace any regex characters
-         actMatch = Match.WILDCARD_REPLACEMENT;
+         actMatch = WILDCARD_REPLACEMENT;
       } else {
          // this is to match with what's documented
          actMatch = 
actMatch.replace(wildcardConfiguration.getDelimiterString() + 
wildcardConfiguration.getAnyWordsString(), 
wildcardConfiguration.getAnyWordsString());
-         actMatch = actMatch.replace(Match.DOT, Match.DOT_REPLACEMENT);
-         actMatch = actMatch.replace(Match.DOLLAR, Match.DOLLAR_REPLACEMENT);
+         actMatch = actMatch.replace(DOT, DOT_REPLACEMENT);
+         if (!wildcardConfiguration.contains(DOLLAR_CHAR)) {
+            actMatch = actMatch.replace(DOLLAR, DOLLAR_REPLACEMENT);
+         }
          actMatch = 
actMatch.replace(wildcardConfiguration.getSingleWordString(), 
String.format(WORD_WILDCARD_REPLACEMENT_FORMAT, 
Pattern.quote(wildcardConfiguration.getDelimiterString())));
 
          // this one has to be done by last as we are using .* and it could be 
replaced wrongly if delimiter is '.'
          actMatch = 
actMatch.replace(wildcardConfiguration.getAnyWordsString(), 
String.format(WILDCARD_CHILD_REPLACEMENT_FORMAT, 
Pattern.quote(wildcardConfiguration.getDelimiterString())));
       }
       // we need to anchor with eot to ensure we have a full match
-      pattern = Pattern.compile(actMatch + "$");
+      pattern = Pattern.compile(actMatch + DOLLAR);
       this.literal = literal;
    }
 
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/WildcardConfigurationTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/WildcardConfigurationTest.java
index 25bbf365df..45f5d1d302 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/WildcardConfigurationTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/WildcardConfigurationTest.java
@@ -150,4 +150,18 @@ public class WildcardConfigurationTest {
       assertTrue(DEFAULT_WILDCARD.isWild("a.*.\\#"));
       assertTrue(DEFAULT_WILDCARD.isWild("a.\\*.#"));
    }
+
+   @Test
+   public void testContains() {
+      assertFalse(DEFAULT_WILDCARD.contains('x'));
+      assertFalse(DEFAULT_WILDCARD.contains('!'));
+
+      assertTrue(DEFAULT_WILDCARD.contains('#'));
+      assertTrue(DEFAULT_WILDCARD.contains('*'));
+      assertTrue(DEFAULT_WILDCARD.contains('.'));
+
+      assertTrue(new WildcardConfiguration().setAnyWords('!').contains('!'));
+      assertTrue(new WildcardConfiguration().setDelimiter('!').contains('!'));
+      assertTrue(new WildcardConfiguration().setSingleWord('!').contains('!'));
+   }
 }
\ No newline at end of file
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/impl/MatchTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/impl/MatchTest.java
index 5a682a229b..6a19892e83 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/impl/MatchTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/settings/impl/MatchTest.java
@@ -28,9 +28,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 public class MatchTest {
 
    @Test
-   public void predicateTestAnyChild() {
+   public void predicateTestAnyChildDefault() {
+      
predicateTestAnyChild(WildcardConfiguration.DEFAULT_WILDCARD_CONFIGURATION.getAnyWords());
+   }
+
+   @Test
+   public void predicateTestAnyChildDollar() {
+      predicateTestAnyChild('$');
+   }
+
+   private void predicateTestAnyChild(char anyWords) {
 
-      final Match<?> underTest = new Match<>("test.#", null, new 
WildcardConfiguration());
+      final Match<?> underTest = new Match<>("test." + anyWords, null, new 
WildcardConfiguration().setAnyWords(anyWords));
       final Predicate<String> predicate = underTest.getPattern().asPredicate();
 
       assertTrue(predicate.test("test"));
diff --git a/docs/user-manual/configuration-index.adoc 
b/docs/user-manual/configuration-index.adoc
index 517f1acb3f..e90943b62a 100644
--- a/docs/user-manual/configuration-index.adoc
+++ b/docs/user-manual/configuration-index.adoc
@@ -565,7 +565,7 @@ In most cases this should be set to '1'.
 
 | internal-naming-prefix
 | the prefix used when naming the internal queues and addresses required for 
implementing certain behaviours.
-| `$.activemq.internal`
+| `$.activemq.internal.`
 
 | xref:security.adoc#tracking-the-validated-user[populate-validated-user]
 | whether or not to add the name of the validated user to the messages that 
user sends.
diff --git a/docs/user-manual/wildcard-syntax.adoc 
b/docs/user-manual/wildcard-syntax.adoc
index f55fc0d51d..308cedcbc0 100644
--- a/docs/user-manual/wildcard-syntax.adoc
+++ b/docs/user-manual/wildcard-syntax.adoc
@@ -3,7 +3,7 @@
 :idseparator: -
 :docinfo: shared
 
-{project-name-full} uses a specific syntax for representing wildcards in 
security settings, address settings and when creating consumers.
+{project-name-full} uses a specific syntax for representing wildcards in 
security settings, address settings, and when creating consumers.
 
 The syntax is similar to that used by https://www.amqp.org[AMQP].
 
@@ -72,3 +72,15 @@ For that, the `<wildcard-addresses>` configuration tag is 
used.
 ----
 
 The example above shows the default configuration.
+
+[NOTE]
+====
+It is technically _possible_ to use `$` as a custom wildcard character, but it 
is **not recommended** for three main reasons:
+
+. The default value of `internal-naming-prefix` is `$.activemq.internal.` 
which includes a `$` character.
+While this value can be changed, doing so may cause problems if, for example, 
you have already created a cluster while the default value was in use.
+In this case the broker will have already created store-and-forward resources 
that will have to be renamed manually.
+Similar problems exist with retroactive addresses.
+. AMQP federation and mirroring use `$` in the names of their internal 
resources.
+. The MQTT protocol uses `$` for certain bits of functionality (e.g. shared 
subscriptions) and this cannot be changed so MQTT functionality would need to 
be completely avoided.
+====


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact


Reply via email to