data = new HashMap<>();
+ String key = null;
+ while ((key = getNextString(byteBuffer)) != null) {
+ data.put(key, getNextString(byteBuffer));
+ }
+ return data;
+ }
+
+ private static byte[] encodeStringToBytes(String value) {
+ return value.getBytes(StandardCharsets.UTF_8);
+ }
+
+ private static String decodeStringFromBytes(byte[] bytes) {
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/Constants.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/Constants.java
new file mode 100644
index 000000000..791a62489
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/Constants.java
@@ -0,0 +1,24 @@
+/*
+ * 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.finagle;
+
+public class Constants {
+
+ public static final String PENDING_OP_NAME = "pending";
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextCarrierHelper.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextCarrierHelper.java
new file mode 100644
index 000000000..1f094513a
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextCarrierHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.finagle;
+
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.trace.ExitSpan;
+
+import static org.apache.skywalking.apm.plugin.finagle.Constants.PENDING_OP_NAME;
+import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getPeerHost;
+import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getSWContextCarrier;
+
+class ContextCarrierHelper {
+
+ /**
+ * In {@link ClientTracingFilterInterceptor}, we create {@link ExitSpan} without op name and peer information, and
+ * we use {@link AnnotationInterceptor.Rpc} and {@link ClientDestTracingFilterInterceptor} to put op name and
+ * peer information into LocalContext, but the order of these two interceptors are uncertain, so after each
+ * interceptor, we check if the op name and peer information are exists in LocalContext, if it exists, we set it
+ * to span and inject to contextCarrier.
+ */
+ static void tryInjectContext(ExitSpan span) {
+ String operationName = span.getOperationName();
+ if (PENDING_OP_NAME.equals(operationName)) {
+ return;
+ }
+ String peer = getPeerHost();
+ if (peer == null) {
+ return;
+ }
+ span.setPeer(peer);
+
+ ContextCarrier contextCarrier = new ContextCarrier();
+ span.inject(contextCarrier);
+
+ SWContextCarrier swContextCarrier = getSWContextCarrier();
+ // we can ensure swContextCarrier is not null here
+ swContextCarrier.setContextCarrier(contextCarrier);
+ swContextCarrier.setOperationName(operationName);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolder.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolder.java
new file mode 100644
index 000000000..bafaf0830
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolder.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.finagle;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+
+/**
+ * Finagle context usage
+ *
+ * The only way we can transfer data through finagle context as below:
+ * {@code
+ * Context context = Contexts.local(); // Contexts.broadcast()
+ * context.let(key, value, (Function0) fn);
+ * }
+ *
+ * which means bind value to key in the scope of fn, even if fn may be executed in any threads. But we can't use this
+ * method directly, for example, when we intercept ClientTracingFilter, what we need is add SWContextCarrier
+ * into the MarshalledContext in beforeMethod, and remove it in afterMethod, as below:
+ * {@code
+ * abstract ClientTracingFilterInterceptor extends InstanceMethodsAroundInterceptor {
+ * void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes
+ * MethodInterceptResult result) throws Throwable {
+ * Context context = Contexts.broadcast();
+ * SWContextCarrier swContextCarrier = new SWContextCarrier();
+ * context.let(key, swContextCarrier);
+ * }
+ *
+ * Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes
+ * Object ret) throws Throwable {
+ * Context context = Contexts.broadcast();
+ * context.remove(key);
+ * }
+ * }}
+ *
+ * So we use ContextHolder to achieve this, the {@link #let(Object, Object)} and {@link #remove(Object)} methos split
+ * the function of let(key, value, (Function0) fn) into two methods.
+ *
+ * ContextHolder usage
+ *
+ * 1. For each let operation, there MUST be a corresponding remove operaton.
+ * 2. The order of remove operation MUST be the opposite of the order of let operation, that is, first let last remove
+ * 3. This class can ONLY be used in subclasses of {@link InstanceMethodsAroundInterceptor}, and the let method can
+ * ONLY called in {@link InstanceMethodsAroundInterceptor#beforeMethod}, the remove method can ONLY be called in
+ * {@link InstanceMethodsAroundInterceptor#afterMethod}.
+ *
+ * {@code
+ * class Interceptor implements InstanceMethodsAroundInterceptor {
+ *
+ * @Override
+ * public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ * MethodInterceptResult result) throws Throwable {
+ * ContextHolder contextHolder = ...;
+ * contextHolder.let(key1, value1);
+ * contextHolder.let(key2, value2);
+ * contextHolder.let(key3, value3);
+ * }
+ *
+ * @Override
+ * public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ * Object ret) throws Throwable {
+ * ContextHolder contextHolder = ...;
+ * contextHolder.remove(key3);
+ * contextHolder.remove(key2);
+ * contextHolder.remove(key1);
+ * return afterMethodImpl(objInst, method, allArguments, argumentsTypes, ret);
+ * }
+ * }}
+ */
+abstract class ContextHolder {
+
+ abstract void let(Object key, Object value);
+
+ abstract void remove(Object key);
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactory.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactory.java
new file mode 100644
index 000000000..02b73df79
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactory.java
@@ -0,0 +1,238 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.context.Context;
+import com.twitter.finagle.context.Contexts;
+import com.twitter.finagle.context.LocalContext;
+import com.twitter.finagle.context.MarshalledContext;
+import com.twitter.io.Buf;
+import com.twitter.util.Local;
+import scala.Some;
+import scala.Some$;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+
+/**
+ * The implementation of {@link ContextHolder} depend on implementation detail of LocalContext and MarshalledContext of
+ * finagle. To implement {@link ContextHolder}, we need know the actual data struct that the underlying Context use,
+ * and use that data struct to impelment {@link ContextHolder#let(Object, Object)} and
+ * {@link ContextHolder#remove(Object)}.
+ */
+class ContextHolderFactory {
+
+ /*
+ * Below version 6.41.0(inclusive), this class is used to implement Context, above version 6.41.0, ImmutableMap
+ * is used. we check if this class is on the classpath, then we can know the actual data struct the underlying
+ * finagle used.
+ */
+ private static final String CONTEXT_ENV_CLASS = "com.twitter.finagle.context.Context$Env";
+
+ private static ContextHolder MARSHALLED_CONTEXT_HOLDER;
+ private static ContextHolder LOCAL_CONTEXT_HOLDER;
+
+ static {
+ try {
+ Class.forName(CONTEXT_ENV_CLASS);
+ /*
+ * Compatible with versions 6.41.0 and below
+ */
+ MARSHALLED_CONTEXT_HOLDER = new EnvContextHolder(Contexts.broadcast());
+ LOCAL_CONTEXT_HOLDER = new EnvContextHolder(Contexts.local());
+ } catch (ClassNotFoundException e) {
+ /*
+ * Compatible with versions above 6.41.0
+ */
+ LOCAL_CONTEXT_HOLDER = new MapLocalContextHolder(Contexts.local());
+ MARSHALLED_CONTEXT_HOLDER = new MapMarshalledContextHolder(Contexts.broadcast());
+ }
+ }
+
+ static ContextHolder getMarshalledContextHolder() {
+ return MARSHALLED_CONTEXT_HOLDER;
+ }
+
+ static ContextHolder getLocalContextHolder() {
+ return LOCAL_CONTEXT_HOLDER;
+ }
+
+ static abstract class AbstractContextHolder extends ContextHolder {
+
+ final Local local;
+ final S initContext;
+ /**
+ * We push each let operation to the stack, when there is a remove operation, the key must be the same with
+ * key of let operation on the stack head.
+ */
+ private final ThreadLocal>> snapshots;
+
+ static class Snapshot {
+ /**
+ * key from let operation
+ */
+ private Object key;
+ /**
+ * value of {@link #local} before current let operation
+ */
+ private S saved;
+
+ private Snapshot(Object key, S saved) {
+ this.key = key;
+ this.saved = saved;
+ }
+ }
+
+ AbstractContextHolder(Context context, String localFieldName) {
+ this.local = getLocal(context, localFieldName);
+ this.initContext = getInitContext(context);
+ this.snapshots = new ThreadLocal>>() {
+ @Override
+ protected LinkedList> initialValue() {
+ return new LinkedList<>();
+ }
+ };
+ }
+
+ @Override
+ void let(Object key, Object value) {
+ S currentContext = getCurrentContext();
+ snapshots.get().push(new Snapshot<>(key, currentContext));
+ local.update(getUpdatedContext(currentContext, key, value));
+ }
+
+ @Override
+ void remove(Object key) {
+ Snapshot snapshot = snapshots.get().peek();
+ if (snapshot == null || !snapshot.key.equals(key)) {
+ throw new IllegalStateException(String.format("can't remove %s. the order of remove must be opposite with" +
+ " let.", key));
+ }
+ local.update(snapshot.saved);
+ snapshots.get().pop();
+ }
+
+ private S getCurrentContext() {
+ if (local.apply().isDefined()) {
+ return local.apply().get();
+ }
+ return initContext;
+ }
+
+ abstract protected S getUpdatedContext(S currentContext, Object key, Object value);
+
+ @SuppressWarnings("unchecked")
+ private Local getLocal(Context context, String localFieldName) {
+ try {
+ Field localField = context.getClass().getDeclaredField(localFieldName);
+ localField.setAccessible(true);
+ return (Local) localField.get(context);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private S getInitContext(Context context) {
+ try {
+ Method method = context.getClass().getDeclaredMethod("env");
+ method.setAccessible(true);
+ return (S) method.invoke(context);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ static class EnvContextHolder extends AbstractContextHolder {
+
+ private static final String LOCAL_FIELD_NAME = "com$twitter$finagle$context$Context$$local";
+
+ EnvContextHolder(Context context) {
+ super(context, LOCAL_FIELD_NAME);
+ }
+
+ @Override
+ protected Context.Env getUpdatedContext(Context.Env currentContext, Object key, Object value) {
+ return currentContext.bound(key, value);
+ }
+ }
+
+ static class MapLocalContextHolder extends ContextHolderFactory.AbstractContextHolder> {
+
+ private static final String LOCAL_FIELD_NAME = "local";
+
+ MapLocalContextHolder(LocalContext context) {
+ super(context, LOCAL_FIELD_NAME);
+ }
+
+ @Override
+ protected scala.collection.immutable.Map getUpdatedContext(scala.collection.immutable.Map currentContext, Object key, Object value) {
+ checkKeyType(key);
+ return currentContext.updated((LocalContext.Key) key, value);
+ }
+
+ private void checkKeyType(Object key) {
+ if (!(key instanceof LocalContext.Key)) {
+ throw new IllegalArgumentException("key should be subclass of LocalContext.Key");
+ }
+ }
+ }
+
+ static class MapMarshalledContextHolder extends ContextHolderFactory.AbstractContextHolder> {
+
+ private static final String LOCAL_FIELD_NAME = "local";
+
+ private static final Constructor REAL_CONSTRUCTOR;
+
+ static {
+ try {
+ Class> clz = Class.forName(MarshalledContext.class.getName() + "$Real");
+ REAL_CONSTRUCTOR = clz.getDeclaredConstructor(MarshalledContext.class,
+ MarshalledContext.Key.class, Some.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ MapMarshalledContextHolder(MarshalledContext context) {
+ super(context, LOCAL_FIELD_NAME);
+ }
+
+ @Override
+ protected scala.collection.immutable.Map getUpdatedContext(scala.collection.immutable.Map currentContext, Object key, Object value) {
+ checkKeyType(key);
+ try {
+ MarshalledContext.Key marshalledContextKey = (MarshalledContext.Key) key;
+ Object real = REAL_CONSTRUCTOR.newInstance(Contexts.broadcast(), marshalledContextKey, Some$.MODULE$.apply(value));
+ return currentContext.updated(marshalledContextKey.marshalId(), real);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void checkKeyType(Object key) {
+ if (!(key instanceof MarshalledContext.Key)) {
+ throw new IllegalArgumentException("key should be subclass of MarshalledContext.Key");
+ }
+ }
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/FinagleCtxs.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/FinagleCtxs.java
new file mode 100644
index 000000000..edb5f933c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/FinagleCtxs.java
@@ -0,0 +1,70 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.context.Contexts;
+import com.twitter.finagle.context.LocalContext;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+
+import javax.annotation.Nullable;
+import java.lang.reflect.Constructor;
+
+class FinagleCtxs {
+
+ static LocalContext.Key SW_SPAN = null;
+
+ static LocalContext.Key PEER_HOST = null;
+
+ static {
+ try {
+ Constructor constructor = LocalContext.Key.class.getConstructor(LocalContext.class);
+ SW_SPAN = (LocalContext.Key) constructor.newInstance(Contexts.local());
+ PEER_HOST = (LocalContext.Key) constructor.newInstance(Contexts.local());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Nullable
+ static AbstractSpan getSpan() {
+ if (Contexts.local().contains(SW_SPAN)) {
+ AbstractSpan abstractSpan = Contexts.local().apply(SW_SPAN);
+ return abstractSpan;
+ }
+ return null;
+ }
+
+ @Nullable
+ static SWContextCarrier getSWContextCarrier() {
+ if (Contexts.broadcast().contains(SWContextCarrier$.MODULE$)) {
+ SWContextCarrier swContextCarrier = Contexts.broadcast().apply(SWContextCarrier$.MODULE$);
+ return swContextCarrier;
+ }
+ return null;
+ }
+
+ @Nullable
+ static String getPeerHost() {
+ if (Contexts.local().contains(PEER_HOST)) {
+ String peerHost = Contexts.local().apply(PEER_HOST);
+ return peerHost;
+ }
+ return null;
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptor.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptor.java
new file mode 100644
index 000000000..6cd22be31
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptor.java
@@ -0,0 +1,88 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.context.Contexts;
+import com.twitter.util.Future;
+import com.twitter.util.FutureEventListener;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+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.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+import static org.apache.skywalking.apm.network.trace.component.ComponentsDefine.FINAGLE;
+import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getLocalContextHolder;
+import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getSpan;
+
+public class ServerTracingFilterInterceptor extends AbstractInterceptor {
+
+ @Override
+ protected void onConstructImpl(EnhancedInstance objInst, Object[] allArguments) {
+
+ }
+
+ @Override
+ public void beforeMethodImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class>[] classes,
+ MethodInterceptResult methodInterceptResult) throws Throwable {
+ AbstractSpan span = null;
+ if (Contexts.broadcast().contains(SWContextCarrier$.MODULE$)) {
+ SWContextCarrier swContextCarrier = Contexts.broadcast().apply(SWContextCarrier$.MODULE$);
+ span = ContextManager.createEntrySpan(swContextCarrier.getOperationName(), swContextCarrier.getCarrier());
+ } else {
+ span = ContextManager.createEntrySpan("unknown", new ContextCarrier());
+ }
+
+ span.setComponent(FINAGLE);
+ SpanLayer.asRPCFramework(span);
+
+ getLocalContextHolder().let(FinagleCtxs.SW_SPAN, span);
+ }
+
+ @Override
+ public Object afterMethodImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class>[] classes, Object ret) throws Throwable {
+ final AbstractSpan finagleSpan = getSpan();
+ getLocalContextHolder().remove(FinagleCtxs.SW_SPAN);
+ finagleSpan.prepareForAsync();
+ ContextManager.stopSpan(finagleSpan);
+ ((Future>) ret).addEventListener(new FutureEventListener() {
+ @Override
+ public void onSuccess(Object value) {
+ finagleSpan.asyncFinish();
+ }
+
+ @Override
+ public void onFailure(Throwable cause) {
+ finagleSpan.errorOccurred();
+ finagleSpan.log(cause);
+ finagleSpan.asyncFinish();
+ }
+ });
+ return ret;
+ }
+
+ @Override
+ public void handleMethodExceptionImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects,
+ Class>[] classes, Throwable t) {
+ ContextManager.activeSpan().errorOccurred().log(t);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AbstractInstrumentation.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AbstractInstrumentation.java
new file mode 100644
index 000000000..39c784c9e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AbstractInstrumentation.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.finagle.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+
+public abstract class AbstractInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ /**
+ * this class exists in version 6.25.0 and above
+ */
+ private static final String ADDRMETADATAEXTRACTION_CLASS = "com.twitter.finagle.client.AddrMetadataExtraction";
+
+ @Override
+ protected String[] witnessClasses() {
+ return new String[]{ADDRMETADATAEXTRACTION_CLASS};
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AnnotationInstrumentation.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AnnotationInstrumentation.java
new file mode 100644
index 000000000..bcf3167a7
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/AnnotationInstrumentation.java
@@ -0,0 +1,81 @@
+/*
+ * 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.finagle.define;
+
+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.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+
+public class AnnotationInstrumentation {
+
+ private static final String ANNOTATION_CLASS = "com.twitter.finagle.tracing.Annotation$";
+ private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.finagle.AnnotationInterceptor$";
+
+ abstract static class Abstract extends AbstractInstrumentation {
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName(ANNOTATION_CLASS + getAnnoationName());
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ new ConstructorInterceptPoint() {
+ @Override
+ public ElementMatcher getConstructorMatcher() {
+ return getConstructor();
+ }
+
+ @Override
+ public String getConstructorInterceptor() {
+ return INTERCEPT_CLASS + getAnnoationName();
+ }
+ }
+ };
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[0];
+ }
+
+ protected abstract String getAnnoationName();
+
+ protected abstract ElementMatcher getConstructor();
+ }
+
+ public static class Rpc extends Abstract {
+
+ @Override
+ protected String getAnnoationName() {
+ return "Rpc";
+ }
+
+ @Override
+ protected ElementMatcher getConstructor() {
+ return takesArgument(0, String.class);
+ }
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientDestTracingFilterInstrumetation.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientDestTracingFilterInstrumetation.java
new file mode 100644
index 000000000..0c0dc6185
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientDestTracingFilterInstrumetation.java
@@ -0,0 +1,79 @@
+/*
+ * 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.finagle.define;
+
+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.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.any;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public class ClientDestTracingFilterInstrumetation extends AbstractInstrumentation {
+
+ private static final String ENHANCE_CLASS = "com.twitter.finagle.tracing.ClientDestTracingFilter";
+ private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.finagle.ClientDestTracingFilterInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ new ConstructorInterceptPoint() {
+ @Override
+ public ElementMatcher getConstructorMatcher() {
+ return any();
+ }
+
+ @Override
+ public String getConstructorInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+ }
+ };
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("apply");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientTracingFilterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientTracingFilterInstrumentation.java
new file mode 100644
index 000000000..29a2e40eb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ClientTracingFilterInstrumentation.java
@@ -0,0 +1,67 @@
+/*
+ * 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.finagle.define;
+
+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.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public class ClientTracingFilterInstrumentation extends AbstractInstrumentation {
+
+ private static final String ENHANCE_CLASS = "com.twitter.finagle.tracing.ClientTracingFilter$TracingFilter";
+ private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.finagle.ClientTracingFilterInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return null;
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("apply");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
+
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ServerTracingFilterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ServerTracingFilterInstrumentation.java
new file mode 100644
index 000000000..fe4a835ff
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/finagle/define/ServerTracingFilterInstrumentation.java
@@ -0,0 +1,66 @@
+/*
+ * 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.finagle.define;
+
+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.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public class ServerTracingFilterInstrumentation extends AbstractInstrumentation {
+
+ private static final String ENHANCE_CLASS = "com.twitter.finagle.tracing.ServerTracingFilter$TracingFilter";
+ private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.finagle.ServerTracingFilterInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return null;
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("apply");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000..33d15ebee
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+finagle=org.apache.skywalking.apm.plugin.finagle.define.AnnotationInstrumentation$Rpc
+finagle=org.apache.skywalking.apm.plugin.finagle.define.ClientTracingFilterInstrumentation
+finagle=org.apache.skywalking.apm.plugin.finagle.define.ClientDestTracingFilterInstrumetation
+finagle=org.apache.skywalking.apm.plugin.finagle.define.ServerTracingFilterInstrumentation
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/scala/org/apache/skywalking/apm/plugin/finagle/SWContextCarrier.scala b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/scala/org/apache/skywalking/apm/plugin/finagle/SWContextCarrier.scala
new file mode 100644
index 000000000..a444f96ca
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/scala/org/apache/skywalking/apm/plugin/finagle/SWContextCarrier.scala
@@ -0,0 +1,57 @@
+/*
+ * 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.finagle
+
+import com.twitter.finagle.context.Contexts
+import com.twitter.io.Buf
+import com.twitter.util.{Return, Try}
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier
+
+class SWContextCarrier() {
+ private var operationName: String = ""
+ private var carrier: ContextCarrier = null;
+
+ def setOperationName(op: String): Unit = {
+ operationName = op
+ }
+
+ def setContextCarrier(carrier: ContextCarrier): Unit = this.carrier = carrier;
+
+ def getOperationName: String = operationName
+
+ def getCarrier(): ContextCarrier = carrier;
+}
+
+object SWContextCarrier extends Contexts.broadcast.Key[SWContextCarrier]("org.apache.skywalking.apm.plugin.finagle.SWContextCarrier") {
+
+ def of(carrier: ContextCarrier): SWContextCarrier = {
+ val sWContextCarrier = new SWContextCarrier()
+ sWContextCarrier.setContextCarrier(carrier)
+ sWContextCarrier
+ }
+
+ override def marshal(context: SWContextCarrier): Buf = {
+ CodecUtils.encode(context)
+ }
+
+ override def tryUnmarshal(buf: Buf): Try[SWContextCarrier] = {
+ val context = CodecUtils.decode(buf)
+ Return(context)
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/AbstractTracingFilterTest.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/AbstractTracingFilterTest.java
new file mode 100644
index 000000000..4b9002f4a
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/AbstractTracingFilterTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.Service;
+import com.twitter.util.Future;
+import com.twitter.util.Promise;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.core.context.util.TagValuePair;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.mockito.Mock;
+
+import java.util.List;
+
+import static org.apache.skywalking.apm.network.trace.component.ComponentsDefine.FINAGLE;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+public abstract class AbstractTracingFilterTest {
+
+ @Rule
+ public AgentServiceRule agentServiceRule = new AgentServiceRule();
+
+ @Mock
+ protected MethodInterceptResult methodInterceptResult;
+
+ protected EnhancedInstance enhancedInstance = new MockEnhancedInstance();
+
+ protected AnnotationInterceptor.Rpc rpcInterceptor = new AnnotationInterceptor.Rpc();
+
+ protected String rpc = "finagleRpc";
+
+ protected Object[] allArguments;
+ protected Class[] argumentTypes;
+
+ protected Promise result;
+
+ @Before
+ public void setup() throws Throwable {
+ result = new Promise();
+ allArguments = new Object[]{new Object(), new Service() {
+ @Override
+ public Future apply(Object request) {
+ return result;
+ }
+ } };
+ argumentTypes = new Class[]{Object.class, Service.class};
+ prepareForTest();
+ }
+
+ protected abstract void prepareForTest() throws Throwable;
+
+ protected abstract void assertSpan(AbstractTracingSpan span);
+
+ protected void assertTraceSegments(List traceSegments) {
+ assertThat(traceSegments.size(), is(1));
+ TraceSegment traceSegment = traceSegments.get(0);
+ List spans = SegmentHelper.getSpans(traceSegment);
+ assertThat(spans.size(), is(1));
+ assertFinagleSpan(spans.get(0));
+ }
+
+ protected void assertTraceSegmentsWithError(List traceSegments) {
+ assertThat(traceSegments.size(), is(1));
+ TraceSegment traceSegment = traceSegments.get(0);
+ List spans = SegmentHelper.getSpans(traceSegment);
+ assertThat(spans.size(), is(1));
+ assertFinagleSpan(spans.get(0));
+
+ assertThat(SpanHelper.getLogs(spans.get(0)).size(), is(1));
+ assertErrorLog(SpanHelper.getLogs(spans.get(0)).get(0));
+ }
+
+ private void assertFinagleSpan(AbstractTracingSpan span) {
+ List tags = SpanHelper.getTags(span);
+ assertThat(tags.size(), is(0));
+ assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.RPC_FRAMEWORK));
+ assertThat(SpanHelper.getComponentId(span), is(FINAGLE.getId()));
+ assertThat(span.getOperationName(), is(rpc));
+
+ assertSpan(span);
+ }
+
+ private void assertErrorLog(LogDataEntity logData) {
+ assertThat(logData.getLogs().size(), is(4));
+ assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.is("error"));
+ assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.is(RuntimeException.class.getName()));
+ assertNull(logData.getLogs().get(2).getValue());
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ClientTracingFilterInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ClientTracingFilterInterceptorTest.java
new file mode 100644
index 000000000..84dc1edff
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ClientTracingFilterInterceptorTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.Address;
+import com.twitter.finagle.Addresses$;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.ExitTypeSpan;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+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.Test;
+import org.junit.runner.RunWith;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import java.net.Inet4Address;
+import java.net.InetSocketAddress;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+public class ClientTracingFilterInterceptorTest extends AbstractTracingFilterTest {
+
+ @SegmentStoragePoint
+ protected SegmentStorage segmentStorage;
+
+ private ClientTracingFilterInterceptor clientTracingFilterInterceptor;
+ private ClientDestTracingFilterInterceptor clientDestTracingFilterInterceptor =
+ new ClientDestTracingFilterInterceptor();
+ private EnhancedInstance enhancedClientDestTracingFilter = new MockEnhancedInstance();
+ private InetSocketAddress serverSocketAddress;
+ private Address serverAddr;
+
+ @Override
+ protected void prepareForTest() throws Throwable {
+ clientTracingFilterInterceptor = new ClientTracingFilterInterceptor();
+ serverSocketAddress = new InetSocketAddress(Inet4Address.getLocalHost(), 9999);
+ serverAddr = Addresses$.MODULE$.newInetAddress(serverSocketAddress);
+ }
+
+ @Override
+ protected void assertSpan(AbstractTracingSpan span) {
+ assertTrue(span.isExit());
+ assertThat(((ExitTypeSpan) span).getPeer(), is(serverSocketAddress.getAddress().getHostAddress() + ":" + serverSocketAddress.getPort()));
+ }
+
+ @Test
+ public void testClient() throws Throwable {
+ clientTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setValue(new Object());
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ clientDestTracingFilterInterceptor.onConstruct(enhancedClientDestTracingFilter, new Object[]{serverAddr});
+
+ clientDestTracingFilterInterceptor.beforeMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, methodInterceptResult);
+ clientDestTracingFilterInterceptor.afterMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, result);
+
+ clientTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+
+ assertTraceSegments(segmentStorage.getTraceSegments());
+ }
+
+ @Test
+ public void testClientWithException() throws Throwable {
+ clientTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setValue(new Object());
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ clientDestTracingFilterInterceptor.onConstruct(enhancedClientDestTracingFilter, new Object[]{serverAddr});
+ clientDestTracingFilterInterceptor.beforeMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, methodInterceptResult);
+ clientDestTracingFilterInterceptor.afterMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, result);
+
+ clientTracingFilterInterceptor.handleMethodException(enhancedInstance, null, allArguments, argumentTypes, new RuntimeException());
+ clientTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+
+ assertTraceSegmentsWithError(segmentStorage.getTraceSegments());
+ }
+
+ @Test
+ public void testClientWithResultHasException() throws Throwable {
+
+ clientTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setException(new RuntimeException());
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ clientDestTracingFilterInterceptor.onConstruct(enhancedClientDestTracingFilter, new Object[]{serverAddr});
+ clientDestTracingFilterInterceptor.beforeMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, methodInterceptResult);
+ clientDestTracingFilterInterceptor.afterMethod(enhancedClientDestTracingFilter, null, allArguments, argumentTypes, result);
+
+ clientTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+
+ assertTraceSegments(segmentStorage.getTraceSegments());
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/CodecUtilsTest.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/CodecUtilsTest.java
new file mode 100644
index 000000000..d7763d6ec
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/CodecUtilsTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.finagle;
+
+import com.twitter.io.Bufs;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class CodecUtilsTest {
+
+ @Test
+ public void encode() {
+ SWContextCarrier swContextCarrier = makeSWContextCarrier();
+ assertSwContextCarrier(swContextCarrier, CodecUtils.decode(CodecUtils.encode(swContextCarrier)));
+
+ swContextCarrier = makeSWContextCarrier();
+ assertSwContextCarrier(swContextCarrier, CodecUtils.decode(CodecUtils.encode(swContextCarrier)));
+
+ swContextCarrier = makeSWContextCarrier();
+ assertSwContextCarrier(swContextCarrier, CodecUtils.decode(CodecUtils.encode(swContextCarrier)));
+
+ ContextCarrier contextCarrier = new ContextCarrier();
+ swContextCarrier = new SWContextCarrier();
+ swContextCarrier.setContextCarrier(contextCarrier);
+ assertSwContextCarrier(swContextCarrier, CodecUtils.decode(Bufs.EMPTY));
+ }
+
+ private SWContextCarrier makeSWContextCarrier() {
+ ContextCarrier contextCarrier = new ContextCarrier();
+ CarrierItem next = contextCarrier.items();
+ while (next.hasNext()) {
+ next = next.next();
+ next.setHeadValue(UUID.randomUUID().toString());
+ }
+ SWContextCarrier swContextCarrier = new SWContextCarrier();
+ swContextCarrier.setContextCarrier(contextCarrier);
+ swContextCarrier.setOperationName(UUID.randomUUID().toString());
+ return swContextCarrier;
+ }
+
+ private void assertSwContextCarrier(SWContextCarrier expected, SWContextCarrier actual) {
+ assertThat(expected.getOperationName(), is(actual.getOperationName()));
+ Map data = new HashMap<>();
+ CarrierItem next = expected.getCarrier().items();
+ while (next.hasNext()) {
+ next = next.next();
+ data.put(next.getHeadKey(), next.getHeadValue());
+ }
+ next = actual.getCarrier().items();
+ while (next.hasNext()) {
+ next = next.next();
+ assertThat(next.getHeadValue(), is(data.get(next.getHeadKey())));
+ }
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactoryTest.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactoryTest.java
new file mode 100644
index 000000000..0b63bce2d
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ContextHolderFactoryTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.context.Contexts;
+import com.twitter.finagle.context.LocalContext;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.lang.reflect.Constructor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getLocalContextHolder;
+import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getMarshalledContextHolder;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class ContextHolderFactoryTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static LocalContext.Key KEY1;
+ private static LocalContext.Key KEY2;
+ private static LocalContext.Key KEY3;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ Constructor constructor = LocalContext.Key.class.getConstructor(LocalContext.class);
+ KEY1 = (LocalContext.Key) constructor.newInstance(Contexts.local());
+ KEY2 = (LocalContext.Key) constructor.newInstance(Contexts.local());
+ KEY3 = (LocalContext.Key) constructor.newInstance(Contexts.local());
+ }
+
+ @Test
+ public void testLCRemoveNonExistKey() {
+ testRemoveNonExistKey(getLocalContextHolder());
+ }
+
+ @Test
+ public void testLCRemoveWrongOrder() {
+ ContextHolder localContextHolder = getLocalContextHolder();
+ try {
+ localContextHolder.let(KEY1, "key1");
+ localContextHolder.let(KEY2, "key2");
+ testLCRemoveWrongOrder(localContextHolder, KEY1);
+ } finally {
+ localContextHolder.remove(KEY2);
+ localContextHolder.remove(KEY1);
+ }
+ }
+
+ @Test
+ public void testLCLetAndRemove() {
+ ContextHolder localContextHolder = getLocalContextHolder();
+ localContextHolder.let(KEY1, Thread.currentThread().getName() + KEY1);
+ localContextHolder.let(KEY2, Thread.currentThread().getName() + KEY2);
+ localContextHolder.let(KEY3, Thread.currentThread().getName() + KEY3);
+ localContextHolder.let(KEY2, Thread.currentThread().getName() + KEY2 + KEY2);
+
+ assertEquals(Contexts.local().apply(KEY1), Thread.currentThread().getName() + KEY1);
+ assertEquals(Contexts.local().apply(KEY2), Thread.currentThread().getName() + KEY2 + KEY2);
+ assertEquals(Contexts.local().apply(KEY3), Thread.currentThread().getName() + KEY3);
+
+ localContextHolder.remove(KEY2);
+ assertEquals(Contexts.local().apply(KEY1), Thread.currentThread().getName() + KEY1);
+ assertEquals(Contexts.local().apply(KEY2), Thread.currentThread().getName() + KEY2);
+ assertEquals(Contexts.local().apply(KEY3), Thread.currentThread().getName() + KEY3);
+
+ localContextHolder.remove(KEY3);
+ assertEquals(Contexts.local().apply(KEY1), Thread.currentThread().getName() + KEY1);
+ assertEquals(Contexts.local().apply(KEY2), Thread.currentThread().getName() + KEY2);
+ assertFalse(Contexts.local().get(KEY3).isDefined());
+
+ localContextHolder.remove(KEY2);
+ assertEquals(Contexts.local().apply(KEY1), Thread.currentThread().getName() + KEY1);
+ assertFalse(Contexts.local().get(KEY2).isDefined());
+ assertFalse(Contexts.local().get(KEY3).isDefined());
+
+ localContextHolder.remove(KEY1);
+ assertFalse(Contexts.local().get(KEY1).isDefined());
+ assertFalse(Contexts.local().get(KEY2).isDefined());
+ assertFalse(Contexts.local().get(KEY3).isDefined());
+ }
+
+ @Test
+ public void testLCLetAndRemoveMultiThread() throws InterruptedException {
+ ExecutorService exec = Executors.newFixedThreadPool(5);
+ final AtomicInteger exceptions = new AtomicInteger(0);
+ for (int i = 0; i < 30; i++) {
+ exec.submit(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ testLCLetAndRemove();
+ } catch (Exception e) {
+ exceptions.incrementAndGet();
+ }
+ }
+ });
+ }
+ exec.shutdown();
+ exec.awaitTermination(3, TimeUnit.MINUTES);
+ assertEquals(exceptions.get(), 0);
+ }
+
+ @Test
+ public void testMCRemoveNonExistKey() {
+ testRemoveNonExistKey(getMarshalledContextHolder());
+ }
+
+ private void testRemoveNonExistKey(ContextHolder contextHolder) {
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("can't remove");
+ contextHolder.remove(new Object());
+ }
+
+ private void testLCRemoveWrongOrder(ContextHolder contextHolder, Object key) {
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("can't remove");
+ thrown.expectMessage(key.toString());
+ contextHolder.remove(key);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/MockEnhancedInstance.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/MockEnhancedInstance.java
new file mode 100644
index 000000000..f47fc5fd6
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/MockEnhancedInstance.java
@@ -0,0 +1,36 @@
+/*
+ * 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.finagle;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+
+public class MockEnhancedInstance implements EnhancedInstance {
+
+ private Object object;
+
+ @Override
+ public Object getSkyWalkingDynamicField() {
+ return object;
+ }
+
+ @Override
+ public void setSkyWalkingDynamicField(Object value) {
+ this.object = value;
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptorTest.java
new file mode 100644
index 000000000..a51305b1d
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/finagle/ServerTracingFilterInterceptorTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.finagle;
+
+import com.twitter.finagle.context.Contexts;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.SW6CarrierItem;
+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.context.trace.TraceSegmentRef;
+import org.apache.skywalking.apm.agent.test.helper.SegmentRefHelper;
+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.Test;
+import org.junit.runner.RunWith;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import scala.runtime.AbstractFunction0;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+public class ServerTracingFilterInterceptorTest extends AbstractTracingFilterTest {
+
+ @SegmentStoragePoint
+ protected SegmentStorage segmentStorage;
+
+ private ServerTracingFilterInterceptor serverTracingFilterInterceptor;
+
+ @Override
+ protected void prepareForTest() {
+ serverTracingFilterInterceptor = new ServerTracingFilterInterceptor();
+ }
+
+ @Override
+ protected void assertSpan(AbstractTracingSpan span) {
+ assertTrue(span.isEntry());
+ }
+
+ @Test
+ public void testServer() {
+ runWithContext(new TestFunction() {
+ @Override
+ public void apply() throws Throwable {
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ serverTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setValue(new Object());
+ serverTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+ assertServer();
+ assertTraceSegments(segmentStorage.getTraceSegments());
+ }
+ });
+ }
+
+ @Test
+ public void testServerWithException() {
+ runWithContext(new TestFunction() {
+ @Override
+ public void apply() throws Throwable {
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ serverTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setValue(new Object());
+ serverTracingFilterInterceptor.handleMethodException(enhancedInstance, null, allArguments, argumentTypes, new RuntimeException());
+ serverTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+ assertServer();
+ assertTraceSegmentsWithError(segmentStorage.getTraceSegments());
+ }
+ });
+ }
+
+ @Test
+ public void testServerWithResultHasException() {
+ runWithContext(new TestFunction() {
+ @Override
+ public void apply() throws Throwable {
+ rpcInterceptor.onConstruct(null, new Object[]{rpc});
+ serverTracingFilterInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
+ result.setException(new RuntimeException());
+ serverTracingFilterInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
+ assertServer();
+ assertTraceSegmentsWithError(segmentStorage.getTraceSegments());
+ }
+ });
+ }
+
+ private void runWithContext(final TestFunction function) {
+ ContextCarrier contextCarrier = new ContextCarrier();
+ CarrierItem next = contextCarrier.items();
+ while (next.hasNext()) {
+ next = next.next();
+ if (next.getHeadKey().equals(SW6CarrierItem.HEADER_NAME)) {
+ next.setHeadValue("1-MC4wLjA=-MS4zMjMuNDQzMw==-3-1-1-IzE5Mi4xNjguMS44IDoxODAwMg==-Iy9wb3J0Y" +
+ "Wwv-Iy90ZXN0RW50cnlTcGFu");
+ }
+ }
+ SWContextCarrier swContextCarrier = new SWContextCarrier();
+ swContextCarrier.setContextCarrier(contextCarrier);
+ swContextCarrier.setOperationName(rpc);
+ Contexts.broadcast().let(SWContextCarrier$.MODULE$, swContextCarrier, new AbstractFunction0() {
+ @Override
+ public Void apply() {
+ try {
+ function.apply();
+ } catch (Throwable throwable) {
+ throw new RuntimeException(throwable);
+ }
+ return null;
+ }
+ });
+ }
+
+ interface TestFunction {
+ void apply() throws Throwable;
+ }
+
+ private void assertServer() {
+ TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+ TraceSegmentRef actual = traceSegment.getRefs().get(0);
+ assertThat(SegmentRefHelper.getSpanId(actual), is(3));
+ assertThat(SegmentRefHelper.getEntryServiceInstanceId(actual), is(1));
+ assertThat(SegmentRefHelper.getTraceSegmentId(actual).toString(), is("1.323.4433"));
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml
index 9b1a53412..9bf5ef848 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -88,6 +88,7 @@
play-2.x-plugin
lettuce-5.x-plugin
avro-plugin
+ finagle-6.25.x-plugin
pom
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 55e93602f..5647c327b 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -42,6 +42,7 @@
* [SOFARPC](https://github.com/alipay/sofa-rpc) 5.4.0
* [Armeria](https://github.com/line/armeria) 0.63.0 -> 0.98.0
* [Apache Avro](http://avro.apache.org) 1.7.0 - 1.8.x
+ * [Finagle](https://github.com/twitter/finagle) 6.25.0 -> 20.1.0
* MQ
* [RocketMQ](https://github.com/apache/rocketmq) 4.x
* [Kafka](http://kafka.apache.org) 0.11.0.0 -> 1.0
diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
index 03c452018..4cd93d983 100755
--- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
+++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
@@ -281,6 +281,9 @@ AvroClient:
Undertow:
id: 84
languages: Java
+Finagle:
+ id: 85
+ languages: Java,Scala
# .NET/.NET Core components
# [3000, 4000) for C#/.NET only
diff --git a/oap-server/server-core/src/test/resources/component-libraries.yml b/oap-server/server-core/src/test/resources/component-libraries.yml
index 05e81cf16..643b0b2b7 100755
--- a/oap-server/server-core/src/test/resources/component-libraries.yml
+++ b/oap-server/server-core/src/test/resources/component-libraries.yml
@@ -248,6 +248,9 @@ AvroServer:
AvroClient:
id: 83
languages: Java
+Finagle:
+ id: 85
+ languages: Java,Scala
# .NET/.NET Core components
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/bin/startup.sh b/test/plugin/scenarios/finagle-17.10.x-scenario/bin/startup.sh
new file mode 100644
index 000000000..8a9c9300e
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/finagle-17.10.x-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/finagle-17.10.x-scenario/config/expectedData.yaml
new file mode 100644
index 000000000..13e28ea81
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/config/expectedData.yaml
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+registryItems:
+ services:
+ - {finagle-17.10.x-scenario: 2}
+ instances:
+ - {finagle-17.10.x-scenario: 1}
+ operationNames:
+ - finagle-17.10.x-scenario: [hello, /finagle-17.10.x-scenario/case/finagle]
+ heartbeat: []
+segmentItems:
+ - serviceName: finagle-17.10.x-scenario
+ segmentSize: gt 2
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ refs:
+ - {parentEndpointId: 0, parentEndpoint: /finagle-17.10.x-scenario/case/finagle, networkAddressId: 0,
+ entryEndpointId: 0, refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
+ parentServiceInstanceId: 1, networkAddress: '127.0.0.1:12220', entryEndpoint: /finagle-17.10.x-scenario/case/finagle,
+ entryServiceInstanceId: 1}
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Exit
+ peer: 127.0.0.1:12220
+ peerId: 0
+ - operationName: /finagle-17.10.x-scenario/case/finagle
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 1
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ tags:
+ - {key: url, value: 'http://localhost:8080/finagle-17.10.x-scenario/case/finagle'}
+ - {key: http.method, value: GET}
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/configuration.yml b/test/plugin/scenarios/finagle-17.10.x-scenario/configuration.yml
new file mode 100644
index 000000000..a6b9e03f4
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/configuration.yml
@@ -0,0 +1,23 @@
+# 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/finagle-17.10.x-scenario/case/finagle
+healthCheck: http://localhost:8080/finagle-17.10.x-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+framework: finagle-17.10.x-scenario
+environment:
+dependencies:
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/pom.xml b/test/plugin/scenarios/finagle-17.10.x-scenario/pom.xml
new file mode 100644
index 000000000..08e963a8d
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/pom.xml
@@ -0,0 +1,170 @@
+
+
+
+
+ org.apache.skywalking.apm.testcase
+ finagle-17.10.x-scenario
+ 1.0.0
+ jar
+
+ 4.0.0
+
+
+ UTF-8
+ 1.8
+ 17.10.0
+ 2.1.6.RELEASE
+ 1.18.10
+
+
+ skywalking-finagle-17.10.x-scenario
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot-version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+
+ com.twitter
+ finagle-core_2.11
+ ${test.framework.version}
+
+
+
+ com.twitter
+ finagle-thrift_2.11
+ ${test.framework.version}
+
+
+ servlet-api
+ javax.servlet
+
+
+
+
+
+ com.twitter
+ scrooge-core_2.11
+ ${test.framework.version}
+
+
+
+
+ finagle-17.10.x-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ 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/
+
+
+
+
+
+ com.twitter
+ scrooge-maven-plugin
+ ${test.framework.version}
+
+ java
+
+ --finagle
+
+ false
+
+
+
+ generate-thrift-sources
+ generate-sources
+
+ compile
+
+
+
+ thrift-test-sources
+ generate-test-sources
+
+ testCompile
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..76b0dbbf7
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+ ${project.build.directory}/finagle-17.10.x-scenario.jar
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
new file mode 100644
index 000000000..f1e40daea
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
@@ -0,0 +1,55 @@
+/*
+ * 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.finagle;
+
+
+import com.twitter.finagle.ListeningServer;
+import com.twitter.finagle.Thrift;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.apache.skywalking.apm.testcase.finagle.service.FinagleRpcDemoServiceImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@SpringBootApplication
+public class FinagleRpcApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(FinagleRpcApplication.class, args);
+ }
+
+
+ @Configuration
+ public static class FinagleRpcConfiguration {
+
+ @Bean(destroyMethod = "close")
+ public ListeningServer server() {
+ ListeningServer server = Thrift.server()
+ .serveIface(":12220", new FinagleRpcDemoServiceImpl());
+ return server;
+ }
+
+ @Bean
+ public FinagleRpcDemoService.ServiceIface client() {
+ return Thrift.client()
+ .newIface("localhost:12220", FinagleRpcDemoService.ServiceIface.class);
+ }
+ }
+}
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java
new file mode 100644
index 000000000..026fc6316
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.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.testcase.finagle.controller;
+
+import com.twitter.util.Await;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.springframework.beans.factory.annotation.Autowired;
+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 {
+
+ private static final String SUCCESS = "Success";
+
+ @Autowired
+ private FinagleRpcDemoService.ServiceIface finagleRpcDemoService;
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() {
+ return SUCCESS;
+ }
+
+ @RequestMapping("/finagle")
+ @ResponseBody
+ public String finagle() throws Exception {
+ System.out.println(Await.result(finagleRpcDemoService.hello("finagle")));
+ return SUCCESS;
+ }
+}
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java
new file mode 100644
index 000000000..784519370
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.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.finagle.service;
+
+import com.twitter.util.Future;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+
+
+public class FinagleRpcDemoServiceImpl implements FinagleRpcDemoService.ServiceIface {
+
+ public Future hello(String name) {
+ return Future.value("hello, " + name);
+ }
+}
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/resources/application.yaml
new file mode 100644
index 000000000..96d5680d5
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/resources/application.yaml
@@ -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: /finagle-17.10.x-scenario
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/thrift/service.thrift b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/thrift/service.thrift
new file mode 100644
index 000000000..f37d915e1
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/src/main/thrift/service.thrift
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ */
+
+namespace java org.apache.skywalking.apm.testcase.finagle.interfaces
+
+service FinagleRpcDemoService {
+ string hello(string name);
+}
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-17.10.x-scenario/support-version.list b/test/plugin/scenarios/finagle-17.10.x-scenario/support-version.list
new file mode 100644
index 000000000..ecd0fac6d
--- /dev/null
+++ b/test/plugin/scenarios/finagle-17.10.x-scenario/support-version.list
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version
+# "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.
+
+17.10.0
+17.11.0
+17.12.0
+18.1.0
+18.2.0
+18.3.0
+18.4.0
+18.5.0
+18.6.0
+18.7.0
+18.8.0
+18.9.0
+18.9.1
+18.10.0
+18.11.0
+18.12.0
+19.1.0
+19.2.0
+19.3.0
+19.4.0
+19.5.0
+19.5.1
+19.6.0
+19.7.0
+19.8.0
+19.9.0
+19.10.0
+19.11.0
+19.12.0
+20.1.0
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/bin/startup.sh b/test/plugin/scenarios/finagle-6.25.x-scenario/bin/startup.sh
new file mode 100644
index 000000000..14e577efd
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/finagle-6.25.x-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/finagle-6.25.x-scenario/config/expectedData.yaml
new file mode 100644
index 000000000..6f49af51e
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/config/expectedData.yaml
@@ -0,0 +1,86 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+registryItems:
+ services:
+ - {finagle-6.25.x-scenario: 2}
+ instances:
+ - {finagle-6.25.x-scenario: 1}
+ operationNames:
+ - finagle-6.25.x-scenario: [hello, /finagle-6.25.x-scenario/case/finagle]
+ heartbeat: []
+segmentItems:
+ - serviceName: finagle-6.25.x-scenario
+ segmentSize: gt 2
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ refs:
+ - {parentEndpointId: 0, parentEndpoint: /finagle-6.25.x-scenario/case/finagle, networkAddressId: 0,
+ entryEndpointId: 0, refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
+ parentServiceInstanceId: 1, networkAddress: '127.0.0.1:12220', entryEndpoint: /finagle-6.25.x-scenario/case/finagle,
+ entryServiceInstanceId: 1}
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Exit
+ peer: 127.0.0.1:12220
+ peerId: 0
+ - operationName: /finagle-6.25.x-scenario/case/finagle
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 1
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ tags:
+ - {key: url, value: 'http://localhost:8080/finagle-6.25.x-scenario/case/finagle'}
+ - {key: http.method, value: GET}
+
+
+
+
+
+
+
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/configuration.yml b/test/plugin/scenarios/finagle-6.25.x-scenario/configuration.yml
new file mode 100644
index 000000000..9cc859af3
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-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/finagle-6.25.x-scenario/case/finagle
+healthCheck: http://localhost:8080/finagle-6.25.x-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+framework: finagle
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/pom.xml b/test/plugin/scenarios/finagle-6.25.x-scenario/pom.xml
new file mode 100644
index 000000000..34a102e2f
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/pom.xml
@@ -0,0 +1,177 @@
+
+
+
+ 4.0.0
+
+ org.apache.skywalking
+ finagle-6.25.x-scenario
+ jar
+ 5.0.0
+
+
+ UTF-8
+ 1.8
+
+ 2.1.6.RELEASE
+ finagle
+ 6.25.0
+
+
+ skywalking-finagle-6.25.x-scenario
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring.boot.version}
+ pom
+ import
+
+
+
+
+
+
+ com.twitter
+ finagle-core_2.11
+ ${test.framework.version}
+
+
+
+ com.twitter
+ finagle-thrift_2.11
+ ${test.framework.version}
+
+
+ servlet-api
+ javax.servlet
+
+
+
+
+
+ org.apache.thrift
+ libthrift
+ 0.9.3
+
+
+
+ com.twitter
+ scrooge-core_2.11
+ 4.7.0
+
+
+
+ com.twitter
+ scrooge-runtime_2.11
+ 4.5.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ finagle-6.25.x-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ 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/
+
+
+
+
+
+ com.twitter
+ scrooge-maven-plugin
+ 4.5.0
+
+ experimental-java
+
+ --finagle
+
+ false
+
+
+
+ generate-thrift-sources
+ generate-sources
+
+ compile
+
+
+
+ thrift-test-sources
+ generate-test-sources
+
+ testCompile
+
+
+
+
+
+
+
+
+
+ spring-snapshots
+ http://repo.spring.io/snapshot
+
+
+ spring-milestones
+ http://repo.spring.io/milestone
+
+
+
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..c0ab4d3b8
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+ ${project.build.directory}/finagle-6.25.x-scenario.jar
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
new file mode 100644
index 000000000..c172b8b6b
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
@@ -0,0 +1,55 @@
+/*
+ * 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.finagle;
+
+
+import com.twitter.finagle.ListeningServer;
+import com.twitter.finagle.Thrift;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.apache.skywalking.apm.testcase.finagle.service.FinagleRpcDemoServiceImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@SpringBootApplication
+public class FinagleRpcApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(FinagleRpcApplication.class, args);
+ }
+
+
+ @Configuration
+ public static class FinagleRpcConfiguration {
+
+ @Bean(destroyMethod = "close")
+ public ListeningServer server() {
+ ListeningServer server = Thrift.server()
+ .serveIface(":12220", new FinagleRpcDemoServiceImpl());
+ return server;
+ }
+
+ @Bean
+ public FinagleRpcDemoService.FutureIface client() {
+ return Thrift.client()
+ .newIface("localhost:12220", FinagleRpcDemoService.FutureIface.class);
+ }
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java
new file mode 100644
index 000000000..7f698c692
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.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.testcase.finagle.controller;
+
+import com.twitter.util.Await;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.springframework.beans.factory.annotation.Autowired;
+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 {
+
+ private static final String SUCCESS = "Success";
+
+ @Autowired
+ private FinagleRpcDemoService.FutureIface finagleRpcDemoService;
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() {
+ return SUCCESS;
+ }
+
+ @RequestMapping("/finagle")
+ @ResponseBody
+ public String finagle() throws Exception {
+ System.out.println(Await.result(finagleRpcDemoService.hello("finagle")));
+ return SUCCESS;
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java
new file mode 100644
index 000000000..91b6f8a9e
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.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.finagle.service;
+
+import com.twitter.util.Future;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+
+
+public class FinagleRpcDemoServiceImpl implements FinagleRpcDemoService.FutureIface {
+
+ public Future hello(String name) {
+ return Future.value("hello, " + name);
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/resources/application.yml b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/resources/application.yml
new file mode 100644
index 000000000..b8c30e939
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/resources/application.yml
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+server:
+ port: 8080
+ servlet:
+ context-path: /finagle-6.25.x-scenario
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/thrift/service.thrift b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/thrift/service.thrift
new file mode 100644
index 000000000..f37d915e1
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/src/main/thrift/service.thrift
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ */
+
+namespace java org.apache.skywalking.apm.testcase.finagle.interfaces
+
+service FinagleRpcDemoService {
+ string hello(string name);
+}
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.25.x-scenario/support-version.list b/test/plugin/scenarios/finagle-6.25.x-scenario/support-version.list
new file mode 100644
index 000000000..ae96648f2
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.25.x-scenario/support-version.list
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version
+# "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.
+
+6.25.0
+6.26.0
+6.27.0
+6.28.0
+6.29.0
+6.30.0
+6.31.0
+6.33.0
+6.34.0
+6.35.0
+6.36.0
+6.37.0
+6.38.0
+6.39.0
+6.40.0
+6.41.0
+6.42.0
+6.43.0
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/bin/startup.sh b/test/plugin/scenarios/finagle-6.44.x-scenario/bin/startup.sh
new file mode 100644
index 000000000..275802029
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/finagle-6.44.x-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/finagle-6.44.x-scenario/config/expectedData.yaml
new file mode 100644
index 000000000..05ba675b1
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/config/expectedData.yaml
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+registryItems:
+ services:
+ - {finagle-6.44.x-scenario: 2}
+ instances:
+ - {finagle-6.44.x-scenario: 1}
+ operationNames:
+ - finagle-6.44.x-scenario: [hello, /finagle-6.44.x-scenario/case/finagle]
+ heartbeat: []
+segmentItems:
+ - serviceName: finagle-6.44.x-scenario
+ segmentSize: gt 2
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ refs:
+ - {parentEndpointId: 0, parentEndpoint: /finagle-6.44.x-scenario/case/finagle, networkAddressId: 0,
+ entryEndpointId: 0, refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
+ parentServiceInstanceId: 1, networkAddress: '127.0.0.1:12220', entryEndpoint: /finagle-6.44.x-scenario/case/finagle,
+ entryServiceInstanceId: 1}
+ - segmentId: not null
+ spans:
+ - operationName: hello
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: RPCFramework
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 85
+ componentName: ''
+ isError: false
+ spanType: Exit
+ peer: 127.0.0.1:12220
+ peerId: 0
+ - operationName: /finagle-6.44.x-scenario/case/finagle
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 1
+ componentName: ''
+ isError: false
+ spanType: Entry
+ peer: ''
+ peerId: 0
+ tags:
+ - {key: url, value: 'http://localhost:8080/finagle-6.44.x-scenario/case/finagle'}
+ - {key: http.method, value: GET}
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/configuration.yml b/test/plugin/scenarios/finagle-6.44.x-scenario/configuration.yml
new file mode 100644
index 000000000..311b45286
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/configuration.yml
@@ -0,0 +1,23 @@
+# 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/finagle-6.44.x-scenario/case/finagle
+healthCheck: http://localhost:8080/finagle-6.44.x-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+framework: finagle-6.44.x-scenario
+environment:
+dependencies:
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/pom.xml b/test/plugin/scenarios/finagle-6.44.x-scenario/pom.xml
new file mode 100644
index 000000000..95ee34088
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/pom.xml
@@ -0,0 +1,170 @@
+
+
+
+
+ org.apache.skywalking.apm.testcase
+ finagle-6.44.x-scenario
+ 1.0.0
+ jar
+
+ 4.0.0
+
+
+ UTF-8
+ 1.8
+ 6.41.0
+ 2.1.6.RELEASE
+ 1.18.10
+
+
+ skywalking-finagle-6.44.x-scenario
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot-version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+
+ com.twitter
+ finagle-core_2.11
+ ${test.framework.version}
+
+
+
+ com.twitter
+ finagle-thrift_2.11
+ ${test.framework.version}
+
+
+ servlet-api
+ javax.servlet
+
+
+
+
+
+ com.twitter
+ scrooge-core_2.11
+ 4.20.0
+
+
+
+
+ finagle-6.44.x-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ 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/
+
+
+
+
+
+ com.twitter
+ scrooge-maven-plugin
+ 4.20.0
+
+ java
+
+ --finagle
+
+ false
+
+
+
+ generate-thrift-sources
+ generate-sources
+
+ compile
+
+
+
+ thrift-test-sources
+ generate-test-sources
+
+ testCompile
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..84da8ccfc
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+ ${project.build.directory}/finagle-6.44.x-scenario.jar
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
new file mode 100644
index 000000000..f1e40daea
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/FinagleRpcApplication.java
@@ -0,0 +1,55 @@
+/*
+ * 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.finagle;
+
+
+import com.twitter.finagle.ListeningServer;
+import com.twitter.finagle.Thrift;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.apache.skywalking.apm.testcase.finagle.service.FinagleRpcDemoServiceImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@SpringBootApplication
+public class FinagleRpcApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(FinagleRpcApplication.class, args);
+ }
+
+
+ @Configuration
+ public static class FinagleRpcConfiguration {
+
+ @Bean(destroyMethod = "close")
+ public ListeningServer server() {
+ ListeningServer server = Thrift.server()
+ .serveIface(":12220", new FinagleRpcDemoServiceImpl());
+ return server;
+ }
+
+ @Bean
+ public FinagleRpcDemoService.ServiceIface client() {
+ return Thrift.client()
+ .newIface("localhost:12220", FinagleRpcDemoService.ServiceIface.class);
+ }
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.java
new file mode 100644
index 000000000..026fc6316
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/controller/CaseController.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.testcase.finagle.controller;
+
+import com.twitter.util.Await;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+import org.springframework.beans.factory.annotation.Autowired;
+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 {
+
+ private static final String SUCCESS = "Success";
+
+ @Autowired
+ private FinagleRpcDemoService.ServiceIface finagleRpcDemoService;
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() {
+ return SUCCESS;
+ }
+
+ @RequestMapping("/finagle")
+ @ResponseBody
+ public String finagle() throws Exception {
+ System.out.println(Await.result(finagleRpcDemoService.hello("finagle")));
+ return SUCCESS;
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.java
new file mode 100644
index 000000000..784519370
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/finagle/service/FinagleRpcDemoServiceImpl.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.finagle.service;
+
+import com.twitter.util.Future;
+import org.apache.skywalking.apm.testcase.finagle.interfaces.FinagleRpcDemoService;
+
+
+public class FinagleRpcDemoServiceImpl implements FinagleRpcDemoService.ServiceIface {
+
+ public Future hello(String name) {
+ return Future.value("hello, " + name);
+ }
+}
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/resources/application.yaml
new file mode 100644
index 000000000..341369212
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/resources/application.yaml
@@ -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: /finagle-6.44.x-scenario
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/thrift/service.thrift b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/thrift/service.thrift
new file mode 100644
index 000000000..f37d915e1
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/src/main/thrift/service.thrift
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ */
+
+namespace java org.apache.skywalking.apm.testcase.finagle.interfaces
+
+service FinagleRpcDemoService {
+ string hello(string name);
+}
\ No newline at end of file
diff --git a/test/plugin/scenarios/finagle-6.44.x-scenario/support-version.list b/test/plugin/scenarios/finagle-6.44.x-scenario/support-version.list
new file mode 100644
index 000000000..34a0e1c17
--- /dev/null
+++ b/test/plugin/scenarios/finagle-6.44.x-scenario/support-version.list
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version
+# "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.
+
+6.44.0
+6.45.0
+7.0.0
+7.1.0
\ No newline at end of file