Make MVC plugin support inherited annotations from interface (#4278)
This commit is contained in:
parent
3252b6ed08
commit
5c6914fc9e
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.match;
|
||||
|
||||
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
|
||||
import net.bytebuddy.description.annotation.AnnotationList;
|
||||
import net.bytebuddy.description.annotation.AnnotationSource;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.description.method.MethodList;
|
||||
import net.bytebuddy.description.method.ParameterList;
|
||||
import net.bytebuddy.description.type.TypeDefinition;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.description.type.TypeList;
|
||||
import net.bytebuddy.matcher.CollectionItemMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.annotationType;
|
||||
|
||||
/**
|
||||
* Matching used to match method annotations, Can match annotations on interface methods
|
||||
* @author jialong
|
||||
*/
|
||||
@HashCodeAndEqualsPlugin.Enhance
|
||||
public class MethodInheritanceAnnotationMatcher<T extends MethodDescription> extends ElementMatcher.Junction.AbstractBase<T> {
|
||||
/**
|
||||
* The matcher to be applied to the provided annotation list.
|
||||
*/
|
||||
private final ElementMatcher<? super AnnotationList> matcher;
|
||||
|
||||
/**
|
||||
* Creates a new matcher for the annotations of an annotated element.
|
||||
*
|
||||
* @param matcher The matcher to be applied to the provided annotation list.
|
||||
*/
|
||||
public MethodInheritanceAnnotationMatcher(ElementMatcher<? super AnnotationList> matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(T target) {
|
||||
if (matcher.matches(target.getDeclaredAnnotations())) {
|
||||
return true;
|
||||
}
|
||||
String name = target.getName();
|
||||
ParameterList<?> parameters = target.getParameters();
|
||||
|
||||
TypeDefinition declaringType = target.getDeclaringType();
|
||||
return recursiveMatches(declaringType, name, parameters);
|
||||
}
|
||||
|
||||
|
||||
private boolean recursiveMatches(TypeDefinition typeDefinition, String methodName, ParameterList<?> parameters) {
|
||||
TypeList.Generic interfaces = typeDefinition.getInterfaces();
|
||||
for (TypeDescription.Generic implInterface : interfaces) {
|
||||
if (recursiveMatches(implInterface, methodName, parameters)) {
|
||||
return true;
|
||||
}
|
||||
MethodList<MethodDescription.InGenericShape> declaredMethods = implInterface.getDeclaredMethods();
|
||||
for (MethodDescription declaredMethod : declaredMethods) {
|
||||
if (Objects.equals(declaredMethod.getName(), methodName) && parameterEquals(parameters, declaredMethod.getParameters())) {
|
||||
return matcher.matches(declaredMethod.getDeclaredAnnotations());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean parameterEquals(ParameterList<?> source, ParameterList<?> impl) {
|
||||
if (source.size() != impl.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < source.size(); i++) {
|
||||
if (!Objects.equals(source.get(i).getType(), impl.get(i).getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T extends AnnotationSource> ElementMatcher.Junction<T> byMethodInheritanceAnnotationMatcher(ElementMatcher<? super TypeDescription> matcher) {
|
||||
return new MethodInheritanceAnnotationMatcher(new CollectionItemMatcher<>(annotationType(matcher)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.bytebuddy;
|
||||
|
||||
import net.bytebuddy.description.annotation.AnnotationSource;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher.byMethodInheritanceAnnotationMatcher;
|
||||
|
||||
/**
|
||||
* @author jialong
|
||||
*/
|
||||
public class MethodInheritanceAnnotationMatcherTest {
|
||||
|
||||
@Test
|
||||
public void testMatch() throws Exception {
|
||||
ElementMatcher.Junction<AnnotationSource> matcher = byMethodInheritanceAnnotationMatcher(named("org.apache.skywalking.apm.agent.core.plugin.bytebuddy.MethodInheritanceAnnotationMatcherTest$TestAnnotaion"));
|
||||
|
||||
Assert.assertTrue(matcher.matches(new MethodDescription.ForLoadedMethod(TestBean.class.getMethod("test1", String.class))));
|
||||
Assert.assertTrue(matcher.matches(new MethodDescription.ForLoadedMethod(TestBean.class.getMethod("test2", String.class))));
|
||||
Assert.assertTrue(matcher.matches(new MethodDescription.ForLoadedMethod(TestBean.class.getMethod("test3", String.class))));
|
||||
}
|
||||
|
||||
private class TestBean implements TestInterface1, TestInterface3 {
|
||||
@Override
|
||||
public String test1(String test) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String test2(String test) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String test3(String test) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private interface TestInterface1 extends TestInterface2 {
|
||||
@TestAnnotaion
|
||||
String test1(String test);
|
||||
}
|
||||
|
||||
private interface TestInterface2 {
|
||||
@TestAnnotaion
|
||||
String test2(String test);
|
||||
}
|
||||
|
||||
private interface TestInterface3 {
|
||||
@TestAnnotaion
|
||||
String test3(String test);
|
||||
}
|
||||
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TestAnnotaion {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch;
|
|||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher.byMethodInheritanceAnnotationMatcher;
|
||||
import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_MAPPING_METHOD_INTERCEPTOR;
|
||||
|
||||
/**
|
||||
|
|
@ -65,7 +66,7 @@ public class ControllerInstrumentation extends AbstractSpring3Instrumentation {
|
|||
new DeclaredInstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return isAnnotatedWith(named(REQUEST_MAPPING_ENHANCE_ANNOTATION));
|
||||
return byMethodInheritanceAnnotationMatcher(named(REQUEST_MAPPING_ENHANCE_ANNOTATION));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
|||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher.byMethodInheritanceAnnotationMatcher;
|
||||
|
||||
/**
|
||||
* {@link ControllerInstrumentation} enhance all constructor and method annotated with
|
||||
|
|
@ -68,7 +69,7 @@ public abstract class AbstractControllerInstrumentation extends AbstractSpring4I
|
|||
new DeclaredInstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return isAnnotatedWith(named("org.springframework.web.bind.annotation.RequestMapping"));
|
||||
return byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.RequestMapping"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -84,11 +85,11 @@ public abstract class AbstractControllerInstrumentation extends AbstractSpring4I
|
|||
new DeclaredInstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return isAnnotatedWith(named("org.springframework.web.bind.annotation.GetMapping"))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PostMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PutMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.DeleteMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PatchMapping")));
|
||||
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
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
|||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher.byMethodInheritanceAnnotationMatcher;
|
||||
|
||||
/**
|
||||
* {@link ControllerInstrumentation} enhance all constructor and method annotated with
|
||||
|
|
@ -67,7 +68,7 @@ public abstract class AbstractControllerInstrumentation extends AbstractSpring5I
|
|||
new DeclaredInstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return isAnnotatedWith(named("org.springframework.web.bind.annotation.RequestMapping"));
|
||||
return byMethodInheritanceAnnotationMatcher(named("org.springframework.web.bind.annotation.RequestMapping"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -83,11 +84,11 @@ public abstract class AbstractControllerInstrumentation extends AbstractSpring5I
|
|||
new DeclaredInstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return isAnnotatedWith(named("org.springframework.web.bind.annotation.GetMapping"))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PostMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PutMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.DeleteMapping")))
|
||||
.or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PatchMapping")));
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Tools for parsing path from annotation
|
||||
* @author jialong
|
||||
*/
|
||||
public class ParsePathUtil {
|
||||
|
||||
public static String recursiveParseMethodAnnotaion(Method method, Function<Method, String> parseFunc) {
|
||||
String result = parseFunc.apply(method);
|
||||
if (Objects.isNull(result)) {
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
result = recursiveMatches(declaringClass, method.getName(), method.getParameters(), parseFunc);
|
||||
}
|
||||
return Optional.ofNullable(result).orElse("");
|
||||
}
|
||||
|
||||
private static String recursiveMatches(Class claz, String methodName, Parameter[] parameters, Function<Method, String> parseFunc) {
|
||||
Class<?>[] interfaces = claz.getInterfaces();
|
||||
for (Class<?> implInterface : interfaces) {
|
||||
String path = recursiveMatches(implInterface, methodName, parameters, parseFunc);
|
||||
if (Objects.nonNull(path)) {
|
||||
return path;
|
||||
}
|
||||
Method[] declaredMethods = implInterface.getDeclaredMethods();
|
||||
for (Method declaredMethod : declaredMethods) {
|
||||
if (Objects.equals(declaredMethod.getName(), methodName) && parameterEquals(parameters, declaredMethod.getParameters())) {
|
||||
return parseFunc.apply(declaredMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean parameterEquals(Parameter[] p1, Parameter[] p2) {
|
||||
if (p1.length != p1.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < p1.length; i++) {
|
||||
if (!Objects.equals(p1[i].getType().getName(), p2[i].getType().getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor;
|
||||
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.ParsePathUtil;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
|
|
@ -32,21 +33,28 @@ import java.lang.reflect.Method;
|
|||
public class RequestMappingMethodInterceptor extends AbstractMethodInterceptor {
|
||||
@Override
|
||||
public String getRequestURL(Method method) {
|
||||
String requestURL = "";
|
||||
RequestMapping methodRequestMapping = AnnotationUtils.getAnnotation(method, RequestMapping.class);
|
||||
if (methodRequestMapping.value().length > 0) {
|
||||
requestURL = methodRequestMapping.value()[0];
|
||||
} else if (methodRequestMapping.path().length > 0) {
|
||||
requestURL = methodRequestMapping.path()[0];
|
||||
}
|
||||
return requestURL;
|
||||
return ParsePathUtil.recursiveParseMethodAnnotaion(method, m -> {
|
||||
String requestURL = null;
|
||||
RequestMapping methodRequestMapping = AnnotationUtils.getAnnotation(m, RequestMapping.class);
|
||||
if (methodRequestMapping != null) {
|
||||
if (methodRequestMapping.value().length > 0) {
|
||||
requestURL = methodRequestMapping.value()[0];
|
||||
} else if (methodRequestMapping.path().length > 0) {
|
||||
requestURL = methodRequestMapping.path()[0];
|
||||
}
|
||||
}
|
||||
return requestURL;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAcceptedMethodTypes(Method method) {
|
||||
RequestMapping methodRequestMapping = AnnotationUtils.getAnnotation(method, RequestMapping.class);
|
||||
StringBuilder methodTypes = new StringBuilder();
|
||||
if (methodRequestMapping.method().length > 0) {
|
||||
return ParsePathUtil.recursiveParseMethodAnnotaion(method, m -> {
|
||||
RequestMapping methodRequestMapping = AnnotationUtils.getAnnotation(m, RequestMapping.class);
|
||||
if (methodRequestMapping == null || methodRequestMapping.method().length == 0) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder methodTypes = new StringBuilder();
|
||||
methodTypes.append("{");
|
||||
for (int i = 0; i < methodRequestMapping.method().length; i++) {
|
||||
methodTypes.append(methodRequestMapping.method()[i].toString());
|
||||
|
|
@ -55,7 +63,7 @@ public class RequestMappingMethodInterceptor extends AbstractMethodInterceptor {
|
|||
}
|
||||
}
|
||||
methodTypes.append("}");
|
||||
}
|
||||
return methodTypes.toString();
|
||||
return methodTypes.toString();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,13 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor;
|
||||
|
||||
import org.apache.skywalking.apm.plugin.spring.mvc.commons.ParsePathUtil;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
|
@ -34,44 +39,46 @@ import java.lang.reflect.Method;
|
|||
public class RestMappingMethodInterceptor extends AbstractMethodInterceptor {
|
||||
@Override
|
||||
public String getRequestURL(Method method) {
|
||||
String requestURL = "";
|
||||
GetMapping getMapping = AnnotationUtils.getAnnotation(method, GetMapping.class);
|
||||
PostMapping postMapping = AnnotationUtils.getAnnotation(method, PostMapping.class);
|
||||
PutMapping putMapping = AnnotationUtils.getAnnotation(method, PutMapping.class);
|
||||
DeleteMapping deleteMapping = AnnotationUtils.getAnnotation(method, DeleteMapping.class);
|
||||
PatchMapping patchMapping = AnnotationUtils.getAnnotation(method, PatchMapping.class);
|
||||
if (getMapping != null) {
|
||||
if (getMapping.value().length > 0) {
|
||||
requestURL = getMapping.value()[0];
|
||||
} else if (getMapping.path().length > 0) {
|
||||
requestURL = getMapping.path()[0];
|
||||
return ParsePathUtil.recursiveParseMethodAnnotaion(method, m -> {
|
||||
String requestURL = null;
|
||||
GetMapping getMapping = AnnotationUtils.getAnnotation(m, GetMapping.class);
|
||||
PostMapping postMapping = AnnotationUtils.getAnnotation(m, PostMapping.class);
|
||||
PutMapping putMapping = AnnotationUtils.getAnnotation(m, PutMapping.class);
|
||||
DeleteMapping deleteMapping = AnnotationUtils.getAnnotation(m, DeleteMapping.class);
|
||||
PatchMapping patchMapping = AnnotationUtils.getAnnotation(m, PatchMapping.class);
|
||||
if (getMapping != null) {
|
||||
if (getMapping.value().length > 0) {
|
||||
requestURL = getMapping.value()[0];
|
||||
} else if (getMapping.path().length > 0) {
|
||||
requestURL = getMapping.path()[0];
|
||||
}
|
||||
} else if (postMapping != null) {
|
||||
if (postMapping.value().length > 0) {
|
||||
requestURL = postMapping.value()[0];
|
||||
} else if (postMapping.path().length > 0) {
|
||||
requestURL = postMapping.path()[0];
|
||||
}
|
||||
} else if (putMapping != null) {
|
||||
if (putMapping.value().length > 0) {
|
||||
requestURL = putMapping.value()[0];
|
||||
} else if (putMapping.path().length > 0) {
|
||||
requestURL = putMapping.path()[0];
|
||||
}
|
||||
} else if (deleteMapping != null) {
|
||||
if (deleteMapping.value().length > 0) {
|
||||
requestURL = deleteMapping.value()[0];
|
||||
} else if (deleteMapping.path().length > 0) {
|
||||
requestURL = deleteMapping.path()[0];
|
||||
}
|
||||
} else if (patchMapping != null) {
|
||||
if (patchMapping.value().length > 0) {
|
||||
requestURL = patchMapping.value()[0];
|
||||
} else if (patchMapping.path().length > 0) {
|
||||
requestURL = patchMapping.path()[0];
|
||||
}
|
||||
}
|
||||
} else if (postMapping != null) {
|
||||
if (postMapping.value().length > 0) {
|
||||
requestURL = postMapping.value()[0];
|
||||
} else if (postMapping.path().length > 0) {
|
||||
requestURL = postMapping.path()[0];
|
||||
}
|
||||
} else if (putMapping != null) {
|
||||
if (putMapping.value().length > 0) {
|
||||
requestURL = putMapping.value()[0];
|
||||
} else if (putMapping.path().length > 0) {
|
||||
requestURL = putMapping.path()[0];
|
||||
}
|
||||
} else if (deleteMapping != null) {
|
||||
if (deleteMapping.value().length > 0) {
|
||||
requestURL = deleteMapping.value()[0];
|
||||
} else if (deleteMapping.path().length > 0) {
|
||||
requestURL = deleteMapping.path()[0];
|
||||
}
|
||||
} else if (patchMapping != null) {
|
||||
if (patchMapping.value().length > 0) {
|
||||
requestURL = patchMapping.value()[0];
|
||||
} else if (patchMapping.path().length > 0) {
|
||||
requestURL = patchMapping.path()[0];
|
||||
}
|
||||
}
|
||||
return requestURL;
|
||||
return requestURL;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ registryItems:
|
|||
operationNames:
|
||||
- spring-4.3.x-scenario: [/create/, '/delete/{id}', /inherit/child/test, /healthCheck,
|
||||
'/get/{id}', '/update/{id}', /case/resttemplate,
|
||||
/case/spring3]
|
||||
/case/spring3, /impl/requestmapping, /impl/restmapping]
|
||||
heartbeat: []
|
||||
segmentItems:
|
||||
- applicationCode: spring-4.3.x-scenario
|
||||
segmentSize: ge 8
|
||||
segmentSize: ge 10
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
|
|
@ -222,6 +222,52 @@ segmentItems:
|
|||
entryEndpointId: 0, refType: CrossProcess, parentSpanId: 6, parentTraceSegmentId: not null,
|
||||
parentServiceInstanceId: 1, networkAddress: 'localhost:8080', entryEndpoint: /case/resttemplate,
|
||||
entryServiceInstanceId: 1}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /impl/requestmapping
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/spring-4.3.x-scenario/impl/requestmapping'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpointId: 0, parentEndpoint: /case/resttemplate, networkAddressId: 0,
|
||||
entryEndpointId: 0, refType: CrossProcess, parentSpanId: 7, parentTraceSegmentId: not null,
|
||||
parentServiceInstanceId: 1, networkAddress: 'localhost:8080', entryEndpoint: /case/resttemplate,
|
||||
entryServiceInstanceId: 1}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /impl/restmapping
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/spring-4.3.x-scenario/impl/restmapping'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpointId: 0, parentEndpoint: /case/resttemplate, networkAddressId: 0,
|
||||
entryEndpointId: 0, refType: CrossProcess, parentSpanId: 8, parentTraceSegmentId: not null,
|
||||
parentServiceInstanceId: 1, networkAddress: 'localhost:8080', entryEndpoint: /case/resttemplate,
|
||||
entryServiceInstanceId: 1}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /spring-4.3.x-scenario/case/spring3/
|
||||
|
|
@ -320,6 +366,38 @@ segmentItems:
|
|||
tags:
|
||||
- {key: http.method, value: GET}
|
||||
- {key: url, value: 'http://localhost:8080/spring-4.3.x-scenario/inherit/child/test'}
|
||||
- operationName: /spring-4.3.x-scenario/impl/requestmapping
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 7
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 12
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: http.method, value: GET}
|
||||
- {key: url, value: 'http://localhost:8080/spring-4.3.x-scenario/impl/requestmapping'}
|
||||
- operationName: /spring-4.3.x-scenario/impl/restmapping
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 8
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 12
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: http.method, value: GET}
|
||||
- {key: url, value: 'http://localhost:8080/spring-4.3.x-scenario/impl/restmapping'}
|
||||
- operationName: /case/resttemplate
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
|
|||
|
|
@ -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 test.org.apache.skywalking.apm.testcase.implinterface;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author jialong
|
||||
*/
|
||||
@RestController
|
||||
public class TestCaseController implements TestCaseInterface {
|
||||
|
||||
@Override
|
||||
public String implRequestMappingAnnotationTestCase() {
|
||||
return "implRequestMappingAnnotationTestCase";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String implRestAnnotationTestCase() {
|
||||
return "implRestAnnotationTestCase";
|
||||
}
|
||||
}
|
||||
|
|
@ -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 test.org.apache.skywalking.apm.testcase.implinterface;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* @author jialong
|
||||
*/
|
||||
public interface TestCaseInterface {
|
||||
@RequestMapping("/impl/requestmapping")
|
||||
String implRequestMappingAnnotationTestCase();
|
||||
|
||||
@GetMapping("/impl/restmapping")
|
||||
String implRestAnnotationTestCase();
|
||||
}
|
||||
|
|
@ -66,6 +66,14 @@ public class RestTemplateController {
|
|||
response = new OkHttpClient().newCall(inheritRequest).execute();
|
||||
logger.info(response.toString());
|
||||
|
||||
Request implRequestMappingRequest = new Request.Builder().url(url + "/impl/requestmapping").build();
|
||||
response = new OkHttpClient().newCall(implRequestMappingRequest).execute();
|
||||
logger.info(response.toString());
|
||||
|
||||
Request implRestMappingRequest = new Request.Builder().url(url + "/impl/restmapping").build();
|
||||
response = new OkHttpClient().newCall(implRestMappingRequest).execute();
|
||||
logger.info(response.toString());
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue