diff --git a/.travis.yml b/.travis.yml index 69492c5060dcf6c8ed3e39923507bc2fd3f363da..9b51e79833f8843894d04b8bffa575a75c14ce00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ install: - mvn install:install-file -Dfile=jmxri-1.2.1.jar -DgroupId=com.sun.jmx -DartifactId=jmxri -Dversion=1.2.1 -Dpackaging=jar - mvn install:install-file -Dfile=dubbox-2.8.4.jar -DgroupId=com.alibaba -DartifactId=dubbox -Dversion=2.8.4 -Dpackaging=jar - mvn install:install-file -Dfile=ojdbc14-10.2.0.4.0.jar -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.4.0 -Dpackaging=jar + - mvn install:install-file -Dfile=resin-4.0.41.jar -DgroupId=com.caucho -DartifactId=resin -Dversion=4.0.41 -Dpackaging=jar - cd .. script: diff --git a/apm-sniffer/apm-agent/pom.xml b/apm-sniffer/apm-agent/pom.xml index bfc577a9e3febc318ee643c2256364ed3b8fa382..b33a84f8b92d001100860319e4d1a6e81b8c5410 100644 --- a/apm-sniffer/apm-agent/pom.xml +++ b/apm-sniffer/apm-agent/pom.xml @@ -60,6 +60,16 @@ apm-mongodb-3.x-plugin ${project.version} + + org.skywalking + apm-resin-3.x-plugin + ${project.version} + + + org.skywalking + apm-resin-4.x-plugin + ${project.version} + diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index accc48abbd6d4e3ecefd2fd561aecd37357828ff..75d35f783c861fe39b80703e36305ccef69cffbb 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -18,6 +18,8 @@ tomcat-7.x-8.x-plugin motan-plugin mongodb-3.x-plugin + resin-3.x-plugin + resin-4.x-plugin pom diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ae8dc3db535ea2d5c5f51c84069178829d98407 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + + apm-sdk-plugin + org.skywalking + 3.1-2017 + + + apm-resin-3.x-plugin + jar + + resin-3.x-plugin + http://maven.apache.org + + + UTF-8 + + + + + com.caucho + resin + 3.0.9 + provided + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + + attach-sources + + jar + + + + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/ResinV3Interceptor.java b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/ResinV3Interceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..c09372faf1237942453bb9572163bf0157e06478 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/ResinV3Interceptor.java @@ -0,0 +1,72 @@ +package org.skywalking.apm.plugin.resin.v3; + +import com.caucho.server.http.HttpResponse; +import com.caucho.server.http.HttpRequest; +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.trace.Span; +import org.skywalking.apm.trace.tag.Tags; +import org.skywalking.apm.util.StringUtil; + +/** + * {@link ResinV3Interceptor} intercept method of{@link com.caucho.server.dispatch.ServletInvocation#service(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse)} record the resin host, port ,url. + * + * @author baiyang + */ +public class ResinV3Interceptor implements InstanceMethodsAroundInterceptor { + /** + * Header name that the serialized context data stored in + * {@link HttpRequest#getHeader(String)}. + */ + public static final String HEADER_NAME_OF_CONTEXT_DATA = "SWTraceContext"; + /** + * Resin component. + */ + public static final String RESIN_COMPONENT = "Resin"; + + @Override + public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, + MethodInterceptResult result) { + Object[] args = interceptorContext.allArguments(); + HttpRequest request = (HttpRequest)args[0]; + Span span = ContextManager.createSpan(request.getRequestURI()); + Tags.COMPONENT.set(span, RESIN_COMPONENT); + Tags.PEER_HOST.set(span, request.getServerName()); + Tags.PEER_PORT.set(span, request.getServerPort()); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); + Tags.URL.set(span, request.getRequestURL().toString()); + Tags.SPAN_LAYER.asHttp(span); + + String tracingHeaderValue = request.getHeader(HEADER_NAME_OF_CONTEXT_DATA); + if (!StringUtil.isEmpty(tracingHeaderValue)) { + ContextManager.extract(new ContextCarrier().deserialize(tracingHeaderValue)); + } + } + + @Override + public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, + Object ret) { + HttpResponse response = (HttpResponse)interceptorContext.allArguments()[1]; + Span span = ContextManager.activeSpan(); + Tags.STATUS_CODE.set(span, response.getStatusCode()); + + if (response.getStatusCode() != 200) { + Tags.ERROR.set(span, true); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, + InstanceMethodInvokeContext interceptorContext) { + Span span = ContextManager.activeSpan(); + span.log(t); + Tags.ERROR.set(span, true); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..7b1369ef1efcf91d22003acd065bd80cc2950a83 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java @@ -0,0 +1,55 @@ +package org.skywalking.apm.plugin.resin.v3.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.skywalking.apm.plugin.resin.v3.ResinV3Interceptor; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * {@link ResinV3Instrumentation} presents that skywalking intercepts {@link com.caucho.server.dispatch.ServletInvocation#service(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse)} by using {@link ResinV3Interceptor}. + * + * @author baiyang + */ +public class ResinV3Instrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "com.caucho.server.dispatch.ServletInvocation"; + + private static final String METHOD_INTERCET_CLASS = "org.skywalking.apm.plugin.resin.v3.ResinV3Interceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return null; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("service"); + } + + @Override + public String getMethodsInterceptor() { + return METHOD_INTERCET_CLASS; + } + } + }; + } + + @Override + protected String enhanceClassName() { + return ENHANCE_CLASS; + } + + @Override + protected String[] witnessClasses() { + return new String[] {"com.caucho.server.connection.AbstractHttpResponse"}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..86586edb85fcdd38390457b3e5bb5b22508c319d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1 @@ +resin-3.x=org.skywalking.apm.plugin.resin.v3.define.ResinV3Instrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..35e61448de7d3ac28e214359a5f232a9b65f2f1d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java @@ -0,0 +1,147 @@ +package org.skywalking.apm.plugin.resin.v3; + +import com.caucho.server.http.HttpResponse; +import com.caucho.server.http.HttpRequest; +import org.hamcrest.CoreMatchers; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.context.TracerContext; +import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.sniffer.mock.context.MockTracerContextListener; +import org.skywalking.apm.sniffer.mock.context.SegmentAssert; +import org.skywalking.apm.trace.LogData; +import org.skywalking.apm.trace.Span; +import org.skywalking.apm.trace.TraceSegment; +import org.skywalking.apm.trace.TraceSegmentRef; +import org.skywalking.apm.trace.tag.Tags; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +/** + * ResinInterceptorTest + * + * @author baiyang + */ +@RunWith(MockitoJUnitRunner.class) +public class ResinV3InterceptorTest { + private ResinV3Interceptor interceptor; + private MockTracerContextListener contextListener; + + @Mock + private HttpRequest request; + @Mock + private HttpResponse response; + @Mock + private EnhancedClassInstanceContext classInstanceContext; + @Mock + private InstanceMethodInvokeContext methodInvokeContext; + @Mock + private MethodInterceptResult methodInterceptResult; + + @Before + public void setUp() throws Exception { + + ServiceManager.INSTANCE.boot(); + + interceptor = new ResinV3Interceptor(); + contextListener = new MockTracerContextListener(); + + TracerContext.ListenerManager.add(contextListener); + + when(request.getRequestURI()).thenReturn("/test/testRequestURL"); + when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); + when(response.getStatusCode()).thenReturn(200); + when(methodInvokeContext.allArguments()).thenReturn(new Object[] {request, response}); + } + + @Test + public void testWithoutSerializedContextData() { + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + } + }); + } + + @Test + public void testWithSerializedContextData() { + when(request.getHeader(ResinV3Interceptor.HEADER_NAME_OF_CONTEXT_DATA)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123|1"); + + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); + } + }); + } + + @Test + public void testWithOccurException() { + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + assertThat(span.getLogs().size(), is(1)); + assertSpanLog(span.getLogs().get(0)); + } + }); + } + + private void assertSpanLog(LogData logData) { + assertThat(logData.getFields().size(), is(4)); + assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); + assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); + assertNull(logData.getFields().get("message")); + } + + private void assertTraceSegmentRef(TraceSegmentRef ref) { + assertThat(ref.getSpanId(), is(1)); + assertThat(ref.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); + } + + private void assertHttpSpan(Span span) { + assertThat(span.getOperationName(), is("/test/testRequestURL")); + assertThat(Tags.COMPONENT.get(span), is("Resin")); + assertThat(Tags.URL.get(span), is("http://localhost:8080/test/testRequestURL")); + assertThat(Tags.STATUS_CODE.get(span), is(200)); + assertThat(Tags.SPAN_KIND.get(span), is(Tags.SPAN_KIND_SERVER)); + assertTrue(Tags.SPAN_LAYER.isHttp(span)); + } + + @After + public void tearDown() throws Exception { + TracerContext.ListenerManager.remove(new MockTracerContextListener()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..0e137b7fa24dc700c52c644f83fe85991c3ab139 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + apm-sdk-plugin + org.skywalking + 3.1-2017 + + + apm-resin-4.x-plugin + jar + + resin-4.x-plugin + http://maven.apache.org + + + UTF-8 + + + + + com.caucho + resin + 4.0.41 + provided + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + + attach-sources + + jar + + + + + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/ResinV4Interceptor.java b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/ResinV4Interceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..1e9aac5ec22a872429fd0396dbcda7817ad53669 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/ResinV4Interceptor.java @@ -0,0 +1,70 @@ +package org.skywalking.apm.plugin.resin.v4; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import com.caucho.server.http.HttpRequest; +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.trace.Span; +import org.skywalking.apm.trace.tag.Tags; +import org.skywalking.apm.util.StringUtil; + +/** + * Created by Baiyang on 2017/5/2. + */ +public class ResinV4Interceptor implements InstanceMethodsAroundInterceptor { + /** + * Header name that the serialized context data stored in + * {@link HttpRequest#getHeader(String)}. + */ + public static final String HEADER_NAME_OF_CONTEXT_DATA = "SWTraceContext"; + /** + * Resin component. + */ + public static final String RESIN_COMPONENT = "Resin"; + + @Override + public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, + MethodInterceptResult result) { + Object[] args = interceptorContext.allArguments(); + HttpServletRequest request = (HttpServletRequest)args[0]; + Span span = ContextManager.createSpan(request.getRequestURI()); + Tags.COMPONENT.set(span, RESIN_COMPONENT); + Tags.PEER_HOST.set(span, request.getServerName()); + Tags.PEER_PORT.set(span, request.getServerPort()); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); + Tags.URL.set(span, request.getRequestURL().toString()); + Tags.SPAN_LAYER.asHttp(span); + + String tracingHeaderValue = request.getHeader(HEADER_NAME_OF_CONTEXT_DATA); + if (!StringUtil.isEmpty(tracingHeaderValue)) { + ContextManager.extract(new ContextCarrier().deserialize(tracingHeaderValue)); + } + } + + @Override + public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, + Object ret) { + HttpServletResponse response = (HttpServletResponse)interceptorContext.allArguments()[1]; + Span span = ContextManager.activeSpan(); + Tags.STATUS_CODE.set(span, response.getStatus()); + + if (response.getStatus() != 200) { + Tags.ERROR.set(span, true); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, + InstanceMethodInvokeContext interceptorContext) { + Span span = ContextManager.activeSpan(); + span.log(t); + Tags.ERROR.set(span, true); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..8f130247e329853a928420c83c3ca42719e036da --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java @@ -0,0 +1,54 @@ +package org.skywalking.apm.plugin.resin.v4.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.skywalking.apm.plugin.resin.v4.ResinV4Interceptor; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * {@link ResinV4Instrumentation} presents that skywalking intercepts {@link com.caucho.server.dispatch.ServletInvocation#service(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse)} by using {@link ResinV4Interceptor}. + * + * @author baiyang + */ +public class ResinV4Instrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "com.caucho.server.dispatch.ServletInvocation"; + + private static final String METHOD_INTERCET_CLASS = "org.skywalking.apm.plugin.resin.v4.ResinV4Interceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return null; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("service"); + } + + @Override + public String getMethodsInterceptor() { + return METHOD_INTERCET_CLASS; + } + } + }; + } + + @Override + protected String enhanceClassName() { + return ENHANCE_CLASS; + } + + @Override + protected String[] witnessClasses() { + return new String[] {"com.caucho.server.http.HttpServletResponseImpl"}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..3bab53d039f922daed87b0359bb3be2403e74c60 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1 @@ +resin-4.x=org.skywalking.apm.plugin.resin.v4.define.ResinV4Instrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..63d1dc0e4606c904bde1731bcc3b7f7d7c2250f4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java @@ -0,0 +1,145 @@ +package org.skywalking.apm.plugin.resin.v4; + +import javax.servlet.http.HttpServletRequest; +import org.hamcrest.CoreMatchers; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.context.TracerContext; +import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.sniffer.mock.context.MockTracerContextListener; +import org.skywalking.apm.sniffer.mock.context.SegmentAssert; +import org.skywalking.apm.trace.LogData; +import org.skywalking.apm.trace.Span; +import org.skywalking.apm.trace.TraceSegment; +import org.skywalking.apm.trace.TraceSegmentRef; +import org.skywalking.apm.trace.tag.Tags; +import javax.servlet.http.HttpServletResponse; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +/** + * Created by Baiyang on 2017/5/6. + */ +@RunWith(MockitoJUnitRunner.class) +public class ResinV4InterceptorTest { + private ResinV4Interceptor interceptor; + private MockTracerContextListener contextListener; + + @Mock + private HttpServletRequest request; + @Mock + private HttpServletResponse response; + @Mock + private EnhancedClassInstanceContext classInstanceContext; + @Mock + private InstanceMethodInvokeContext methodInvokeContext; + @Mock + private MethodInterceptResult methodInterceptResult; + + @Before + public void setUp() throws Exception { + + ServiceManager.INSTANCE.boot(); + + interceptor = new ResinV4Interceptor(); + contextListener = new MockTracerContextListener(); + + TracerContext.ListenerManager.add(contextListener); + + when(request.getRequestURI()).thenReturn("/test/testRequestURL"); + when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); + when(response.getStatus()).thenReturn(200); + when(methodInvokeContext.allArguments()).thenReturn(new Object[] {request, response}); + } + + @Test + public void testWithoutSerializedContextData() { + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + } + }); + } + + @Test + public void testWithSerializedContextData() { + when(request.getHeader(ResinV4Interceptor.HEADER_NAME_OF_CONTEXT_DATA)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123|1"); + + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); + } + }); + } + + @Test + public void testWithOccurException() { + interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); + interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); + interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); + + contextListener.assertSize(1); + contextListener.assertTraceSegment(0, new SegmentAssert() { + @Override + public void call(TraceSegment traceSegment) { + assertThat(traceSegment.getSpans().size(), is(1)); + Span span = traceSegment.getSpans().get(0); + assertHttpSpan(span); + assertThat(span.getLogs().size(), is(1)); + assertSpanLog(span.getLogs().get(0)); + } + }); + } + + private void assertSpanLog(LogData logData) { + assertThat(logData.getFields().size(), is(4)); + assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); + assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); + assertNull(logData.getFields().get("message")); + } + + private void assertTraceSegmentRef(TraceSegmentRef ref) { + assertThat(ref.getSpanId(), is(1)); + assertThat(ref.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); + } + + private void assertHttpSpan(Span span) { + assertThat(span.getOperationName(), is("/test/testRequestURL")); + assertThat(Tags.COMPONENT.get(span), is("Resin")); + assertThat(Tags.URL.get(span), is("http://localhost:8080/test/testRequestURL")); + assertThat(Tags.STATUS_CODE.get(span), is(200)); + assertThat(Tags.SPAN_KIND.get(span), is(Tags.SPAN_KIND_SERVER)); + assertTrue(Tags.SPAN_LAYER.isHttp(span)); + } + + @After + public void tearDown() throws Exception { + TracerContext.ListenerManager.remove(new MockTracerContextListener()); + } +} diff --git a/ci-dependencies/resin-4.0.41.jar b/ci-dependencies/resin-4.0.41.jar new file mode 100644 index 0000000000000000000000000000000000000000..9e04f4ce77abc269589b35e84a04624733adf0dd Binary files /dev/null and b/ci-dependencies/resin-4.0.41.jar differ