未验证 提交 98968122 编写于 作者: D Daming 提交者: GitHub

Provide Thrift Plugin (#5644)

上级 d5a28baa
......@@ -54,6 +54,7 @@ jobs:
- elasticjob-2.x-scenario
- quartz-scheduler-2.x-scenario
- xxl-job-2.x-scenario
- thrift-scenario
steps:
- uses: actions/checkout@v2
with:
......
......@@ -180,4 +180,9 @@ public class ComponentsDefine {
public static final OfficialComponent XXL_JOB = new OfficialComponent(98, "xxl-job");
public static final OfficialComponent SPRING_WEBCLIENT = new OfficialComponent(99, "spring-webflux-webclient");
public static final OfficialComponent THRIFT_SERVER = new OfficialComponent(100, "thrift-server");
public static final OfficialComponent THRIFT_CLIENT = new OfficialComponent(101, "thrift-client");
}
\ No newline at end of file
......@@ -100,6 +100,7 @@
<module>hbase-1.x-plugin</module>
<module>graphql-plugin</module>
<module>xxl-job-2.x-plugin</module>
<module>thrift-plugin</module>
</modules>
<packaging>pom</packaging>
......
<?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>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-sdk-plugin</artifactId>
<version>8.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>thrift-plugin</artifactId>
<packaging>jar</packaging>
<name>apm-thrift-plugin</name>
<properties>
<thrift.version>0.13.0</thrift.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${thrift.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
* 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.thrift;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.plugin.thrift.wrapper.AsyncContext;
import org.apache.skywalking.apm.plugin.thrift.wrapper.ServerInProtocolWrapper;
import org.apache.thrift.AsyncProcessFunction;
import org.apache.thrift.TBaseAsyncProcessor;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.server.AbstractNonblockingServer;
/**
* To wrap the AsyncProcessFunction for getting arguments of method.
*
* @see TBaseAsyncProcessor
*/
public class TBaseAsyncProcessorInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
private Map<String, AsyncProcessFunction> processMapView = null;
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
processMapView = ((TBaseAsyncProcessor) objInst).getProcessMapView();
}
@Override
public void beforeMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
TProtocol protocol = ((AbstractNonblockingServer.AsyncFrameBuffer) allArguments[0]).getInputProtocol();
((ServerInProtocolWrapper) protocol).initial(new AsyncContext(processMapView));
}
@Override
public Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
ContextManager.activeSpan().log(t);
}
}
/*
* 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.thrift;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.plugin.thrift.wrapper.Context;
import org.apache.skywalking.apm.plugin.thrift.wrapper.ServerInProtocolWrapper;
import org.apache.thrift.ProcessFunction;
import org.apache.thrift.TBaseAsyncProcessor;
import org.apache.thrift.TBaseProcessor;
/**
* To wrap the ProcessFunction for getting arguments of method.
*
* @see TBaseAsyncProcessor
* @see TBaseProcessorInterceptor
*/
public class TBaseProcessorInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
private Map<String, ProcessFunction> processMap;
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
processMap = ((TBaseProcessor) objInst).getProcessMapView();
}
@Override
public void beforeMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
ServerInProtocolWrapper in = (ServerInProtocolWrapper) allArguments[0];
in.initial(new Context(processMap));
}
@Override
public Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
ContextManager.activeSpan().log(t);
}
}
/*
* 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.thrift;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
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.plugin.thrift.commons.ReflectionUtils;
import org.apache.skywalking.apm.plugin.thrift.wrapper.ServerInProtocolWrapper;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.TServer;
/**
* Hijack the ProtocolFactory for wrapping the Protocol object to propagate trace context(receiver).
*/
public class TServerInterceptor implements InstanceConstructorInterceptor {
private static final ILog LOGGER = LogManager.getLogger(TServerInterceptor.class);
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
try {
final TProtocolFactory inputProtocolFactory = (TProtocolFactory) ReflectionUtils.getValue(
TServer.class,
objInst,
"inputProtocolFactory_"
);
ReflectionUtils.setValue(
TServer.class,
objInst,
"inputProtocolFactory_",
(TProtocolFactory) trans -> new ServerInProtocolWrapper(inputProtocolFactory.getProtocol(trans))
);
} catch (Exception e) {
LOGGER.error("Failed to hijack TServer's TProtocolFactory.", e);
}
}
}
/*
* 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.thrift.client;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
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.plugin.thrift.commons.ReflectionUtils;
import org.apache.skywalking.apm.plugin.thrift.wrapper.ClientOutProtocolWrapper;
import org.apache.thrift.async.TAsyncClient;
import org.apache.thrift.protocol.TProtocolFactory;
/**
* Hijack the TProtocolFactory for wrapping the Protocol object to propagate trace context(write out).
*
* @see TAsyncClient
*/
public class TAsyncClientInterceptor implements InstanceConstructorInterceptor {
private static final ILog LOGGER = LogManager.getLogger(TAsyncClientInterceptor.class);
@Override
public void onConstruct(final EnhancedInstance objInst, final Object[] objects) {
try {
ReflectionUtils.setValue(
TAsyncClient.class,
objInst,
"___protocolFactory",
(TProtocolFactory) transport ->
new ClientOutProtocolWrapper(((TProtocolFactory) objects[0]).getProtocol(transport))
);
} catch (NoSuchFieldException | IllegalAccessException e) {
LOGGER.error("Failed to hijack TAsyncClient's TProtocolFactory.", e);
}
}
}
/*
* 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.thrift.client;
import java.lang.reflect.Method;
import org.apache.skywalking.apm.agent.core.context.AsyncSpan;
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.InstanceConstructorInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.apache.skywalking.apm.plugin.thrift.commons.ReflectionUtils;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncMethodCall;
/**
* Here is asynchronized client.
*/
public class TAsyncMethodCallInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
private String remotePeer = "UNKNOWN";
@Override
public void onConstruct(EnhancedInstance objInst,
Object[] allArguments) throws NoSuchFieldException, IllegalAccessException {
ReflectionUtils.setValue(TAsyncMethodCall.class, objInst, "callback", new AsyncMethodCallback<Object>() {
final AsyncMethodCallback<Object> callback = (AsyncMethodCallback) allArguments[3];
@Override
public void onComplete(final Object response) {
try {
AsyncSpan span = (AsyncSpan) objInst.getSkyWalkingDynamicField();
span.asyncFinish();
} finally {
callback.onComplete(response);
}
}
@Override
public void onError(final Exception exception) {
try {
AsyncSpan span = (AsyncSpan) objInst.getSkyWalkingDynamicField();
span.asyncFinish().log(exception);
} finally {
callback.onError(exception);
}
}
});
if (allArguments[2] instanceof EnhancedInstance) {
remotePeer = (String) ((EnhancedInstance) allArguments[2]).getSkyWalkingDynamicField();
}
}
@Override
public void beforeMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
AbstractSpan span = ContextManager.createExitSpan(objInst.getClass().getName(), remotePeer);
span.setComponent(ComponentsDefine.THRIFT_CLIENT);
SpanLayer.asRPCFramework(span);
AbstractSpan async = span.prepareForAsync();
objInst.setSkyWalkingDynamicField(async);
}
@Override
public Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
\ No newline at end of file
/*
* 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.thrift.client;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
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.InstanceConstructorInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.apache.skywalking.apm.plugin.thrift.commons.ReflectionUtils;
import org.apache.skywalking.apm.plugin.thrift.wrapper.ClientOutProtocolWrapper;
import org.apache.thrift.TBase;
import org.apache.thrift.TFieldIdEnum;
import org.apache.thrift.TServiceClient;
import org.apache.thrift.protocol.TProtocol;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* Here is synchronized client.
*
* @see TServiceClient
*/
public class TServiceClientInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
private static final StringTag TAG_ARGS = new StringTag("args");
@Override
public void onConstruct(EnhancedInstance objInst,
Object[] allArguments) throws NoSuchFieldException, IllegalAccessException {
if (!(allArguments[1] instanceof ClientOutProtocolWrapper)) {
TProtocol protocol = (TProtocol) allArguments[1];
ReflectionUtils.setValue(
TServiceClient.class,
objInst,
"oprot_",
new ClientOutProtocolWrapper(protocol)
);
Object dynamicField = ((EnhancedInstance) protocol.getTransport()).getSkyWalkingDynamicField();
objInst.setSkyWalkingDynamicField(Objects.isNull(dynamicField) ? "UNKNOWN" : dynamicField);
}
}
@Override
public void beforeMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
AbstractSpan span = ContextManager.createExitSpan(
objInst.getClass().getName() + "." + allArguments[0],
(String) objInst.getSkyWalkingDynamicField()
);
SpanLayer.asRPCFramework(span);
span.setComponent(ComponentsDefine.THRIFT_CLIENT);
span.tag(TAG_ARGS, getArguments((String) allArguments[0], (TBase) allArguments[1]));
}
@Override
public Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
ContextManager.activeSpan().log(t);
}
private String getArguments(String method, TBase base) {
int idx = 0;
StringBuilder buffer = new StringBuilder(method).append("(");
while (true) {
TFieldIdEnum field = base.fieldForId(++idx);
if (field == null) {
break;
}
buffer.append(field.getFieldName()).append(", ");
}
if (idx > 0) {
buffer.delete(buffer.length() - 2, buffer.length());
}
return buffer.append(")").toString();
}
}
\ No newline at end of file
/*
* 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.thrift.client;
import java.lang.reflect.Method;
import java.util.Objects;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
/**
* TAsyncClient creates a TServiceClient for receiving the response. So splitting this method,
* TAsyncClient#receiveBase(...), into here for more efficiency.
*/
public class TServiceClientReceiveInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(final EnhancedInstance objInst,
final Method method,
final Object[] objects,
final Class<?>[] classes,
final MethodInterceptResult ret) throws Throwable {
}
@Override
public Object afterMethod(final EnhancedInstance objInst,
final Method method,
final Object[] objects,
final Class<?>[] classes,
final Object ret) throws Throwable {
// Have to stop only when the span is created by TServiceClientInterceptor#beforeMethod(...).
if (Objects.nonNull(objInst.getSkyWalkingDynamicField())) {
ContextManager.stopSpan();
}
return ret;
}
@Override
public void handleMethodException(final EnhancedInstance enhancedInstance,
final Method method,
final Object[] objects,
final Class<?>[] classes,
final Throwable throwable) {
ContextManager.activeSpan().log(throwable);
}
}
/*
* 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.thrift.commons;
import java.lang.reflect.Field;
public class ReflectionUtils {
public static final void setValue(Class klass, Object instance, String name, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = klass.getDeclaredField(name);
field.setAccessible(true);
field.set(instance, value);
}
public static final Object getValue(Class klass, Object instance, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = klass.getDeclaredField(name);
field.setAccessible(true);
return field.get(instance);
}
}
/*
* 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.thrift.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
public class TBaseAsyncProcessorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.TBaseAsyncProcessorInterceptor";
private static final String ENHANCE_CLASS = "org.apache.thrift.TBaseAsyncProcessor";
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.any();
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers.named("process");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
}
/*
* 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.thrift.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
public class TBaseProcessorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "org.apache.thrift.TBaseProcessor";
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.TBaseProcessorInterceptor";
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.any();
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers.named("process").and(ElementMatchers.takesArguments(2));
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
}
/*
* 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.thrift.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch;
public class TServerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.TServerInterceptor";
@Override
protected ClassMatch enhanceClass() {
return MultiClassNameMatch.byMultiClassMatch(
"org.apache.thrift.server.TServer",
"org.apache.thrift.server.TServlet"
);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.any();
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {};
}
}
/*
* 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.thrift.define.client;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
/**
* Hijack the TProtocolFactory.(Asynchronized Client)
*
* @see org.apache.thrift.async.TAsyncClient
*/
public class TAsyncClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "org.apache.thrift.async.TAsyncClient";
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.client.TAsyncClientInterceptor";
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.takesArguments(4);
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {};
}
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
}
/*
* 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.thrift.define.client;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
public class TAsyncMethodCallInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.client.TAsyncMethodCallInterceptor";
private static final String ENHANCE_CLASS = "org.apache.thrift.async.TAsyncMethodCall";
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.any();
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers.named("prepareMethodCall");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
/*
* 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.thrift.define.client;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
/**
* Hijack the TProtocolFactory.(Synchronized Client)
*
* @see org.apache.thrift.TServiceClient
*/
public class TServiceClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.client.TServiceClientInterceptor";
private static final String RECEIVE_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.thrift.client.TServiceClientReceiveInterceptor";
private static final String ENHANCE_CLASS = "org.apache.thrift.TServiceClient";
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.takesArguments(2);
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers.named("sendBase").and(ElementMatchers.takesArguments(3));
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers.named("receiveBase");
}
@Override
public String getMethodsInterceptor() {
return RECEIVE_INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
/*
* 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.thrift.define.transport;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch;
public class TSocketInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
@Override
protected ClassMatch enhanceClass() {
return MultiClassNameMatch.byMultiClassMatch(
"org.apache.thrift.transport.TSocket",
"org.apache.thrift.transport.TNonblockingSocket"
);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.takesArguments(String.class, int.class, int.class);
}
@Override
public String getConstructorInterceptor() {
return "org.apache.skywalking.apm.plugin.thrift.transport.TSocketInterceptor";
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {};
}
}
\ No newline at end of file
/*
* 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.thrift.transport;
import java.io.IOException;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
/**
* For getting remote peer.
*/
public class TSocketInterceptor implements InstanceConstructorInterceptor {
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws IOException {
objInst.setSkyWalkingDynamicField(allArguments[0] + ":" + allArguments[1]);
}
}
/*
* 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.thrift.wrapper;
/**
* A context
*/
public abstract class AbstractContext {
public String methodName;
public long startTime = 0L;
public abstract String getArguments();
public abstract String getOperatorName();
public final void setup(String methodName) {
this.methodName = methodName;
this.startTime = System.currentTimeMillis();
}
}
/*
* 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.thrift.wrapper;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolDecorator;
/**
* Note that the 8888th field of record is reserved for transporting trace header. Because Thrift doesn't support to
* transport metadata.
*/
public abstract class AbstractProtocolWrapper extends TProtocolDecorator {
public static final String SW_MAGIC_FIELD = "SW_MAGIC_FIELD"; // Field Name
public static final short SW_MAGIC_FIELD_ID = 8888; // Field ID, a magic number
public AbstractProtocolWrapper(final TProtocol protocol) {
super(protocol);
}
}
/*
* 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.thrift.wrapper;
import java.util.Map;
import org.apache.thrift.AsyncProcessFunction;
public class AsyncContext extends AbstractContext {
private final Map<String, AsyncProcessFunction> processMapView;
public AsyncContext(Map<String, AsyncProcessFunction> processMapView) {
this.processMapView = processMapView;
}
@Override
public String getArguments() {
return processMapView.get(methodName).getEmptyArgsInstance().toString();
}
@Override
public String getOperatorName() {
return processMapView.get(methodName).getClass().getName();
}
}
/*
* 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.thrift.wrapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
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.ContextManager;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TField;
import org.apache.thrift.protocol.TMap;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TType;
/**
* Wrapping client output protocol for injecting and propagating the trace header. This is also safe even if the server
* doesn't deal with it.
*/
public class ClientOutProtocolWrapper extends AbstractProtocolWrapper {
private static final ILog LOGGER = LogManager.getLogger(ClientOutProtocolWrapper.class);
private boolean injected = true;
public ClientOutProtocolWrapper(final TProtocol protocol) {
super(protocol);
}
@Override
public final void writeMessageBegin(final TMessage message) throws TException {
injected = false;
super.writeMessageBegin(message);
}
@Override
public final void writeFieldStop() throws TException {
if (!injected && ContextManager.isActive()) {
try {
final ContextCarrier carrier = new ContextCarrier();
ContextManager.inject(carrier);
CarrierItem items = carrier.items();
final Map<String, String> header = new HashMap<>(3);
while (items.hasNext()) {
items = items.next();
header.put(items.getHeadKey(), items.getHeadValue());
}
writeHeader(header);
} catch (Throwable throwable) {
LOGGER.error("Failed to propagating CarrierItems.", throwable);
} finally {
injected = true;
}
}
super.writeFieldStop();
}
private void writeHeader(Map<String, String> header) throws TException {
super.writeFieldBegin(new TField(SW_MAGIC_FIELD, TType.MAP, SW_MAGIC_FIELD_ID));
super.writeMapBegin(new TMap(TType.STRING, TType.STRING, header.size()));
final Set<Map.Entry<String, String>> entries = header.entrySet();
for (Map.Entry<String, String> entry : entries) {
super.writeString(entry.getKey());
super.writeString(entry.getValue());
}
super.writeMapEnd();
super.writeFieldEnd();
}
}
/*
* 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.thrift.wrapper;
import java.util.Map;
import org.apache.thrift.ProcessFunction;
public class Context extends AbstractContext {
private final Map<String, ProcessFunction> processMapView;
public Context(Map<String, ProcessFunction> processMapView) {
this.processMapView = processMapView;
}
@Override
public String getArguments() {
return processMapView.get(methodName).getEmptyArgsInstance().toString();
}
@Override
public String getOperatorName() {
return processMapView.get(methodName).getClass().getName();
}
}
/*
* 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.thrift.wrapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
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.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
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.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TField;
import org.apache.thrift.protocol.TMap;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TType;
/**
* Wrapping server input protocol for reading and parsing the trace header from the original protocol. It is a special
* field which will be skipped without one deal with.
*/
public class ServerInProtocolWrapper extends AbstractProtocolWrapper {
private static final ILog LOGGER = LogManager.getLogger(ServerInProtocolWrapper.class);
private static final StringTag TAG_ARGS = new StringTag("args");
private AbstractContext context;
public ServerInProtocolWrapper(final TProtocol protocol) {
super(protocol);
}
public void initial(AbstractContext context) {
this.context = context;
}
@Override
public TField readFieldBegin() throws TException {
final TField field = super.readFieldBegin();
if (field.id == SW_MAGIC_FIELD_ID && field.type == TType.MAP) {
try {
TMap tMap = super.readMapBegin();
Map<String, String> header = new HashMap<>(tMap.size);
for (int i = 0; i < tMap.size; i++) {
header.put(readString(), readString());
}
AbstractSpan span = ContextManager.createEntrySpan(
context.getOperatorName(), createContextCarrier(header));
span.start(context.startTime);
span.tag(TAG_ARGS, context.getArguments());
span.setComponent(ComponentsDefine.THRIFT_SERVER);
SpanLayer.asRPCFramework(span);
} catch (Throwable throwable) {
LOGGER.error("Failed to resolve header or create EntrySpan.", throwable);
} finally {
context = null;
super.readMapEnd();
super.readFieldEnd();
}
return readFieldBegin();
}
return field;
}
private ContextCarrier createContextCarrier(Map<String, String> header) {
ContextCarrier carrier = new ContextCarrier();
if (Objects.nonNull(header)) {
CarrierItem items = carrier.items();
while (items.hasNext()) {
items = items.next();
items.setHeadValue(header.get(items.getHeadKey()));
}
}
return carrier;
}
@Override
public TMessage readMessageBegin() throws TException {
final TMessage message = super.readMessageBegin();
if (Objects.nonNull(message)) {
context.setup(message.name);
}
return message;
}
}
# 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.
thrift=org.apache.skywalking.apm.plugin.thrift.define.TServerInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.client.TAsyncClientInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.client.TAsyncMethodCallInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.client.TServiceClientInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.client.TServiceClientReceiveInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.TBaseProcessorInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.TBaseAsyncProcessorInstrumentation
thrift=org.apache.skywalking.apm.plugin.thrift.define.transport.TSocketInstrumentation
......@@ -26,3 +26,4 @@ These are known and common FAQs. We welcome you to contribute yours.
* [Use the profile exporter tool if the profile analysis is not right](../guides/backend-profile-export.md)
* [Compatible with other javaagent bytecode processing](Compatible-with-other-javaagent-bytecode-processing.md)
* [**Java agent memory leak** when enhance `Worker thread` at use Thread Pool](Memory-leak-enhance-Worker-thread.md)
* [Thrift plugin](thrift-plugin.md)
\ No newline at end of file
### Problem
The message with Field ID, 8888, must be revered.
### Reason
Because Thrift cannot carry metadata to transport Trace Header in the original API, we transport those by wrapping TProtocolFactory to do that.
Thrift allows us to append any additional field in the Message even if the receiver doesn't deal with them. This data is going to be skipped while no one reads. Base on this, we take the 8888th field of Message to store Trace Header(or metadata) and to transport. That means the message with Field ID, 8888, must be revered.
### Resolve
Avoiding to use the Field(ID is 8888) in your application.
\ No newline at end of file
......@@ -90,6 +90,7 @@
- spring-webflux-5.x-webclient
- spymemcached-2.x
- struts2-2.x
- thrift
- tomcat-7.x/8.x
- toolkit-counter
- toolkit-gauge
......
......@@ -46,6 +46,7 @@
* [Apache Avro](http://avro.apache.org) 1.7.0 - 1.8.x
* [Finagle](https://github.com/twitter/finagle) 6.25.0 -> 20.1.0
* [Brpc-Java](https://github.com/baidu/brpc-java) 2.3.7 -> 2.5.3
* [Thrift](https://github.com/apache/thrift/tree/master/lib/java) 0.10.0 -> 0.12.0
* MQ
* [RocketMQ](https://github.com/apache/rocketmq) 4.x
* [Kafka](http://kafka.apache.org) 0.11.0.0 -> 1.0
......
......@@ -329,6 +329,13 @@ xxl-job:
spring-webflux-webclient:
id: 99
languages: Java
thrift-server:
id: 100
languages: Java
thrift-client:
id: 101
languages: Java
# .NET/.NET Core components
# [3000, 4000) for C#/.NET only
......@@ -525,4 +532,4 @@ Component-Server-Mappings:
influxdb-java: InfluxDB
Predis: Redis
PyMysql: Mysql
spring-kafka-consumer: kafka-consumer
spring-kafka-consumer: kafka-consumer
\ No newline at end of file
......@@ -275,6 +275,15 @@ quartz-scheduler:
xxl-job:
id: 98
languages: Java
spring-webflux-webclient:
id: 99
languages: Java
thrift-server:
id: 100
languages: Java
thrift-client:
id: 101
languages: Java
# .NET/.NET Core components
# [3000, 4000) for C#/.NET only
......
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
segmentItems:
- serviceName: thrift-server-scenario
segmentSize: 2
segments:
- segmentId: not null
spans:
- operationName: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$AsyncProcessor$echo
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: RPCFramework
startTime: gt 0
endTime: gt 0
componentId: 100
isError: false
spanType: Entry
peer: ''
skipAnalysis: false
tags:
- {key: args, value: 'echo_args(message:null)'}
refs:
- {parentEndpoint: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$AsyncClient$echo_call,
networkAddress: 'localhost:9091', refType: CrossProcess, parentSpanId: 0,
parentTraceSegmentId: not null,
parentServiceInstance: not null, parentService: thrift-client-scenario,
traceId: not null }
- segmentId: not null
spans:
- operationName: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$Processor$echo
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: RPCFramework
startTime: gt 0
endTime: gt 0
componentId: 100
isError: false
spanType: Entry
peer: ''
skipAnalysis: false
tags:
- {key: args, value: 'echo_args(message:null)'}
refs:
- {parentEndpoint: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$Client.echo,
networkAddress: 'localhost:9090', refType: CrossProcess, parentSpanId: 0,
parentTraceSegmentId: not null,
parentServiceInstance: not null, parentService: thrift-client-scenario,
traceId: not null }
- serviceName: thrift-client-scenario
segmentSize: ge 2
segments:
- segmentId: not null
spans:
- operationName: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$Client.echo
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: RPCFramework
startTime: gt 0
endTime: gt 0
componentId: 101
isError: false
spanType: Exit
peer: localhost:9090
skipAnalysis: false
tags:
- {key: args, value: echo(message)}
- segmentId: not null
spans:
- operationName: org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService$AsyncClient$echo_call
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: RPCFramework
startTime: gt 0
endTime: gt 0
componentId: 101
isError: false
spanType: Exit
peer: 'localhost:9091'
skipAnalysis: false
\ No newline at end of file
# 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/thrift-scenario/case/thrift-scenario
healthCheck: http://localhost:8080/thrift-scenario/case/healthCheck
startScript: ./bin/startup.sh
environment:
dependencies:
<?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>thrift-scenario</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>1.8</compiler.version>
<test.framework.version>0.12.0</test.framework.version>
<spring-boot-version>2.1.6.RELEASE</spring-boot-version>
<lombok.version>1.18.10</lombok.version>
<thrift.version>${test.framework.version}</thrift.version>
</properties>
<name>skywalking-thrift-scenario</name>
<modules>
<module>thrift-common</module>
<module>thrift-client</module>
<module>thrift-server</module>
<module>thrift-dist</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${thrift.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${thrift.version}</version>
</dependency>
</dependencies>
<build>
<finalName>thrift-scenario</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
# 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.
0.12.0
0.11.0
0.10.0
\ No newline at end of file
<?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>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-scenario</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>thrift-client</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-common</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>${spring-boot-version}</version>
</dependency>
</dependencies>
<build>
<finalName>thrift-client</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.apache.skywalking.apm.testcase.thrift.client.Application</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package org.apache.skywalking.apm.testcase.thrift.client;/*
* 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.
*
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
// Never do this
}
}
}
/*
* 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.thrift.client.controller;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.skywalking.apm.testcase.thrift.client.service.AsyncClient;
import org.apache.skywalking.apm.testcase.thrift.client.service.IClient;
import org.apache.skywalking.apm.testcase.thrift.client.service.SyncClient;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
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 Logger logger = LogManager.getLogger(CaseController.class);
private static final String SUCCESS = "Success";
private IClient async;
private IClient sync;
private IClient hasync;
private final AtomicInteger status = new AtomicInteger(0);
private final CountDownLatch initialized = new CountDownLatch(1);
@RequestMapping("/thrift-scenario")
@ResponseBody
public String testcase() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(3);
call(async, latch);
call(sync, latch);
latch.await();
return SUCCESS;
}
@RequestMapping("/healthCheck")
@ResponseBody
public String healthCheck() throws IOException, TTransportException {
if (status.compareAndSet(0, 1)) {
async = new AsyncClient(9091);
sync = new SyncClient(9090);
async.start();
sync.start();
initialized.countDown();
}
try {
initialized.await(2000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new IOException("pending");
}
return SUCCESS;
}
private void call(IClient client, CountDownLatch latch) {
new Thread(() -> {
try {
client.echo("skywalking");
} catch (TException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}).start();
}
}
\ No newline at end of file
/*
* 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.thrift.client.service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TTransportException;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class AsyncClient implements IClient {
private static final Logger logger = LogManager.getLogger(AsyncClient.class);
private final TNonblockingSocket transport;
private final GreeterService.AsyncClient client;
public AsyncClient(final int port) throws IOException {
this.transport = new TNonblockingSocket("localhost", port);
this.client = new GreeterService.AsyncClient(
TCompactProtocol::new,
new TAsyncClientManager(),
this.transport
);
}
@Override
public void start() throws TTransportException {
}
@Override
public String echo(final String message) throws TException {
final CountDownLatch latch = new CountDownLatch(1);
AtomicReference<String> resp = new AtomicReference<>();
client.echo(message, new AsyncMethodCallback<String>() {
@Override
public void onComplete(final String response) {
resp.set(response);
latch.countDown();
}
@Override
public void onError(final Exception exception) {
latch.countDown();
logger.error("", exception);
}
});
try {
latch.await();
} catch (InterruptedException e) {
logger.error("", e);
}
return resp.get();
}
@Override
public void close() {
transport.close();
}
}
/*
* 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.thrift.client.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransportException;
public class HttpClient implements IClient {
private final THttpClient transport;
private final GreeterService.Client client;
public HttpClient() throws TTransportException {
transport = new THttpClient("http://localhost:9080/thrift");
client = new GreeterService.Client(new TCompactProtocol(transport));
}
@Override
public void start() throws TTransportException {
transport.open();
}
@Override
public void close() {
transport.close();
}
@Override
public String echo(String message) throws TException {
return client.echo(message);
}
}
\ No newline at end of file
/*
* 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.thrift.client.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.transport.TTransportException;
import java.io.IOException;
public interface IClient extends GreeterService.Iface {
void start() throws TTransportException, IOException;
void close();
}
/*
* 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.thrift.client.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
public class SyncClient implements IClient {
private final TTransport transport;
private final GreeterService.Client client;
public SyncClient(int port) throws TTransportException {
this.transport = new TSocket("localhost", port);
client = new GreeterService.Client(new TCompactProtocol(this.transport));
}
@Override
public void start() throws TTransportException {
this.transport.open();
}
@Override
public void close() {
transport.close();
}
@Override
public String echo(String message) throws TException {
return client.echo(message);
}
}
#
# 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: /thrift-scenario
logging:
config: classpath:log4j2.xml
\ No newline at end of file
<?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.
~
-->
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
<?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>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-scenario</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>thrift-common</artifactId>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
<plugins>
<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.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/generated-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>docker</executable>
<arguments>
<argument>run</argument>
<argument>-v</argument>
<argument>${project.basedir}/src/main/thrift:/data</argument>
<argument>-v</argument>
<argument>${project.basedir}/generated-sources:/out</argument>
<argument>thrift:${thrift.version}</argument>
<argument>thrift</argument>
<argument>-o</argument>
<argument>/out</argument>
<argument>--gen</argument>
<argument>java</argument>
<argument>/data/greeter.thrift</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
/*
* 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.thrift.protocol
service GreeterService
{
string echo(1:string message)
}
\ No newline at end of file
#!/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} "-Dskywalking.agent.service_name=thrift-server-scenario" ${home}/../libs/thrift-server.jar &
java -jar ${agent_opts} "-Dskywalking.agent.service_name=thrift-client-scenario" ${home}/../libs/thrift-client.jar &
<?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>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-scenario</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>thrift-dist</artifactId>
<build>
<plugins>
<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>
</plugins>
</build>
</project>
<?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.basedir}/../thrift-client/target/thrift-client.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
<file>
<source>${project.basedir}/../thrift-server/target/thrift-server.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
</files>
</assembly>
<?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>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-scenario</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>thrift-server</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>thrift-common</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.31.v20200723</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.31.v20200723</version>
</dependency>
</dependencies>
<build>
<finalName>thrift-server</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.apache.skywalking.apm.testcase.thrift.server.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
/*
* 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.thrift.server;
import org.apache.skywalking.apm.testcase.thrift.server.service.AsyncServer;
import org.apache.skywalking.apm.testcase.thrift.server.service.SyncServer;
public class Application {
public static void main(String[] args) throws Exception {
new AsyncServer().start();
new SyncServer().start();
}
}
\ No newline at end of file
/*
* 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.thrift.server.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
public class AsyncServer implements IServer {
TNonblockingServer server;
@Override
public void start() throws TTransportException {
TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(9091);
server = new TNonblockingServer(new TNonblockingServer.Args(serverSocket)
.processor(new GreeterService.AsyncProcessor<>(new AsyncHandler()))
.protocolFactory(TCompactProtocol::new));
new Thread(() -> server.serve()).start();
}
@Override
public void close() {
server.stop();
}
}
/*
* 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.thrift.server.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import java.net.InetSocketAddress;
public class HttpServer implements IServer {
public static void main(String[] args) throws Exception {
new HttpServer().start();
}
@Override
public void start() throws Exception {
Server jettyServer = new Server(new InetSocketAddress("0.0.0.0", Integer.valueOf(9080)));
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
servletContextHandler.setContextPath("/");
servletContextHandler.addServlet(new ServletHolder(
new TServlet(new GreeterService.Processor<>(new Handler()), TCompactProtocol::new)),
"/thrift"
);
jettyServer.setHandler(servletContextHandler);
jettyServer.start();
}
@Override
public void close() {
}
}
/*
* 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.thrift.server.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
public interface IServer {
void start() throws Exception;
void close() throws Exception;
final class AsyncHandler implements GreeterService.AsyncIface {
@Override
public void echo(final String message, final AsyncMethodCallback<String> resultHandler) throws TException {
resultHandler.onComplete("echo async: " + message);
}
}
final class Handler implements GreeterService.Iface {
@Override
public String echo(final String message) throws TException {
return "echo sync: " + message;
}
}
}
/*
* 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.thrift.server.service;
import org.apache.skywalking.apm.testcase.thrift.protocol.GreeterService;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;
public class SyncServer implements IServer {
TSimpleServer server;
@Override
public void start() throws TTransportException {
TServerTransport transport = new TServerSocket(9090);
server = new TSimpleServer(new TServer.Args(transport)
.processor(new GreeterService.Processor<>(new Handler()))
.protocolFactory(TCompactProtocol::new));
new Thread(() -> server.serve()).start();
}
@Override
public void close() {
server.stop();
}
}
#
# 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: /thrift-scenario
logging:
config: classpath:log4j2.xml
\ No newline at end of file
<?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.
~
-->
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册