diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/pom.xml b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/pom.xml index bf999bed07..c07dc8fa63 100644 --- a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/pom.xml +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/pom.xml @@ -27,6 +27,7 @@ 3.2.0 2.6.12 5.4.0 + 2.6.0 @@ -89,6 +90,12 @@ ${sofa-rpc.version} provided + + org.apache.servicecomb + java-chassis-core + ${servicecomb-java-chassis.version} + provided + junit junit diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcConsumerDeclarer.java b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcConsumerDeclarer.java new file mode 100644 index 0000000000..2fd7ce9018 --- /dev/null +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcConsumerDeclarer.java @@ -0,0 +1,46 @@ +/* + * 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.declarers.rpc.servicecomb; + +import com.huaweicloud.sermant.core.plugin.agent.declarer.AbstractPluginDeclarer; +import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer; +import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher; +import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher; +import com.huaweicloud.sermant.tag.transmission.interceptors.rpc.servicecomb.ServiceCombRpcConsumerInterceptor; + +/** + * servicecombRPC consumer端declarer,支持servicecomb2.x版本 + * + * @author daizhenyu + * @since 2023-08-26 + **/ +public class ServiceCombRpcConsumerDeclarer extends AbstractPluginDeclarer { + private static final String ENHANCE_CLASS = "org.apache.servicecomb.core.handler.impl.TransportClientHandler"; + + private static final String METHOD_NAME = "handle"; + + @Override + public ClassMatcher getClassMatcher() { + return ClassMatcher.nameEquals(ENHANCE_CLASS); + } + + @Override + public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) { + return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(METHOD_NAME), + new ServiceCombRpcConsumerInterceptor())}; + } +} diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcProviderDeclarer.java b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcProviderDeclarer.java new file mode 100644 index 0000000000..45a712a19b --- /dev/null +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/declarers/rpc/servicecomb/ServiceCombRpcProviderDeclarer.java @@ -0,0 +1,46 @@ +/* + * 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.declarers.rpc.servicecomb; + +import com.huaweicloud.sermant.core.plugin.agent.declarer.AbstractPluginDeclarer; +import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer; +import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher; +import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher; +import com.huaweicloud.sermant.tag.transmission.interceptors.rpc.servicecomb.ServiceCombRpcProviderInterceptor; + +/** + * servicecombRPC provider端declarer,支持servicecomb2.x版本 + * + * @author daizhenyu + * @since 2023-08-26 + **/ +public class ServiceCombRpcProviderDeclarer extends AbstractPluginDeclarer { + private static final String ENHANCE_CLASS = "org.apache.servicecomb.core.handler.impl.ProducerOperationHandler"; + + private static final String METHOD_NAME = "handle"; + + @Override + public ClassMatcher getClassMatcher() { + return ClassMatcher.nameEquals(ENHANCE_CLASS); + } + + @Override + public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) { + return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(METHOD_NAME), + new ServiceCombRpcProviderInterceptor())}; + } +} diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcConsumerInterceptor.java b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcConsumerInterceptor.java new file mode 100644 index 0000000000..cd0d903eef --- /dev/null +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcConsumerInterceptor.java @@ -0,0 +1,76 @@ +/* + * 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.interceptors.rpc.servicecomb; + +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.interceptors.AbstractClientInterceptor; + +import org.apache.servicecomb.core.Invocation; + +import java.util.List; + +/** + * servicecombRPC consumer端interceptor,支持servicecomb2.x版本 + * + * @author daizhenyu + * @since 2023-08-26 + **/ +public class ServiceCombRpcConsumerInterceptor extends AbstractClientInterceptor { + private static final String CONSUMER_KEY = "consumer_key"; + + private static final String CONSUMER_VALUE = "consumer_value"; + + @Override + protected ExecuteContext doBefore(ExecuteContext context) { + Object[] arguments = context.getArguments(); + if (arguments == null || arguments.length == 0) { + return context; + } + Object invocationObject = arguments[0]; + if (invocationObject instanceof Invocation) { + Invocation invocation = (Invocation) invocationObject; + + // 传入servicecombrpc的header中,用于provider端识别本次调用是否来自servicecombrpc consumer端 + invocation.getContext().put(CONSUMER_KEY, CONSUMER_VALUE); + injectTrafficTag2Carrier(invocation); + } + return context; + } + + @Override + protected ExecuteContext doAfter(ExecuteContext context) { + return context; + } + + /** + * 向Invocation中添加流量标签 + * + * @param invocation servicecomb rpc客服端 标签传递载体 + */ + @Override + protected void injectTrafficTag2Carrier(Invocation invocation) { + for (String key : tagTransmissionConfig.getTagKeys()) { + List values = TrafficUtils.getTrafficTag().getTag().get(key); + if (CollectionUtils.isEmpty(values)) { + continue; + } + invocation.getContext().put(key, values.get(0)); + } + } +} diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcProviderInterceptor.java b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcProviderInterceptor.java new file mode 100644 index 0000000000..a827d3d09b --- /dev/null +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/java/com/huaweicloud/sermant/tag/transmission/interceptors/rpc/servicecomb/ServiceCombRpcProviderInterceptor.java @@ -0,0 +1,99 @@ +/* + * 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.interceptors.rpc.servicecomb; + +import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext; +import com.huaweicloud.sermant.core.utils.tag.TrafficUtils; +import com.huaweicloud.sermant.tag.transmission.interceptors.AbstractServerInterceptor; + +import org.apache.servicecomb.core.Invocation; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * servicecombRPC provider端interceptor,支持servicecomb2.x版本 + * + * @author daizhenyu + * @since 2023-08-26 + **/ +public class ServiceCombRpcProviderInterceptor extends AbstractServerInterceptor { + private static final String CONSUMER_KEY = "consumer_key"; + + @Override + protected ExecuteContext doBefore(ExecuteContext context) { + Object[] arguments = context.getArguments(); + if (arguments == null || arguments.length == 0) { + return context; + } + Object invocationObject = arguments[0]; + if (invocationObject instanceof Invocation) { + Invocation invocation = (Invocation) invocationObject; + + // 判断本次rpc调用是否来自servicecombrpc consumer端 + if (invocation.getContext().containsKey(CONSUMER_KEY) + || invocation.getRequestEx().getHeader(CONSUMER_KEY) != null) { + TrafficUtils.updateTrafficTag(extractTrafficTagFromCarrier(invocation)); + } + } + return context; + } + + @Override + protected ExecuteContext doAfter(ExecuteContext context) { + TrafficUtils.removeTrafficTag(); + return context; + } + + @Override + public ExecuteContext onThrow(ExecuteContext context) { + TrafficUtils.removeTrafficTag(); + return context; + } + + /** + * 从Invocation中解析流量标签 + * + * @param invocation servicecomb rpc服务端的流量标签载体 + * @return 流量标签 + */ + @Override + protected Map> extractTrafficTagFromCarrier(Invocation invocation) { + Map> tag = new HashMap<>(); + for (String key : tagTransmissionConfig.getTagKeys()) { + String value = invocation.getContext().get(key); + if (value != null) { + // cse 场景 + tag.put(key, Collections.singletonList(value)); + continue; + } + + // 非cse 场景 + value = invocation.getRequestEx().getHeader(key); + if (value != null) { + tag.put(key, Collections.singletonList(value)); + continue; + } + + // 流量标签的value为null时,也需存入本地变量,覆盖原来的value,以防误用旧流量标签 + tag.put(key, null); + } + return tag; + } +} diff --git a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer index fa9f3516d6..f77ab4493f 100644 --- a/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer +++ b/sermant-plugins/sermant-tag-transmission/tag-transmission-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer @@ -25,6 +25,8 @@ com.huaweicloud.sermant.tag.transmission.declarers.rpc.dubbo.ApacheDubboConsumer com.huaweicloud.sermant.tag.transmission.declarers.rpc.dubbo.AlibabaDubboConsumerDeclarer com.huaweicloud.sermant.tag.transmission.declarers.rpc.sofarpc.SofaRpcClientDeclarer com.huaweicloud.sermant.tag.transmission.declarers.rpc.sofarpc.SofaRpcServerDeclarer +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