From a48a16b6d6c890bfbcce3bbd94d6498bb71a7bd2 Mon Sep 17 00:00:00 2001 From: wallezhang Date: Thu, 10 Feb 2022 20:24:17 +0800 Subject: [PATCH] Add plugin to support google guava EventBus (#107) * feat: Add Guava EventBus plugin * refactor: Remove serviceComb 1.0.0 from the test matric to avoid the influence of guava-event-bus plugin on scenario test results. --- .github/workflows/plugins-test.3.yaml | 1 + CHANGES.md | 1 + .../trace/component/ComponentsDefine.java | 2 + .../guava-eventbus-plugin/pom.xml | 44 +++++++ .../eventbus/EventBusDispatchInterceptor.java | 53 +++++++++ ...ntBusSubscriberConstructorInterceptor.java | 39 +++++++ .../EventBusSubscriberInterceptor.java | 62 ++++++++++ .../plugin/guava/eventbus/EventWrapper.java | 50 ++++++++ .../plugin/guava/eventbus/SubscriberInfo.java | 44 +++++++ .../EventBusDispatcherInstrumentation.java | 72 ++++++++++++ .../EventBusSubscriberInstrumentation.java | 89 +++++++++++++++ .../src/main/resources/skywalking-plugin.def | 18 +++ .../EventBusDispatchInterceptorTest.java | 69 +++++++++++ ...sSubscriberConstructorInterceptorTest.java | 68 +++++++++++ .../EventBusSubscriberInterceptorTest.java | 90 +++++++++++++++ apm-sniffer/apm-sdk-plugin/pom.xml | 1 + .../service-agent/java-agent/Plugin-list.md | 1 + .../java-agent/Supported-list.md | 2 + .../guava-eventbus-scenario/bin/startup.sh | 24 ++++ .../config/expectedData.yaml | 68 +++++++++++ .../guava-eventbus-scenario/configuration.yml | 21 ++++ .../scenarios/guava-eventbus-scenario/pom.xml | 107 ++++++++++++++++++ .../src/main/assembly/assembly.xml | 41 +++++++ .../testcase/guava/eventbus/Application.java | 30 +++++ .../eventbus/controller/CaseController.java | 60 ++++++++++ .../eventbus/service/SubscriberService.java | 51 +++++++++ .../guava/eventbus/service/TestEvent.java | 43 +++++++ .../src/main/resources/application.yml | 21 ++++ .../support-version.list | 21 ++++ .../support-version.list | 1 - 30 files changed, 1193 insertions(+), 1 deletion(-) create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/pom.xml create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventWrapper.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/SubscriberInfo.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusDispatcherInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusSubscriberInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/resources/skywalking-plugin.def create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptorTest.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptorTest.java create mode 100644 apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptorTest.java create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/bin/startup.sh create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/config/expectedData.yaml create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/configuration.yml create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/pom.xml create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/assembly/assembly.xml create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/Application.java create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/controller/CaseController.java create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/SubscriberService.java create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/TestEvent.java create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/src/main/resources/application.yml create mode 100644 test/plugin/scenarios/guava-eventbus-scenario/support-version.list diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index ed003977c..a5781788f 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -94,6 +94,7 @@ jobs: - kylin-jdbc-2.6.x-3.x-4.x-scenario - undertow-worker-thread-pool-scenario - tomcat-thread-pool-scenario + - guava-eventbus-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index ea93f636f..d0faa98a3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Release Notes. * Support Undertow thread pool metrics collecting. * Support Tomcat thread pool metric collect. * Remove plugin for ServiceComb Java Chassis 0.x +* Add Guava EventBus plugin. #### Documentation diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index d23cf2ef5..75a8b377d 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -218,4 +218,6 @@ public class ComponentsDefine { public static final OfficialComponent CLICKHOUSE_JDBC_DRIVER = new OfficialComponent(119, "ClickHouse-jdbc-driver"); public static final OfficialComponent APACHE_KYLIN_JDBC_DRIVER = new OfficialComponent(121, "apache-kylin-jdbc-driver"); + + public static final OfficialComponent GUAVA_EVENT_BUS = new OfficialComponent(123, "GuavaEventBus"); } diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/pom.xml new file mode 100644 index 000000000..40e7f8bc0 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/pom.xml @@ -0,0 +1,44 @@ + + + + + apm-sdk-plugin + org.apache.skywalking + 8.10.0-SNAPSHOT + + 4.0.0 + + apm-guava-eventbus-plugin + + + 31.0.1-jre + + + + + com.google.guava + guava + ${guava.version} + provided + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptor.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptor.java new file mode 100644 index 000000000..34ab37ab8 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptor.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.guava.eventbus; + +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; + +/** + * {@link EventBusDispatchInterceptor} will capture context and create a new wrapper to + * hold the original event object. + */ +public class EventBusDispatchInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + final Object event = allArguments[0]; + if (event != null) { + allArguments[0] = EventWrapper.wrapEvent(event, ContextManager.capture()); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptor.java new file mode 100644 index 000000000..fdb84283a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptor.java @@ -0,0 +1,39 @@ +/* + * 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.guava.eventbus; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +/** + * {@link EventBusSubscriberConstructorInterceptor} will set the target object information from constructor arguments. + */ +public class EventBusSubscriberConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { + final Object targetObject = allArguments[1]; + final Method method = (Method) allArguments[2]; + final SubscriberInfo subscriberInfo = new SubscriberInfo(); + subscriberInfo.setClassName(targetObject.getClass().getName()); + subscriberInfo.setMethodName(method.getName()); + objInst.setSkyWalkingDynamicField(subscriberInfo); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptor.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptor.java new file mode 100644 index 000000000..0e8f1c5fe --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptor.java @@ -0,0 +1,62 @@ +/* + * 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.guava.eventbus; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +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.network.trace.component.ComponentsDefine; + +/** + * {@link EventBusSubscriberInterceptor} will restore the context snapshot and original event object. + */ +public class EventBusSubscriberInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + SubscriberInfo subscriberInfo = (SubscriberInfo) objInst.getSkyWalkingDynamicField(); + final AbstractSpan span = ContextManager.createLocalSpan( + "Guava/EventBus/" + subscriberInfo.getClassName() + "/" + subscriberInfo.getMethodName()); + span.setComponent(ComponentsDefine.GUAVA_EVENT_BUS); + Object event = allArguments[0]; + if (event instanceof EventWrapper) { + final EventWrapper eventWrapper = (EventWrapper) event; + // restore original event object + allArguments[0] = eventWrapper.getEvent(); + ContextManager.continued(eventWrapper.getContextSnapshot()); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventWrapper.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventWrapper.java new file mode 100644 index 000000000..441d43839 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventWrapper.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.guava.eventbus; + +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; + +/** + * This class hold the original event object and context snapshot + */ +public class EventWrapper { + + /** + * Original event object + */ + private final Object event; + private final ContextSnapshot contextSnapshot; + + private EventWrapper(Object event, ContextSnapshot contextSnapshot) { + this.event = event; + this.contextSnapshot = contextSnapshot; + } + + public static EventWrapper wrapEvent(Object event, ContextSnapshot contextSnapshot) { + return new EventWrapper(event, contextSnapshot); + } + + public Object getEvent() { + return event; + } + + public ContextSnapshot getContextSnapshot() { + return contextSnapshot; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/SubscriberInfo.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/SubscriberInfo.java new file mode 100644 index 000000000..e105bc2e8 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/SubscriberInfo.java @@ -0,0 +1,44 @@ +/* + * 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.guava.eventbus; + +/** + * This class hold the subscriber class name and method name. + */ +public class SubscriberInfo { + + private String className; + private String methodName; + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusDispatcherInstrumentation.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusDispatcherInstrumentation.java new file mode 100644 index 000000000..6c34e881a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusDispatcherInstrumentation.java @@ -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. + * + */ + +package org.apache.skywalking.apm.plugin.guava.eventbus.define; + +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; +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; + +/** + * {@link EventBusDispatcherInstrumentation} defines method interceptor. + */ +public class EventBusDispatcherInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "com.google.common.eventbus.Dispatcher$LegacyAsyncDispatcher"; + private static final String DISPATCH_METHOD_NAME = "dispatch"; + private static final String DISPATCH_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.guava.eventbus.EventBusDispatchInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return ElementMatchers.named(DISPATCH_METHOD_NAME) + .and(ElementMatchers.takesArgument(0, Object.class)); + } + + @Override + public String getMethodsInterceptor() { + return DISPATCH_METHOD_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return true; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusSubscriberInstrumentation.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusSubscriberInstrumentation.java new file mode 100644 index 000000000..78332d77d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/java/org/apache/skywalking/apm/plugin/guava/eventbus/define/EventBusSubscriberInstrumentation.java @@ -0,0 +1,89 @@ +/* + * 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.guava.eventbus.define; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +import java.lang.reflect.Method; +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; + +/** + * {@link EventBusSubscriberInstrumentation} define com.google.common.eventbus.Subscriber#invokeSubscriberMethod + * method interceptor. + */ +public class EventBusSubscriberInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private final static String ENHANCE_CLASS = "com.google.common.eventbus.Subscriber"; + private final static String INVOKE_METHOD_NAME = "invokeSubscriberMethod"; + private final static String INVOKE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.guava.eventbus.EventBusSubscriberInterceptor"; + private final static String CONSTRUCTOR_INTERCEPTOR = "org.apache.skywalking.apm.plugin.guava.eventbus.EventBusSubscriberConstructorInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return takesArgument(0, named("com.google.common.eventbus.EventBus")) + .and(takesArgument(1, Object.class)) + .and(takesArgument(2, Method.class)); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_INTERCEPTOR; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(INVOKE_METHOD_NAME).and(takesArgument(0, Object.class)); + } + + @Override + public String getMethodsInterceptor() { + return INVOKE_METHOD_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return true; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..5e3aa0bdf --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/resources/skywalking-plugin.def @@ -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. + +guava-eventbus=org.apache.skywalking.apm.plugin.guava.eventbus.define.EventBusDispatcherInstrumentation +guava-eventbus=org.apache.skywalking.apm.plugin.guava.eventbus.define.EventBusSubscriberInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptorTest.java new file mode 100644 index 000000000..fe891ddf7 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusDispatchInterceptorTest.java @@ -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.guava.eventbus; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ContextManager.class) +public class EventBusDispatchInterceptorTest { + + private EventBusDispatchInterceptor interceptor; + private Object originalEventObj; + @Mock + private ContextSnapshot contextSnapshot; + + @Before + public void setUp() throws Exception { + interceptor = new EventBusDispatchInterceptor(); + originalEventObj = new Object(); + mockStatic(ContextManager.class); + when(ContextManager.capture()).thenReturn(contextSnapshot); + } + + @Test + public void test() throws Throwable { + Object[] arguments = new Object[] {originalEventObj}; + interceptor.beforeMethod(null, null, arguments, new Class[1], null); + assertEquals(EventWrapper.class, arguments[0].getClass()); + assertEquals(originalEventObj, ((EventWrapper) arguments[0]).getEvent()); + assertNotNull(((EventWrapper) arguments[0]).getContextSnapshot()); + } + + @Test + public void testNullEventObject() throws Throwable { + Object[] arguments = new Object[1]; + interceptor.beforeMethod(null, null, arguments, new Class[1], null); + assertNull(arguments[0]); + } + +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptorTest.java new file mode 100644 index 000000000..2ac63b836 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberConstructorInterceptorTest.java @@ -0,0 +1,68 @@ +/* + * 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.guava.eventbus; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +public class EventBusSubscriberConstructorInterceptorTest { + + private EventBusSubscriberConstructorInterceptor interceptor; + private EnhancedInstance enhancedInstance; + + @Before + public void setUp() throws Exception { + interceptor = new EventBusSubscriberConstructorInterceptor(); + enhancedInstance = new EnhancedInstance() { + private Object field; + + @Override + public Object getSkyWalkingDynamicField() { + return field; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + field = value; + } + }; + } + + @Test + public void test() throws Throwable { + final Method method = this.getClass().getDeclaredMethod("test"); + Object[] arguments = new Object[] {null, new Object(), method}; + interceptor.onConstruct(enhancedInstance, arguments); + + final Object dynamicField = enhancedInstance.getSkyWalkingDynamicField(); + assertNotNull(dynamicField); + assertEquals(SubscriberInfo.class, dynamicField.getClass()); + SubscriberInfo subscriberInfo = (SubscriberInfo) dynamicField; + assertEquals("test", subscriberInfo.getMethodName()); + assertEquals(Object.class.getName(), subscriberInfo.getClassName()); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptorTest.java new file mode 100644 index 000000000..1d6a5ea11 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/test/java/org/apache/skywalking/apm/plugin/guava/eventbus/EventBusSubscriberInterceptorTest.java @@ -0,0 +1,90 @@ +/* + * 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.guava.eventbus; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.List; +import org.apache.skywalking.apm.agent.core.context.MockContextSnapshot; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class EventBusSubscriberInterceptorTest { + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + private EventBusSubscriberInterceptor interceptor; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + private EventWrapper eventWrapper; + private EnhancedInstance enhancedInstance; + private SubscriberInfo subscriberInfo; + + @Before + public void setUp() throws Exception { + interceptor = new EventBusSubscriberInterceptor(); + eventWrapper = EventWrapper.wrapEvent(new Object(), MockContextSnapshot.INSTANCE.mockContextSnapshot()); + enhancedInstance = new EnhancedInstance() { + private Object value; + + @Override + public Object getSkyWalkingDynamicField() { + return value; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + this.value = value; + } + }; + subscriberInfo = new SubscriberInfo(); + subscriberInfo.setMethodName("testMethodName"); + subscriberInfo.setClassName("testClassName"); + } + + @Test + public void test() throws Throwable { + Object[] arguments = new Object[] {eventWrapper}; + enhancedInstance.setSkyWalkingDynamicField(subscriberInfo); + interceptor.beforeMethod(enhancedInstance, null, arguments, new Class[1], null); + interceptor.afterMethod(null, null, null, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + final TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans, notNullValue()); + assertThat(spans.size(), is(1)); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 0bbb4c6d2..1a445f477 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -119,6 +119,7 @@ pulsar-2.8.x-plugin undertow-worker-thread-pool-plugin tomcat-thread-pool-plugin + guava-eventbus-plugin pom diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index 7f79257ad..6b535cacf 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -131,3 +131,4 @@ - pulsar-2.8.x - undertow-worker-thread-pool - tomcat-thread-pool +- guava-eventbus diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index c47085f34..98e8edf2e 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -135,6 +135,8 @@ metrics based on the tracing data. * [logback](https://github.com/qos-ch/logback) 1.2.x * ORM * [MyBatis](https://github.com/mybatis/mybatis-3) 3.4.x -> 3.5.x +* Event + * [GuavaEventBus](https://github.com/google/guava) 19.x -> 31.x-jre # Meter Plugins The meter plugin provides the advanced metrics collections, which are not a part of tracing. diff --git a/test/plugin/scenarios/guava-eventbus-scenario/bin/startup.sh b/test/plugin/scenarios/guava-eventbus-scenario/bin/startup.sh new file mode 100644 index 000000000..efcab1288 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/bin/startup.sh @@ -0,0 +1,24 @@ +#!/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/guava-eventbus-scenario.jar & diff --git a/test/plugin/scenarios/guava-eventbus-scenario/config/expectedData.yaml b/test/plugin/scenarios/guava-eventbus-scenario/config/expectedData.yaml new file mode 100644 index 000000000..f96603fbe --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/config/expectedData.yaml @@ -0,0 +1,68 @@ +# 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: guava-eventbus-scenario + segmentSize: ge 2 + segments: + - segmentId: not null + spans: + - operationName: Guava/EventBus/org.apache.skywalking.apm.testcase.guava.eventbus.service.SubscriberService/consumer + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 123 + isError: false + spanType: Local + peer: '' + skipAnalysis: false + - operationName: GET:/guava-eventbus-scenario/case/guava-scenario + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/guava-eventbus-scenario/case/guava-scenario'} + - {key: http.method, value: GET} + - segmentId: not null + spans: + - operationName: Guava/EventBus/org.apache.skywalking.apm.testcase.guava.eventbus.service.SubscriberService/consumer + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 123 + isError: false + spanType: Local + peer: '' + skipAnalysis: false + refs: + - { parentEndpoint: 'GET:/guava-eventbus-scenario/case/guava-scenario', networkAddress: '', + refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: guava-eventbus-scenario, + traceId: not null } +meterItems: [] \ No newline at end of file diff --git a/test/plugin/scenarios/guava-eventbus-scenario/configuration.yml b/test/plugin/scenarios/guava-eventbus-scenario/configuration.yml new file mode 100644 index 000000000..67717ee15 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/configuration.yml @@ -0,0 +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 +# +# 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/guava-eventbus-scenario/case/guava-scenario +healthCheck: http://localhost:8080/guava-eventbus-scenario/case/healthCheck +startScript: ./bin/startup.sh +environment: diff --git a/test/plugin/scenarios/guava-eventbus-scenario/pom.xml b/test/plugin/scenarios/guava-eventbus-scenario/pom.xml new file mode 100644 index 000000000..86a05c24c --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + org.apache.skywalking.apm.testcase + guava-eventbus-scenario + 1.0.0 + jar + + + UTF-8 + 1.8 + guava + 19.0 + 2.5.1 + + + skywalking-guava-eventbus-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + com.google.guava + guava + ${test.framework.version} + + + + + guava-eventbus-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/guava-eventbus-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/guava-eventbus-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..a4e9bbcc5 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/guava-eventbus-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/Application.java b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/Application.java new file mode 100644 index 000000000..822fc03e2 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/Application.java @@ -0,0 +1,30 @@ +/* + * 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.testcase.guava.eventbus; + +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/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/controller/CaseController.java b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/controller/CaseController.java new file mode 100644 index 000000000..adee578ee --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/controller/CaseController.java @@ -0,0 +1,60 @@ +/* + * 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.testcase.guava.eventbus.controller; + +import com.google.common.eventbus.AsyncEventBus; +import com.google.common.eventbus.EventBus; +import java.util.concurrent.Executors; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import org.apache.skywalking.apm.testcase.guava.eventbus.service.SubscriberService; +import org.apache.skywalking.apm.testcase.guava.eventbus.service.TestEvent; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/case") +public class CaseController { + + public static final String SUCCESS = "Success"; + private final EventBus eventBus = new EventBus(); + private final AsyncEventBus asyncEventBus = new AsyncEventBus(Executors.newFixedThreadPool(5)); + @Resource + private SubscriberService subscriberService; + + @RequestMapping("/guava-scenario") + @ResponseBody + public void testcase(HttpServletRequest request) throws Exception { + eventBus.register(subscriberService); + asyncEventBus.register(subscriberService); + final TestEvent testEvent = new TestEvent(); + testEvent.setContent("test"); + eventBus.post(testEvent); + testEvent.setAsyncContext(request.startAsync()); + asyncEventBus.post(testEvent); + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() throws Exception { + return SUCCESS; + } + +} diff --git a/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/SubscriberService.java b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/SubscriberService.java new file mode 100644 index 000000000..74f502412 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/SubscriberService.java @@ -0,0 +1,51 @@ +/* + * 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.testcase.guava.eventbus.service; + +import com.google.common.eventbus.Subscribe; +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.AsyncContext; +import org.apache.skywalking.apm.testcase.guava.eventbus.controller.CaseController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class SubscriberService { + + private final Logger logger = LoggerFactory.getLogger(SubscriberService.class); + + @Subscribe + public void consumer(TestEvent event) { + logger.info("Consume event content: {}", event.getContent()); + final AsyncContext asyncContext = event.getAsyncContext(); + if (asyncContext != null) { + try { + final PrintWriter writer = asyncContext.getResponse().getWriter(); + writer.write(CaseController.SUCCESS); + writer.flush(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + asyncContext.complete(); + } + } + } +} diff --git a/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/TestEvent.java b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/TestEvent.java new file mode 100644 index 000000000..d6ddefce3 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/java/org/apache/skywalking/apm/testcase/guava/eventbus/service/TestEvent.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.guava.eventbus.service; + +import javax.servlet.AsyncContext; + +public class TestEvent { + + private String content; + private AsyncContext asyncContext; + + public AsyncContext getAsyncContext() { + return asyncContext; + } + + public void setAsyncContext(AsyncContext asyncContext) { + this.asyncContext = asyncContext; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/test/plugin/scenarios/guava-eventbus-scenario/src/main/resources/application.yml b/test/plugin/scenarios/guava-eventbus-scenario/src/main/resources/application.yml new file mode 100644 index 000000000..41201016d --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/src/main/resources/application.yml @@ -0,0 +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 +# +# 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 + servlet: + context-path: /guava-eventbus-scenario \ No newline at end of file diff --git a/test/plugin/scenarios/guava-eventbus-scenario/support-version.list b/test/plugin/scenarios/guava-eventbus-scenario/support-version.list new file mode 100644 index 000000000..43d53a426 --- /dev/null +++ b/test/plugin/scenarios/guava-eventbus-scenario/support-version.list @@ -0,0 +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 +# +# 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. + +19.0 +23.0 +24.0-jre +27.0-jre +31.0-jre \ No newline at end of file diff --git a/test/plugin/scenarios/servicecomb-1.x-scenario/support-version.list b/test/plugin/scenarios/servicecomb-1.x-scenario/support-version.list index 38ff728b1..8ddde05f7 100644 --- a/test/plugin/scenarios/servicecomb-1.x-scenario/support-version.list +++ b/test/plugin/scenarios/servicecomb-1.x-scenario/support-version.list @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -1.0.0 1.1.0 1.2.1 1.3.0