From 77d94b4d2a906cf160cfab28fd8a045ec2a2ce1d Mon Sep 17 00:00:00 2001 From: "Xin,Zhang" Date: Wed, 26 Aug 2020 13:22:39 +0800 Subject: [PATCH] Fix issue that spring mvc plugin doesn't works when running on reactive api (#5360) --- .github/workflows/plugins-test.0.yaml | 1 + .../v3/HandlerMethodInvokerInterceptor.java | 5 +- .../spring/mvc/v4/SpringTestCaseHelper.java | 6 +- .../spring/mvc/v5/GetBeanInterceptor.java | 27 ++-- .../spring/mvc/v5/InvokeInterceptor.java | 63 +++++++++ ...ractReactiveControllerInstrumentation.java | 120 ++++++++++++++++++ ...bstractSpring5ReactiveInstrumentation.java | 29 +++++ ...InvocableHandlerMethodInstrumentation.java | 64 ++++++++++ .../ReactiveControllerInstrumentation.java | 13 +- ...ReactiveRestControllerInstrumentation.java | 29 +++++ .../src/main/resources/skywalking-plugin.def | 5 +- .../mvc-annotation-commons/pom.xml | 6 + .../commons/JavaxServletRequestHolder.java | 56 ++++++++ .../commons/JavaxServletResponseHolder.java | 35 +++++ .../mvc/commons/ReactiveRequestHolder.java | 61 +++++++++ .../mvc/commons/ReactiveResponseHolder.java | 34 +++++ .../spring/mvc/commons/RequestHolder.java | 33 +++++ .../spring/mvc/commons/ResponseHolder.java | 22 ++++ .../AbstractMethodInterceptor.java | 56 ++++---- .../interceptor/GetBeanInterceptor.java | 5 +- .../InvokeForRequestInterceptor.java | 11 +- .../InvokeHandlerMethodInterceptor.java | 16 ++- .../bin/startup.sh | 21 +++ .../config/expectedData.yaml | 50 ++++++++ .../configuration.yml | 20 +++ .../springmvc-reactive-scenario/pom.xml | 97 ++++++++++++++ .../src/main/assembly/assembly.xml | 41 ++++++ .../sc/springmvcreactive/Application.java | 29 +++++ .../controller/Controller.java | 46 +++++++ .../service/TestService.java | 42 ++++++ .../src/main/resources/application.yml | 18 +++ .../support-version.list | 25 ++++ .../sc/webflux/projectB/Application.java | 29 +++++ .../webflux/projectB/config/CustomFilter.java | 20 +-- .../controller/TestAnnotationController.java | 20 +-- .../projectB/route/RoutingConfiguration.java | 20 +-- .../webflux/projectB/route/TestHandler.java | 20 +-- 37 files changed, 1098 insertions(+), 97 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/InvokeInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractReactiveControllerInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractSpring5ReactiveInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/InvocableHandlerMethodInstrumentation.java rename test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java => apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveControllerInstrumentation.java (68%) create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveRestControllerInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletRequestHolder.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletResponseHolder.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveRequestHolder.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveResponseHolder.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/RequestHolder.java create mode 100644 apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ResponseHolder.java create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/bin/startup.sh create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/config/expectedData.yaml create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/configuration.yml create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/pom.xml create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/src/main/assembly/assembly.xml create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/Application.java create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/controller/Controller.java create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/service/TestService.java create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/src/main/resources/application.yml create mode 100644 test/plugin/scenarios/springmvc-reactive-scenario/support-version.list create mode 100644 test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java rename test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/{org => test}/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java (56%) rename test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/{org => test}/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java (64%) rename test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/{org => test}/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java (53%) rename test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/{org => test}/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java (55%) diff --git a/.github/workflows/plugins-test.0.yaml b/.github/workflows/plugins-test.0.yaml index 63fa1a227..c40ec57a9 100644 --- a/.github/workflows/plugins-test.0.yaml +++ b/.github/workflows/plugins-test.0.yaml @@ -56,6 +56,7 @@ jobs: - { name: 'grpc-scenario', title: 'gRPC 1.6.0-1.25.0 (22)' } - { name: 'gson-scenario', title: 'Gson (7)' } - { name: 'elasticjob-3.x-scenario', title: 'elasticjob-3.x-scenario (1)' } + - { name: 'springmvc-reactive-scenario', title: 'springmvc-reactive-scenario (7)' } steps: - uses: actions/checkout@v2 with: diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v3/HandlerMethodInvokerInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v3/HandlerMethodInvokerInterceptor.java index 212333873..dd6058714 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v3/HandlerMethodInvokerInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v3/HandlerMethodInvokerInterceptor.java @@ -19,10 +19,12 @@ package org.apache.skywalking.apm.plugin.spring.mvc.v3; import java.lang.reflect.Method; +import javax.servlet.http.HttpServletResponse; 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 org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletResponseHolder; import org.springframework.web.context.request.NativeWebRequest; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; @@ -38,7 +40,8 @@ public class HandlerMethodInvokerInterceptor implements InstanceMethodsAroundInt Object handler = allArguments[1]; if (handler instanceof EnhancedInstance) { ContextManager.getRuntimeContext() - .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((NativeWebRequest) allArguments[2]).getNativeResponse()); + .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, new JavaxServletResponseHolder( + (HttpServletResponse) ((NativeWebRequest) allArguments[2]).getNativeResponse())); } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/SpringTestCaseHelper.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/SpringTestCaseHelper.java index ffcee2a6f..2447d20dd 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/SpringTestCaseHelper.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/SpringTestCaseHelper.java @@ -22,14 +22,16 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.skywalking.apm.agent.core.context.ContextManager; import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletRequestHolder; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletResponseHolder; public final class SpringTestCaseHelper { public final static void createCaseHandler(HttpServletRequest request, HttpServletResponse response, CaseHandler a) throws Throwable { ContextManager.createLocalSpan("For-Test"); - ContextManager.getRuntimeContext().put(Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT, request); - ContextManager.getRuntimeContext().put(Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT, response); + ContextManager.getRuntimeContext().put(Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT, new JavaxServletRequestHolder(request)); + ContextManager.getRuntimeContext().put(Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT, new JavaxServletResponseHolder(response)); a.handleCase(); ContextManager.stopSpan(); ContextManager.getRuntimeContext().remove(Constants.CONTROLLER_METHOD_STACK_DEPTH); diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java index 51e21852d..b2014c7ab 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java @@ -22,6 +22,8 @@ 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 org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletRequestHolder; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletResponseHolder; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -36,26 +38,33 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESP public class GetBeanInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - MethodInterceptResult result) throws Throwable { + MethodInterceptResult result) throws Throwable { } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - Object ret) throws Throwable { + Object ret) throws Throwable { if (ret instanceof EnhancedInstance) { - ContextManager.getRuntimeContext() - .put(REQUEST_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) - .getRequest()); - ContextManager.getRuntimeContext() - .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) - .getResponse()); + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes != null) { + ContextManager.getRuntimeContext() + .put( + REQUEST_KEY_IN_RUNTIME_CONTEXT, + new JavaxServletRequestHolder(requestAttributes.getRequest()) + ); + ContextManager.getRuntimeContext() + .put( + RESPONSE_KEY_IN_RUNTIME_CONTEXT, + new JavaxServletResponseHolder(requestAttributes.getResponse()) + ); + } } return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class[] argumentsTypes, Throwable t) { + Class[] argumentsTypes, Throwable t) { } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/InvokeInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/InvokeInterceptor.java new file mode 100644 index 000000000..d5f57f78f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/InvokeInterceptor.java @@ -0,0 +1,63 @@ +/* + * 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.spring.mvc.v5; + +import java.lang.reflect.Method; +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 org.apache.skywalking.apm.plugin.spring.mvc.commons.ReactiveRequestHolder; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.ReactiveResponseHolder; +import org.springframework.web.server.ServerWebExchange; + +import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT; +import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; + +public class InvokeInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final MethodInterceptResult result) throws Throwable { + ServerWebExchange exchange = (ServerWebExchange) allArguments[0]; + ContextManager.getRuntimeContext() + .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, new ReactiveResponseHolder(exchange.getResponse())); + ContextManager.getRuntimeContext() + .put(REQUEST_KEY_IN_RUNTIME_CONTEXT, new ReactiveRequestHolder(exchange.getRequest())); + } + + @Override + public Object afterMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractReactiveControllerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractReactiveControllerInstrumentation.java new file mode 100644 index 000000000..2dac559d0 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractReactiveControllerInstrumentation.java @@ -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. + */ + +package org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive; + +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.DeclaredInstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants; +import org.apache.skywalking.apm.plugin.spring.mvc.v5.define.ControllerInstrumentation; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher.byMethodInheritanceAnnotationMatcher; + +/** + * {@link ControllerInstrumentation} enhance all constructor and method annotated with + * org.springframework.web.bind.annotation.RequestMapping that class has + * org.springframework.stereotype.Controller annotation. + * + * ControllerConstructorInterceptor set the controller base path to + * dynamic field before execute constructor. + * + * org.apache.skywalking.apm.plugin.spring.mvc.v4.RequestMappingMethodInterceptor get the request path + * from dynamic field first, if not found, RequestMappingMethodInterceptor generate request path that + * combine the path value of current annotation on current method and the base path and set the new path to the dynamic + * filed + */ +public abstract class AbstractReactiveControllerInstrumentation extends AbstractSpring5ReactiveInstrumentation { + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return "org.apache.skywalking.apm.plugin.spring.mvc.v5.ControllerConstructorInterceptor"; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new DeclaredInstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.RequestMapping")); + } + + @Override + public String getMethodsInterceptor() { + return Constants.REQUEST_MAPPING_METHOD_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new DeclaredInstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.GetMapping")) + .or(byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.PostMapping"))) + .or(byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.PutMapping"))) + .or(byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.DeleteMapping"))) + .or(byMethodInheritanceAnnotationMatcher( + named("org.springframework.web.bind.annotation.PatchMapping"))); + } + + @Override + public String getMethodsInterceptor() { + return Constants.REST_MAPPING_METHOD_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return ClassAnnotationMatch.byClassAnnotationMatch(getEnhanceAnnotations()); + } + + protected abstract String[] getEnhanceAnnotations(); + +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractSpring5ReactiveInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractSpring5ReactiveInstrumentation.java new file mode 100644 index 000000000..8d37b84d6 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/AbstractSpring5ReactiveInstrumentation.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 org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; + +public abstract class AbstractSpring5ReactiveInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + public static final String WITHNESS_CLASSES = "org.springframework.web.reactive.result.method.InvocableHandlerMethod"; + + @Override + protected final String[] witnessClasses() { + return new String[] {WITHNESS_CLASSES}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/InvocableHandlerMethodInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/InvocableHandlerMethodInstrumentation.java new file mode 100644 index 000000000..0e09d5ccb --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/InvocableHandlerMethodInstrumentation.java @@ -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. + */ + +package org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive; + +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.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +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.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class InvocableHandlerMethodInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + @Override + protected ClassMatch enhanceClass() { + return byName("org.springframework.web.reactive.result.method.InvocableHandlerMethod"); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("getMethodArgumentValues").and( + takesArgumentWithType(0, "org.springframework.web.server.ServerWebExchange")); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.spring.mvc.v5.InvokeInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveControllerInstrumentation.java similarity index 68% rename from test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java rename to apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveControllerInstrumentation.java index 733fdf41a..3c1091e70 100644 --- a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveControllerInstrumentation.java @@ -15,15 +15,14 @@ * limitations under the License. */ -package org.apache.skywalking.apm.testcase.sc.webflux.projectB; +package org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; +public class ReactiveControllerInstrumentation extends AbstractReactiveControllerInstrumentation { -@SpringBootApplication -public class Application { + public static final String ENHANCE_ANNOTATION = "org.springframework.stereotype.Controller"; - public static void main(String[] args) { - SpringApplication.run(Application.class, args); + @Override + protected String[] getEnhanceAnnotations() { + return new String[] {ENHANCE_ANNOTATION}; } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveRestControllerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveRestControllerInstrumentation.java new file mode 100644 index 000000000..693bb5db3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/reactive/ReactiveRestControllerInstrumentation.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 org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive; + +public class ReactiveRestControllerInstrumentation extends AbstractReactiveControllerInstrumentation { + + public static final String ENHANCE_ANNOTATION = "org.springframework.web.bind.annotation.RestController"; + + @Override + protected String[] getEnhanceAnnotations() { + return new String[] {ENHANCE_ANNOTATION}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def index fa3b452c1..38d7929aa 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def @@ -16,4 +16,7 @@ spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.ControllerInstrumentation spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.RestControllerInstrumentation -spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.HandlerMethodInstrumentation \ No newline at end of file +spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.HandlerMethodInstrumentation +spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive.InvocableHandlerMethodInstrumentation +spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive.ReactiveControllerInstrumentation +spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.reactive.ReactiveRestControllerInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/pom.xml index c2c2e2301..e274c38a3 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/pom.xml @@ -49,6 +49,12 @@ ${spring-webmvc.version} provided + + org.springframework + spring-web + 5.2.4.RELEASE + provided + javax.servlet javax.servlet-api diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletRequestHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletRequestHolder.java new file mode 100644 index 000000000..8eb5705ba --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletRequestHolder.java @@ -0,0 +1,56 @@ +/* + * 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.spring.mvc.commons; + +import java.util.Enumeration; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; + +public class JavaxServletRequestHolder implements RequestHolder { + + private final HttpServletRequest request; + + public JavaxServletRequestHolder(HttpServletRequest request) { + this.request = request; + } + + @Override + public String getHeader(final String headerName) { + return request.getHeader(headerName); + } + + @Override + public Enumeration getHeaders(final String headerName) { + return request.getHeaders(headerName); + } + + @Override + public String requestURL() { + return request.getRequestURL().toString(); + } + + @Override + public String requestMethod() { + return request.getMethod(); + } + + @Override + public Map getParameterMap() { + return request.getParameterMap(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletResponseHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletResponseHolder.java new file mode 100644 index 000000000..7fc014456 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/JavaxServletResponseHolder.java @@ -0,0 +1,35 @@ +/* + * 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.spring.mvc.commons; + +import javax.servlet.http.HttpServletResponse; + +public class JavaxServletResponseHolder implements ResponseHolder { + + private final HttpServletResponse response; + + public JavaxServletResponseHolder(final HttpServletResponse response) { + this.response = response; + } + + @Override + public int statusCode() { + return response.getStatus(); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveRequestHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveRequestHolder.java new file mode 100644 index 000000000..d7130775c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveRequestHolder.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.spring.mvc.commons; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import org.springframework.http.server.reactive.ServerHttpRequest; + +public class ReactiveRequestHolder implements RequestHolder { + private final ServerHttpRequest serverHttpRequest; + + public ReactiveRequestHolder(final ServerHttpRequest serverHttpRequest) { + this.serverHttpRequest = serverHttpRequest; + } + + @Override + public String getHeader(final String headerName) { + return this.serverHttpRequest.getHeaders().getFirst(headerName); + } + + @Override + public Enumeration getHeaders(final String headerName) { + return Collections.enumeration(this.serverHttpRequest.getHeaders().get(headerName)); + } + + @Override + public String requestURL() { + return this.serverHttpRequest.getURI().toString(); + } + + @Override + public String requestMethod() { + return this.serverHttpRequest.getMethodValue(); + } + + @Override + public Map getParameterMap() { + Map parameterMap = new HashMap<>(this.serverHttpRequest.getQueryParams().size()); + this.serverHttpRequest.getQueryParams().forEach((key, value) -> { + parameterMap.put(key, value.toArray(new String[0])); + }); + return parameterMap; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveResponseHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveResponseHolder.java new file mode 100644 index 000000000..7ef27fb77 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ReactiveResponseHolder.java @@ -0,0 +1,34 @@ +/* + * 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.spring.mvc.commons; + +import org.springframework.http.server.reactive.ServerHttpResponse; + +public class ReactiveResponseHolder implements ResponseHolder { + + private final ServerHttpResponse response; + + public ReactiveResponseHolder(final ServerHttpResponse response) { + this.response = response; + } + + @Override + public int statusCode() { + return response.getStatusCode().value(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/RequestHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/RequestHolder.java new file mode 100644 index 000000000..8f4c933d6 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/RequestHolder.java @@ -0,0 +1,33 @@ +/* + * 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.spring.mvc.commons; + +import java.util.Enumeration; +import java.util.Map; + +public interface RequestHolder { + String getHeader(String headerName); + + Enumeration getHeaders(String headerName); + + String requestURL(); + + String requestMethod(); + + Map getParameterMap(); +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ResponseHolder.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ResponseHolder.java new file mode 100644 index 000000000..b46c4f236 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/ResponseHolder.java @@ -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. + */ + +package org.apache.skywalking.apm.plugin.spring.mvc.commons; + +public interface ResponseHolder { + int statusCode(); +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java index d7817d67d..9015ef8fe 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java @@ -22,12 +22,9 @@ import java.lang.reflect.Method; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedList; -import java.util.Map; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.apache.skywalking.apm.agent.core.context.CarrierItem; import org.apache.skywalking.apm.agent.core.context.ContextCarrier; import org.apache.skywalking.apm.agent.core.context.ContextManager; @@ -41,6 +38,8 @@ import org.apache.skywalking.apm.agent.core.util.CollectionUtil; import org.apache.skywalking.apm.agent.core.util.MethodUtil; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.RequestHolder; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.ResponseHolder; import org.apache.skywalking.apm.plugin.spring.mvc.commons.SpringMVCPluginConfig; import org.apache.skywalking.apm.plugin.spring.mvc.commons.exception.IllegalMethodStackDepthException; import org.apache.skywalking.apm.plugin.spring.mvc.commons.exception.ServletResponseNotFoundException; @@ -96,8 +95,8 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround operationName = getAcceptedMethodTypes(method) + requestURL; } - HttpServletRequest request = (HttpServletRequest) ContextManager.getRuntimeContext() - .get(REQUEST_KEY_IN_RUNTIME_CONTEXT); + RequestHolder request = (RequestHolder) ContextManager.getRuntimeContext() + .get(REQUEST_KEY_IN_RUNTIME_CONTEXT); if (request != null) { StackDepth stackDepth = (StackDepth) ContextManager.getRuntimeContext().get(CONTROLLER_METHOD_STACK_DEPTH); @@ -110,8 +109,8 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround } AbstractSpan span = ContextManager.createEntrySpan(operationName, contextCarrier); - Tags.URL.set(span, request.getRequestURL().toString()); - Tags.HTTP.METHOD.set(span, request.getMethod()); + Tags.URL.set(span, request.requestURL()); + Tags.HTTP.METHOD.set(span, request.requestMethod()); span.setComponent(ComponentsDefine.SPRING_MVC_ANNOTATION); SpanLayer.asHttp(span); @@ -161,8 +160,8 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround return ret; } - HttpServletRequest request = (HttpServletRequest) ContextManager.getRuntimeContext() - .get(REQUEST_KEY_IN_RUNTIME_CONTEXT); + RequestHolder request = (RequestHolder) ContextManager.getRuntimeContext() + .get(REQUEST_KEY_IN_RUNTIME_CONTEXT); if (request != null) { StackDepth stackDepth = (StackDepth) ContextManager.getRuntimeContext().get(CONTROLLER_METHOD_STACK_DEPTH); @@ -175,16 +174,16 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround AbstractSpan span = ContextManager.activeSpan(); if (stackDepth.depth() == 0) { - HttpServletResponse response = (HttpServletResponse) ContextManager.getRuntimeContext() - .get( - RESPONSE_KEY_IN_RUNTIME_CONTEXT); + ResponseHolder response = (ResponseHolder) ContextManager.getRuntimeContext() + .get( + RESPONSE_KEY_IN_RUNTIME_CONTEXT); if (response == null) { throw new ServletResponseNotFoundException(); } - if (IS_SERVLET_GET_STATUS_METHOD_EXIST && response.getStatus() >= 400) { + if (IS_SERVLET_GET_STATUS_METHOD_EXIST && response.statusCode() >= 400) { span.errorOccurred(); - Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus())); + Tags.STATUS_CODE.set(span, Integer.toString(response.statusCode())); } ContextManager.getRuntimeContext().remove(REQUEST_KEY_IN_RUNTIME_CONTEXT); @@ -209,7 +208,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround ContextManager.activeSpan().errorOccurred().log(t); } - private void collectHttpParam(HttpServletRequest request, AbstractSpan span) { + private void collectHttpParam(RequestHolder request, AbstractSpan span) { final Map parameterMap = request.getParameterMap(); if (parameterMap != null && !parameterMap.isEmpty()) { String tagValue = CollectionUtil.toString(parameterMap); @@ -219,21 +218,26 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround } } - private void collectHttpHeaders(HttpServletRequest request, AbstractSpan span) { + private void collectHttpHeaders(RequestHolder request, AbstractSpan span) { final List headersList = new LinkedList<>(); - SpringMVCPluginConfig.Plugin.Http.INCLUDE_HTTP_HEADERS.stream().filter(headerName -> request.getHeaders(headerName) != null).forEach(headerName -> { - Enumeration headerValues = request.getHeaders(headerName); - List valueList = Collections.list(headerValues); - if (!CollectionUtil.isEmpty(valueList)) { - String headerValue = valueList.toString(); - headersList.add(headerName + "=" + headerValue); - } - }); + SpringMVCPluginConfig.Plugin.Http.INCLUDE_HTTP_HEADERS.stream() + .filter( + headerName -> request.getHeaders(headerName) != null) + .forEach(headerName -> { + Enumeration headerValues = request.getHeaders( + headerName); + List valueList = Collections.list( + headerValues); + if (!CollectionUtil.isEmpty(valueList)) { + String headerValue = valueList.toString(); + headersList.add(headerName + "=" + headerValue); + } + }); if (!headersList.isEmpty()) { String tagValue = headersList.stream().collect(Collectors.joining("\n")); tagValue = SpringMVCPluginConfig.Plugin.Http.HTTP_HEADERS_LENGTH_THRESHOLD > 0 ? - StringUtil.cut(tagValue, SpringMVCPluginConfig.Plugin.Http.HTTP_HEADERS_LENGTH_THRESHOLD) : tagValue; + StringUtil.cut(tagValue, SpringMVCPluginConfig.Plugin.Http.HTTP_HEADERS_LENGTH_THRESHOLD) : tagValue; Tags.HTTP.HEADERS.set(span, tagValue); } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/GetBeanInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/GetBeanInterceptor.java index 6cc6c6233..3fd2d6175 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/GetBeanInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/GetBeanInterceptor.java @@ -23,6 +23,7 @@ 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 org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletRequestHolder; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -44,8 +45,8 @@ public class GetBeanInterceptor implements InstanceMethodsAroundInterceptor { Object ret) throws Throwable { if (ret instanceof EnhancedInstance) { ContextManager.getRuntimeContext() - .put(REQUEST_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) - .getRequest()); + .put(REQUEST_KEY_IN_RUNTIME_CONTEXT, new JavaxServletRequestHolder(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) + .getRequest())); } return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeForRequestInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeForRequestInterceptor.java index e5430f7be..4360048f6 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeForRequestInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeForRequestInterceptor.java @@ -19,10 +19,12 @@ package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor; import java.lang.reflect.Method; +import javax.servlet.http.HttpServletResponse; 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 org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletResponseHolder; import org.springframework.web.context.request.NativeWebRequest; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; @@ -34,20 +36,21 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESP public class InvokeForRequestInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - MethodInterceptResult result) throws Throwable { + MethodInterceptResult result) throws Throwable { ContextManager.getRuntimeContext() - .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((NativeWebRequest) allArguments[0]).getNativeResponse()); + .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, new JavaxServletResponseHolder( + (HttpServletResponse) ((NativeWebRequest) allArguments[0]).getNativeResponse())); } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - Object ret) throws Throwable { + Object ret) throws Throwable { return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class[] argumentsTypes, Throwable t) { + Class[] argumentsTypes, Throwable t) { } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeHandlerMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeHandlerMethodInterceptor.java index 8785d554a..9d7df037d 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeHandlerMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/InvokeHandlerMethodInterceptor.java @@ -19,10 +19,14 @@ package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor; import java.lang.reflect.Method; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; 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 org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletRequestHolder; +import org.apache.skywalking.apm.plugin.spring.mvc.commons.JavaxServletResponseHolder; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; @@ -30,21 +34,23 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESP public class InvokeHandlerMethodInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - MethodInterceptResult result) throws Throwable { + MethodInterceptResult result) throws Throwable { if (allArguments[2] instanceof EnhancedInstance) { - ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, allArguments[1]); - ContextManager.getRuntimeContext().put(REQUEST_KEY_IN_RUNTIME_CONTEXT, allArguments[0]); + ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, new JavaxServletResponseHolder( + (HttpServletResponse) allArguments[1])); + ContextManager.getRuntimeContext().put(REQUEST_KEY_IN_RUNTIME_CONTEXT, new JavaxServletRequestHolder( + (HttpServletRequest) allArguments[0])); } } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - Object ret) throws Throwable { + Object ret) throws Throwable { return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class[] argumentsTypes, Throwable t) { + Class[] argumentsTypes, Throwable t) { } } diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/bin/startup.sh b/test/plugin/scenarios/springmvc-reactive-scenario/bin/startup.sh new file mode 100644 index 000000000..a6b8ccb58 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-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 -jar ${agent_opts} ${home}/../libs/springmvc-reactive-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/config/expectedData.yaml b/test/plugin/scenarios/springmvc-reactive-scenario/config/expectedData.yaml new file mode 100644 index 000000000..3659a7696 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/config/expectedData.yaml @@ -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. + +segmentItems: +- serviceName: springmvc-reactive-scenario + segmentSize: nq 0 + segments: + - segmentId: not null + spans: + - operationName: H2/JDBI/PreparedStatement/executeQuery + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Database + startTime: not null + endTime: not null + componentId: 32 + isError: false + spanType: Exit + peer: not null + tags: + - {key: db.type, value: not null} + - {key: db.instance, value: test} + - {key: db.statement, value: not null} + skipAnalysis: 'false' + - operationName: /testcase/{test} + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: not null + endTime: not null + componentId: 14 + tags: + - {key: url, value: not null} + - {key: http.method, value: GET} + skipAnalysis: 'false' \ No newline at end of file diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/configuration.yml b/test/plugin/scenarios/springmvc-reactive-scenario/configuration.yml new file mode 100644 index 000000000..12cb454c0 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/configuration.yml @@ -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. + +type: jvm +entryService: http://localhost:8080/testcase/test +healthCheck: http://localhost:8080/testcase/healthCheck +startScript: ./bin/startup.sh diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/pom.xml b/test/plugin/scenarios/springmvc-reactive-scenario/pom.xml new file mode 100644 index 000000000..aa3c075cd --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/pom.xml @@ -0,0 +1,97 @@ + + + + 4.0.0 + + org.apache.skywalking + springmvc-reactive-scenario + jar + 5.0.0 + + skywalking-springmvc-reactive-scenario + + + UTF-8 + 2.1.1.RELEASE + ${test.framework.version} + + + + + org.springframework.boot + spring-boot-starter-webflux + ${test.framework.version} + + + com.h2database + h2 + 1.4.200 + + + + + springmvc-reactive-scenario + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.0 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.springframework.boot + spring-boot-maven-plugin + 1.5.9.RELEASE + + + + repackage + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + + diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..09e49a2cb --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/springmvc-reactive-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/Application.java b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/Application.java new file mode 100644 index 000000000..4d6eae358 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/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.springmvcreactive; + +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/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/controller/Controller.java b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/controller/Controller.java new file mode 100644 index 000000000..3359de3a2 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/controller/Controller.java @@ -0,0 +1,46 @@ +/* + * 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.springmvcreactive.controller; + +import java.sql.SQLException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import test.apache.skywalking.apm.testcase.sc.springmvcreactive.service.TestService; + +@RestController +public class Controller { + + @Autowired + private TestService testService; + + @RequestMapping("/testcase/healthCheck") + public String healthCheck() { + return "healthCheck"; + } + + @GetMapping("/testcase/{test}") + public Mono hello(@RequestBody(required = false) String body, @PathVariable("test") String test) throws SQLException { + testService.executeSQL(); + return Mono.just("Hello World"); + } +} diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/service/TestService.java b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/service/TestService.java new file mode 100644 index 000000000..aff108f3b --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/springmvcreactive/service/TestService.java @@ -0,0 +1,42 @@ +/* + * 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.springmvcreactive.service; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import javax.annotation.PostConstruct; +import org.springframework.stereotype.Service; + +@Service +public class TestService { + + private Connection connection; + + @PostConstruct + private void setUp() throws SQLException { + connection = DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", ""); + } + + public void executeSQL() throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1 = 1"); + preparedStatement.executeQuery(); + } + +} diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/src/main/resources/application.yml b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/resources/application.yml new file mode 100644 index 000000000..e916bcda1 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/src/main/resources/application.yml @@ -0,0 +1,18 @@ +# +# 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 \ No newline at end of file diff --git a/test/plugin/scenarios/springmvc-reactive-scenario/support-version.list b/test/plugin/scenarios/springmvc-reactive-scenario/support-version.list new file mode 100644 index 000000000..553ef8e28 --- /dev/null +++ b/test/plugin/scenarios/springmvc-reactive-scenario/support-version.list @@ -0,0 +1,25 @@ +# 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.0-2.1.0 are supported, but due to the status code bug(https://github.com/spring-projects/spring-framework/issues/21901) +# we don’t test them +2.1.1.RELEASE +2.1.2.RELEASE +2.1.3.RELEASE +2.1.4.RELEASE +2.1.5.RELEASE +2.1.6.RELEASE +2.1.7.RELEASE diff --git a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/Application.java new file mode 100644 index 000000000..0278e9945 --- /dev/null +++ b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/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.webflux.projectB; + +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/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java similarity index 56% rename from test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java rename to test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java index 5d850df8f..001a254ab 100644 --- a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java +++ b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/config/CustomFilter.java @@ -1,21 +1,21 @@ /* - * 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 + * 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. + * 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.testcase.sc.webflux.projectB.config; +package test.apache.skywalking.apm.testcase.sc.webflux.projectB.config; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; diff --git a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java similarity index 64% rename from test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java rename to test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java index 2b45fe924..dfd121f2d 100644 --- a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java +++ b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/controller/TestAnnotationController.java @@ -1,21 +1,21 @@ /* - * 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 + * 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. + * 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.testcase.sc.webflux.projectB.controller; +package test.apache.skywalking.apm.testcase.sc.webflux.projectB.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java similarity index 53% rename from test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java rename to test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java index 43bc5b9a5..137ea5d54 100644 --- a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java +++ b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/RoutingConfiguration.java @@ -1,21 +1,21 @@ /* - * 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 + * 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. + * 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.testcase.sc.webflux.projectB.route; +package test.apache.skywalking.apm.testcase.sc.webflux.projectB.route; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java similarity index 55% rename from test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java rename to test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java index c7e6afa13..78a7cfc02 100644 --- a/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/org/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java +++ b/test/plugin/scenarios/webflux-scenario/webflux-projectB-scenario/src/main/java/test/apache/skywalking/apm/testcase/sc/webflux/projectB/route/TestHandler.java @@ -1,21 +1,21 @@ /* - * 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 + * 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. + * 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.testcase.sc.webflux.projectB.route; +package test.apache.skywalking.apm.testcase.sc.webflux.projectB.route; import org.springframework.http.MediaType; import org.springframework.stereotype.Component;