ARTEMIS-1422 Fix match change to support wildcard config
This commit is contained in:
parent
533797fbc4
commit
e9eaa7daf6
|
@ -392,7 +392,7 @@ public final class XmlDataExporter extends OptionalLocking {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(storageManager, config.getPagingLocation(), 1000L, scheduled, executorFactory, true, null);
|
PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(storageManager, config.getPagingLocation(), 1000L, scheduled, executorFactory, true, null);
|
||||||
HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<>();
|
HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<>(config.getWildcardConfiguration());
|
||||||
addressSettingsRepository.setDefault(new AddressSettings());
|
addressSettingsRepository.setDefault(new AddressSettings());
|
||||||
PagingManager manager = new PagingManagerImpl(pageStoreFactory, addressSettingsRepository);
|
PagingManager manager = new PagingManagerImpl(pageStoreFactory, addressSettingsRepository);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class WildcardConfiguration implements Serializable {
|
||||||
|
|
||||||
static final char DELIMITER = '.';
|
static final char DELIMITER = '.';
|
||||||
|
|
||||||
boolean enabled = true;
|
boolean routingEnabled = true;
|
||||||
|
|
||||||
char singleWord = SINGLE_WORD;
|
char singleWord = SINGLE_WORD;
|
||||||
|
|
||||||
|
@ -34,6 +34,13 @@ public class WildcardConfiguration implements Serializable {
|
||||||
|
|
||||||
char delimiter = DELIMITER;
|
char delimiter = DELIMITER;
|
||||||
|
|
||||||
|
String singleWordString = String.valueOf(singleWord);
|
||||||
|
|
||||||
|
String anyWordsString = String.valueOf(anyWords);
|
||||||
|
|
||||||
|
String delimiterString = String.valueOf(delimiter);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
@ -41,7 +48,7 @@ public class WildcardConfiguration implements Serializable {
|
||||||
|
|
||||||
WildcardConfiguration that = (WildcardConfiguration) o;
|
WildcardConfiguration that = (WildcardConfiguration) o;
|
||||||
|
|
||||||
if (enabled != that.enabled) return false;
|
if (routingEnabled != that.routingEnabled) return false;
|
||||||
if (singleWord != that.singleWord) return false;
|
if (singleWord != that.singleWord) return false;
|
||||||
if (anyWords != that.anyWords) return false;
|
if (anyWords != that.anyWords) return false;
|
||||||
return delimiter == that.delimiter;
|
return delimiter == that.delimiter;
|
||||||
|
@ -50,7 +57,7 @@ public class WildcardConfiguration implements Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = (enabled ? 1 : 0);
|
int result = (routingEnabled ? 1 : 0);
|
||||||
result = 31 * result + (int) singleWord;
|
result = 31 * result + (int) singleWord;
|
||||||
result = 31 * result + (int) anyWords;
|
result = 31 * result + (int) anyWords;
|
||||||
result = 31 * result + (int) delimiter;
|
result = 31 * result + (int) delimiter;
|
||||||
|
@ -60,43 +67,59 @@ public class WildcardConfiguration implements Serializable {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "WildcardConfiguration{" +
|
return "WildcardConfiguration{" +
|
||||||
"anyWords=" + anyWords +
|
"routingEnabled=" + routingEnabled +
|
||||||
", enabled=" + enabled +
|
", anyWords=" + anyWords +
|
||||||
", singleWord=" + singleWord +
|
", singleWord=" + singleWord +
|
||||||
", delimiter=" + delimiter +
|
", delimiter=" + delimiter +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isRoutingEnabled() {
|
||||||
return enabled;
|
return routingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
public void setRoutingEnabled(boolean routingEnabled) {
|
||||||
this.enabled = enabled;
|
this.routingEnabled = routingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char getAnyWords() {
|
public char getAnyWords() {
|
||||||
return anyWords;
|
return anyWords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAnyWordsString() {
|
||||||
|
return anyWordsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setAnyWords(char anyWords) {
|
public void setAnyWords(char anyWords) {
|
||||||
this.anyWords = anyWords;
|
this.anyWords = anyWords;
|
||||||
|
this.anyWordsString = String.valueOf(anyWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
public char getDelimiter() {
|
public char getDelimiter() {
|
||||||
return delimiter;
|
return delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDelimiterString() {
|
||||||
|
return delimiterString;
|
||||||
|
}
|
||||||
|
|
||||||
public void setDelimiter(char delimiter) {
|
public void setDelimiter(char delimiter) {
|
||||||
this.delimiter = delimiter;
|
this.delimiter = delimiter;
|
||||||
|
this.delimiterString = String.valueOf(delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public char getSingleWord() {
|
public char getSingleWord() {
|
||||||
return singleWord;
|
return singleWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSingleWordString() {
|
||||||
|
return singleWordString;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSingleWord(char singleWord) {
|
public void setSingleWord(char singleWord) {
|
||||||
this.singleWord = singleWord;
|
this.singleWord = singleWord;
|
||||||
|
this.singleWordString = String.valueOf(singleWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String convert(String filter, WildcardConfiguration to) {
|
public String convert(String filter, WildcardConfiguration to) {
|
||||||
|
|
|
@ -912,14 +912,14 @@ public class ConfigurationImpl implements Configuration, Serializable {
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean isWildcardRoutingEnabled() {
|
public boolean isWildcardRoutingEnabled() {
|
||||||
return wildcardConfiguration.isEnabled();
|
return wildcardConfiguration.isRoutingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public ConfigurationImpl setWildcardRoutingEnabled(final boolean enabled) {
|
public ConfigurationImpl setWildcardRoutingEnabled(final boolean enabled) {
|
||||||
logger.info("Usage of wildcardRoutingEnabled configuration property is deprecated, please use wildCardConfiguration.enabled instead");
|
logger.info("Usage of wildcardRoutingEnabled configuration property is deprecated, please use wildCardConfiguration.routingEnabled instead");
|
||||||
wildcardConfiguration.setEnabled(enabled);
|
wildcardConfiguration.setRoutingEnabled(enabled);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1764,14 +1764,13 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected void parseWildcardConfiguration(final Element e, final Configuration mainConfig) {
|
protected void parseWildcardConfiguration(final Element e, final Configuration mainConfig) {
|
||||||
WildcardConfiguration conf = new WildcardConfiguration();
|
WildcardConfiguration conf = mainConfig.getWildcardConfiguration();
|
||||||
|
|
||||||
conf.setDelimiter(getString(e, "delimiter", Character.toString(conf.getDelimiter()), Validators.NO_CHECK).charAt(0));
|
conf.setDelimiter(getString(e, "delimiter", Character.toString(conf.getDelimiter()), Validators.NO_CHECK).charAt(0));
|
||||||
conf.setAnyWords(getString(e, "any-words", Character.toString(conf.getAnyWords()), Validators.NO_CHECK).charAt(0));
|
conf.setAnyWords(getString(e, "any-words", Character.toString(conf.getAnyWords()), Validators.NO_CHECK).charAt(0));
|
||||||
conf.setSingleWord(getString(e, "single-word", Character.toString(conf.getSingleWord()), Validators.NO_CHECK).charAt(0));
|
conf.setSingleWord(getString(e, "single-word", Character.toString(conf.getSingleWord()), Validators.NO_CHECK).charAt(0));
|
||||||
conf.setEnabled(getBoolean(e, "enabled", conf.isEnabled()));
|
conf.setRoutingEnabled(getBoolean(e, "enabled", conf.isRoutingEnabled()));
|
||||||
|
conf.setRoutingEnabled(getBoolean(e, "routing-enabled", conf.isRoutingEnabled()));
|
||||||
mainConfig.setWildCardConfiguration(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConnectorServiceConfiguration parseConnectorService(final Element e) {
|
private ConnectorServiceConfiguration parseConnectorService(final Element e) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
|
||||||
|
|
||||||
this.reaperPriority = reaperPriority;
|
this.reaperPriority = reaperPriority;
|
||||||
|
|
||||||
if (wildcardConfiguration.isEnabled()) {
|
if (wildcardConfiguration.isRoutingEnabled()) {
|
||||||
addressManager = new WildcardAddressManager(this, wildcardConfiguration, storageManager);
|
addressManager = new WildcardAddressManager(this, wildcardConfiguration, storageManager);
|
||||||
} else {
|
} else {
|
||||||
addressManager = new SimpleAddressManager(this, wildcardConfiguration, storageManager);
|
addressManager = new SimpleAddressManager(this, wildcardConfiguration, storageManager);
|
||||||
|
|
|
@ -423,11 +423,11 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
||||||
|
|
||||||
this.securityManager = securityManager;
|
this.securityManager = securityManager;
|
||||||
|
|
||||||
addressSettingsRepository = new HierarchicalObjectRepository<>();
|
addressSettingsRepository = new HierarchicalObjectRepository<>(configuration.getWildcardConfiguration());
|
||||||
|
|
||||||
addressSettingsRepository.setDefault(new AddressSettings());
|
addressSettingsRepository.setDefault(new AddressSettings());
|
||||||
|
|
||||||
securityRepository = new HierarchicalObjectRepository<>();
|
securityRepository = new HierarchicalObjectRepository<>(configuration.getWildcardConfiguration());
|
||||||
|
|
||||||
securityRepository.setDefault(new HashSet<Role>());
|
securityRepository.setDefault(new HashSet<Role>());
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,9 @@ import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||||
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
|
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
|
||||||
import org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeListener;
|
import org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeListener;
|
||||||
|
@ -43,6 +45,7 @@ public class HierarchicalObjectRepository<T> implements HierarchicalRepository<T
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(HierarchicalObjectRepository.class);
|
private static final Logger logger = Logger.getLogger(HierarchicalObjectRepository.class);
|
||||||
|
|
||||||
|
private static final WildcardConfiguration DEFAULT_WILDCARD_CONFIGURATION = new WildcardConfiguration();
|
||||||
private boolean listenersEnabled = true;
|
private boolean listenersEnabled = true;
|
||||||
/**
|
/**
|
||||||
* The default Match to fall back to
|
* The default Match to fall back to
|
||||||
|
@ -66,7 +69,9 @@ public class HierarchicalObjectRepository<T> implements HierarchicalRepository<T
|
||||||
/**
|
/**
|
||||||
* a regex comparator
|
* a regex comparator
|
||||||
*/
|
*/
|
||||||
private final MatchComparator matchComparator = new MatchComparator();
|
private final MatchComparator matchComparator;
|
||||||
|
|
||||||
|
private final WildcardConfiguration wildcardConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a cache
|
* a cache
|
||||||
|
@ -94,6 +99,15 @@ public class HierarchicalObjectRepository<T> implements HierarchicalRepository<T
|
||||||
*/
|
*/
|
||||||
private final ArrayList<HierarchicalRepositoryChangeListener> listeners = new ArrayList<>();
|
private final ArrayList<HierarchicalRepositoryChangeListener> listeners = new ArrayList<>();
|
||||||
|
|
||||||
|
public HierarchicalObjectRepository() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HierarchicalObjectRepository(final WildcardConfiguration wildcardConfiguration) {
|
||||||
|
this.wildcardConfiguration = wildcardConfiguration == null ? DEFAULT_WILDCARD_CONFIGURATION : wildcardConfiguration;
|
||||||
|
this.matchComparator = new MatchComparator(this.wildcardConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disableListeners() {
|
public void disableListeners() {
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
|
@ -155,9 +169,8 @@ public class HierarchicalObjectRepository<T> implements HierarchicalRepository<T
|
||||||
if (immutableMatch) {
|
if (immutableMatch) {
|
||||||
immutables.add(match);
|
immutables.add(match);
|
||||||
}
|
}
|
||||||
Match.verify(match);
|
Match.verify(match, wildcardConfiguration);
|
||||||
Match<T> match1 = new Match<>(match);
|
Match<T> match1 = new Match<>(match, value, wildcardConfiguration);
|
||||||
match1.setValue(value);
|
|
||||||
matches.put(match, match1);
|
matches.put(match, match1);
|
||||||
} finally {
|
} finally {
|
||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
|
@ -381,25 +394,35 @@ public class HierarchicalObjectRepository<T> implements HierarchicalRepository<T
|
||||||
|
|
||||||
private static final long serialVersionUID = -6182535107518999740L;
|
private static final long serialVersionUID = -6182535107518999740L;
|
||||||
|
|
||||||
|
private final String quotedDelimiter;
|
||||||
|
private final String anyWords;
|
||||||
|
private final String singleWord;
|
||||||
|
|
||||||
|
MatchComparator(final WildcardConfiguration wildcardConfiguration) {
|
||||||
|
this.quotedDelimiter = Pattern.quote(wildcardConfiguration.getDelimiterString());
|
||||||
|
this.singleWord = wildcardConfiguration.getSingleWordString();
|
||||||
|
this.anyWords = wildcardConfiguration.getAnyWordsString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(final String o1, final String o2) {
|
public int compare(final String o1, final String o2) {
|
||||||
if (o1.contains(Match.WILDCARD) && !o2.contains(Match.WILDCARD)) {
|
if (o1.contains(anyWords) && !o2.contains(anyWords)) {
|
||||||
return +1;
|
return +1;
|
||||||
} else if (!o1.contains(Match.WILDCARD) && o2.contains(Match.WILDCARD)) {
|
} else if (!o1.contains(anyWords) && o2.contains(anyWords)) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (o1.contains(Match.WILDCARD) && o2.contains(Match.WILDCARD)) {
|
} else if (o1.contains(anyWords) && o2.contains(anyWords)) {
|
||||||
return o2.length() - o1.length();
|
return o2.length() - o1.length();
|
||||||
} else if (o1.contains(Match.WORD_WILDCARD) && !o2.contains(Match.WORD_WILDCARD)) {
|
} else if (o1.contains(singleWord) && !o2.contains(singleWord)) {
|
||||||
return +1;
|
return +1;
|
||||||
} else if (!o1.contains(Match.WORD_WILDCARD) && o2.contains(Match.WORD_WILDCARD)) {
|
} else if (!o1.contains(singleWord) && o2.contains(singleWord)) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (o1.contains(Match.WORD_WILDCARD) && o2.contains(Match.WORD_WILDCARD)) {
|
} else if (o1.contains(singleWord) && o2.contains(singleWord)) {
|
||||||
String[] leftSplits = o1.split("\\.");
|
String[] leftSplits = o1.split(quotedDelimiter);
|
||||||
String[] rightSplits = o2.split("\\.");
|
String[] rightSplits = o2.split(quotedDelimiter);
|
||||||
for (int i = 0; i < leftSplits.length; i++) {
|
for (int i = 0; i < leftSplits.length; i++) {
|
||||||
String left = leftSplits[i];
|
String left = leftSplits[i];
|
||||||
if (left.equals(Match.WORD_WILDCARD)) {
|
if (left.equals(singleWord)) {
|
||||||
if (rightSplits.length < i || !rightSplits[i].equals(Match.WORD_WILDCARD)) {
|
if (rightSplits.length < i || !rightSplits[i].equals(singleWord)) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return +1;
|
return +1;
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.activemq.artemis.core.settings.impl;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle;
|
import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,68 +26,54 @@ import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle;
|
||||||
*/
|
*/
|
||||||
public class Match<T> {
|
public class Match<T> {
|
||||||
|
|
||||||
public static final String WORD_WILDCARD = "*";
|
|
||||||
|
|
||||||
private static final String WORD_WILDCARD_REPLACEMENT = "[^.]+";
|
|
||||||
|
|
||||||
public static final String WILDCARD = "#";
|
|
||||||
|
|
||||||
public static final String DOT_WILDCARD = ".#";
|
|
||||||
|
|
||||||
private static final String WILDCARD_REPLACEMENT = ".*";
|
private static final String WILDCARD_REPLACEMENT = ".*";
|
||||||
|
|
||||||
private static final String WILDCARD_CHILD_REPLACEMENT = "(\\..+)*";
|
private static final String WORD_WILDCARD_REPLACEMENT_FORMAT = "[^%s]+";
|
||||||
|
|
||||||
|
private static final String WILDCARD_CHILD_REPLACEMENT_FORMAT = "(%s.+)*";
|
||||||
|
|
||||||
private static final String DOT = ".";
|
private static final String DOT = ".";
|
||||||
|
|
||||||
private static final String DOT_REPLACEMENT = "\\.";
|
private static final String DOT_REPLACEMENT = "\\.";
|
||||||
|
|
||||||
private String match;
|
private final String match;
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
|
||||||
private T value;
|
private final T value;
|
||||||
|
|
||||||
public Match(final String match) {
|
public Match(final String match, final T value, final WildcardConfiguration wildcardConfiguration) {
|
||||||
this.match = match;
|
this.match = match;
|
||||||
|
this.value = value;
|
||||||
String actMatch = match;
|
String actMatch = match;
|
||||||
// replace any regex characters
|
|
||||||
if (Match.WILDCARD.equals(match)) {
|
if (wildcardConfiguration.getAnyWordsString().equals(match)) {
|
||||||
|
// replace any regex characters
|
||||||
actMatch = Match.WILDCARD_REPLACEMENT;
|
actMatch = Match.WILDCARD_REPLACEMENT;
|
||||||
} else {
|
} else {
|
||||||
// this is to match with what's documented
|
// this is to match with what's documented
|
||||||
actMatch = actMatch.replace(DOT_WILDCARD, WILDCARD);
|
actMatch = actMatch.replace(wildcardConfiguration.getDelimiterString() + wildcardConfiguration.getAnyWordsString(), wildcardConfiguration.getAnyWordsString());
|
||||||
|
|
||||||
actMatch = actMatch.replace(Match.DOT, Match.DOT_REPLACEMENT);
|
actMatch = actMatch.replace(Match.DOT, Match.DOT_REPLACEMENT);
|
||||||
actMatch = actMatch.replace(Match.WORD_WILDCARD, Match.WORD_WILDCARD_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
|
// this one has to be done by last as we are using .* and it could be replaced wrongly if delimiter is '.'
|
||||||
actMatch = actMatch.replace(Match.WILDCARD, Match.WILDCARD_CHILD_REPLACEMENT);
|
actMatch = actMatch.replace(wildcardConfiguration.getAnyWordsString(), String.format(WILDCARD_CHILD_REPLACEMENT_FORMAT, Pattern.quote(wildcardConfiguration.getDelimiterString())));
|
||||||
}
|
}
|
||||||
pattern = Pattern.compile(actMatch);
|
pattern = Pattern.compile(actMatch);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMatch() {
|
public final String getMatch() {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMatch(final String match) {
|
public final Pattern getPattern() {
|
||||||
this.match = match;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pattern getPattern() {
|
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getValue() {
|
public final T getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(final T value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
@ -114,11 +101,12 @@ public class Match<T> {
|
||||||
* @param match the match to validate
|
* @param match the match to validate
|
||||||
* @throws IllegalArgumentException if a match isn't valid
|
* @throws IllegalArgumentException if a match isn't valid
|
||||||
*/
|
*/
|
||||||
public static void verify(final String match) throws IllegalArgumentException {
|
public static void verify(final String match, final WildcardConfiguration wildcardConfiguration) throws IllegalArgumentException {
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
throw ActiveMQMessageBundle.BUNDLE.nullMatch();
|
throw ActiveMQMessageBundle.BUNDLE.nullMatch();
|
||||||
}
|
}
|
||||||
if (match.contains("#") && match.indexOf("#") < match.length() - 1) {
|
final String anyWords = wildcardConfiguration.getAnyWordsString();
|
||||||
|
if (match.contains(anyWords) && match.indexOf(anyWords) < match.length() - 1) {
|
||||||
throw ActiveMQMessageBundle.BUNDLE.invalidMatch();
|
throw ActiveMQMessageBundle.BUNDLE.invalidMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2940,7 +2940,14 @@
|
||||||
<xsd:element maxOccurs="1" minOccurs="0" name="enabled" type="xsd:boolean">
|
<xsd:element maxOccurs="1" minOccurs="0" name="enabled" type="xsd:boolean">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
are wildcard addresses enabled
|
deprecated please use routing-enabled.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="routing-enabled" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
is wildcard addresses routing enabled.
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
|
@ -107,13 +107,13 @@ public class FileConfigurationParserTest extends ActiveMQTestBase {
|
||||||
public void testWildcardConfiguration() throws Exception {
|
public void testWildcardConfiguration() throws Exception {
|
||||||
FileConfigurationParser parser = new FileConfigurationParser();
|
FileConfigurationParser parser = new FileConfigurationParser();
|
||||||
|
|
||||||
String configStr = firstPart + "<wildcard-addresses>\n<enabled>true</enabled>\n<delimiter>/</delimiter>\n<any-words>></any-words></wildcard-addresses>" + lastPart;
|
String configStr = firstPart + "<wildcard-addresses>\n<routing-enabled>true</routing-enabled>\n<delimiter>/</delimiter>\n<any-words>></any-words></wildcard-addresses>" + lastPart;
|
||||||
ByteArrayInputStream input = new ByteArrayInputStream(configStr.getBytes(StandardCharsets.UTF_8));
|
ByteArrayInputStream input = new ByteArrayInputStream(configStr.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
Configuration config = parser.parseMainConfig(input);
|
Configuration config = parser.parseMainConfig(input);
|
||||||
WildcardConfiguration wildCard = config.getWildcardConfiguration();
|
WildcardConfiguration wildCard = config.getWildcardConfiguration();
|
||||||
assertEquals('/', wildCard.getDelimiter());
|
assertEquals('/', wildCard.getDelimiter());
|
||||||
assertTrue(wildCard.isEnabled());
|
assertTrue(wildCard.isRoutingEnabled());
|
||||||
assertEquals('>', wildCard.getAnyWords());
|
assertEquals('>', wildCard.getAnyWords());
|
||||||
assertEquals('*', wildCard.getSingleWord());
|
assertEquals('*', wildCard.getSingleWord());
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
|
||||||
import org.apache.activemq.artemis.core.security.Role;
|
import org.apache.activemq.artemis.core.security.Role;
|
||||||
import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
|
import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
|
||||||
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
|
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
|
||||||
|
@ -64,6 +65,44 @@ public class RepositoryTest extends ActiveMQTestBase {
|
||||||
Assert.assertEquals("abd#", repo.getMatch("a.b.d"));
|
Assert.assertEquals("abd#", repo.getMatch("a.b.d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingDocsCustomUnderscorDelimiter() throws Throwable {
|
||||||
|
WildcardConfiguration wildcardConfiguration = new WildcardConfiguration();
|
||||||
|
wildcardConfiguration.setDelimiter('_');
|
||||||
|
HierarchicalObjectRepository<String> repo = new HierarchicalObjectRepository<>(wildcardConfiguration);
|
||||||
|
|
||||||
|
repo.addMatch("a_b_#", "ab#");
|
||||||
|
repo.addMatch("a_b_d_#", "abd#");
|
||||||
|
repo.addMatch("#", "root");
|
||||||
|
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a_b"));
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a_b_c"));
|
||||||
|
Assert.assertEquals("abd#", repo.getMatch("a_b_d_lll"));
|
||||||
|
Assert.assertEquals("root", repo.getMatch("z_z_z_z_z"));
|
||||||
|
Assert.assertEquals("root", repo.getMatch("a_babc"));
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a_b_dabc"));
|
||||||
|
Assert.assertEquals("abd#", repo.getMatch("a_b_d"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingDocsCustomForwardSlashDelimiter() throws Throwable {
|
||||||
|
WildcardConfiguration wildcardConfiguration = new WildcardConfiguration();
|
||||||
|
wildcardConfiguration.setDelimiter('/');
|
||||||
|
HierarchicalObjectRepository<String> repo = new HierarchicalObjectRepository<>(wildcardConfiguration);
|
||||||
|
|
||||||
|
repo.addMatch("a/b/#", "ab#");
|
||||||
|
repo.addMatch("a/b/d/#", "abd#");
|
||||||
|
repo.addMatch("#", "root");
|
||||||
|
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a/b"));
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a/b/c"));
|
||||||
|
Assert.assertEquals("abd#", repo.getMatch("a/b/d/lll"));
|
||||||
|
Assert.assertEquals("root", repo.getMatch("z/z/z/z/z"));
|
||||||
|
Assert.assertEquals("root", repo.getMatch("a/babc"));
|
||||||
|
Assert.assertEquals("ab#", repo.getMatch("a/b/dabc"));
|
||||||
|
Assert.assertEquals("abd#", repo.getMatch("a/b/d"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSingleMatch() {
|
public void testSingleMatch() {
|
||||||
securityRepository.addMatch("queues.*", new HashSet<Role>());
|
securityRepository.addMatch("queues.*", new HashSet<Role>());
|
||||||
|
|
|
@ -861,6 +861,14 @@
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
<xsd:element name="addresses" type="addressesType" maxOccurs="1" minOccurs="0" />
|
<xsd:element name="addresses" type="addressesType" maxOccurs="1" minOccurs="0" />
|
||||||
|
|
||||||
|
<xsd:element name="wildcard-addresses" type="wildcardType" maxOccurs="1" minOccurs="0">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Wildcard addresses format
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
</xsd:all>
|
</xsd:all>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
|
@ -2664,4 +2672,48 @@
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="wildcardType">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Complex type element to configure wildcard address format.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:all>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="enabled" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
deprecated please use routing-enabled.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="routing-enabled" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
is wildcard addresses routing enabled.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="delimiter" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
wildcard address parts delimiter. Default '.'
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="any-words" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
wildcard address any words character. Default '#'
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element maxOccurs="1" minOccurs="0" name="single-word" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
wildcard address single word character. Default '*'
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:all>
|
||||||
|
</xsd:complexType>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
|
|
@ -15,7 +15,7 @@ messages which are sent to a *hierarchy* of addresses.
|
||||||
This functionality is enabled by default. To turn it off add the following to the `broker.xml` configuration.
|
This functionality is enabled by default. To turn it off add the following to the `broker.xml` configuration.
|
||||||
|
|
||||||
<wildcard-addresses>
|
<wildcard-addresses>
|
||||||
<enabled>false</enabled>
|
<routing-enabled>false</routing-enabled>
|
||||||
</wildcard-addresses>
|
</wildcard-addresses>
|
||||||
|
|
||||||
For more information on the wild card syntax and how to configure it, take a look at [wildcard syntax](wildcard-syntax.md) chapter,
|
For more information on the wild card syntax and how to configure it, take a look at [wildcard syntax](wildcard-syntax.md) chapter,
|
||||||
|
|
|
@ -32,7 +32,7 @@ It's possible to further configure the syntax of the wildcard addresses using th
|
||||||
For that, the `<wildcard-addresses>` configuration tag is used.
|
For that, the `<wildcard-addresses>` configuration tag is used.
|
||||||
|
|
||||||
<wildcard-addresses>
|
<wildcard-addresses>
|
||||||
<enabled>true</enabled>
|
<routing-enabled>true</routing-enabled>
|
||||||
<delimiter>.</delimiter>
|
<delimiter>.</delimiter>
|
||||||
<any-words>#</any-words>
|
<any-words>#</any-words>
|
||||||
<single-word>*</single-word>
|
<single-word>*</single-word>
|
||||||
|
|
|
@ -111,7 +111,11 @@ under the License.
|
||||||
<config-delete-addresses>FORCE</config-delete-addresses>
|
<config-delete-addresses>FORCE</config-delete-addresses>
|
||||||
</address-setting>
|
</address-setting>
|
||||||
</address-settings>
|
</address-settings>
|
||||||
|
|
||||||
|
<wildcard-addresses>
|
||||||
|
<delimiter>_</delimiter>
|
||||||
|
</wildcard-addresses>
|
||||||
|
|
||||||
<addresses>
|
<addresses>
|
||||||
<address name="config_test_queue_removal">
|
<address name="config_test_queue_removal">
|
||||||
<multicast>
|
<multicast>
|
||||||
|
|
|
@ -115,6 +115,10 @@ under the License.
|
||||||
</address-setting>
|
</address-setting>
|
||||||
</address-settings>
|
</address-settings>
|
||||||
|
|
||||||
|
<wildcard-addresses>
|
||||||
|
<delimiter>_</delimiter>
|
||||||
|
</wildcard-addresses>
|
||||||
|
|
||||||
<addresses>
|
<addresses>
|
||||||
<address name="config_test_queue_removal">
|
<address name="config_test_queue_removal">
|
||||||
<multicast>
|
<multicast>
|
||||||
|
|
Loading…
Reference in New Issue