Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traffic label transparent transmission plugin: optimize servicecomb server-side interception scenario #1310

Merged
merged 1 commit into from
Sep 18, 2023
Merged
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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
package com.huaweicloud.sermant.tag.transmission.interceptors.http.server;

import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager;
import com.huaweicloud.sermant.core.utils.StringUtils;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.config.strategy.TagKeyMatcher;
import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractServerInterceptor;
import com.huaweicloud.sermant.tag.transmission.service.ServiceCombHeaderParseService;

import java.util.Collections;
import java.util.Enumeration;
Expand All @@ -41,6 +44,11 @@ public class HttpServletInterceptor extends AbstractServerInterceptor<HttpServle
*/
protected static final ThreadLocal<Boolean> LOCK_MARK = new ThreadLocal<>();

private static final String SERVICECOMB_HEADER_KEY = "x-cse-context";

private static ServiceCombHeaderParseService parseService =
PluginServiceManager.getPluginService(ServiceCombHeaderParseService.class);

@Override
public ExecuteContext doBefore(ExecuteContext context) {
if (LOCK_MARK.get() != null) {
Expand Down Expand Up @@ -81,6 +89,27 @@ public ExecuteContext onThrow(ExecuteContext context) {
@Override
protected Map<String, List<String>> extractTrafficTagFromCarrier(HttpServletRequest httpServletRequest) {
Map<String, List<String>> tagMap = new HashMap<>();

// servicecomb场景,consumer端为servicecomb rpc,需从http的request中获取servicecomb的header字符串并解析
String serviceCombHeaderValue = httpServletRequest.getHeader(SERVICECOMB_HEADER_KEY);
if (!StringUtils.isBlank(serviceCombHeaderValue)) {
Map<String, String> headers = parseService.parseHeaderFromJson(serviceCombHeaderValue);
for (String key : headers.keySet()) {
if (!TagKeyMatcher.isMatch(key)) {
continue;
}
String value = headers.get(key);
if (value != null) {
tagMap.put(key, Collections.singletonList(value));
continue;
}

// 流量标签的value为null时,也需存入本地变量,覆盖原来的value,以防误用旧流量标签
tagMap.put(key, null);
}
}

// 常规http访问场景
Enumeration<String> keyEnumeration = httpServletRequest.getHeaderNames();
while (keyEnumeration.hasMoreElements()) {
String key = keyEnumeration.nextElement();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.service;

import com.huaweicloud.sermant.core.plugin.service.PluginService;

import java.util.Map;

/**
* 用于从http header的value中解析json字符串为rpc服务的header
*
* @author daizhenyu
* @since 2023-09-14
**/
public interface ServiceCombHeaderParseService extends PluginService {
/**
* 将json字符串解析为rpc服务 的header
*
* @param header Json字符串
* @return rpc服务 的header
*/
Map<String, String> parseHeaderFromJson(String header);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ com.huaweicloud.sermant.tag.transmission.declarers.rpc.sofarpc.SofaRpcServerDecl
com.huaweicloud.sermant.tag.transmission.declarers.rpc.grpc.GrpcServerDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.rpc.grpc.ClientCallImplDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.rpc.servicecomb.ServiceCombRpcConsumerDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.rpc.servicecomb.ServiceCombRpcProviderDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.mq.kafka.KafkaProducerDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.http.client.httpclient.HttpClient3xDeclarer
com.huaweicloud.sermant.tag.transmission.declarers.http.client.okhttp.OkHttp2xDeclarer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@
package com.huaweicloud.sermant.tag.transmission.interceptors.http.server;

import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager;
import com.huaweicloud.sermant.core.utils.tag.TrafficUtils;
import com.huaweicloud.sermant.tag.transmission.interceptors.BaseInterceptorTest;
import com.huaweicloud.sermant.tag.transmission.service.ServiceCombHeaderParseService;

import org.apache.catalina.connector.Connector;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.tomcat.util.http.MimeHeaders;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import java.lang.reflect.Field;
import java.util.ArrayList;
Expand All @@ -40,11 +45,18 @@
* @since 2023-07-27
*/
public class HttpServletInterceptorTest extends BaseInterceptorTest {
private final ServiceCombHeaderParseService parseService = Mockito.mock(ServiceCombHeaderParseService.class);

private final HttpServletInterceptor interceptor;

private final Object[] arguments;

public MockedStatic<PluginServiceManager> pluginServiceManagerMockedStatic;

public HttpServletInterceptorTest() {
pluginServiceManagerMockedStatic = Mockito.mockStatic(PluginServiceManager.class);
pluginServiceManagerMockedStatic.when(() -> PluginServiceManager.getPluginService(ServiceCombHeaderParseService.class))
.thenReturn(parseService);
interceptor = new HttpServletInterceptor();
arguments = new Object[2];
}
Expand Down Expand Up @@ -103,4 +115,9 @@ public ExecuteContext buildContext(Map<String, List<String>> addHeaders)
arguments[0] = new RequestFacade(request);
return ExecuteContext.forMemberMethod(new Object(), null, arguments, null, null);
}

@After
public void afterTest() {
pluginServiceManagerMockedStatic.close();
}
}
Loading