Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public final class TsfMetadataConstants {
*/
public static final String TSF_PREFER_IPV6 = "TSF_PREFER_IPV6";

/**
* tsf service tag operator.
*/
public static final String TSF_SERVICE_TAG_OPERATOR = "TSF_SERVICE_TAG_OPERATOR";

private TsfMetadataConstants() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.tencent.polaris.api.exception.PolarisException;
import com.tencent.polaris.api.plugin.cache.FlowCache;
import com.tencent.polaris.api.plugin.compose.Extensions;
import com.tencent.polaris.api.plugin.route.RouterConstants;
import com.tencent.polaris.api.plugin.route.RoutingUtils;
import com.tencent.polaris.api.pojo.*;
import com.tencent.polaris.api.rpc.RequestBaseEntity;
Expand Down Expand Up @@ -88,7 +89,7 @@ public FaultResponse fault(FaultRequest faultRequest) throws PolarisException {
LOG.debug("FaultInjectionProto.FaultInjection:{}", faultInjection);

// 匹配source规则
boolean sourceMatched = matchSource(faultInjection.getSourcesList(),
boolean sourceMatched = matchSource(faultInjection,
faultRequest.getSourceService(), faultRequest.getMetadataContext().getMetadataContainerGroup(false));
if (!sourceMatched) {
LOG.debug("Source not matched, skipping fault injection. FaultInjectionProto.FaultInjection:{}", faultInjection);
Expand Down Expand Up @@ -158,23 +159,33 @@ public List<FaultInjectionProto.FaultInjection> getFaultInjectionRules(ServiceKe
/**
* 匹配source规则
*/
private boolean matchSource(List<RoutingProto.Source> sources, Service sourceService, MetadataContainerGroup metadataContainerGroup) {
private boolean matchSource(FaultInjectionProto.FaultInjection faultInjection, Service sourceService, MetadataContainerGroup metadataContainerGroup) {
List<RoutingProto.Source> sources = faultInjection.getSourcesList();

if (CollectionUtils.isEmpty(sources)) {
return true;
}
boolean tsfSourcesMatchMode = faultInjection.containsMetadata(RouterConstants.TSF_SOURCES_MATCH_MODE);
// source匹配成功标志
boolean matched = true;
for (RoutingProto.Source source : sources) {
// 匹配source服务
matched = RoutingUtils.matchSourceService(source, sourceService);
if (!matched) {
if (tsfSourcesMatchMode) {
break;
}
continue;
}
// 匹配source metadata
matched = RoutingUtils.matchSourceMetadata(source, sourceService, metadataContainerGroup,
key -> getFlowCache().loadPluginCacheObject(API_ID, key, path -> TrieUtil.buildSimpleApiTrieNode((String) path)));
if (matched) {
break;
if (tsfSourcesMatchMode) {
if (!matched) {
return false;
}
} else if (matched) {
return true;
}
}
return matched;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

public interface RouterConstants {

// TSF sources match mode
String TSF_SOURCES_MATCH_MODE = "tsf-sources-match-mode";

//set路由
String SET_ENABLE_KEY = "internal-enable-set";
String SET_NAME_KEY = "internal-set-name";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import com.tencent.polaris.api.utils.MapUtils;
import com.tencent.polaris.api.utils.RuleUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.metadata.core.constant.TsfMetadataConstants;
import com.tencent.polaris.metadata.core.manager.MetadataContainerGroup;
import com.tencent.polaris.specification.api.v1.model.ModelProto;
import com.tencent.polaris.specification.api.v1.traffic.manage.RoutingProto;

import java.util.HashMap;
Expand All @@ -49,34 +51,62 @@ public static boolean matchSourceService(RoutingProto.Source ruleSource, Service
.equals(ruleSource.getService().getValue())) {
return false;
}
return true;
} else {
// 如果有source服务信息, 需要匹配服务信息
// 如果命名空间|服务不为"*"且不等于原服务, 则匹配失败
String namespace = ruleSource.getNamespace().getValue();
if (!RuleUtils.MATCH_ALL.equals(namespace)
&& !StringUtils.equals(namespace, targetSourceService.getNamespace())) {
return false;
if (ruleSource.containsMetadata(TsfMetadataConstants.TSF_SERVICE_TAG_OPERATOR)) {
ModelProto.MatchString.MatchStringType matchType = ruleSource.getMetadataMap().get(TsfMetadataConstants.TSF_SERVICE_TAG_OPERATOR).getType();
return matchTsfSourceService(matchType, ruleSource, targetSourceService);
} else {
return matchPolarisSourceService(ruleSource, targetSourceService);
}
String service = ruleSource.getService().getValue();
if (!RuleUtils.MATCH_ALL.equals(service) && !StringUtils.startsWith(service, "!")
&& !StringUtils.startsWith(service, "*")
&& !StringUtils.equals(service, targetSourceService.getService())) {
}
}

private static boolean matchTsfSourceService(ModelProto.MatchString.MatchStringType matchType, RoutingProto.Source ruleSource, Service targetSourceService) {
// 如果有source服务信息, 需要匹配服务信息
// 如果命名空间|服务不为"*"且不等于原服务, 则匹配失败
String namespace = ruleSource.getNamespace().getValue();
if (!RuleUtils.MATCH_ALL.equals(namespace)
&& !StringUtils.equals(namespace, targetSourceService.getNamespace())) {
switch (matchType) {
case NOT_EQUALS:
case NOT_IN:
return true;
default:
return false;
}
// 如果服务名不等于“*”,且服务名规则以“!”开头,则使用取反匹配
if (!RuleUtils.MATCH_ALL.equals(service) && StringUtils.startsWith(service, "!")) {
String realService = StringUtils.substring(service, 1);
if (StringUtils.equals(realService, targetSourceService.getService())) {
return false;
}
}
return RuleUtils.matchStringValue(matchType, targetSourceService.getService(),
ruleSource.getService().getValue());
}

private static boolean matchPolarisSourceService(RoutingProto.Source ruleSource, Service targetSourceService) {
// 如果有source服务信息, 需要匹配服务信息
// 如果命名空间|服务不为"*"且不等于原服务, 则匹配失败
String namespace = ruleSource.getNamespace().getValue();
if (!RuleUtils.MATCH_ALL.equals(namespace)
&& !StringUtils.equals(namespace, targetSourceService.getNamespace())) {
return false;
}
String service = ruleSource.getService().getValue();
if (!RuleUtils.MATCH_ALL.equals(service) && !StringUtils.startsWith(service, "!")
&& !StringUtils.startsWith(service, "*")
&& !StringUtils.equals(service, targetSourceService.getService())) {
return false;
}
// 如果服务名不等于“*”,且服务名规则以“!”开头,则使用取反匹配
if (!RuleUtils.MATCH_ALL.equals(service) && StringUtils.startsWith(service, "!")) {
String realService = StringUtils.substring(service, 1);
if (StringUtils.equals(realService, targetSourceService.getService())) {
return false;
}
// 如果服务名不等于“*”,且服务名规则以“*”开头,则使用正则匹配
if (!RuleUtils.MATCH_ALL.equals(service) && StringUtils.startsWith(service, "*")) {
String regex = StringUtils.substring(service, 1);
Pattern pattern = Pattern.compile(regex);
if (!pattern.matcher(targetSourceService.getService()).find()) {
return false;
}
}
// 如果服务名不等于“*”,且服务名规则以“*”开头,则使用正则匹配
if (!RuleUtils.MATCH_ALL.equals(service) && StringUtils.startsWith(service, "*")) {
String regex = StringUtils.substring(service, 1);
Pattern pattern = Pattern.compile(regex);
if (!pattern.matcher(targetSourceService.getService()).find()) {
return false;
}
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.tencent.polaris.api.exception.PolarisException;
import com.tencent.polaris.api.exception.ServerCodes;
import com.tencent.polaris.api.exception.ServerErrorResponseException;
import com.tencent.polaris.api.plugin.route.RouterConstants;
import com.tencent.polaris.api.plugin.server.ServerEvent;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.logging.LoggerFactory;
Expand Down Expand Up @@ -196,6 +197,7 @@ private List<FaultInjectionProto.FaultInjection> parseResponse(final HttpRespons
continue;
}
FaultInjectionProto.FaultInjection.Builder faultInjectionBuilder = FaultInjectionProto.FaultInjection.newBuilder();
faultInjectionBuilder.putMetadata(RouterConstants.TSF_SOURCES_MATCH_MODE, "true");
// parse sources
List<RoutingProto.Source> sources = RouterUtils.parseTagListToSourceList(routeRule.getTagList());
faultInjectionBuilder.addAllSources(sources);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.tencent.polaris.api.exception.PolarisException;
import com.tencent.polaris.api.exception.ServerCodes;
import com.tencent.polaris.api.exception.ServerErrorResponseException;
import com.tencent.polaris.api.plugin.route.RouterConstants;
import com.tencent.polaris.api.plugin.server.ServerEvent;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.logging.LoggerFactory;
Expand Down Expand Up @@ -202,7 +203,7 @@ private List<TrafficMirroringProto.TrafficMirroring> parseResponse(final HttpRes

// parse enabled
trafficMirroringBuilder.setEnabled(BoolValue.of(mirrorRule.getEnabled()));

trafficMirroringBuilder.putMetadata(RouterConstants.TSF_SOURCES_MATCH_MODE, "true");
// parse sources
List<RoutingProto.Source> sources = RouterUtils.parseTagListToSourceList(routeRule.getTagList());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@

import com.google.protobuf.StringValue;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.RuleUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.metadata.core.constant.TsfMetadataConstants;
import com.tencent.polaris.plugins.connector.consul.service.common.TagConditionUtil;
import com.tencent.polaris.plugins.connector.consul.service.common.TagConstant;
import com.tencent.polaris.plugins.connector.consul.service.router.entity.RouteTag;
import com.tencent.polaris.specification.api.v1.model.ModelProto;
Expand All @@ -39,75 +42,56 @@ public class RouterUtils {
public static List<RoutingProto.Source> parseTagListToSourceList(List<RouteTag> tagList) {
List<RoutingProto.Source> sources = new ArrayList<>();
if (CollectionUtils.isNotEmpty(tagList)) {
List<RoutingProto.Source.Builder> sourceBuilders = new ArrayList<>();
List<RoutingProto.Source.Builder> metadataSourceBuilders = new ArrayList<>();
for (RouteTag routeTag : tagList) {
if (StringUtils.equals(routeTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_SERVICE_NAME)) {
String[] tagValues = routeTag.getTagValue().split(",");
for (String tagValue : tagValues) {
if (StringUtils.isNotEmpty(tagValue)) {
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
String serviceName = tagValue;
if (routeTag.getTagOperator().equals(TagConstant.OPERATOR.NOT_EQUAL) || routeTag.getTagOperator().equals(TagConstant.OPERATOR.NOT_IN)) {
serviceName = "!" + serviceName;
} else if (routeTag.getTagOperator().equals(TagConstant.OPERATOR.REGEX)) {
serviceName = "*" + serviceName;
}
sourceBuilder.setService(StringValue.of(serviceName));
sourceBuilders.add(sourceBuilder);
}
String tagValue = routeTag.getTagValue();
if (StringUtils.isNotEmpty(tagValue)) {
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
sourceBuilder.setService(StringValue.of(tagValue));

ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
matchStringBuilder.setType(TagConditionUtil.parseMatchStringType(routeTag.getTagOperator()));
sourceBuilder.putMetadata(TsfMetadataConstants.TSF_SERVICE_TAG_OPERATOR, matchStringBuilder.build());
// TSF 服务名匹配时无其他 metadata, 设置 *, 跳过 RuleUtils.matchMetadata
sourceBuilder.putMetadata(RuleUtils.MATCH_ALL, ModelProto.MatchString.newBuilder().build());

sources.add(sourceBuilder.build());
}
} else if (StringUtils.equals(routeTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_NAMESPACE_SERVICE_NAME)) {
String[] tagValues = routeTag.getTagValue().split(",");
for (String tagValue : tagValues) {
if (StringUtils.isNotEmpty(tagValue)) {
String[] split = tagValue.split("/");
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
String serviceName = tagValue;
if (split.length == 2) {
// namespace/service format
sourceBuilder.setNamespace(StringValue.of(split[0]));
serviceName = split[1];
}
if (routeTag.getTagOperator().equals(TagConstant.OPERATOR.NOT_EQUAL) || routeTag.getTagOperator().equals(TagConstant.OPERATOR.NOT_IN)) {
serviceName = "!" + serviceName;
} else if (routeTag.getTagOperator().equals(TagConstant.OPERATOR.REGEX)) {
serviceName = "*" + serviceName;
}
sourceBuilder.setService(StringValue.of(serviceName));
sourceBuilders.add(sourceBuilder);
String tagValue = routeTag.getTagValue();
if (StringUtils.isNotEmpty(tagValue)) {
String[] split = tagValue.split("/");
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
String serviceName = tagValue;
if (split.length == 2) {
// namespace/service format
sourceBuilder.setNamespace(StringValue.of(split[0]));
serviceName = split[1];
}
sourceBuilder.setService(StringValue.of(serviceName));

ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
matchStringBuilder.setType(TagConditionUtil.parseMatchStringType(routeTag.getTagOperator()));
sourceBuilder.putMetadata(TsfMetadataConstants.TSF_SERVICE_TAG_OPERATOR, matchStringBuilder.build());
// TSF 服务名匹配时无其他 metadata, 设置 *, 跳过 RuleUtils.matchMetadata
sourceBuilder.putMetadata(RuleUtils.MATCH_ALL, ModelProto.MatchString.newBuilder().build());

sources.add(sourceBuilder.build());
}
} else {
RoutingProto.Source.Builder metadataSourceBuilder = RoutingProto.Source.newBuilder();
metadataSourceBuilder.setNamespace(StringValue.of("*"));
metadataSourceBuilder.setService(StringValue.of("*"));
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
sourceBuilder.setService(StringValue.of("*"));
ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
matchStringBuilder.setType(parseMatchStringType(routeTag));
matchStringBuilder.setValue(StringValue.of(routeTag.getTagValue()));
matchStringBuilder.setValueType(ModelProto.MatchString.ValueType.TEXT);
String metadataKey = routeTag.getTagField();
metadataSourceBuilder.putMetadata(parseMetadataKey(metadataKey), matchStringBuilder.build());
metadataSourceBuilders.add(metadataSourceBuilder);
}
}
if (CollectionUtils.isNotEmpty(sourceBuilders)) {
for (RoutingProto.Source.Builder sourceBuilder : sourceBuilders) {
for (RoutingProto.Source.Builder metadataSourceBuilder : metadataSourceBuilders) {
sourceBuilder.putAllMetadata(metadataSourceBuilder.getMetadataMap());
}
sourceBuilder.putMetadata(parseMetadataKey(metadataKey), matchStringBuilder.build());
sources.add(sourceBuilder.build());
}
} else {
RoutingProto.Source.Builder sourceBuilder = RoutingProto.Source.newBuilder();
sourceBuilder.setNamespace(StringValue.of("*"));
sourceBuilder.setService(StringValue.of("*"));
for (RoutingProto.Source.Builder metadataSourceBuilder : metadataSourceBuilders) {
sourceBuilder.putAllMetadata(metadataSourceBuilder.getMetadataMap());
}
sources.add(sourceBuilder.build());
}
}
return sources;
Expand Down
Loading