Add finagle plugin (#4441)
* Add finagle plugin (#4433) * fix failed checks for pr(#4441) * Add licenses for some files * Update Supported doc * Add finagle to test component-libraries.yml * Add finagle automatic tests into CI * Add comments * update comments * Remove CompatibilityChecker * Move query-protocol submodule to the right version * Remove `enhancedInstance.setSkyWalkingDynamicField` in `ClientTracingFilterInterceptor`. * Update expectedData.yaml of finagle tests * Use lazy ContextCarrier injection. * Add comments for `ContextCarrierHelper` * Fix ContextHolderFactory to avoid context pollution Co-authored-by: huangyongjie <huangyongjie@tigerbrokers> Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
parent
069b99bdbc
commit
ced5cb2828
|
|
@ -239,7 +239,7 @@ jobs:
|
|||
- name: Run kotlin coroutine 1.0.1-1.3.3 (4)
|
||||
run: bash test/plugin/run.sh kotlin-coroutine-scenario
|
||||
|
||||
Ehcache_Undertow_Jedis:
|
||||
Ehcache_Undertow_Jedis_Finagle:
|
||||
runs-on: ubuntu-18.04
|
||||
timeout-minutes: 90
|
||||
strategy:
|
||||
|
|
@ -271,6 +271,12 @@ jobs:
|
|||
run: bash test/plugin/run.sh undertow-scenario
|
||||
- name: Run jedis 2.4.0-2.9.0 (18)
|
||||
run: bash test/plugin/run.sh jedis-scenario
|
||||
- name: Run finagle 6.25.0-6.43.0
|
||||
run: bash test/plugin/run.sh finagle-6.25.x-scenario
|
||||
- name: Run finagle 6.44.0-7.1.0
|
||||
run: bash test/plugin/run.sh finagle-6.44.x-scenario
|
||||
- name: Run finagle 17.10.0-20.1.0
|
||||
run: bash test/plugin/run.sh finagle-17.10.x-scenario
|
||||
|
||||
Spring41x_SolrJ-Http:
|
||||
runs-on: ubuntu-18.04
|
||||
|
|
|
|||
|
|
@ -154,4 +154,6 @@ public class ComponentsDefine {
|
|||
public static final OfficialComponent AVRO_CLIENT = new OfficialComponent(83, "AvroClient");
|
||||
|
||||
public static final OfficialComponent UNDERTOW = new OfficialComponent(84, "Undertow");
|
||||
|
||||
public static final OfficialComponent FINAGLE = new OfficialComponent(85, "Finagle");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>7.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-finagle-6.25.x-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>apm-finagle-6.25.x-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<finagle.version>6.34.0</finagle.version>
|
||||
<scala.library.version>2.11.8</scala.library.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-core_2.11</artifactId>
|
||||
<version>${finagle.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>${scala.library.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>scala-compile-first</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>scala-test-compile</id>
|
||||
<phase>process-test-resources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -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 org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Finagle is an asynchronous rpc framework, every method in its rpc call stack return a future, which means each
|
||||
* method may be executed in other thread. The data transfer mechanism across threads or across processes of finagle is
|
||||
* achieved by using com.twitter.finagle.context. There are two kinds of context, LocalContext used to transfer data
|
||||
* across threads, MarshalledContext used to transfer data across processes.
|
||||
*
|
||||
* <h3> A simple finagle rpc stack </h3>
|
||||
*
|
||||
* +-----------------------------------------------------------------------------------------------+
|
||||
* | Client Server |
|
||||
* | |
|
||||
* | initiate rpc (user thread) invoke service (usually io thread) |
|
||||
* | | /|\ |
|
||||
* | \|/ | |
|
||||
* | ClientTracingFilter (user thread) +------------------+ |
|
||||
* | | | other filters | |
|
||||
* | \|/ | in the | |
|
||||
* | +------------------+ | rpc call stack | |
|
||||
* | | other filters | +------------------+ |
|
||||
* | | in the | (other thread) /|\ |
|
||||
* | | rpc call stack | | |
|
||||
* | +----------+-------+ | |
|
||||
* | | ServerTracingFilter (usually io thread) |
|
||||
* | \|/ /|\ |
|
||||
* | ClientDestTracingFilter (other thread) | |
|
||||
* | | +------------------+ |
|
||||
* | \|/ | other filters | |
|
||||
* | +------------------+ | in the | (usually io thread) |
|
||||
* | | other filters | | rpc call stack | |
|
||||
* | | in the | (other thread) +------------------+ |
|
||||
* | | rpc call stack | /|\ |
|
||||
* | +----------+-------+ | |
|
||||
* | | | |
|
||||
* | \|/ | |
|
||||
* | +----------------------------------------------------------------------------------+ |
|
||||
* | | Protocol specified transport | |
|
||||
* | | such as http, thrift, redis, mysql, etc. | |
|
||||
* | +----------------------------------------------------------------------------------+ |
|
||||
* +-----------------------------------------------------------------------------------------------+
|
||||
*
|
||||
* <h3> Plugin Implementation </h3>
|
||||
*
|
||||
* In client side, We create finagle exitspan in the ClientTracingFilter, then add SWContextCarrier into the
|
||||
* MarshalledContext, however in ClientTracingFilter, we can not know the remote address, So we add exitspan
|
||||
* into the LocalContext, when the request reaches ClientDestTracingFilter, we know the remote address, then we can get
|
||||
* exitspan from LocalContext and set remote address.
|
||||
*
|
||||
* In Server side, with default config, the ServerTracingFilter and the user code will be executed in the same thread,
|
||||
* unless users use a com.twitter.util.FuturePool to execute business code or the com.twitter.finagle.filter
|
||||
* .OffloadFilter is enabled which default is disabled, in bose cases, we had better do nothing and leave this to
|
||||
* users, they can custom FuturePool to propagate context correctly. So we just create finagel entryspan in
|
||||
* ServerTracingFilter to meet the default behavior of finagle.
|
||||
*/
|
||||
abstract class AbstractInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
onConstructImpl(objInst, allArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
beforeMethodImpl(objInst, method, allArguments, argumentsTypes, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
return afterMethodImpl(objInst, method, allArguments, argumentsTypes, ret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
|
||||
handleMethodExceptionImpl(objInst, method, allArguments, argumentsTypes, t);
|
||||
}
|
||||
|
||||
abstract protected void onConstructImpl(EnhancedInstance objInst, Object[] allArguments);
|
||||
|
||||
abstract protected void beforeMethodImpl(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable;
|
||||
|
||||
abstract protected Object afterMethodImpl(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable;
|
||||
|
||||
abstract protected void handleMethodExceptionImpl(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.finagle;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.ExitSpan;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.finagle.ContextCarrierHelper.tryInjectContext;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getSpan;
|
||||
|
||||
/**
|
||||
* Finagle use Annotation to represent data that tracing system interested, usually these annotations are created by
|
||||
* filters after ClientTracingFilter in the rpc call stack. We can intercept annotations that we interested.
|
||||
*/
|
||||
public class AnnotationInterceptor {
|
||||
|
||||
abstract static class Abstract implements InstanceConstructorInterceptor {
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance enhancedInstance, Object[] objects) {
|
||||
onConstruct(enhancedInstance, objects, getSpan());
|
||||
}
|
||||
|
||||
protected abstract void onConstruct(EnhancedInstance enhancedInstance, Object[] objects, AbstractSpan span);
|
||||
}
|
||||
|
||||
/**
|
||||
* When we create exitspan in ClientTracingFilter, we can't know the operation name, however the Rpc annotation
|
||||
* contains the operation name we need, so we intercept the constructor of this Annotation and set operation name
|
||||
* to exitspan.
|
||||
*/
|
||||
public static class Rpc extends Abstract {
|
||||
|
||||
@Override
|
||||
protected void onConstruct(EnhancedInstance enhancedInstance, Object[] objects, AbstractSpan span) {
|
||||
if (objects != null && objects.length == 1) {
|
||||
String rpc = (String) objects[0];
|
||||
if (span != null && span.isExit()) {
|
||||
/*
|
||||
* The Rpc Annotation is created both in client side and server side, in server side, this
|
||||
* annotation is created only in finagle versions below 17.12.0.
|
||||
*
|
||||
* If the span is not null, which means we are in the client side, we just set op name to the
|
||||
* exitspan.
|
||||
*
|
||||
* If the span is null, which means we are in the server side with finagle version below 17.12.0.
|
||||
* In server side, we don't need this annotation, because we can get op name from Contexts.broadcast
|
||||
* which comes from client.
|
||||
*/
|
||||
span.setOperationName(rpc);
|
||||
tryInjectContext((ExitSpan) span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.ExitSpan;
|
||||
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 java.net.InetSocketAddress;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.finagle.ContextCarrierHelper.tryInjectContext;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getLocalContextHolder;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getSpan;
|
||||
|
||||
/**
|
||||
* When we create exitspan in ClientTracingFilter, we can't know the remote address because the ClientTracingFilter
|
||||
* is above the loadbalancefilter in the rpc call stack. However by intercept the ClientDestTracingFilter, we can get
|
||||
* the remote adress and set it to exitspan and contextCarrier.
|
||||
*/
|
||||
public class ClientDestTracingFilterInterceptor extends AbstractInterceptor {
|
||||
|
||||
@Override
|
||||
public void onConstructImpl(EnhancedInstance enhancedInstance, Object[] objects) {
|
||||
enhancedInstance.setSkyWalkingDynamicField(getRemote(objects));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeMethodImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, MethodInterceptResult methodInterceptResult) throws Throwable {
|
||||
String peer = (String) enhancedInstance.getSkyWalkingDynamicField();
|
||||
getLocalContextHolder().let(FinagleCtxs.PEER_HOST, peer);
|
||||
tryInjectContext((ExitSpan) getSpan());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethodImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Object o) throws Throwable {
|
||||
getLocalContextHolder().remove(FinagleCtxs.PEER_HOST);
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodExceptionImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects,
|
||||
Class<?>[] classes, Throwable t) {
|
||||
ContextManager.activeSpan().errorOccurred().log(t);
|
||||
}
|
||||
|
||||
private String getRemote(Object[] objects) {
|
||||
if (objects == null || objects.length == 0) {
|
||||
return "";
|
||||
}
|
||||
if (objects[0] instanceof InetSocketAddress) {
|
||||
/*
|
||||
* Compatible with versions below 6.33.0
|
||||
* 6.33.0 and below use {@link java.net.SocketAddress} as parameter
|
||||
*/
|
||||
return formatPeer((InetSocketAddress) objects[0]);
|
||||
} else if (objects[0] instanceof Address.Inet) {
|
||||
return formatPeer(((Address.Inet) objects[0]).addr());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String formatPeer(InetSocketAddress socketAddress) {
|
||||
return socketAddress.getAddress().getHostAddress() + ":" + socketAddress.getPort();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.util.Future;
|
||||
import com.twitter.util.FutureEventListener;
|
||||
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.Constants.PENDING_OP_NAME;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getLocalContextHolder;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.ContextHolderFactory.getMarshalledContextHolder;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.SW_SPAN;
|
||||
import static org.apache.skywalking.apm.plugin.finagle.FinagleCtxs.getSpan;
|
||||
|
||||
public class ClientTracingFilterInterceptor 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 {
|
||||
/*
|
||||
* At this time, we can't know the operation name and peer address, so we just use placeholders here, the
|
||||
* operation name will be filled by {@link AnnotationInterceptor$Rpc} and the peer address will be filled by
|
||||
* {@link ClientDestTracingFilterInterceptor} later.
|
||||
*/
|
||||
AbstractSpan finagleSpan = ContextManager.createExitSpan(PENDING_OP_NAME, "");
|
||||
|
||||
finagleSpan.setComponent(FINAGLE);
|
||||
SpanLayer.asRPCFramework(finagleSpan);
|
||||
|
||||
getLocalContextHolder().let(SW_SPAN, finagleSpan);
|
||||
getMarshalledContextHolder().let(SWContextCarrier$.MODULE$, new SWContextCarrier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethodImpl(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Object ret) throws Throwable {
|
||||
|
||||
final AbstractSpan finagleSpan = getSpan();
|
||||
getLocalContextHolder().remove(SW_SPAN);
|
||||
getMarshalledContextHolder().remove(SWContextCarrier$.MODULE$);
|
||||
|
||||
finagleSpan.prepareForAsync();
|
||||
ContextManager.stopSpan(finagleSpan);
|
||||
|
||||
((Future<?>) ret).addEventListener(new FutureEventListener<Object>() {
|
||||
@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 throwable) {
|
||||
ContextManager.activeSpan().errorOccurred().log(throwable);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* 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.Buf;
|
||||
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.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CodecUtils {
|
||||
|
||||
static ILog LOGGER = LogManager.getLogger(CodecUtils.class);
|
||||
|
||||
private static ThreadLocal<ByteArrayOutputStream> REUSED_BOS = new ThreadLocal<ByteArrayOutputStream>() {
|
||||
@Override
|
||||
protected ByteArrayOutputStream initialValue() {
|
||||
return new ByteArrayOutputStream(128);
|
||||
}
|
||||
};
|
||||
|
||||
private static ByteArrayOutputStream getBos() {
|
||||
ByteArrayOutputStream bos = REUSED_BOS.get();
|
||||
bos.reset();
|
||||
return bos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the swContextCarrier to byte array.
|
||||
*
|
||||
* SWContextCarrier consists of some strings, such as operation name, {@link CarrierItem#getHeadKey()},
|
||||
* {@link CarrierItem#getHeadValue()}. We encode each string to byte array by
|
||||
* {@link #encodeStringToBytes(String)}, then assemble these byte arrays in a certain order, each byte array has
|
||||
* a fixed length of 4 bytes before it to record the length. The format as follow:
|
||||
*
|
||||
* |length of following byte array,4 byte|byte array|length of following byte array,4 byte|byte array|...
|
||||
*
|
||||
* The first byte array is operation name, followed by byte array of the key of first {@code CarrierItem},
|
||||
* followed by byte array of the value of first {@code CarrierItem}, followed by byte array of second {@code
|
||||
* CarrierItem}, and so on.
|
||||
*
|
||||
* @param swContextCarrier the swContextCarrier to encode
|
||||
* @return
|
||||
*/
|
||||
static Buf encode(SWContextCarrier swContextCarrier) {
|
||||
ByteArrayOutputStream bos = getBos();
|
||||
try (DataOutputStream dos = new DataOutputStream(bos)) {
|
||||
putString(dos, swContextCarrier.getOperationName());
|
||||
CarrierItem next = swContextCarrier.getCarrier().items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
if (next.getHeadKey() != null && next.getHeadValue() != null) {
|
||||
putString(dos, next.getHeadKey());
|
||||
putString(dos, next.getHeadValue());
|
||||
}
|
||||
}
|
||||
bos.flush();
|
||||
return Bufs.ownedBuf(bos.toByteArray());
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("encode swContextCarrier exception.", e);
|
||||
}
|
||||
return Bufs.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes byte array to SWContextCarrier.
|
||||
*
|
||||
* First we read 4 bytes from byte array, composing them into an int value n, and read the following n bytes,
|
||||
* decodes them to a string by {@link #decodeStringFromBytes(byte[])}, and so on.
|
||||
*
|
||||
* The first string is operation name, other strings are a list pair of key and value, can be translated to
|
||||
* {@link ContextCarrier}
|
||||
*
|
||||
* For convenient, we use {@link ByteBuffer} to wrap byte array.
|
||||
*
|
||||
* @param buf the byte array to decode
|
||||
* @return
|
||||
*/
|
||||
static SWContextCarrier decode(Buf buf) {
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
SWContextCarrier swContextCarrier = new SWContextCarrier();
|
||||
swContextCarrier.setContextCarrier(contextCarrier);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(Bufs.ownedByteArray(buf));
|
||||
String operationName = getNextString(byteBuffer);
|
||||
if (operationName != null) {
|
||||
swContextCarrier.setOperationName(operationName);
|
||||
}
|
||||
|
||||
Map<String, String> data = readToMap(byteBuffer);
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
next.setHeadValue(data.get(next.getHeadKey()));
|
||||
}
|
||||
return swContextCarrier;
|
||||
}
|
||||
|
||||
private static void putString(DataOutputStream dos, String value) throws IOException {
|
||||
byte[] bytes = encodeStringToBytes(value);
|
||||
dos.writeInt(bytes.length);
|
||||
dos.write(bytes);
|
||||
}
|
||||
|
||||
private static String getNextString(ByteBuffer byteBuffer) {
|
||||
if (byteBuffer.hasRemaining()) {
|
||||
byte[] bytes = new byte[byteBuffer.getInt()];
|
||||
byteBuffer.get(bytes);
|
||||
return decodeStringFromBytes(bytes);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<String, String> readToMap(ByteBuffer byteBuffer) {
|
||||
Map<String, String> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <h3> Finagle context usage </h3>
|
||||
*
|
||||
* The only way we can transfer data through finagle context as below:
|
||||
* <pre>{@code
|
||||
* Context context = Contexts.local(); // Contexts.broadcast()
|
||||
* context.let(key, value, (Function0) fn);
|
||||
* }</pre>
|
||||
*
|
||||
* 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:
|
||||
* <pre>{@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);
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* So we use ContextHolder to achieve this, the {@link #let(Object, Object)} and {@link #remove(Object)} methos split
|
||||
* the function of <pre>let(key, value, (Function0) fn)</pre> into two methods.
|
||||
*
|
||||
* <h3> ContextHolder usage </h3>
|
||||
*
|
||||
* 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}.
|
||||
*
|
||||
* <pre>{@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);
|
||||
* }
|
||||
* }}</pre>
|
||||
*/
|
||||
abstract class ContextHolder {
|
||||
|
||||
abstract void let(Object key, Object value);
|
||||
|
||||
abstract void remove(Object key);
|
||||
}
|
||||
|
|
@ -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<S> extends ContextHolder {
|
||||
|
||||
final Local<S> 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<LinkedList<Snapshot<S>>> snapshots;
|
||||
|
||||
static class Snapshot<S> {
|
||||
/**
|
||||
* 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<LinkedList<Snapshot<S>>>() {
|
||||
@Override
|
||||
protected LinkedList<Snapshot<S>> 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<S> 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<S> getLocal(Context context, String localFieldName) {
|
||||
try {
|
||||
Field localField = context.getClass().getDeclaredField(localFieldName);
|
||||
localField.setAccessible(true);
|
||||
return (Local<S>) 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<Context.Env> {
|
||||
|
||||
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<scala.collection.immutable.Map<LocalContext.Key, Object>> {
|
||||
|
||||
private static final String LOCAL_FIELD_NAME = "local";
|
||||
|
||||
MapLocalContextHolder(LocalContext context) {
|
||||
super(context, LOCAL_FIELD_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected scala.collection.immutable.Map<LocalContext.Key, Object> getUpdatedContext(scala.collection.immutable.Map<LocalContext.Key, Object> 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<scala.collection.immutable.Map<Buf, Object>> {
|
||||
|
||||
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<Buf, Object> getUpdatedContext(scala.collection.immutable.Map<Buf, Object> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AbstractSpan> SW_SPAN = null;
|
||||
|
||||
static LocalContext.Key<String> PEER_HOST = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Constructor constructor = LocalContext.Key.class.getConstructor(LocalContext.class);
|
||||
SW_SPAN = (LocalContext.Key<AbstractSpan>) constructor.newInstance(Contexts.local());
|
||||
PEER_HOST = (LocalContext.Key<String>) 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Object>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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};
|
||||
}
|
||||
}
|
||||
|
|
@ -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<MethodDescription> 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<MethodDescription> getConstructor();
|
||||
}
|
||||
|
||||
public static class Rpc extends Abstract {
|
||||
|
||||
@Override
|
||||
protected String getAnnoationName() {
|
||||
return "Rpc";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ElementMatcher<MethodDescription> getConstructor() {
|
||||
return takesArgument(0, String.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("apply");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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<MethodDescription> getMethodsMatcher() {
|
||||
return named("apply");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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<MethodDescription> getMethodsMatcher() {
|
||||
return named("apply");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TraceSegment> traceSegments) {
|
||||
assertThat(traceSegments.size(), is(1));
|
||||
TraceSegment traceSegment = traceSegments.get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertFinagleSpan(spans.get(0));
|
||||
}
|
||||
|
||||
protected void assertTraceSegmentsWithError(List<TraceSegment> traceSegments) {
|
||||
assertThat(traceSegments.size(), is(1));
|
||||
TraceSegment traceSegment = traceSegments.get(0);
|
||||
List<AbstractTracingSpan> 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<TagValuePair> 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.<Object>is("error"));
|
||||
assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(RuntimeException.class.getName()));
|
||||
assertNull(logData.getLogs().get(2).getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, String> 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())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> KEY1;
|
||||
private static LocalContext.Key<String> KEY2;
|
||||
private static LocalContext.Key<String> KEY3;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws Exception {
|
||||
Constructor constructor = LocalContext.Key.class.getConstructor(LocalContext.class);
|
||||
KEY1 = (LocalContext.Key<String>) constructor.newInstance(Contexts.local());
|
||||
KEY2 = (LocalContext.Key<String>) constructor.newInstance(Contexts.local());
|
||||
KEY3 = (LocalContext.Key<String>) 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Void>() {
|
||||
@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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -88,6 +88,7 @@
|
|||
<module>play-2.x-plugin</module>
|
||||
<module>lettuce-5.x-plugin</module>
|
||||
<module>avro-plugin</module>
|
||||
<module>finagle-6.25.x-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -248,6 +248,9 @@ AvroServer:
|
|||
AvroClient:
|
||||
id: 83
|
||||
languages: Java
|
||||
Finagle:
|
||||
id: 85
|
||||
languages: Java,Scala
|
||||
|
||||
|
||||
# .NET/.NET Core components
|
||||
|
|
|
|||
|
|
@ -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 &
|
||||
|
|
@ -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}
|
||||
|
|
@ -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:
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<groupId>org.apache.skywalking.apm.testcase</groupId>
|
||||
<artifactId>finagle-17.10.x-scenario</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<test.framework.version>17.10.0</test.framework.version>
|
||||
<spring-boot-version>2.1.6.RELEASE</spring-boot-version>
|
||||
<lombok.version>1.18.10</lombok.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-finagle-17.10.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-core_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-thrift_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-core_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>finagle-17.10.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-maven-plugin</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
<configuration>
|
||||
<language>java</language>
|
||||
<thriftOpts>
|
||||
<thriftOpt>--finagle</thriftOpt>
|
||||
</thriftOpts>
|
||||
<buildExtractedThrift>false</buildExtractedThrift>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-thrift-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>thrift-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/finagle-17.10.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> hello(String name) {
|
||||
return Future.value("hello, " + name);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 &
|
||||
|
|
@ -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}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>finagle-6.25.x-scenario</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>5.0.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
|
||||
<spring.boot.version>2.1.6.RELEASE</spring.boot.version>
|
||||
<test.framework>finagle</test.framework>
|
||||
<test.framework.version>6.25.0</test.framework.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-finagle-6.25.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-core_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-thrift_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.thrift</groupId>
|
||||
<artifactId>libthrift</artifactId>
|
||||
<version>0.9.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-core_2.11</artifactId>
|
||||
<version>4.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-runtime_2.11</artifactId>
|
||||
<version>4.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>finagle-6.25.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-maven-plugin</artifactId>
|
||||
<version>4.5.0</version>
|
||||
<configuration>
|
||||
<language>experimental-java</language>
|
||||
<thriftOpts>
|
||||
<thriftOpt>--finagle</thriftOpt>
|
||||
</thriftOpts>
|
||||
<buildExtractedThrift>false</buildExtractedThrift>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-thrift-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>thrift-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<url>http://repo.spring.io/snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<url>http://repo.spring.io/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/finagle-6.25.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> hello(String name) {
|
||||
return Future.value("hello, " + name);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 &
|
||||
|
|
@ -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}
|
||||
|
|
@ -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:
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<groupId>org.apache.skywalking.apm.testcase</groupId>
|
||||
<artifactId>finagle-6.44.x-scenario</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<test.framework.version>6.41.0</test.framework.version>
|
||||
<spring-boot-version>2.1.6.RELEASE</spring-boot-version>
|
||||
<lombok.version>1.18.10</lombok.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-finagle-6.44.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-core_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-thrift_2.11</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-core_2.11</artifactId>
|
||||
<version>4.20.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>finagle-6.44.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>scrooge-maven-plugin</artifactId>
|
||||
<version>4.20.0</version>
|
||||
<configuration>
|
||||
<language>java</language>
|
||||
<thriftOpts>
|
||||
<thriftOpt>--finagle</thriftOpt>
|
||||
</thriftOpts>
|
||||
<buildExtractedThrift>false</buildExtractedThrift>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-thrift-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>thrift-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/finagle-6.44.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> hello(String name) {
|
||||
return Future.value("hello, " + name);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue