This is an automated email from the ASF dual-hosted git repository. huangli pushed a commit to branch 4.9.2_dev_community in repository https://gitbox.apache.org/repos/asf/rocketmq.git
commit e70d8e46e159c8dc98c92ca8cb1bf0b5d53af08e Author: sunshuangcheng <[email protected]> AuthorDate: Mon Nov 22 11:25:11 2021 +0800 优化Topic和Group检查的性能,改变算法消除正则表达式匹配 --- .../org/apache/rocketmq/client/Validators.java | 52 ++++++---------------- .../org/apache/rocketmq/client/ValidatorsTest.java | 2 +- .../rocketmq/common/topic/TopicValidator.java | 45 ++++++++++++++----- 3 files changed, 47 insertions(+), 52 deletions(-) diff --git a/client/src/main/java/org/apache/rocketmq/client/Validators.java b/client/src/main/java/org/apache/rocketmq/client/Validators.java index cf5f078..0db55cc 100644 --- a/client/src/main/java/org/apache/rocketmq/client/Validators.java +++ b/client/src/main/java/org/apache/rocketmq/client/Validators.java @@ -17,8 +17,8 @@ package org.apache.rocketmq.client; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import static org.apache.rocketmq.common.topic.TopicValidator.isTopicOrGroupIllegal; + import org.apache.rocketmq.client.exception.MQClientException; import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.UtilAll; @@ -31,24 +31,10 @@ import org.apache.rocketmq.common.topic.TopicValidator; * Common Validator */ public class Validators { - public static final String VALID_PATTERN_STR = "^[%|a-zA-Z0-9_-]+$"; - public static final Pattern PATTERN = Pattern.compile(VALID_PATTERN_STR); public static final int CHARACTER_MAX_LENGTH = 255; public static final int TOPIC_MAX_LENGTH = 127; /** - * @return The resulting {@code String} - */ - public static String getGroupWithRegularExpression(String origin, String patternStr) { - Pattern pattern = Pattern.compile(patternStr); - Matcher matcher = pattern.matcher(origin); - while (matcher.find()) { - return matcher.group(0); - } - return null; - } - - /** * Validate group */ public static void checkGroup(String group) throws MQClientException { @@ -60,27 +46,15 @@ public class Validators { throw new MQClientException("the specified group is longer than group max length 255.", null); } - if (!regularExpressionMatcher(group, PATTERN)) { - throw new MQClientException(String.format( - "the specified group[%s] contains illegal characters, allowing only %s", group, - VALID_PATTERN_STR), null); - } - - } - /** - * @return <tt>true</tt> if, and only if, the entire origin sequence matches this matcher's pattern - */ - public static boolean regularExpressionMatcher(String origin, Pattern pattern) { - if (pattern == null) { - return true; + if (isTopicOrGroupIllegal(group)) { + throw new MQClientException(String.format( + "the specified group[%s] contains illegal characters, allowing only %s", group, + "^[%|a-zA-Z0-9_-]+$"), null); } - Matcher matcher = pattern.matcher(origin); - return matcher.matches(); } - public static void checkMessage(Message msg, DefaultMQProducer defaultMQProducer) - throws MQClientException { + public static void checkMessage(Message msg, DefaultMQProducer defaultMQProducer) throws MQClientException { if (null == msg) { throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL, "the message is null"); } @@ -112,16 +86,16 @@ public class Validators { throw new MQClientException("The specified topic is blank", null); } - if (!regularExpressionMatcher(topic, PATTERN)) { - throw new MQClientException(String.format( - "The specified topic[%s] contains illegal characters, allowing only %s", topic, - VALID_PATTERN_STR), null); - } - if (topic.length() > TOPIC_MAX_LENGTH) { throw new MQClientException( String.format("The specified topic is longer than topic max length %d.", TOPIC_MAX_LENGTH), null); } + + if (isTopicOrGroupIllegal(topic)) { + throw new MQClientException(String.format( + "The specified topic[%s] contains illegal characters, allowing only %s", topic, + "^[%|a-zA-Z0-9_-]+$"), null); + } } public static void isSystemTopic(String topic) throws MQClientException { diff --git a/client/src/test/java/org/apache/rocketmq/client/ValidatorsTest.java b/client/src/test/java/org/apache/rocketmq/client/ValidatorsTest.java index 343fe4b..aa448dc 100644 --- a/client/src/test/java/org/apache/rocketmq/client/ValidatorsTest.java +++ b/client/src/test/java/org/apache/rocketmq/client/ValidatorsTest.java @@ -44,7 +44,7 @@ public class ValidatorsTest { Validators.checkTopic(illegalTopic); failBecauseExceptionWasNotThrown(MQClientException.class); } catch (MQClientException e) { - assertThat(e).hasMessageStartingWith(String.format("The specified topic[%s] contains illegal characters, allowing only %s", illegalTopic, Validators.VALID_PATTERN_STR)); + assertThat(e).hasMessageStartingWith(String.format("The specified topic[%s] contains illegal characters, allowing only %s", illegalTopic, "^[%|a-zA-Z0-9_-]+$")); } } diff --git a/common/src/main/java/org/apache/rocketmq/common/topic/TopicValidator.java b/common/src/main/java/org/apache/rocketmq/common/topic/TopicValidator.java index 7b0a839..5e67dc5 100644 --- a/common/src/main/java/org/apache/rocketmq/common/topic/TopicValidator.java +++ b/common/src/main/java/org/apache/rocketmq/common/topic/TopicValidator.java @@ -22,8 +22,6 @@ import org.apache.rocketmq.remoting.protocol.RemotingCommand; import java.util.HashSet; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class TopicValidator { @@ -38,9 +36,7 @@ public class TopicValidator { public static final String RMQ_SYS_OFFSET_MOVED_EVENT = "OFFSET_MOVED_EVENT"; public static final String SYSTEM_TOPIC_PREFIX = "rmq_sys_"; - - private static final String VALID_PATTERN_STR = "^[%|a-zA-Z0-9_-]+$"; - private static final Pattern PATTERN = Pattern.compile(VALID_PATTERN_STR); + public static final boolean[] VALID_CHAR_BIT_MAP = new boolean[128]; private static final int TOPIC_MAX_LENGTH = 127; private static final Set<String> SYSTEM_TOPIC_SET = new HashSet<String>(); @@ -62,14 +58,39 @@ public class TopicValidator { SYSTEM_TOPIC_SET.add(RMQ_SYS_OFFSET_MOVED_EVENT); NOT_ALLOWED_SEND_TOPIC_SET.add(RMQ_SYS_SCHEDULE_TOPIC); + + // regex:^[%|a-zA-Z0-9_-]+$ + // % + VALID_CHAR_BIT_MAP['%'] = true; + // - + VALID_CHAR_BIT_MAP['-'] = true; + // _ + VALID_CHAR_BIT_MAP['_'] = true; + for (int i = 0; i < VALID_CHAR_BIT_MAP.length; i++) { + if (i >= '0' && i <= '9') { + // 0-9 + VALID_CHAR_BIT_MAP[i] = true; + } else if (i >= 'A' && i <= 'Z') { + // A-Z + VALID_CHAR_BIT_MAP[i] = true; + } else if (i >= 'a' && i <= 'z') { + // a-z + VALID_CHAR_BIT_MAP[i] = true; + } + } } - private static boolean regularExpressionMatcher(String origin, Pattern pattern) { - if (pattern == null) { - return true; + public static boolean isTopicOrGroupIllegal(String str) { + int strLen = str.length(); + int len = VALID_CHAR_BIT_MAP.length; + boolean[] bitMap = VALID_CHAR_BIT_MAP; + for (int i = 0; i < strLen; i++) { + char ch = str.charAt(i); + if (ch >= len || !bitMap[ch]) { + return true; + } } - Matcher matcher = pattern.matcher(origin); - return matcher.matches(); + return false; } public static boolean validateTopic(String topic, RemotingCommand response) { @@ -80,9 +101,9 @@ public class TopicValidator { return false; } - if (!regularExpressionMatcher(topic, PATTERN)) { + if (isTopicOrGroupIllegal(topic)) { response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("The specified topic contains illegal characters, allowing only " + VALID_PATTERN_STR); + response.setRemark("The specified topic contains illegal characters, allowing only ^[%|a-zA-Z0-9_-]+$"); return false; }
