From e31b9bb6a23d1d359948eeb743473d0c6485958b Mon Sep 17 00:00:00 2001
From: peachisai <96932958+peachisai@users.noreply.github.com>
Date: Fri, 18 Aug 2023 08:45:46 +0800
Subject: [PATCH] Add nacos-client 2.x plugin (#593)
---
.github/workflows/plugins-test.2.yaml | 1 +
CHANGES.md | 1 +
.../trace/component/ComponentsDefine.java | 1 +
.../nacos-client-2.x-plugin/pom.xml | 53 +++++++
.../ClientHandleServerRequestInterceptor.java | 61 ++++++++
.../v2/ClientServerCheckInterceptor.java | 58 +++++++
.../nacos/v2/GrpcConnectionInterceptor.java | 58 +++++++
.../apm/plugin/nacos/v2/NacosRequestOpt.java | 145 ++++++++++++++++++
.../nacos/v2/constant/NacosConstants.java | 52 +++++++
.../AbstractGrpcClientIntrumentation.java | 28 ++++
.../GrpcConnectionClientIntrumentation.java | 67 ++++++++
.../v2/define/RpcClientIntrumentation.java | 85 ++++++++++
.../src/main/resources/skywalking-plugin.def | 20 +++
apm-sniffer/optional-plugins/pom.xml | 1 +
.../java-agent/Optional-plugins.md | 1 +
.../service-agent/java-agent/Plugin-list.md | 1 +
.../java-agent/Supported-list.md | 1 +
.../nacos-client-2.x-scenario/bin/startup.sh | 21 +++
.../config/expectedData.yaml | 120 +++++++++++++++
.../configuration.yml | 32 ++++
.../nacos-client-2.x-scenario/pom.xml | 96 ++++++++++++
.../src/main/assembly/assembly.xml | 41 +++++
.../testcase/nacos/client/Application.java | 30 ++++
.../client/controller/CaseController.java | 71 +++++++++
.../src/main/resources/application.yaml | 22 +++
.../support-version.list | 19 +++
26 files changed, 1086 insertions(+)
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/pom.xml
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientHandleServerRequestInterceptor.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientServerCheckInterceptor.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/GrpcConnectionInterceptor.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/NacosRequestOpt.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/constant/NacosConstants.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/AbstractGrpcClientIntrumentation.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/GrpcConnectionClientIntrumentation.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/RpcClientIntrumentation.java
create mode 100644 apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/resources/skywalking-plugin.def
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/bin/startup.sh
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/config/expectedData.yaml
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/configuration.yml
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/pom.xml
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/src/main/assembly/assembly.xml
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/Application.java
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/controller/CaseController.java
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/src/main/resources/application.yaml
create mode 100644 test/plugin/scenarios/nacos-client-2.x-scenario/support-version.list
diff --git a/.github/workflows/plugins-test.2.yaml b/.github/workflows/plugins-test.2.yaml
index d1f0a9b56..a439aa44b 100644
--- a/.github/workflows/plugins-test.2.yaml
+++ b/.github/workflows/plugins-test.2.yaml
@@ -80,6 +80,7 @@ jobs:
- jersey-2.0.x-2.25.x-scenario
- jersey-2.26.x-2.39.x-scenario
- websphere-liberty-23.x-scenario
+ - nacos-client-2.x-scenario
steps:
- uses: actions/checkout@v2
with:
diff --git a/CHANGES.md b/CHANGES.md
index 042d97069..648e13ee0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -151,6 +151,7 @@ Callable {
* Fix Jedis-2.x plugin bug and add test for Redis cluster scene
* Merge two instrumentation classes to avoid duplicate enhancements in MySQL plugins.
* Support asynchronous invocation in jetty client 9.0 and 9.x plugin
+* Add nacos-client 2.x plugin
#### Documentation
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index facacc64e..fff71474d 100755
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -241,4 +241,5 @@ public class ComponentsDefine {
public static final OfficialComponent AEROSPIKE = new OfficialComponent(149, "Aerospike");
+ public static final OfficialComponent NACOS = new OfficialComponent(150, "Nacos");
}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/pom.xml b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/pom.xml
new file mode 100644
index 000000000..a5c8d0dc7
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/pom.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+ org.apache.skywalking
+ optional-plugins
+ 9.0.0-SNAPSHOT
+
+ 4.0.0
+
+ apm-nacos-client-2.x-plugin
+ nacos-client-2.x-plugin
+
+
+ UTF-8
+ 2.0.3
+
+
+
+
+ com.alibaba.nacos
+ nacos-client
+ ${nacos-client.version}
+ provided
+
+
+
+
+
+
+ maven-deploy-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientHandleServerRequestInterceptor.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientHandleServerRequestInterceptor.java
new file mode 100644
index 000000000..09f5f5151
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientHandleServerRequestInterceptor.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2;
+
+import com.alibaba.nacos.api.remote.request.Request;
+import com.alibaba.nacos.common.remote.client.RpcClient;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+public class ClientHandleServerRequestInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+ String peer = getPeer(objInst);
+ NacosRequestOpt.getHandler(allArguments[0].getClass()).ifPresent(o -> o.buildRequestSpanInfo((Request) allArguments[0], peer));
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Object ret) throws Throwable {
+ if (ContextManager.isActive()) {
+ ContextManager.stopSpan();
+ }
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ if (ContextManager.isActive()) {
+ ContextManager.activeSpan().log(t);
+ }
+ }
+
+ private String getPeer(EnhancedInstance objInst) {
+ Object dynamicField = objInst.getSkyWalkingDynamicField();
+ if (dynamicField instanceof RpcClient.ServerInfo) {
+ RpcClient.ServerInfo serverInfo = (RpcClient.ServerInfo) dynamicField;
+ return serverInfo.getAddress();
+ }
+ return "no peer";
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientServerCheckInterceptor.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientServerCheckInterceptor.java
new file mode 100644
index 000000000..544d265dc
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/ClientServerCheckInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2;
+
+import com.alibaba.nacos.api.remote.response.Response;
+import com.alibaba.nacos.common.remote.client.RpcClient;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+import java.lang.reflect.Method;
+
+public class ClientServerCheckInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+ String ip = (String) allArguments[0];
+ int port = (Integer) allArguments[1];
+ objInst.setSkyWalkingDynamicField(new RpcClient.ServerInfo(ip, port));
+ AbstractSpan span = ContextManager.createExitSpan("Nacos/serverCheck", ip + ":" + port);
+ SpanLayer.asRPCFramework(span);
+ span.setComponent(ComponentsDefine.NACOS);
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Object ret) throws Throwable {
+ if (ret == null || !((Response) ret).isSuccess()) {
+ ContextManager.activeSpan().errorOccurred();
+ }
+ ContextManager.stopSpan();
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ ContextManager.activeSpan().log(t);
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/GrpcConnectionInterceptor.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/GrpcConnectionInterceptor.java
new file mode 100644
index 000000000..58fed34a4
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/GrpcConnectionInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2;
+
+import com.alibaba.nacos.api.remote.request.Request;
+import com.alibaba.nacos.api.remote.response.Response;
+import com.alibaba.nacos.common.remote.client.grpc.GrpcConnection;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+public class GrpcConnectionInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+ GrpcConnection connection = (GrpcConnection) objInst;
+ NacosRequestOpt.getHandler(allArguments[0].getClass()).ifPresent(o -> o.buildRequestSpanInfo((Request) allArguments[0], connection.getChannel().authority()));
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Object ret) throws Throwable {
+ if (ContextManager.isActive()) {
+ if (ret == null || !((Response) ret).isSuccess()) {
+ AbstractSpan span = ContextManager.activeSpan();
+ span.errorOccurred();
+ }
+ ContextManager.stopSpan();
+ }
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ if (ContextManager.isActive()) {
+ ContextManager.activeSpan().log(t);
+ }
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/NacosRequestOpt.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/NacosRequestOpt.java
new file mode 100644
index 000000000..c254e8a40
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/NacosRequestOpt.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2;
+
+import com.alibaba.nacos.api.config.remote.request.ConfigChangeNotifyRequest;
+import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
+import com.alibaba.nacos.api.config.remote.request.ConfigQueryRequest;
+import com.alibaba.nacos.api.config.remote.request.ConfigRemoveRequest;
+import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
+import com.alibaba.nacos.api.naming.remote.request.InstanceRequest;
+import com.alibaba.nacos.api.naming.remote.request.NotifySubscriberRequest;
+import com.alibaba.nacos.api.naming.remote.request.ServiceListRequest;
+import com.alibaba.nacos.api.naming.remote.request.ServiceQueryRequest;
+import com.alibaba.nacos.api.naming.remote.request.SubscribeServiceRequest;
+import com.alibaba.nacos.api.remote.request.Request;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.nacos.v2.constant.NacosConstants;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+@SuppressWarnings("rawtypes")
+public class NacosRequestOpt {
+
+ private static final Map OPTS = new HashMap<>();
+
+ static {
+ OPTS.put(InstanceRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + ((InstanceRequest) request).getType());
+ span.tag(Tags.ofKey(NacosConstants.NAMESPACE), ((InstanceRequest) request).getNamespace());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((InstanceRequest) request).getGroupName());
+ span.tag(Tags.ofKey(NacosConstants.SERVICE_NAME), ((InstanceRequest) request).getServiceName());
+ });
+
+ OPTS.put(ServiceQueryRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.QUERY_SERVICE);
+ span.tag(Tags.ofKey(NacosConstants.NAMESPACE), ((ServiceQueryRequest) request).getNamespace());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ServiceQueryRequest) request).getGroupName());
+ span.tag(Tags.ofKey(NacosConstants.SERVICE_NAME), ((ServiceQueryRequest) request).getServiceName());
+ });
+
+ OPTS.put(SubscribeServiceRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + (((SubscribeServiceRequest) request).isSubscribe() ?
+ NacosConstants.SUBSCRIBE_SERVICE : NacosConstants.UNSUBSCRIBE_SERVICE));
+ span.tag(Tags.ofKey(NacosConstants.NAMESPACE), ((SubscribeServiceRequest) request).getNamespace());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((SubscribeServiceRequest) request).getGroupName());
+ span.tag(Tags.ofKey(NacosConstants.SERVICE_NAME), ((SubscribeServiceRequest) request).getServiceName());
+ });
+
+ OPTS.put(ServiceListRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.GET_SERVICE_LIST);
+ span.tag(Tags.ofKey(NacosConstants.NAMESPACE), ((ServiceListRequest) request).getNamespace());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ServiceListRequest) request).getGroupName());
+ span.tag(Tags.ofKey(NacosConstants.SERVICE_NAME), ((ServiceListRequest) request).getServiceName());
+ });
+
+ OPTS.put(ConfigQueryRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.QUERY_CONFIG);
+ span.tag(Tags.ofKey(NacosConstants.DATA_ID), ((ConfigQueryRequest) request).getDataId());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ConfigQueryRequest) request).getGroup());
+ span.tag(Tags.ofKey(NacosConstants.TENANT), ((ConfigQueryRequest) request).getTenant());
+ });
+
+ OPTS.put(ConfigPublishRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.PUBLISH_CONFIG);
+ span.tag(Tags.ofKey(NacosConstants.DATA_ID), ((ConfigPublishRequest) request).getDataId());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ConfigPublishRequest) request).getGroup());
+ span.tag(Tags.ofKey(NacosConstants.TENANT), ((ConfigPublishRequest) request).getTenant());
+ });
+
+ OPTS.put(ConfigRemoveRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosExitSpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.REMOVE_CONFIG);
+ span.tag(Tags.ofKey(NacosConstants.DATA_ID), ((ConfigRemoveRequest) request).getDataId());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ConfigRemoveRequest) request).getGroup());
+ span.tag(Tags.ofKey(NacosConstants.TENANT), ((ConfigRemoveRequest) request).getTenant());
+ });
+
+ OPTS.put(NotifySubscriberRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosEntrySpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.NOTIFY_SUBSCRIBE_CHANGE);
+ ServiceInfo serviceInfo = ((NotifySubscriberRequest) request).getServiceInfo();
+ span.tag(Tags.ofKey(NacosConstants.GROUP), serviceInfo.getGroupName());
+ span.tag(Tags.ofKey(NacosConstants.SERVICE_NAME), serviceInfo.getName());
+ });
+
+ OPTS.put(ConfigChangeNotifyRequest.class, (request, peer) -> {
+ AbstractSpan span = getNacosEntrySpan(peer);
+ span.setOperationName(span.getOperationName() + NacosConstants.NOTIFY_CONFIG_CHANGE);
+ span.tag(Tags.ofKey(NacosConstants.DATA_ID), ((ConfigChangeNotifyRequest) request).getDataId());
+ span.tag(Tags.ofKey(NacosConstants.GROUP), ((ConfigChangeNotifyRequest) request).getGroup());
+ span.tag(Tags.ofKey(NacosConstants.TENANT), ((ConfigChangeNotifyRequest) request).getTenant());
+ });
+ }
+
+ private static AbstractSpan getNacosEntrySpan(String peer) {
+ AbstractSpan span = ContextManager.createEntrySpan(NacosConstants.NACOS_PREFIX, null);
+ span.setComponent(ComponentsDefine.NACOS);
+ span.setPeer(peer);
+ SpanLayer.asRPCFramework(span);
+ return span;
+ }
+
+ private static AbstractSpan getNacosExitSpan(String peer) {
+ AbstractSpan span = ContextManager.createExitSpan(NacosConstants.NACOS_PREFIX, peer);
+ span.setComponent(ComponentsDefine.NACOS);
+ SpanLayer.asRPCFramework(span);
+ return span;
+ }
+
+ public static Optional getHandler(Class clazz) {
+ return Optional.ofNullable(OPTS.get(clazz));
+ }
+
+ interface Handler {
+ void buildRequestSpanInfo(Request request, String peer);
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/constant/NacosConstants.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/constant/NacosConstants.java
new file mode 100644
index 000000000..ab8ce5266
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/constant/NacosConstants.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2.constant;
+
+public class NacosConstants {
+
+ public static final String NACOS_PREFIX = "Nacos/";
+
+ public static final String QUERY_SERVICE = "queryService";
+
+ public static final String SUBSCRIBE_SERVICE = "subscribeService";
+
+ public static final String UNSUBSCRIBE_SERVICE = "unsubscribeService";
+
+ public static final String QUERY_CONFIG = "queryConfig";
+
+ public static final String PUBLISH_CONFIG = "publishConfig";
+
+ public static final String REMOVE_CONFIG = "removeConfig";
+
+ public static final String GET_SERVICE_LIST = "getServiceList";
+
+ public static final String NOTIFY_SUBSCRIBE_CHANGE = "notifySubscribeChange";
+
+ public static final String NOTIFY_CONFIG_CHANGE = "notifyConfigChange";
+
+ public static final String NAMESPACE = "namespace";
+
+ public static final String GROUP = "group";
+
+ public static final String SERVICE_NAME = "serviceName";
+
+ public static final String DATA_ID = "dataId";
+
+ public static final String TENANT = "tenant";
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/AbstractGrpcClientIntrumentation.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/AbstractGrpcClientIntrumentation.java
new file mode 100644
index 000000000..0dc0ff272
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/AbstractGrpcClientIntrumentation.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+
+public abstract class AbstractGrpcClientIntrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+ @Override
+ protected String[] witnessClasses() {
+ return new String[]{"com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy"};
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/GrpcConnectionClientIntrumentation.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/GrpcConnectionClientIntrumentation.java
new file mode 100644
index 000000000..9d4398cb4
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/GrpcConnectionClientIntrumentation.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class GrpcConnectionClientIntrumentation extends AbstractGrpcClientIntrumentation {
+
+ private static final String ENHANCE_CLASS = "com.alibaba.nacos.common.remote.client.grpc.GrpcConnection";
+
+ private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.nacos.v2.GrpcConnectionInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return byName(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[0];
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("request");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/RpcClientIntrumentation.java b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/RpcClientIntrumentation.java
new file mode 100644
index 000000000..69e0673b2
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/nacos/v2/define/RpcClientIntrumentation.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.nacos.v2.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public class RpcClientIntrumentation extends AbstractGrpcClientIntrumentation {
+
+ private static final String ENHANCE_CLASS = "com.alibaba.nacos.common.remote.client.RpcClient";
+
+ private static final String HANDLE_SERVER_REQUEST_CLASS = "org.apache.skywalking.apm.plugin.nacos.v2.ClientHandleServerRequestInterceptor";
+
+ private static final String CONNECT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.nacos.v2.ClientServerCheckInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return HierarchyMatch.byHierarchyMatch(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[0];
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("serverCheck");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return CONNECT_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("handleServerRequest");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return HANDLE_SERVER_REQUEST_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000..f1b7b41ad
--- /dev/null
+++ b/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+nacos-client-2.x=org.apache.skywalking.apm.plugin.nacos.v2.define.GrpcConnectionClientIntrumentation
+nacos-client-2.x=org.apache.skywalking.apm.plugin.nacos.v2.define.RpcClientIntrumentation
+
+
diff --git a/apm-sniffer/optional-plugins/pom.xml b/apm-sniffer/optional-plugins/pom.xml
index 3a968ff71..fcbafe433 100644
--- a/apm-sniffer/optional-plugins/pom.xml
+++ b/apm-sniffer/optional-plugins/pom.xml
@@ -57,6 +57,7 @@
jackson-2.x-pluginshenyu-2.4.x-plugintrace-sampler-cpu-policy-plugin
+ nacos-client-2.x-plugin
diff --git a/docs/en/setup/service-agent/java-agent/Optional-plugins.md b/docs/en/setup/service-agent/java-agent/Optional-plugins.md
index 7272790a7..f6f30d88a 100644
--- a/docs/en/setup/service-agent/java-agent/Optional-plugins.md
+++ b/docs/en/setup/service-agent/java-agent/Optional-plugins.md
@@ -23,3 +23,4 @@ Now, we have the following known optional plugins.
* Plugin of Apache ShenYu(incubating) Gateway 2.4.x in optional plugin folder. Please only activate this plugin when you install agent in Apache ShenYu Gateway.
* Plugin of trace sampler CPU policy in the optional plugin folder. Please only activate this plugin when you need to disable trace collecting when the agent process CPU usage is too high(over threshold).
* Plugin for Spring 6.x and RestTemplate 6.x are in the optional plugin folder. Spring 6 requires Java 17 but SkyWalking is still compatible with Java 8. So, we put it in the optional plugin folder.
+* Plugin of nacos-client 2.x lib in optional plugin folder.The reason is many business irrelevant traces are generated, which cause extra payload to agents and backends, also spend more CPU, memory and network.
\ No newline at end of file
diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md
index 168334e4e..186d1507f 100644
--- a/docs/en/setup/service-agent/java-agent/Plugin-list.md
+++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md
@@ -68,6 +68,7 @@
- mysql-5.x
- mysql-6.x
- mysql-8.x
+- nacos-client-2.x
- netty-socketio
- nutz-http-1.x
- nutz-mvc-annotation-1.x
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
index c85d65327..9d172e5e1 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -69,6 +69,7 @@ metrics based on the tracing data.
* [Thrift](https://github.com/apache/thrift/tree/master/lib/java) 0.10.0 -> 0.12.0
* [Apache CXF](https://github.com/apache/cxf) 3.x
* [JSONRPC4J](https://github.com/briandilley/jsonrpc4j) 1.2.0 -> 1.6
+ * [Nacos-Client](https://github.com/alibaba/nacos) 2.x (Optional²)
* MQ
* [RocketMQ](https://github.com/apache/rocketmq) 3.x-> 5.x
* [Kafka](http://kafka.apache.org) 0.11.0.0 -> 3.2.3
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/bin/startup.sh b/test/plugin/scenarios/nacos-client-2.x-scenario/bin/startup.sh
new file mode 100644
index 000000000..8ff3c16e3
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -Dnacos.serverAddr=${NACOS_SERVERADDR} -jar ${agent_opts} ${home}/../libs/nacos-client-2.x-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/nacos-client-2.x-scenario/config/expectedData.yaml
new file mode 100644
index 000000000..d96c8941b
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/config/expectedData.yaml
@@ -0,0 +1,120 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+segmentItems:
+- serviceName: nacos-client-2.x-scenario
+ segmentSize: gt 0
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: Nacos/serverCheck
+ parentSpanId: 0
+ spanId: ge 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Exit
+ peer: nacos-server:9848
+ skipAnalysis: 'false'
+ - operationName: Nacos/registerInstance
+ parentSpanId: 0
+ spanId: nq 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Exit
+ peer: nacos-server:9848
+ tags:
+ - {key: namespace, value: public}
+ - {key: group, value: DEFAULT_GROUP}
+ - {key: serviceName, value: nacos-scenario}
+ skipAnalysis: 'false'
+ - operationName: Nacos/subscribeService
+ parentSpanId: 0
+ spanId: nq 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Exit
+ peer: nacos-server:9848
+ skipAnalysis: false
+ tags:
+ - { key: namespace, value: public }
+ - { key: group, value: DEFAULT_GROUP }
+ - { key: serviceName, value: nacos-scenario }
+ - operationName: Nacos/serverCheck
+ parentSpanId: 0
+ spanId: nq 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Exit
+ peer: nacos-server:9848
+ skipAnalysis: 'false'
+ - operationName: Nacos/publishConfig
+ parentSpanId: 0
+ spanId: nq 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Exit
+ peer: nacos-server:9848
+ skipAnalysis: false
+ tags:
+ - { key: dataId, value: dataId }
+ - { key: group, value: DEFAULT_GROUP }
+ - { key: tenant, value: null }
+ - operationName: GET:/case/nacos-client-2.x-case
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: not null
+ endTime: not null
+ componentId: 14
+ isError: false
+ spanType: Entry
+ peer: ''
+ tags:
+ - {key: url, value: not null}
+ - {key: http.method, value: GET}
+ - {key: http.status_code, value: '200'}
+ skipAnalysis: 'false'
+ - segmentId: not null
+ spans:
+ - operationName: Nacos/notifySubscribeChange
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: RPCFramework
+ startTime: not null
+ endTime: not null
+ componentId: 150
+ isError: false
+ spanType: Entry
+ peer: nacos-server:9848
+ skipAnalysis: 'false'
+ tags:
+ - { key: group, value: DEFAULT_GROUP }
+ - { key: serviceName, value: nacos-scenario }
+
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/configuration.yml b/test/plugin/scenarios/nacos-client-2.x-scenario/configuration.yml
new file mode 100644
index 000000000..9d6972598
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/configuration.yml
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+type: jvm
+entryService: http://localhost:8080/nacos-client-2.x-scenario/case/nacos-client-2.x-case
+healthCheck: http://localhost:8080/nacos-client-2.x-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+runningMode: with_optional
+withPlugins: apm-nacos-client-2.x-plugin-*.jar
+environment:
+ - NACOS_SERVERADDR=nacos-server:8848
+depends_on:
+ - nacos-server
+dependencies:
+ nacos-server:
+ image: nacos/nacos-server:v2.2.0
+ hostname: nacos-server
+ environment:
+ - MODE=standalone
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/pom.xml b/test/plugin/scenarios/nacos-client-2.x-scenario/pom.xml
new file mode 100644
index 000000000..f6bfef22a
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/pom.xml
@@ -0,0 +1,96 @@
+
+
+
+ 4.0.0
+
+ org.apache.skywalking
+ nacos-client-2.x-scenario
+ 1.0.0
+
+
+ UTF-8
+ 1.8
+ 3.8.1
+ 2.1.6.RELEASE
+ 2.0.3
+
+
+ skywalking-nacos-client-scenario
+
+
+
+ com.alibaba.nacos
+ nacos-client
+ ${test.framework.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring.boot.version}
+
+
+
+
+ nacos-client-2.x-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 1.5.9.RELEASE
+
+
+
+ repackage
+
+
+
+
+
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${compiler.version}
+ ${compiler.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ assemble
+ package
+
+ single
+
+
+
+ src/main/assembly/assembly.xml
+
+ ./target/
+
+
+
+
+
+
+
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..4dc9c67f1
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+ ${project.build.directory}/nacos-client-2.x-scenario.jar
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/Application.java b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/Application.java
new file mode 100644
index 000000000..79edc654a
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/Application.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 test.apache.skywalking.apm.testcase.nacos.client;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/controller/CaseController.java b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/controller/CaseController.java
new file mode 100644
index 000000000..c19549de7
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/nacos/client/controller/CaseController.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 test.apache.skywalking.apm.testcase.nacos.client.controller;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.PropertyKeyConst;
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.naming.NamingFactory;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.listener.EventListener;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Properties;
+
+@RestController
+@RequestMapping("/case")
+public class CaseController {
+
+ @Value("${nacos.serverAddr}")
+ private String nacosServerAddr;
+
+ @RequestMapping("/nacos-client-2.x-case")
+ @ResponseBody
+ public String nacosClientCase() throws Exception {
+ Properties prop = new Properties();
+ prop.setProperty("serverAddr", nacosServerAddr);
+ ConfigService configService = NacosFactory.createConfigService(prop);
+ prop.put(PropertyKeyConst.NAMESPACE, "public");
+
+ NamingService namingService = NamingFactory.createNamingService(prop);
+ String serviceName = "nacos-scenario";
+ String ip = "1.1.1.1";
+ int port = 10000;
+
+ namingService.registerInstance(serviceName, ip, port);
+
+ EventListener listener = event -> {
+ };
+ namingService.subscribe(serviceName, listener);
+
+ configService.publishConfig(Constants.DATAID, Constants.DEFAULT_GROUP, "content");
+ return "Success";
+ }
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() {
+ return "success";
+ }
+}
+
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/resources/application.yaml
new file mode 100644
index 000000000..8a75cf7c4
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/src/main/resources/application.yaml
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+#
+
+server:
+ port: 8080
+ servlet:
+ context-path: /nacos-client-2.x-scenario
\ No newline at end of file
diff --git a/test/plugin/scenarios/nacos-client-2.x-scenario/support-version.list b/test/plugin/scenarios/nacos-client-2.x-scenario/support-version.list
new file mode 100644
index 000000000..dbf53d807
--- /dev/null
+++ b/test/plugin/scenarios/nacos-client-2.x-scenario/support-version.list
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+2.0.3
+2.1.1
+2.2.0
\ No newline at end of file