From d5efc97c803d3ea249a157751d6aa7af8b0fcc9b Mon Sep 17 00:00:00 2001 From: cngdkxw Date: Fri, 13 Mar 2020 23:13:51 +0800 Subject: [PATCH] RestTemplate async plugin ClassCastException (#4507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ClassCastException * resttemplate 4.x scenario * add support versions & fix expectedData format- Co-authored-by: 吴晟 Wu Sheng --- .github/workflows/plugins-test.yaml | 4 +- .../async/FutureGetInterceptor.java | 5 +- .../config/expectedData.yaml | 148 ++++++++++++++++++ .../configuration.yml | 18 +++ .../resttemplate-4.x-scenario/pom.xml | 79 ++++++++++ .../testcase/resttemplate/BackController.java | 37 +++++ .../resttemplate/FrontController.java | 74 +++++++++ .../ResttemplateConfiguration.java | 38 +++++ .../src/main/resource/log4j2.xml | 31 ++++ .../webapp/WEB-INF/spring-mvc-servlet.xml | 30 ++++ .../src/main/webapp/WEB-INF/web.xml | 35 +++++ .../support-version.list | 72 +++++++++ 12 files changed, 568 insertions(+), 3 deletions(-) create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/config/expectedData.yaml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/configuration.yml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/pom.xml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/resource/log4j2.xml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/web.xml create mode 100644 test/plugin/scenarios/resttemplate-4.x-scenario/support-version.list diff --git a/.github/workflows/plugins-test.yaml b/.github/workflows/plugins-test.yaml index b8f2091f24..7c979331a7 100644 --- a/.github/workflows/plugins-test.yaml +++ b/.github/workflows/plugins-test.yaml @@ -278,7 +278,7 @@ jobs: - name: Run finagle 17.10.0-20.1.0 run: bash test/plugin/run.sh finagle-17.10.x-scenario - Spring41x_SolrJ-Http: + Spring41x_Resttemplate-SolrJ-Http: runs-on: ubuntu-18.04 timeout-minutes: 90 strategy: @@ -306,6 +306,8 @@ jobs: run: ./mvnw --batch-mode -f test/plugin/pom.xml clean package -DskipTests docker:build -DBUILD_NO=local >/dev/null - name: Run spring 4.1.x-4.2.x (20) run: bash test/plugin/run.sh spring-4.1.x-scenario + - name: Run resttemplate 4.0.0.RELEASE-4.3.26.RELEASE (57) + run: bash test/plugin/run.sh resttemplate-4.x-scenario - name: Run solrj 7.x (12) run: bash test/plugin/run.sh solrj-7.x-scenario - name: Run httpclient 2.0-3.1 (5) diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/resttemplate/async/FutureGetInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/resttemplate/async/FutureGetInterceptor.java index 88d322878d..e9bea414d0 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/resttemplate/async/FutureGetInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/resttemplate/async/FutureGetInterceptor.java @@ -24,14 +24,15 @@ import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.plugin.spring.commons.EnhanceCacheObjects; public class FutureGetInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - Object[] cacheValues = (Object[]) objInst.getSkyWalkingDynamicField(); - ContextManager.createLocalSpan("future/get:" + cacheValues[0]); + EnhanceCacheObjects cacheValues = (EnhanceCacheObjects) objInst.getSkyWalkingDynamicField(); + ContextManager.createLocalSpan("future/get:" + cacheValues.getOperationName()); } @Override diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/resttemplate-4.x-scenario/config/expectedData.yaml new file mode 100644 index 0000000000..43d57d39c9 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/config/expectedData.yaml @@ -0,0 +1,148 @@ +# 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. +registryItems: + services: + - {resttemplate-4.x-scenario: nq 0} + instances: + - {resttemplate-4.x-scenario: 1} + operationNames: + - resttemplate-4.x-scenario: [/resttemplate-4.x-scenario/resttemplate/asyncback, /resttemplate-4.x-scenario/resttemplate/case/resttemplate, + /resttemplate-4.x-scenario/resttemplate/syncback] + heartbeat: [] +segmentItems: + - serviceName: resttemplate-4.x-scenario + segmentSize: ge 4 + segments: + - segmentId: not null + spans: + - operationName: /resttemplate-4.x-scenario/resttemplate/case/healthcheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/case/healthcheck'} + - {key: http.method, value: HEAD} + - segmentId: not null + spans: + - operationName: /resttemplate-4.x-scenario/resttemplate/asyncback + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/asyncback'} + - {key: http.method, value: GET} + refs: + - {parentEndpointId: 0, parentEndpoint: /resttemplate-4.x-scenario/resttemplate/case/resttemplate, + networkAddressId: 0, entryEndpointId: 0, refType: CrossProcess, parentSpanId: 1, + parentTraceSegmentId: not null, parentServiceInstanceId: 1, + networkAddress: 'localhost:8080', entryEndpoint: /resttemplate-4.x-scenario/resttemplate/case/resttemplate, + entryServiceInstanceId: 1} + - segmentId: not null + spans: + - operationName: /resttemplate-4.x-scenario/resttemplate/syncback + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/syncback'} + - {key: http.method, value: GET} + refs: + - {parentEndpointId: 0, parentEndpoint: /resttemplate-4.x-scenario/resttemplate/case/resttemplate, + networkAddressId: 0, entryEndpointId: 0, refType: CrossProcess, parentSpanId: 3, + parentTraceSegmentId: not null, parentServiceInstanceId: 1, + networkAddress: 'localhost:8080', entryEndpoint: /resttemplate-4.x-scenario/resttemplate/case/resttemplate, + entryServiceInstanceId: 1} + - segmentId: not null + spans: + - operationName: /resttemplate-4.x-scenario/resttemplate/asyncback + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Exit + peer: localhost:8080 + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/asyncback'} + - {key: http.method, value: GET} + - {operationName: 'future/get:/resttemplate-4.x-scenario/resttemplate/asyncback', + operationId: 0, parentSpanId: 0, spanId: 2, spanLayer: Unknown, startTime: nq 0, + endTime: nq 0, componentId: 0, componentName: '', isError: false, spanType: Local, + peer: '', peerId: 0} + - operationName: /resttemplate-4.x-scenario/resttemplate/syncback + operationId: 0 + parentSpanId: 0 + spanId: 3 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Exit + peer: localhost:8080 + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/syncback'} + - {key: http.method, value: GET} + - operationName: /resttemplate-4.x-scenario/resttemplate/case/resttemplate + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: not null + componentName: '' + isError: false + spanType: Entry + peer: '' + peerId: 0 + tags: + - {key: url, value: 'http://localhost:8080/resttemplate-4.x-scenario/resttemplate/case/resttemplate'} + - {key: http.method, value: GET} diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/configuration.yml b/test/plugin/scenarios/resttemplate-4.x-scenario/configuration.yml new file mode 100644 index 0000000000..37bb74be4e --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/configuration.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. +type: tomcat +entryService: http://localhost:8080/resttemplate-4.x-scenario/resttemplate/case/resttemplate +healthCheck: http://localhost:8080/resttemplate-4.x-scenario/resttemplate/case/healthcheck +framework: resttemplate diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/pom.xml b/test/plugin/scenarios/resttemplate-4.x-scenario/pom.xml new file mode 100644 index 0000000000..24ecf4d827 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/pom.xml @@ -0,0 +1,79 @@ + + + + 4.0.0 + + org.apache.skywalking + resttemplate-4.x-scenario + 6.5.0 + war + + + UTF-8 + UTF-8 + 1.8 + 4.3.0.RELEASE + ${test.framework.version} + 2.8.1 + + + skywalking-resttemplate-4.x-scenario + + + + org.springframework + spring-webmvc + ${test.framework.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + + resttemplate-4.x-scenario + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.0 + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + + diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java new file mode 100644 index 0000000000..28b791cb83 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java @@ -0,0 +1,37 @@ +/* + * 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.testcase.resttemplate; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/resttemplate") +public class BackController { + @RequestMapping(value = "/syncback", method = RequestMethod.GET) + public String syncBack() { + return "Hello back"; + } + + @RequestMapping(value = "/asyncback", method = RequestMethod.GET) + public String asyncBack() { + return "Hello back"; + } +} diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java new file mode 100644 index 0000000000..5798cc58d0 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java @@ -0,0 +1,74 @@ +/* + * 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.testcase.resttemplate; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.AsyncRestTemplate; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/resttemplate/case") +public class FrontController { + + private static Logger logger = LogManager.getLogger(FrontController.class); + + @Autowired + private AsyncRestTemplate asyncRestTemplate; + + @Autowired + private RestTemplate restTemplate; + + @RequestMapping(value = "/healthcheck") + public String healthcheck() { + return "Success"; + } + + @RequestMapping(value = "/resttemplate", method = RequestMethod.GET) + public String front() { + asyncRequest("http://localhost:8080/resttemplate-4.x-scenario/resttemplate/asyncback"); + syncRequest("http://localhost:8080/resttemplate-4.x-scenario/resttemplate/syncback"); + return "Success"; + } + + private String asyncRequest(String url) { + + ListenableFuture> forEntity = asyncRestTemplate.getForEntity(url, String.class); + + try { + forEntity.get(); + } catch (Exception e) { + logger.error("exception:", e); + } + + return "Success"; + } + + private String syncRequest(String url) { + restTemplate.getForObject(url, String.class); + + return "Success"; + } +} diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java new file mode 100644 index 0000000000..8c37a39d0e --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java @@ -0,0 +1,38 @@ +/* + * 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.testcase.resttemplate; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.AsyncRestTemplate; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class ResttemplateConfiguration { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @Bean + public AsyncRestTemplate asyncRestTemplate() { + return new AsyncRestTemplate(); + } +} \ No newline at end of file diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/resource/log4j2.xml b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/resource/log4j2.xml new file mode 100644 index 0000000000..985bd03bf3 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/resource/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml new file mode 100644 index 0000000000..1ede76abd1 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/web.xml b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..7cbbd0e09f --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,35 @@ + + + + skywalking-resttemplate-4.x-scenario + + + spring-mvc + org.springframework.web.servlet.DispatcherServlet + 1 + + + spring-mvc + / + + diff --git a/test/plugin/scenarios/resttemplate-4.x-scenario/support-version.list b/test/plugin/scenarios/resttemplate-4.x-scenario/support-version.list new file mode 100644 index 0000000000..c6c0eb93ae --- /dev/null +++ b/test/plugin/scenarios/resttemplate-4.x-scenario/support-version.list @@ -0,0 +1,72 @@ +# 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. +4.0.0.RELEASE +4.0.1.RELEASE +4.0.2.RELEASE +4.0.3.RELEASE +4.0.4.RELEASE +4.0.5.RELEASE +4.0.6.RELEASE +4.0.7.RELEASE +4.0.8.RELEASE +4.0.9.RELEASE +4.1.0.RELEASE +4.1.2.RELEASE +4.1.3.RELEASE +4.1.4.RELEASE +4.1.5.RELEASE +4.1.6.RELEASE +4.1.7.RELEASE +4.1.8.RELEASE +4.1.9.RELEASE +4.2.0.RELEASE +4.2.1.RELEASE +4.2.2.RELEASE +4.2.3.RELEASE +4.2.4.RELEASE +4.2.5.RELEASE +4.2.6.RELEASE +4.2.7.RELEASE +4.2.8.RELEASE +4.2.9.RELEASE +4.3.0.RELEASE +4.3.1.RELEASE +4.3.2.RELEASE +4.3.3.RELEASE +4.3.4.RELEASE +4.3.5.RELEASE +4.3.6.RELEASE +4.3.7.RELEASE +4.3.8.RELEASE +4.3.8.RELEASE +4.3.9.RELEASE +4.3.10.RELEASE +4.3.11.RELEASE +4.3.12.RELEASE +4.3.13.RELEASE +4.3.14.RELEASE +4.3.15.RELEASE +4.3.16.RELEASE +4.3.17.RELEASE +4.3.18.RELEASE +4.3.19.RELEASE +4.3.20.RELEASE +4.3.21.RELEASE +4.3.22.RELEASE +4.3.23.RELEASE +4.3.24.RELEASE +4.3.25.RELEASE +4.3.26.RELEASE \ No newline at end of file -- GitLab