Skip to content

Commit

Permalink
[ISSUE #10380] Change Fuzzy Watch Pattern Rule (#11276)
Browse files Browse the repository at this point in the history
* change fuzzy watch service name pattern construct rule

* add namespaceId in fuzzy watch redo log
  • Loading branch information
Chionanthus authored Oct 23, 2023
1 parent 4be6f3e commit 6f5e20e
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 88 deletions.
13 changes: 2 additions & 11 deletions api/src/main/java/com/alibaba/nacos/api/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ public class Constants {

public static final String ALL_PATTERN = "*";

public static final String FUZZY_WATCH_PATTERN_WILDCARD = "*";

public static final String COLON = ":";

public static final String LINE_BREAK = "\n";
Expand Down Expand Up @@ -240,17 +242,6 @@ public static class Naming {
public static final String CMDB_CONTEXT_TYPE = "CMDB";
}

/**
* The constants in fuzzy watch pattern match rule directory.
*/
public static class FuzzyWatchMatchRule {

public static final String MATCH_ALL = "MATCH_ALL";

public static final String MATCH_PREFIX = "MATCH_PREFIX";

}

/**
* The constants in fuzzy watch event type directory.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,9 @@ void unsubscribe(String serviceName, String groupName, List<String> clusters, Ev
throws NacosException;

/**
* Watch a range of services by rule to receive notify events of matched services alteration.
* According to matching rules, watch services within a specific scope, and receive notifications when
* changes occur in the services within the scope.
* When given a fixed group name, watch changes in all services under this group.
*
* @param fixedGroupName fixed group name for fuzzy watch
* @param listener event listener
Expand All @@ -543,7 +545,10 @@ void unsubscribe(String serviceName, String groupName, List<String> clusters, Ev
void fuzzyWatch(String fixedGroupName, AbstractFuzzyWatchEventListener listener) throws NacosException;

/**
* Watch a range of services by rule to receive notify events of matched services alteration.
* According to matching rules, watch services within a specific scope, and receive notifications when
* changes occur in the services within the scope.
* When provided with a fixed group name and pattern of service name, watch changes in services under
* this group that match the specified pattern.
*
* @param serviceNamePattern service name pattern for fuzzy watch
* @param fixedGroupName fixed group name for fuzzy watch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.regex.Pattern;

import static com.alibaba.nacos.api.common.Constants.CLUSTER_NAME_PATTERN_STRING;
import static com.alibaba.nacos.api.common.Constants.FUZZY_WATCH_PATTERN_WILDCARD;
import static com.alibaba.nacos.api.common.Constants.NUMBER_PATTERN_STRING;

/**
Expand Down Expand Up @@ -209,68 +210,20 @@ public static String getPatternRemovedNamespace(String completedPattern) {

/**
* Get the pattern watched under given namespace id.
*
* @param namespaceId name space id
* @param completedPattern a set of all watch pattern(with namespace id)
* @param completedPatterns a set of all watched pattern(with namespace id)
* @return filtered pattern set
*/
public static Set<String> filterPatternWithNamespace(String namespaceId, Set<String> completedPattern) {
Set<String> patterns = new HashSet<>();
for (String each : completedPattern) {
String eachId = getNamespaceFromPattern(each);
if (namespaceId.equals(eachId)) {
patterns.add(getPatternRemovedNamespace(each));
public static Set<String> filterPatternWithNamespace(String namespaceId, Set<String> completedPatterns) {
Set<String> patternsOfGivenNamespace = new HashSet<>();
for (String each : completedPatterns) {
String nameSpaceOfPattern = getNamespaceFromPattern(each);
if (namespaceId.equals(nameSpaceOfPattern)) {
patternsOfGivenNamespace.add(getPatternRemovedNamespace(each));
}
}
return patterns;
}

/**
* Returns a combined string with matchPattern and matchType.
* @param matchPattern a match pattern. Such as a 'serviceNamePrefix'
* @param matchType The match type want to use
* @return grouped pattern like 'matchPattern##matchType'
*/
public static String getGroupedPattern(final String matchPattern, final String matchType) {
if (StringUtils.isBlank(matchPattern) && !matchType.equals(Constants.FuzzyWatchMatchRule.MATCH_ALL)) {
throw new IllegalArgumentException("Param 'matchPattern' is illegal, matchPattern is blank");
}
if (StringUtils.isBlank(matchType)) {
throw new IllegalArgumentException("Param 'matchType' is illegal, matchType is blank");
} else if (matchType.equals(Constants.FuzzyWatchMatchRule.MATCH_ALL)) {
return Constants.FuzzyWatchMatchRule.MATCH_ALL;
}
final String resultGroupedName = matchPattern + Constants.MATCH_PATTERN_SPLITER + matchType;
return resultGroupedName.intern();
}

/**
* Given a Pattern, return the string to be used for the match.
* @param groupedPattern a grouped pattern, format: [match string ## match type]
* @return the string to be used for the match.
*/
public static String getMatchName(String groupedPattern) {
if (StringUtils.isBlank(groupedPattern)) {
return StringUtils.EMPTY;
}
if (!groupedPattern.contains(Constants.MATCH_PATTERN_SPLITER)) {
return groupedPattern;
}
return groupedPattern.split(Constants.MATCH_PATTERN_SPLITER)[0];
}

/**
* Given a Pattern, return the matching rule type.
* @param groupedPattern a grouped pattern (match string ## match type)
* @return the matching rule type.
*/
public static String getMatchRule(String groupedPattern) {
if (StringUtils.isBlank(groupedPattern)) {
return StringUtils.EMPTY;
}
if (!groupedPattern.contains(Constants.MATCH_PATTERN_SPLITER)) {
return Constants.FuzzyWatchMatchRule.MATCH_ALL;
}
return groupedPattern.split(Constants.MATCH_PATTERN_SPLITER)[1];
return patternsOfGivenNamespace;
}

/**
Expand Down Expand Up @@ -318,6 +271,7 @@ public static Set<String> getPatternMatchedServices(Collection<String> servicesL

/**
* Given a service name and a pattern to match, determine whether it can match.
* TODO:If want to add a matching method, can implement in here.
*
* @param serviceName service name to judge
* @param groupName group name to judge
Expand All @@ -326,14 +280,13 @@ public static Set<String> getPatternMatchedServices(Collection<String> servicesL
* @return matching result
*/
public static boolean isMatchPattern(String serviceName, String groupName, String serviceNamePattern, String groupNamePattern) {
String serviceMatchName = getMatchName(serviceNamePattern);
String serviceMatchType = getMatchRule(serviceNamePattern);
// Only support prefix match or all match right now
// Only support prefix match or all match service name right now
// Only support fixed group name right now
if (serviceMatchType.equals(Constants.FuzzyWatchMatchRule.MATCH_ALL)) {
if (serviceNamePattern.equals(FUZZY_WATCH_PATTERN_WILDCARD)) {
return groupName.equals(groupNamePattern);
} else if (serviceMatchType.equals(Constants.FuzzyWatchMatchRule.MATCH_PREFIX)) {
return prefixMatchWithFixedGroupName(serviceName, serviceMatchName, groupName, getMatchName(groupNamePattern));
} else if (serviceNamePattern.endsWith(FUZZY_WATCH_PATTERN_WILDCARD)) {
String serviceMatchName = serviceNamePattern.substring(0, serviceNamePattern.length() - 1);
return prefixMatchWithFixedGroupName(serviceName, serviceMatchName, groupName, groupNamePattern);
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
import java.util.Properties;
import java.util.UUID;

import static com.alibaba.nacos.api.common.Constants.FUZZY_WATCH_PATTERN_WILDCARD;

/**
* Nacos Naming Service.
*
Expand Down Expand Up @@ -446,17 +448,22 @@ public void unsubscribe(String serviceName, String groupName, List<String> clust

@Override
public void fuzzyWatch(String fixedGroupName, AbstractFuzzyWatchEventListener listener) throws NacosException {
// pattern e.g. DEFAULT_GROUP@@MATCH_ALL
doFuzzyWatch(Constants.FuzzyWatchMatchRule.MATCH_ALL, fixedGroupName, listener);
doFuzzyWatch(FUZZY_WATCH_PATTERN_WILDCARD, fixedGroupName, listener);
}

@Override
public void fuzzyWatch(String serviceNamePattern, String fixedGroupName,
AbstractFuzzyWatchEventListener listener) throws NacosException {
// only support prefix match right now
// pattern e.g. DEFAULT_GROUP@@nacos.test##MATCH_PREFIX
String serviceNamePrefixPattern = NamingUtils.getGroupedPattern(serviceNamePattern, Constants.FuzzyWatchMatchRule.MATCH_PREFIX);
doFuzzyWatch(serviceNamePrefixPattern, fixedGroupName, listener);
if (!serviceNamePattern.endsWith(FUZZY_WATCH_PATTERN_WILDCARD)) {
if (serviceNamePattern.startsWith(FUZZY_WATCH_PATTERN_WILDCARD)) {
throw new UnsupportedOperationException("Suffix matching for service names is not supported yet."
+ " It will be supported in future updates if needed.");
} else {
throw new UnsupportedOperationException("Illegal service name pattern, please read the documentation and pass a valid pattern.");
}
}
doFuzzyWatch(serviceNamePattern, fixedGroupName, listener);
}

private void doFuzzyWatch(String serviceNamePattern, String groupNamePattern,
Expand All @@ -472,13 +479,12 @@ private void doFuzzyWatch(String serviceNamePattern, String groupNamePattern,

@Override
public void cancelFuzzyWatch(String fixedGroupName, AbstractFuzzyWatchEventListener listener) throws NacosException {
doCancelFuzzyWatch(Constants.FuzzyWatchMatchRule.MATCH_ALL, fixedGroupName, listener);
doCancelFuzzyWatch(FUZZY_WATCH_PATTERN_WILDCARD, fixedGroupName, listener);
}

@Override
public void cancelFuzzyWatch(String serviceNamePattern, String fixedGroupName, AbstractFuzzyWatchEventListener listener) throws NacosException {
String serviceNamePrefixPattern = NamingUtils.getGroupedPattern(serviceNamePattern, Constants.FuzzyWatchMatchRule.MATCH_PREFIX);
doCancelFuzzyWatch(serviceNamePrefixPattern, fixedGroupName, listener);
doCancelFuzzyWatch(serviceNamePattern, fixedGroupName, listener);
}

private void doCancelFuzzyWatch(String serviceNamePattern, String groupNamePattern,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,8 @@ private void shutDownAndRemove(String uuid) {
public boolean isEnable() {
return rpcClient.isRunning();
}

public String getNamespaceId() {
return namespaceId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ private void redoForFuzzyWatchers() {
try {
redoForFuzzyWatcher(each);
} catch (NacosException e) {
LogUtils.NAMING_LOGGER.error("Redo fuzzy watcher operation {} for pattern {}@@{} failed. ", each.getRedoType(),
each.getGroupName(), each.getServiceName(), e);
LogUtils.NAMING_LOGGER.error("Redo fuzzy watcher operation {} for pattern {}@@{} in namespace {} failed. ",
each.getRedoType(), each.getGroupName(), each.getServiceName(), clientProxy.getNamespaceId(), e);
}
}
}
Expand All @@ -156,7 +156,8 @@ private void redoForFuzzyWatcher(FuzzyWatcherRedoData redoData) throws NacosExce
RedoData.RedoType redoType = redoData.getRedoType();
String serviceNamePattern = redoData.getServiceName();
String groupNamePattern = redoData.getGroupName();
LogUtils.NAMING_LOGGER.info("Redo fuzzy watcher operation {} for pattern {}@@{}", redoType, groupNamePattern, serviceNamePattern);
LogUtils.NAMING_LOGGER.info("Redo fuzzy watcher operation {} for pattern {}@@{} in namespace {}", redoType,
groupNamePattern, serviceNamePattern, clientProxy.getNamespaceId());
switch (redoType) {
case REGISTER:
if (isClientDisabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void onEvent(FuzzyWatchNotifyEvent event) {
}
});

naming.fuzzyWatch("nacos.test", DEFAULT_GROUP, new AbstractFuzzyWatchEventListener() {
naming.fuzzyWatch("nacos.test.*", DEFAULT_GROUP, new AbstractFuzzyWatchEventListener() {

@Override
public Executor getExecutor() {
Expand Down

0 comments on commit 6f5e20e

Please sign in to comment.