Skip to content

Commit

Permalink
Merge pull request #1297 from lilai23/tag_transmission
Browse files Browse the repository at this point in the history
流量标签透传特性:支持标签键的前缀后缀匹配方式
  • Loading branch information
Sherlockhan authored Sep 8, 2023
2 parents 98d9cad + 1e6f648 commit 64d7eeb
Show file tree
Hide file tree
Showing 28 changed files with 418 additions and 65 deletions.
10 changes: 8 additions & 2 deletions sermant-plugins/sermant-tag-transmission/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
tag.transmission.config:
# 是否开启流量标签透传
enabled: true
# 需要透传的流量标签的key
tagKeys: [id,name]
# 需要透传的流量标签的key的匹配规则, 支持等于、前缀、后缀匹配
matchRule:
# 精确匹配
exact: ["id", "name"]
# 前缀匹配
prefix: []
# 后缀匹配
suffix: []

# 跨线程传递标签的配置,该能力可单独使用
crossthread.config:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@

import com.huaweicloud.sermant.core.config.common.ConfigTypeKey;
import com.huaweicloud.sermant.core.plugin.config.PluginConfig;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.MapUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 流量标签透传配置
Expand All @@ -37,9 +38,9 @@ public class TagTransmissionConfig implements PluginConfig {
private boolean enabled;

/**
* 需要透传的标签的key
* 需要透传的标签的key的规则
*/
private List<String> tagKeys = new ArrayList<>();
private Map<String, List<String>> matchRule = new HashMap<>();

public boolean isEnabled() {
return enabled;
Expand All @@ -49,23 +50,23 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public List<String> getTagKeys() {
return tagKeys;
}

public void setTagKeys(List<String> tagKeys) {
this.tagKeys = tagKeys;
}

public boolean isEffect() {
return enabled && !CollectionUtils.isEmpty(tagKeys);
return enabled && !MapUtils.isEmpty(matchRule);
}

@Override
public String toString() {
return "TagTransmissionConfig{"
+ "enabled=" + enabled
+ ", tagKeys=" + tagKeys
+ ", matchRule=" + matchRule
+ '}';
}

public Map<String, List<String>> getMatchRule() {
return matchRule;
}

public void setMatchRule(Map<String, List<String>> matchRule) {
this.matchRule = matchRule;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.huaweicloud.sermant.tag.transmission.config.strategy;

import java.util.List;

/**
* 精确匹配策略
*
* @author lilai
* @since 2023-09-07
*/
public class ExactMatchStrategy implements MatchStrategy {
@Override
public boolean isMatch(String key, List<String> keyConfigs) {
return keyConfigs.stream().anyMatch(key::equals);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.huaweicloud.sermant.tag.transmission.config.strategy;

import java.util.List;

/**
* 需要透传的key的匹配策略接口
*
* @author lilai
* @since 2023-09-07
*/
public interface MatchStrategy {
/**
* 请求中或线程变量中的key是否匹配配置中要透传的规则
*
* @param key 被匹配的键
* @param keyConfigs key的匹配配置
* @return 匹配结果
*/
boolean isMatch(String key, List<String> keyConfigs);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.huaweicloud.sermant.tag.transmission.config.strategy;

import java.util.List;

/**
* 前缀匹配策略
*
* @author lilai
* @since 2023-09-07
*/
public class PrefixMatchStrategy implements MatchStrategy {
@Override
public boolean isMatch(String key, List<String> keyConfigs) {
return keyConfigs.stream().anyMatch(key::startsWith);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.huaweicloud.sermant.tag.transmission.config.strategy;

import java.util.List;

/**
* 后缀匹配策略
*
* @author lilai
* @since 2023-09-07
*/
public class SuffixMatchStrategy implements MatchStrategy {
@Override
public boolean isMatch(String key, List<String> keyConfigs) {
return keyConfigs.stream().anyMatch(key::endsWith);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.huaweicloud.sermant.tag.transmission.config.strategy;

import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager;
import com.huaweicloud.sermant.tag.transmission.config.TagTransmissionConfig;

import java.util.HashMap;
import java.util.Map;

/**
* 流量标签是否需要透传的匹配器
*
* @author lilai
* @since 2023-09-07
*/
public class TagKeyMatcher {
private static final Map<String, MatchStrategy> STRATEGY_MAP = new HashMap<>();

private static final TagTransmissionConfig CONFIG = PluginConfigManager.getPluginConfig(
TagTransmissionConfig.class);

private static final String EXACT_RULE_KEY = "exact";

private static final String PREFIX_RULE_KEY = "prefix";

private static final String SUFFIX_RULE_KEY = "suffix";

static {
STRATEGY_MAP.put(EXACT_RULE_KEY, new ExactMatchStrategy());
STRATEGY_MAP.put(PREFIX_RULE_KEY, new PrefixMatchStrategy());
STRATEGY_MAP.put(SUFFIX_RULE_KEY, new SuffixMatchStrategy());
}

private TagKeyMatcher() {
}

/**
* 是否匹配配置中需要透传的key的规则
*
* @param key 被匹配的key
* @return 匹配结果
*/
public static boolean isMatch(String key) {
for (String rule : CONFIG.getMatchRule().keySet()) {
MatchStrategy matchStrategy = STRATEGY_MAP.get(rule);
if (matchStrategy.isMatch(key, CONFIG.getMatchRule().get(rule))) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.config.strategy.TagKeyMatcher;
import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractClientInterceptor;

import org.apache.commons.httpclient.HttpMethod;
Expand Down Expand Up @@ -54,9 +55,13 @@ public ExecuteContext doAfter(ExecuteContext context) {
*/
@Override
protected void injectTrafficTag2Carrier(HttpMethod httpMethod) {
for (String key : tagTransmissionConfig.getTagKeys()) {
for (String key : TrafficUtils.getTrafficTag().getTag().keySet()) {
if (!TagKeyMatcher.isMatch(key)) {
continue;
}
List<String> values = TrafficUtils.getTrafficTag().getTag().get(key);
if (CollectionUtils.isEmpty(values)) {
httpMethod.setRequestHeader(key, null);
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.config.strategy.TagKeyMatcher;
import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractClientInterceptor;

import org.apache.http.HttpRequest;
Expand Down Expand Up @@ -54,9 +55,13 @@ public ExecuteContext doAfter(ExecuteContext context) {
*/
@Override
protected void injectTrafficTag2Carrier(HttpRequest httpRequest) {
for (String key : tagTransmissionConfig.getTagKeys()) {
for (String key : TrafficUtils.getTrafficTag().getTag().keySet()) {
if (!TagKeyMatcher.isMatch(key)) {
continue;
}
List<String> values = TrafficUtils.getTrafficTag().getTag().get(key);
if (CollectionUtils.isEmpty(values)) {
httpRequest.addHeader(key, null);
continue;
}
for (String value : values) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.config.strategy.TagKeyMatcher;
import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractClientInterceptor;

import sun.net.www.MessageHeader;
Expand Down Expand Up @@ -72,9 +73,13 @@ public ExecuteContext onThrow(ExecuteContext context) {
*/
@Override
protected void injectTrafficTag2Carrier(MessageHeader messageHeader) {
for (String key : tagTransmissionConfig.getTagKeys()) {
for (String key : TrafficUtils.getTrafficTag().getTag().keySet()) {
if (!TagKeyMatcher.isMatch(key)) {
continue;
}
List<String> values = TrafficUtils.getTrafficTag().getTag().get(key);
if (CollectionUtils.isEmpty(values)) {
messageHeader.add(key, null);
continue;
}
for (String value : values) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.config.strategy.TagKeyMatcher;
import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractClientInterceptor;

import com.squareup.okhttp.Request.Builder;
Expand Down Expand Up @@ -63,9 +64,13 @@ public ExecuteContext doAfter(ExecuteContext context) {
*/
@Override
protected void injectTrafficTag2Carrier(Builder builder) {
for (String key : tagTransmissionConfig.getTagKeys()) {
for (String key : TrafficUtils.getTrafficTag().getTag().keySet()) {
if (!TagKeyMatcher.isMatch(key)) {
continue;
}
List<String> values = TrafficUtils.getTrafficTag().getTag().get(key);
if (CollectionUtils.isEmpty(values)) {
builder.addHeader(key, null);
continue;
}
for (String value : values) {
Expand Down
Loading

0 comments on commit 64d7eeb

Please sign in to comment.