You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/07/07 18:26:24 UTC
[skywalking-java] branch main updated: Support access the tracer context in spring gateway filter (#539)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git
The following commit(s) were added to refs/heads/main by this push:
new c9a61701f1 Support access the tracer context in spring gateway filter (#539)
c9a61701f1 is described below
commit c9a61701f1b40075af78fcd829d9baed9f710a23
Author: DarknessTM <da...@gmail.com>
AuthorDate: Sat Jul 8 02:26:18 2023 +0800
Support access the tracer context in spring gateway filter (#539)
Co-authored-by: darknesstm <as...@163.com>
---
.github/workflows/plugins-test.3.yaml | 1 +
CHANGES.md | 1 +
.../webflux/WebFluxSkyWalkingTraceContext.java | 79 ++++++++++++
.../apm/agent/core/context/CorrelationContext.java | 4 +-
...SkyWalkingCorrelationContextGetInterceptor.java | 49 +++++++
...SkyWalkingCorrelationContextPutInterceptor.java | 50 ++++++++
.../WebFluxSkyWalkingOperatorsInterceptor.java | 15 +--
.../WebFluxSkyWalkingSegmentIDInterceptor.java | 53 ++++++++
.../WebFluxSkyWalkingSpanIDInterceptor.java | 53 ++++++++
...uxSkyWalkingStaticMethodsAroundInterceptor.java | 50 ++++++++
.../WebFluxSkyWalkingTraceContextActivation.java | 142 +++++++++++++++++++++
.../WebFluxSkyWalkingTraceIDInterceptor.java | 53 ++++++++
.../src/main/resources/skywalking-plugin.def | 3 +-
.../java-agent/Application-toolkit-webflux.md | 50 +++++++-
.../config/expectedData.yaml | 64 ++++++++++
.../configuration.yml | 7 +-
.../gateway-dist/bin/startup.sh | 9 +-
.../gateway-dist/pom.xml | 54 ++++++++
.../gateway-dist/src/main/assembly/assembly.xml | 46 +++++++
.../gateway-projectA-scenario/pom.xml | 67 ++++++++++
.../webflux/WebFluxSkyWalkingTraceContext.java | 79 ++++++++++++
.../sc/gateway/projectA/ApiKeyResolver.java | 31 +++++
.../testcase/sc/gateway/projectA/Application.java | 29 +++++
.../testcase/sc/gateway/projectA/Test1Filter.java | 43 +++++++
.../testcase/sc/gateway/projectA/Test2Filter.java | 48 +++++++
.../testcase/sc/gateway/projectA/Test3Filter.java | 48 +++++++
.../sc/gateway/projectA/TestFilterConfig.java | 40 ++++++
.../src/main/resources/application.yml | 29 +++++
.../gateway-projectB-scenario/pom.xml | 57 +++++++++
.../skywalking/apm/toolkit/trace/TraceContext.java | 76 +++++++++++
.../testcase/sc/gateway/projectB/Application.java | 31 +++++
.../projectB/controller/TestController.java | 117 +++++++++++++++++
.../src/main/resources/application.properties | 17 +++
.../gateway-3.x-filter-context-scenario/pom.xml | 59 +++++++++
.../support-version.list | 2 +-
35 files changed, 1531 insertions(+), 25 deletions(-)
diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml
index 5d651642e6..a4cfe3cb54 100644
--- a/.github/workflows/plugins-test.3.yaml
+++ b/.github/workflows/plugins-test.3.yaml
@@ -90,6 +90,7 @@ jobs:
- dbcp-2.x-scenario
- jsonrpc4j-1.x-scenario
- gateway-3.x-scenario
+ - gateway-3.x-filter-context-scenario
- neo4j-4.x-scenario
- oracle-scenario
- druid-1.x-scenario
diff --git a/CHANGES.md b/CHANGES.md
index d8560ee0c9..40fe33c01f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -133,6 +133,7 @@ Callable {
* Support Jdk17 ZGC metric collect
* Support Jetty 11.x plugin
+* Support access the sky-walking tracer context in spring gateway filter
* Fix the scenario of using the HBase plugin with spring-data-hadoop.
* Add RocketMQ 5.x plugin
* Fix the conflict between the logging kernel and the JDK threadpool plugin.
diff --git a/apm-application-toolkit/apm-toolkit-webflux/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java b/apm-application-toolkit/apm-toolkit-webflux/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java
new file mode 100644
index 0000000000..82198edb5c
--- /dev/null
+++ b/apm-application-toolkit/apm-toolkit-webflux/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java
@@ -0,0 +1,79 @@
+/*
+ * 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.toolkit.webflux;
+
+import org.springframework.web.server.ServerWebExchange;
+
+import java.util.Optional;
+
+/**
+ * TraceContext for WebFlux.
+ */
+public class WebFluxSkyWalkingTraceContext {
+ /**
+ * Try to get the traceId of current trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return traceId, if it exists, or empty {@link String}.
+ */
+ public static String traceId(ServerWebExchange serverWebExchange) {
+ return "";
+ }
+
+ /**
+ * Try to get the segmentId of current trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return segmentId, if it exists, or empty {@link String}.
+ */
+ public static String segmentId(ServerWebExchange serverWebExchange) {
+ return "";
+ }
+
+ /**
+ * Try to get the spanId of current trace context. The spanId is a negative number when the trace context is
+ * missing.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return spanId, if it exists, or empty {@link String}.
+ */
+ public static int spanId(ServerWebExchange serverWebExchange) {
+ return -1;
+ }
+
+ /**
+ * Try to get the custom value from trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return custom data value.
+ */
+ public static Optional<String> getCorrelation(ServerWebExchange serverWebExchange, String key) {
+ return Optional.empty();
+ }
+
+ /**
+ * Put the custom key/value into trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return previous value if it exists.
+ */
+ public static Optional<String> putCorrelation(ServerWebExchange serverWebExchange, String key, String value) {
+ return Optional.empty();
+ }
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/CorrelationContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/CorrelationContext.java
index 658fb5fcb0..2b1356c28b 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/CorrelationContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/CorrelationContext.java
@@ -19,11 +19,11 @@ package org.apache.skywalking.apm.agent.core.context;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.apache.skywalking.apm.agent.core.base64.Base64;
import org.apache.skywalking.apm.agent.core.conf.Config;
@@ -49,7 +49,7 @@ public class CorrelationContext {
}
public CorrelationContext() {
- this.data = new HashMap<>(Config.Correlation.ELEMENT_MAX_NUMBER);
+ this.data = new ConcurrentHashMap<>(Config.Correlation.ELEMENT_MAX_NUMBER);
}
/**
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextGetInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextGetInterceptor.java
new file mode 100644
index 0000000000..73b06431e1
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextGetInterceptor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+public class WebFluxSkyWalkingCorrelationContextGetInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, MethodInterceptResult result) {
+ final ContextSnapshot contextSnapshot = getContextSnapshot(allArguments[0]);
+ if (contextSnapshot == null || contextSnapshot.getCorrelationContext() == null) {
+ return;
+ }
+
+ final String key = (String) allArguments[1];
+ final Optional<String> data = contextSnapshot.getCorrelationContext().get(key);
+
+ result.defineReturnValue(data);
+ }
+
+ @Override
+ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Object ret) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Throwable t) {
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextPutInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextPutInterceptor.java
new file mode 100644
index 0000000000..49bc2a3658
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingCorrelationContextPutInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+public class WebFluxSkyWalkingCorrelationContextPutInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, MethodInterceptResult result) {
+ final ContextSnapshot contextSnapshot = getContextSnapshot(allArguments[0]);
+ if (contextSnapshot == null || contextSnapshot.getCorrelationContext() == null) {
+ return;
+ }
+
+ final String key = (String) allArguments[1];
+ final String value = (String) allArguments[2];
+ final Optional<String> previous = contextSnapshot.getCorrelationContext().put(key, value);
+
+ result.defineReturnValue(previous);
+ }
+
+ @Override
+ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Object ret) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Throwable t) {
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingOperatorsInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingOperatorsInterceptor.java
index 679710700f..8ae39dfff8 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingOperatorsInterceptor.java
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingOperatorsInterceptor.java
@@ -22,18 +22,15 @@ import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.springframework.web.server.ServerWebExchange;
-import org.springframework.web.server.ServerWebExchangeDecorator;
-import org.springframework.web.server.adapter.DefaultServerWebExchange;
import reactor.util.context.Context;
import java.lang.reflect.Method;
/**
*/
-public class WebFluxSkyWalkingOperatorsInterceptor implements StaticMethodsAroundInterceptor {
+public class WebFluxSkyWalkingOperatorsInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
@Override
public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
@@ -67,14 +64,4 @@ public class WebFluxSkyWalkingOperatorsInterceptor implements StaticMethodsAroun
ContextManager.activeSpan().log(t);
}
- private static EnhancedInstance getInstance(Object o) {
- EnhancedInstance instance = null;
- if (o instanceof DefaultServerWebExchange && o instanceof EnhancedInstance) {
- instance = (EnhancedInstance) o;
- } else if (o instanceof ServerWebExchangeDecorator) {
- ServerWebExchange delegate = ((ServerWebExchangeDecorator) o).getDelegate();
- return getInstance(delegate);
- }
- return instance;
- }
}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSegmentIDInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSegmentIDInterceptor.java
new file mode 100644
index 0000000000..a8dc12a80c
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSegmentIDInterceptor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+public class WebFluxSkyWalkingSegmentIDInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
+
+ private static final ILog LOGGER = LogManager.getLogger(WebFluxSkyWalkingSegmentIDInterceptor.class);
+
+ @Override
+ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ MethodInterceptResult result) {
+ final ContextSnapshot contextSnapshot = getContextSnapshot(allArguments[0]);
+ if (contextSnapshot == null || contextSnapshot.getCorrelationContext() == null) {
+ return;
+ }
+ result.defineReturnValue(contextSnapshot.getTraceSegmentId());
+ }
+
+ @Override
+ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Object ret) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Throwable t) {
+ LOGGER.error("Failed to get segment Id.", t);
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSpanIDInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSpanIDInterceptor.java
new file mode 100644
index 0000000000..9055a707e8
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingSpanIDInterceptor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+public class WebFluxSkyWalkingSpanIDInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
+
+ private static final ILog LOGGER = LogManager.getLogger(WebFluxSkyWalkingSpanIDInterceptor.class);
+
+ @Override
+ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ MethodInterceptResult result) {
+ final ContextSnapshot contextSnapshot = getContextSnapshot(allArguments[0]);
+ if (contextSnapshot == null || contextSnapshot.getCorrelationContext() == null) {
+ return;
+ }
+ result.defineReturnValue(contextSnapshot.getSpanId());
+ }
+
+ @Override
+ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Object ret) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Throwable t) {
+ LOGGER.error("Failed to getDefault span Id.", t);
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingStaticMethodsAroundInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingStaticMethodsAroundInterceptor.java
new file mode 100644
index 0000000000..138d9440eb
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingStaticMethodsAroundInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.ServerWebExchangeDecorator;
+import org.springframework.web.server.adapter.DefaultServerWebExchange;
+
+import java.util.Optional;
+
+public abstract class WebFluxSkyWalkingStaticMethodsAroundInterceptor implements StaticMethodsAroundInterceptor {
+
+ protected EnhancedInstance getInstance(Object o) {
+ EnhancedInstance instance = null;
+ if (o instanceof DefaultServerWebExchange && o instanceof EnhancedInstance) {
+ instance = (EnhancedInstance) o;
+ } else if (o instanceof ServerWebExchangeDecorator) {
+ ServerWebExchange delegate = ((ServerWebExchangeDecorator) o).getDelegate();
+ return getInstance(delegate);
+ }
+ return instance;
+ }
+
+ protected ContextSnapshot getContextSnapshot(Object o) {
+ return Optional.ofNullable(getInstance(o))
+ .map(EnhancedInstance::getSkyWalkingDynamicField)
+ .filter(ContextSnapshot.class::isInstance)
+ .map(ContextSnapshot.class::cast)
+ .orElse(null);
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceContextActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceContextActivation.java
new file mode 100644
index 0000000000..77d522f740
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceContextActivation.java
@@ -0,0 +1,142 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public class WebFluxSkyWalkingTraceContextActivation extends ClassStaticMethodsEnhancePluginDefine {
+
+ public static final String TRACE_ID_INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingTraceIDInterceptor";
+ public static final String SEGMENT_ID_INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingSegmentIDInterceptor";
+ public static final String SPAN_ID_INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingSpanIDInterceptor";
+ public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.webflux.WebFluxSkyWalkingTraceContext";
+ public static final String ENHANCE_TRACE_ID_METHOD = "traceId";
+ public static final String ENHANCE_SEGMENT_ID_METHOD = "segmentId";
+ public static final String ENHANCE_SPAN_ID_METHOD = "spanId";
+ public static final String ENHANCE_GET_CORRELATION_METHOD = "getCorrelation";
+ public static final String INTERCEPT_GET_CORRELATION_CLASS = "org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingCorrelationContextGetInterceptor";
+ public static final String ENHANCE_PUT_CORRELATION_METHOD = "putCorrelation";
+ public static final String INTERCEPT_PUT_CORRELATION_CLASS = "org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingCorrelationContextPutInterceptor";
+
+ /**
+ * @return the target class, which needs active.
+ */
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName(ENHANCE_CLASS);
+ }
+
+ /**
+ * @return the collection of {@link StaticMethodsInterceptPoint}, represent the intercepted methods and their
+ * interceptors.
+ */
+ @Override
+ public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
+ return new StaticMethodsInterceptPoint[] {
+ new StaticMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher<MethodDescription> getMethodsMatcher() {
+ return named(ENHANCE_TRACE_ID_METHOD);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return TRACE_ID_INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new StaticMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher<MethodDescription> getMethodsMatcher() {
+ return named(ENHANCE_SEGMENT_ID_METHOD);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return SEGMENT_ID_INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new StaticMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher<MethodDescription> getMethodsMatcher() {
+ return named(ENHANCE_SPAN_ID_METHOD);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return SPAN_ID_INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+
+ new StaticMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher<MethodDescription> getMethodsMatcher() {
+ return named(ENHANCE_GET_CORRELATION_METHOD);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_GET_CORRELATION_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new StaticMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher<MethodDescription> getMethodsMatcher() {
+ return named(ENHANCE_PUT_CORRELATION_METHOD);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_PUT_CORRELATION_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceIDInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceIDInterceptor.java
new file mode 100644
index 0000000000..c3b53ecea4
--- /dev/null
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/webflux/WebFluxSkyWalkingTraceIDInterceptor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.toolkit.activation.webflux;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+public class WebFluxSkyWalkingTraceIDInterceptor extends WebFluxSkyWalkingStaticMethodsAroundInterceptor {
+
+ private static final ILog LOGGER = LogManager.getLogger(WebFluxSkyWalkingTraceIDInterceptor.class);
+
+ @Override
+ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ MethodInterceptResult result) {
+ final ContextSnapshot contextSnapshot = getContextSnapshot(allArguments[0]);
+ if (contextSnapshot == null || contextSnapshot.getCorrelationContext() == null) {
+ return;
+ }
+ result.defineReturnValue(contextSnapshot.getTraceId().getId());
+ }
+
+ @Override
+ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Object ret) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
+ Throwable t) {
+ LOGGER.error("Failed to getDefault trace Id.", t);
+ }
+}
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
index de46b3ce11..660b453807 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
@@ -14,4 +14,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingOperatorsActivation
\ No newline at end of file
+toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingOperatorsActivation
+toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingTraceContextActivation
\ No newline at end of file
diff --git a/docs/en/setup/service-agent/java-agent/Application-toolkit-webflux.md b/docs/en/setup/service-agent/java-agent/Application-toolkit-webflux.md
index 32a2662384..0fa738c54c 100644
--- a/docs/en/setup/service-agent/java-agent/Application-toolkit-webflux.md
+++ b/docs/en/setup/service-agent/java-agent/Application-toolkit-webflux.md
@@ -1,5 +1,8 @@
-# Mannual propagation of tracing context for Webflux
-* Dependency the toolkit, such as using maven or gradle
+# Webflux Tracing Assistant APIs
+
+These APIs provide advanced features to enhance interaction capabilities in Webflux cases.
+
+Add the toolkit to your project dependency, through Maven or Gradle
```xml
<dependency>
<groupId>org.apache.skywalking</groupId>
@@ -8,7 +11,11 @@
</dependency>
```
-* usage 1.
+The following scenarios are supported for tracing assistance.
+
+### Continue Tracing from Client
+The `WebFluxSkyWalkingOperators#continueTracing` provides manual tracing continuous capabilities to adopt native Webflux APIs
+
```java
@GetMapping("/testcase/annotation/mono/onnext")
public Mono<String> monoOnNext(@RequestBody(required = false) String body) {
@@ -19,7 +26,7 @@
}));
}
```
-* usage 2.
+
```java
@GetMapping("/login/userFunctions")
public Mono<Response<FunctionInfoResult>> functionInfo(ServerWebExchange exchange, @RequestParam String userId) {
@@ -34,7 +41,6 @@
}
```
-* usage 3.
```java
Mono.just("key").subscribeOn(Schedulers.boundedElastic())
.doOnEach(WebFluxSkyWalkingOperators.continueTracing(SignalType.ON_NEXT, () -> log.info("test log with tid")))
@@ -46,6 +52,40 @@
...
```
+### Fetch trace context relative IDs
+```java
+ @Override
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
+ // fetch trace ID
+ String traceId = WebFluxSkyWalkingTraceContext.traceId(exchange);
+
+ // fetch segment ID
+ String segmentId = WebFluxSkyWalkingTraceContext.segmentId(exchange);
+
+ // fetch span ID
+ int spanId = WebFluxSkyWalkingTraceContext.spanId(exchange);
+
+ return chain.filter(exchange);
+ }
+```
+
+### Manipulate Correlation Context
+
+```java
+ @Override
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
+ // Set correlation data can be retrieved by upstream nodes.
+ WebFluxSkyWalkingTraceContext.putCorrelation(exchange, "key1", "value");
+
+ // Get correlation data
+ Optional<String> value2 = WebFluxSkyWalkingTraceContext.getCorrelation(exchange, "key2");
+
+ // dosomething...
+
+ return chain.filter(exchange);
+ }
+```
+
_Sample codes only_
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/config/expectedData.yaml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..61852cba38
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/config/expectedData.yaml
@@ -0,0 +1,64 @@
+# 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: gateway-projectB-scenario
+ segmentSize: nq 0
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: /provider/b/context
+ parentSpanId: 0
+ spanId: 1
+ isError: false
+ spanType: Exit
+ tags:
+ - { key: url, value: not null }
+ - { key: http.method, value: GET }
+ - { key: http.status_code, value: '200' }
+ - operationName: GET:/provider/b/testcase
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 14
+ isError: false
+ spanType: Entry
+ peer: ''
+ tags:
+ - {key: url, value: not null}
+ - {key: http.method, value: GET}
+ - {key: http.status_code, value: '200'}
+ refs:
+ - {parentEndpoint: SpringCloudGateway/RoutingFilter, networkAddress: 'localhost:18070',
+ refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not
+ null, parentService: not null, traceId: not null}
+ skipAnalysis: 'false'
+- serviceName: gateway-projectA-scenario
+ segmentSize: nq 0
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: /provider/b/context
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ isError: false
+ spanType: Entry
+ tags:
+ - {key: url, value: 'http://localhost:8080/provider/b/context' }
+ - {key: http.method, value: GET}
+ - {key: http.status_code, value: '200'}
\ No newline at end of file
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/configuration.yml
similarity index 74%
copy from apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/gateway-3.x-filter-context-scenario/configuration.yml
index de46b3ce11..1e81d708a5 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/configuration.yml
@@ -14,4 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingOperatorsActivation
\ No newline at end of file
+type: jvm
+entryService: http://localhost:8080/provider/b/testcase
+healthCheck: http://localhost:8080/provider/b/healthCheck
+startScript: ./bin/startup.sh
+runningMode: with_optional
+withPlugins: apm-spring-cloud-gateway-3.x-plugin-*.jar;apm-spring-webflux-5.x-plugin-*.jar
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/bin/startup.sh
similarity index 70%
copy from apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/bin/startup.sh
index de46b3ce11..0d28675632 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/bin/startup.sh
@@ -1,3 +1,5 @@
+#!/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
@@ -14,4 +16,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingOperatorsActivation
\ No newline at end of file
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} "-Dskywalking.agent.service_name=gateway-projectA-scenario" ${home}/../libs/gateway-projectA-scenario.jar &
+sleep 1
+
+java -jar ${agent_opts} "-Dskywalking.agent.service_name=gateway-projectB-scenario" ${home}/../libs/gateway-projectB-scenario.jar &
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/pom.xml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/pom.xml
new file mode 100644
index 0000000000..37f4011509
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>gateway-3.x-filter-context-scenario</artifactId>
+ <version>5.0.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>gateway-dist</artifactId>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ </descriptors>
+ <outputDirectory>../target/</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/src/main/assembly/assembly.xml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..00d04e28e0
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-dist/src/main/assembly/assembly.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <fileSets>
+ <fileSet>
+ <directory>./bin</directory>
+ <fileMode>0775</fileMode>
+ </fileSet>
+ </fileSets>
+
+ <files>
+ <file>
+ <source>../gateway-projectA-scenario/target/gateway-projectA-scenario.jar</source>
+ <outputDirectory>./libs</outputDirectory>
+ <fileMode>0775</fileMode>
+ </file>
+ <file>
+ <source>../gateway-projectB-scenario/target/gateway-projectB-scenario.jar</source>
+ <outputDirectory>./libs</outputDirectory>
+ <fileMode>0775</fileMode>
+ </file>
+ </files>
+</assembly>
\ No newline at end of file
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/pom.xml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/pom.xml
new file mode 100644
index 0000000000..1056776972
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>gateway-3.x-filter-context-scenario</artifactId>
+ <version>5.0.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>gateway-projectA-scenario</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-gateway</artifactId>
+ <version>${test.framework.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>gateway-projectA-scenario</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>1.5.9.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>spring-snapshots</id>
+ <url>https://repo.spring.io/snapshot</url>
+ </pluginRepository>
+ <pluginRepository>
+ <id>spring-milestones</id>
+ <url>https://repo.spring.io/milestone</url>
+ </pluginRepository>
+ </pluginRepositories>
+</project>
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java
new file mode 100644
index 0000000000..82198edb5c
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/org/apache/skywalking/apm/toolkit/webflux/WebFluxSkyWalkingTraceContext.java
@@ -0,0 +1,79 @@
+/*
+ * 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.toolkit.webflux;
+
+import org.springframework.web.server.ServerWebExchange;
+
+import java.util.Optional;
+
+/**
+ * TraceContext for WebFlux.
+ */
+public class WebFluxSkyWalkingTraceContext {
+ /**
+ * Try to get the traceId of current trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return traceId, if it exists, or empty {@link String}.
+ */
+ public static String traceId(ServerWebExchange serverWebExchange) {
+ return "";
+ }
+
+ /**
+ * Try to get the segmentId of current trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return segmentId, if it exists, or empty {@link String}.
+ */
+ public static String segmentId(ServerWebExchange serverWebExchange) {
+ return "";
+ }
+
+ /**
+ * Try to get the spanId of current trace context. The spanId is a negative number when the trace context is
+ * missing.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return spanId, if it exists, or empty {@link String}.
+ */
+ public static int spanId(ServerWebExchange serverWebExchange) {
+ return -1;
+ }
+
+ /**
+ * Try to get the custom value from trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return custom data value.
+ */
+ public static Optional<String> getCorrelation(ServerWebExchange serverWebExchange, String key) {
+ return Optional.empty();
+ }
+
+ /**
+ * Put the custom key/value into trace context.
+ *
+ * @param serverWebExchange - EnhancedInstance that contains the tracing context
+ * @return previous value if it exists.
+ */
+ public static Optional<String> putCorrelation(ServerWebExchange serverWebExchange, String key, String value) {
+ return Optional.empty();
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/ApiKeyResolver.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/ApiKeyResolver.java
new file mode 100644
index 0000000000..40517d1d3f
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/ApiKeyResolver.java
@@ -0,0 +1,31 @@
+/*
+ * 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.sc.gateway.projectA;
+
+import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+@Component
+public class ApiKeyResolver implements KeyResolver {
+
+ public Mono<String> resolve(ServerWebExchange exchange) {
+ return Mono.just(exchange.getRequest().getPath().value());
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Application.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Application.java
new file mode 100644
index 0000000000..68eb95b0c6
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Application.java
@@ -0,0 +1,29 @@
+/*
+ * 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.sc.gateway.projectA;
+
+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/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test1Filter.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test1Filter.java
new file mode 100644
index 0000000000..32a4d4d809
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test1Filter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sc.gateway.projectA;
+
+import org.apache.skywalking.apm.toolkit.webflux.WebFluxSkyWalkingTraceContext;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+public class Test1Filter implements GlobalFilter, Ordered {
+ @Override
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+
+ WebFluxSkyWalkingTraceContext.putCorrelation(exchange, "custom-data1",
+ exchange.getRequest().getHeaders().getFirst("x-custom-data1"));
+
+ ServerHttpRequest buildRequest = exchange.getRequest().mutate().build();
+ return chain.filter(exchange.mutate().request(buildRequest).build());
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test2Filter.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test2Filter.java
new file mode 100644
index 0000000000..2b8f780ec7
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test2Filter.java
@@ -0,0 +1,48 @@
+/*
+ * 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.sc.gateway.projectA;
+
+import org.apache.skywalking.apm.toolkit.webflux.WebFluxSkyWalkingTraceContext;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.Optional;
+
+public class Test2Filter implements GlobalFilter, Ordered {
+
+ @Override
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+
+ Optional<String> data1 = WebFluxSkyWalkingTraceContext.getCorrelation(exchange, "custom-data1");
+
+ WebFluxSkyWalkingTraceContext.putCorrelation(exchange, "custom-data2",
+ data1.orElse("") + ";" + exchange.getRequest().getHeaders().getFirst("x-custom-data2"));
+
+ ServerHttpRequest buildRequest = exchange.getRequest().mutate().build();
+ return chain.filter(exchange.mutate().request(buildRequest).build());
+ }
+
+ @Override
+ public int getOrder() {
+ return 1;
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test3Filter.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test3Filter.java
new file mode 100644
index 0000000000..58ee0b9b38
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/Test3Filter.java
@@ -0,0 +1,48 @@
+/*
+ * 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.sc.gateway.projectA;
+
+import org.apache.skywalking.apm.toolkit.webflux.WebFluxSkyWalkingTraceContext;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+public class Test3Filter implements GlobalFilter, Ordered {
+
+ @Override
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+
+ ServerHttpRequest buildRequest = exchange.getRequest()
+ .mutate()
+ .headers(httpHeaders -> {
+ httpHeaders.add("x-trace-id", WebFluxSkyWalkingTraceContext.traceId(exchange));
+ httpHeaders.add("x-segment-id", WebFluxSkyWalkingTraceContext.segmentId(exchange));
+ httpHeaders.add("x-span-id", String.valueOf(WebFluxSkyWalkingTraceContext.spanId(exchange)));
+ })
+ .build();
+ return chain.filter(exchange.mutate().request(buildRequest).build());
+ }
+
+ @Override
+ public int getOrder() {
+ return 2;
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/TestFilterConfig.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/TestFilterConfig.java
new file mode 100644
index 0000000000..fb83b75c02
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectA/TestFilterConfig.java
@@ -0,0 +1,40 @@
+/*
+ * 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.sc.gateway.projectA;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class TestFilterConfig {
+
+ @Bean
+ public Test1Filter test1Filter() {
+ return new Test1Filter();
+ }
+
+ @Bean
+ public Test2Filter test2Filter() {
+ return new Test2Filter();
+ }
+
+ @Bean
+ public Test3Filter test3Filter() {
+ return new Test3Filter();
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/resources/application.yml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/resources/application.yml
new file mode 100644
index 0000000000..5836ff87b2
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectA-scenario/src/main/resources/application.yml
@@ -0,0 +1,29 @@
+#
+# 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
+spring:
+ cloud:
+ gateway:
+ httpclient:
+ connect-timeout: 2000
+ routes:
+ - id: provider_route
+ uri: http://localhost:18070
+ predicates:
+ - Path=/provider/b/*
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/pom.xml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/pom.xml
new file mode 100644
index 0000000000..dd9752365d
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>gateway-3.x-filter-context-scenario</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>5.0.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>gateway-projectB-scenario</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <version>2.1.0.RELEASE</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>gateway-projectB-scenario</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>1.5.9.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/org/apache/skywalking/apm/toolkit/trace/TraceContext.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/org/apache/skywalking/apm/toolkit/trace/TraceContext.java
new file mode 100644
index 0000000000..dd191c16a0
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/org/apache/skywalking/apm/toolkit/trace/TraceContext.java
@@ -0,0 +1,76 @@
+/*
+ * 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.toolkit.trace;
+
+import java.util.Optional;
+
+/**
+ * Try to access the sky-walking tracer context. The context is not existed, always. only the middleware, component, or
+ * rpc-framework are supported in the current invoke stack, in the same thread, the context will be available.
+ * <p>
+ */
+public class TraceContext {
+
+ /**
+ * Try to get the traceId of current trace context.
+ *
+ * @return traceId, if it exists, or empty {@link String}.
+ */
+ public static String traceId() {
+ return "";
+ }
+
+ /**
+ * Try to get the segmentId of current trace context.
+ *
+ * @return segmentId, if it exists, or empty {@link String}.
+ */
+ public static String segmentId() {
+ return "";
+ }
+
+ /**
+ * Try to get the spanId of current trace context. The spanId is a negative number when the trace context is
+ * missing.
+ *
+ * @return spanId, if it exists, or empty {@link String}.
+ */
+ public static int spanId() {
+ return -1;
+ }
+
+ /**
+ * Try to get the custom value from trace context.
+ *
+ * @return custom data value.
+ */
+ public static Optional<String> getCorrelation(String key) {
+ return Optional.empty();
+ }
+
+ /**
+ * Put the custom key/value into trace context.
+ *
+ * @return previous value if it exists.
+ */
+ public static Optional<String> putCorrelation(String key, String value) {
+ return Optional.empty();
+ }
+
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/Application.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/Application.java
new file mode 100644
index 0000000000..51c94655c7
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/Application.java
@@ -0,0 +1,31 @@
+/*
+ * 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.sc.gateway.projectB;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(value = {"test.apache.skywalking.apm.testcase.sc.gateway.projectB.controller"})
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/controller/TestController.java b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/controller/TestController.java
new file mode 100644
index 0000000000..75c5cef354
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/gateway/projectB/controller/TestController.java
@@ -0,0 +1,117 @@
+/*
+ * 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.sc.gateway.projectB.controller;
+
+import org.apache.skywalking.apm.toolkit.trace.TraceContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.RequestEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Random;
+
+@RestController
+public class TestController {
+
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ static String randomString(int length) {
+ String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ int strLen = str.length();
+ Random random = new Random();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ int number = random.nextInt(strLen);
+ sb.append(str.charAt(number));
+ }
+ return sb.toString();
+ }
+
+ @RequestMapping("/provider/b/testcase")
+ public String testcase() {
+
+ String d1 = randomString(10);
+ String d2 = randomString(13);
+
+ RequestEntity<Void> requestEntity = RequestEntity.get(URI.create("http://localhost:8080/provider/b/context"))
+ .header("x-custom-data1", d1)
+ .header("x-custom-data2", d2)
+ .build();
+
+ logger.info("requestEntity: {}", requestEntity);
+
+ ResponseEntity<String> response = new RestTemplate().exchange(requestEntity, String.class);
+
+ logger.info("response: {}", response);
+
+ if (!response.getStatusCode().is2xxSuccessful()) {
+ throw new IllegalStateException("response status code is not 2xx");
+ }
+
+ String body = response.getBody();
+ if (StringUtils.isEmpty(body)) {
+ throw new IllegalStateException("response body is empty");
+ }
+
+ if (!checkResponseBody(d1, d2, body)) {
+ throw new IllegalStateException("response body is not expected");
+ }
+
+ return "1";
+ }
+
+ private boolean checkResponseBody(String d1, String d2, String body) {
+ String[] lines = body.split("\n");
+ return lines.length == 2 && (lines[0].equals(d1) && lines[1].equals(d1 + ";" + d2));
+ }
+
+ @RequestMapping("/provider/b/context")
+ public String context(@RequestHeader Map<String, String> headers) {
+
+ String traceIdInHeader = headers.get("x-trace-id");
+
+ logger.info("traceId:{} vs {}", TraceContext.traceId(), traceIdInHeader);
+
+ if (!TraceContext.traceId().equals(traceIdInHeader)) {
+ throw new IllegalStateException("response header x-trace-id is not expected");
+ }
+
+ if (StringUtils.isEmpty(headers.get("x-segment-id"))) {
+ throw new IllegalStateException("response header x-segment-id is empty");
+ }
+
+ if (StringUtils.isEmpty(headers.get("x-span-id"))) {
+ throw new IllegalStateException("response header x-span-id is empty");
+ }
+
+ return TraceContext.getCorrelation("custom-data1").orElse("") + "\n" +
+ TraceContext.getCorrelation("custom-data2").orElse("");
+ }
+
+ @RequestMapping("/provider/b/healthCheck")
+ public String healthCheck() {
+ return "Success";
+ }
+}
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/resources/application.properties b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/resources/application.properties
new file mode 100644
index 0000000000..cac2c4d5a1
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/gateway-projectB-scenario/src/main/resources/application.properties
@@ -0,0 +1,17 @@
+#
+# 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=18070
\ No newline at end of file
diff --git a/test/plugin/scenarios/gateway-3.x-filter-context-scenario/pom.xml b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/pom.xml
new file mode 100644
index 0000000000..97851b0090
--- /dev/null
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>gateway-3.x-filter-context-scenario</artifactId>
+ <packaging>pom</packaging>
+ <version>5.0.0</version>
+ <modules>
+ <module>gateway-projectA-scenario</module>
+ <module>gateway-projectB-scenario</module>
+ <module>gateway-dist</module>
+ </modules>
+
+ <name>skywalking-gateway-3.x-filter-context-scenario</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <compiler.version>1.8</compiler.version>
+ <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+ <test.framework.version>3.0.0</test.framework.version>
+ <docker.image.version>${test.framework.version}</docker.image.version>
+ </properties>
+
+ <build>
+ <finalName>gateway-3.x-filter-context-scenario</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <configuration>
+ <source>${compiler.version}</source>
+ <target>${compiler.version}</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/support-version.list
similarity index 88%
copy from apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/gateway-3.x-filter-context-scenario/support-version.list
index de46b3ce11..3662698b83 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/gateway-3.x-filter-context-scenario/support-version.list
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-toolkit-webflux=org.apache.skywalking.apm.toolkit.activation.webflux.WebFluxSkyWalkingOperatorsActivation
\ No newline at end of file
+3.0.0
\ No newline at end of file