dubbo3 plugin support (#73)
This commit is contained in:
parent
2557749617
commit
ee5bb80fc3
|
|
@ -67,6 +67,7 @@ jobs:
|
|||
- correlation-autotag-scenario
|
||||
- dubbo-2.5.x-scenario
|
||||
- dubbo-2.7.x-scenario
|
||||
- dubbo-3.x-scenario
|
||||
- ehcache-2.x-scenario
|
||||
- elasticsearch-5.x-scenario
|
||||
- elasticsearch-6.x-scenario
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Release Notes.
|
|||
* Avoid `ProfileTaskChannelService.addProfilingSnapshot` throw IllegalStateException(Queue full)
|
||||
* Increase `ProfileTaskChannelService.snapshotQueue` default size from 50 to 4500
|
||||
* Support 2.8 and 2.9 of pulsar client.
|
||||
* Add dubbo 3.x plugin.
|
||||
|
||||
#### Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@ package org.apache.skywalking.apm.plugin.asf.dubbo.patch;
|
|||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
|
|
@ -35,6 +40,11 @@ import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName
|
|||
* to ensure the correct compilation of the code.
|
||||
*/
|
||||
public class WrapperInstrumentation extends ClassStaticMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String CONTEXT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContext";
|
||||
|
||||
private static final String GET_SERVER_CONTEXT_METHOD_NAME = "getServerContext";
|
||||
|
||||
@Override
|
||||
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
|
||||
return new StaticMethodsInterceptPoint[] {
|
||||
|
|
@ -61,4 +71,14 @@ public class WrapperInstrumentation extends ClassStaticMethodsEnhancePluginDefin
|
|||
protected ClassMatch enhanceClass() {
|
||||
return byName("org.apache.dubbo.common.bytecode.Wrapper");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<WitnessMethod> witnessMethods() {
|
||||
return Collections.singletonList(new WitnessMethod(
|
||||
CONTEXT_TYPE_NAME,
|
||||
named(GET_SERVER_CONTEXT_METHOD_NAME).and(
|
||||
returns(named(CONTEXT_TYPE_NAME)))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
dubbo=org.apache.skywalking.apm.plugin.asf.dubbo.patch.WrapperInstrumentation
|
||||
dubbo-2.7.x=org.apache.skywalking.apm.plugin.asf.dubbo.patch.WrapperInstrumentation
|
||||
|
|
|
|||
|
|
@ -20,13 +20,18 @@ package org.apache.skywalking.apm.plugin.asf.dubbo;
|
|||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
|
||||
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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
|
|
@ -34,6 +39,10 @@ public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefin
|
|||
|
||||
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.asf.dubbo.DubboInterceptor";
|
||||
|
||||
private static final String CONTEXT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContext";
|
||||
|
||||
private static final String GET_SERVER_CONTEXT_METHOD_NAME = "getServerContext";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
|
|
@ -65,4 +74,14 @@ public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefin
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<WitnessMethod> witnessMethods() {
|
||||
return Collections.singletonList(new WitnessMethod(
|
||||
CONTEXT_TYPE_NAME,
|
||||
named(GET_SERVER_CONTEXT_METHOD_NAME).and(
|
||||
returns(named(CONTEXT_TYPE_NAME)))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
dubbo=org.apache.skywalking.apm.plugin.asf.dubbo.DubboInstrumentation
|
||||
dubbo-2.7.x=org.apache.skywalking.apm.plugin.asf.dubbo.DubboInstrumentation
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>8.9.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>dubbo-3.x-conflict-patch</artifactId>
|
||||
|
||||
<name>apm-dubbo-3.x-conflict-path</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<dubbo.version>3.0.0</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* 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.asf.dubbo3.patch;
|
||||
|
||||
import org.apache.dubbo.common.bytecode.ClassGenerator;
|
||||
import org.apache.dubbo.common.bytecode.NoSuchPropertyException;
|
||||
import org.apache.dubbo.common.bytecode.Wrapper;
|
||||
import org.apache.dubbo.common.utils.ClassHelper;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.regex.Matcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
|
||||
|
||||
public class MakeWrapperInterceptor implements StaticMethodsAroundInterceptor {
|
||||
|
||||
private static final AtomicLong WRAPPER_CLASS_COUNTER = new AtomicLong(0);
|
||||
|
||||
@Override
|
||||
public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
|
||||
MethodInterceptResult result) {
|
||||
Class wrapperClass = (Class<?>) allArguments[0];
|
||||
if (EnhancedInstance.class.isAssignableFrom(wrapperClass)) {
|
||||
result.defineReturnValue(makeWrapper(wrapperClass));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
|
||||
Object ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
|
||||
Throwable t) {
|
||||
}
|
||||
|
||||
private static Wrapper makeWrapper(Class<?> c) {
|
||||
if (c.isPrimitive())
|
||||
throw new IllegalArgumentException("Can not create wrapper for primitive type: " + c);
|
||||
|
||||
String name = c.getName();
|
||||
ClassLoader cl = ClassHelper.getClassLoader(c);
|
||||
|
||||
StringBuilder c1 = new StringBuilder("public void setPropertyValue(Object o, String n, Object v){ ");
|
||||
StringBuilder c2 = new StringBuilder("public Object getPropertyValue(Object o, String n){ ");
|
||||
StringBuilder c3 = new StringBuilder(
|
||||
"public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws " + InvocationTargetException.class
|
||||
.getName() + "{ ");
|
||||
|
||||
c1.append(name)
|
||||
.append(" w; try{ w = ((")
|
||||
.append(name)
|
||||
.append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }");
|
||||
c2.append(name)
|
||||
.append(" w; try{ w = ((")
|
||||
.append(name)
|
||||
.append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }");
|
||||
c3.append(name)
|
||||
.append(" w; try{ w = ((")
|
||||
.append(name)
|
||||
.append(")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }");
|
||||
|
||||
Map<String, Class<?>> pts = new HashMap<String, Class<?>>(); // <property name, property types>
|
||||
Map<String, Method> ms = new LinkedHashMap<String, Method>(); // <method desc, Method instance>
|
||||
List<String> mns = new ArrayList<String>(); // method names.
|
||||
List<String> dmns = new ArrayList<String>(); // declaring method names.
|
||||
|
||||
// get all public field.
|
||||
for (Field f : c.getFields()) {
|
||||
String fn = f.getName();
|
||||
Class<?> ft = f.getType();
|
||||
if (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers()))
|
||||
continue;
|
||||
|
||||
c1.append(" if( $2.equals(\"")
|
||||
.append(fn)
|
||||
.append("\") ){ w.")
|
||||
.append(fn)
|
||||
.append("=")
|
||||
.append(arg(ft, "$3"))
|
||||
.append("; return; }");
|
||||
c2.append(" if( $2.equals(\"").append(fn).append("\") ){ return ($w)w.").append(fn).append("; }");
|
||||
pts.put(fn, ft);
|
||||
}
|
||||
|
||||
Method[] methods = c.getMethods();
|
||||
// get all public method.
|
||||
boolean hasMethod = hasMethods(methods);
|
||||
if (hasMethod) {
|
||||
c3.append(" try{");
|
||||
}
|
||||
for (Method m : methods) {
|
||||
// ignore Object's method
|
||||
// ignore EnhanceInstance's method
|
||||
if (m.getDeclaringClass() == Object.class || "getSkyWalkingDynamicField".equals(
|
||||
m.getName()) || "setSkyWalkingDynamicField"
|
||||
.equals(m.getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String mn = m.getName();
|
||||
c3.append(" if( \"").append(mn).append("\".equals( $2 ) ");
|
||||
int len = m.getParameterTypes().length;
|
||||
c3.append(" && ").append(" $3.length == ").append(len);
|
||||
|
||||
boolean override = false;
|
||||
for (Method m2 : methods) {
|
||||
if (!m.equals(m2) && m.getName().equals(m2.getName())) {
|
||||
override = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (override) {
|
||||
if (len > 0) {
|
||||
for (int l = 0; l < len; l++) {
|
||||
c3.append(" && ")
|
||||
.append(" $3[")
|
||||
.append(l)
|
||||
.append("].getName().equals(\"")
|
||||
.append(m.getParameterTypes()[l].getName())
|
||||
.append("\")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c3.append(" ) { ");
|
||||
|
||||
if (m.getReturnType() == Void.TYPE)
|
||||
c3.append(" w.")
|
||||
.append(mn)
|
||||
.append('(')
|
||||
.append(args(m.getParameterTypes(), "$4"))
|
||||
.append(");")
|
||||
.append(" return null;");
|
||||
else
|
||||
c3.append(" return ($w)w.")
|
||||
.append(mn)
|
||||
.append('(')
|
||||
.append(args(m.getParameterTypes(), "$4"))
|
||||
.append(");");
|
||||
|
||||
c3.append(" }");
|
||||
|
||||
mns.add(mn);
|
||||
if (m.getDeclaringClass() == c)
|
||||
dmns.add(mn);
|
||||
ms.put(ReflectUtils.getDesc(m), m);
|
||||
}
|
||||
if (hasMethod) {
|
||||
c3.append(" } catch(Throwable e) { ");
|
||||
c3.append(" throw new java.lang.reflect.InvocationTargetException(e); ");
|
||||
c3.append(" }");
|
||||
}
|
||||
|
||||
c3.append(
|
||||
" throw new " + NoSuchMethodException.class.getName() + "(\"Not found method \\\"\"+$2+\"\\\" in class " + c
|
||||
.getName() + ".\"); }");
|
||||
|
||||
// deal with get/set method.
|
||||
Matcher matcher;
|
||||
for (Map.Entry<String, Method> entry : ms.entrySet()) {
|
||||
String md = entry.getKey();
|
||||
Method method = (Method) entry.getValue();
|
||||
if ((matcher = ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {
|
||||
String pn = propertyName(matcher.group(1));
|
||||
c2.append(" if( $2.equals(\"")
|
||||
.append(pn)
|
||||
.append("\") ){ return ($w)w.")
|
||||
.append(method.getName())
|
||||
.append("(); }");
|
||||
pts.put(pn, method.getReturnType());
|
||||
} else if ((matcher = ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(md)).matches()) {
|
||||
String pn = propertyName(matcher.group(1));
|
||||
c2.append(" if( $2.equals(\"")
|
||||
.append(pn)
|
||||
.append("\") ){ return ($w)w.")
|
||||
.append(method.getName())
|
||||
.append("(); }");
|
||||
pts.put(pn, method.getReturnType());
|
||||
} else if ((matcher = ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {
|
||||
Class<?> pt = method.getParameterTypes()[0];
|
||||
String pn = propertyName(matcher.group(1));
|
||||
c1.append(" if( $2.equals(\"")
|
||||
.append(pn)
|
||||
.append("\") ){ w.")
|
||||
.append(method.getName())
|
||||
.append("(")
|
||||
.append(arg(pt, "$3"))
|
||||
.append("); return; }");
|
||||
pts.put(pn, pt);
|
||||
}
|
||||
}
|
||||
c1.append(
|
||||
" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class " + c
|
||||
.getName() + ".\"); }");
|
||||
c2.append(
|
||||
" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class " + c
|
||||
.getName() + ".\"); }");
|
||||
|
||||
// make class
|
||||
long id = WRAPPER_CLASS_COUNTER.getAndIncrement();
|
||||
ClassGenerator cc = ClassGenerator.newInstance(cl);
|
||||
cc.setClassName((Modifier.isPublic(
|
||||
c.getModifiers()) ? Wrapper.class.getName() + "_swEnhance" : c.getName() + "$sw$_swEnhance") + id);
|
||||
cc.setSuperClass(Wrapper.class);
|
||||
|
||||
cc.addDefaultConstructor();
|
||||
cc.addField("public static String[] pns;"); // property name array.
|
||||
cc.addField("public static " + Map.class.getName() + " pts;"); // property type map.
|
||||
cc.addField("public static String[] mns;"); // all method name array.
|
||||
cc.addField("public static String[] dmns;"); // declared method name array.
|
||||
for (int i = 0, len = ms.size(); i < len; i++)
|
||||
cc.addField("public static Class[] mts" + i + ";");
|
||||
|
||||
cc.addMethod("public String[] getPropertyNames(){ return pns; }");
|
||||
cc.addMethod("public boolean hasProperty(String n){ return pts.containsKey($1); }");
|
||||
cc.addMethod("public Class getPropertyType(String n){ return (Class)pts.get($1); }");
|
||||
cc.addMethod("public String[] getMethodNames(){ return mns; }");
|
||||
cc.addMethod("public String[] getDeclaredMethodNames(){ return dmns; }");
|
||||
cc.addMethod(c1.toString());
|
||||
cc.addMethod(c2.toString());
|
||||
cc.addMethod(c3.toString());
|
||||
|
||||
try {
|
||||
Class<?> wc = cc.toClass();
|
||||
// setup static field.
|
||||
wc.getField("pts").set(null, pts);
|
||||
wc.getField("pns").set(null, pts.keySet().toArray(new String[0]));
|
||||
wc.getField("mns").set(null, mns.toArray(new String[0]));
|
||||
wc.getField("dmns").set(null, dmns.toArray(new String[0]));
|
||||
int ix = 0;
|
||||
for (Method m : ms.values())
|
||||
wc.getField("mts" + ix++).set(null, m.getParameterTypes());
|
||||
return (Wrapper) wc.getDeclaredConstructor().newInstance();
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
} finally {
|
||||
cc.release();
|
||||
ms.clear();
|
||||
mns.clear();
|
||||
dmns.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static String args(Class<?>[] cs, String name) {
|
||||
int len = cs.length;
|
||||
if (len == 0)
|
||||
return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i > 0)
|
||||
sb.append(',');
|
||||
sb.append(arg(cs[i], name + "[" + i + "]"));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String propertyName(String pn) {
|
||||
return pn.length() == 1 || Character.isLowerCase(pn.charAt(1)) ? Character.toLowerCase(
|
||||
pn.charAt(0)) + pn.substring(1) : pn;
|
||||
}
|
||||
|
||||
private static boolean hasMethods(Method[] methods) {
|
||||
if (methods == null || methods.length == 0) {
|
||||
return false;
|
||||
}
|
||||
for (Method m : methods) {
|
||||
if (m.getDeclaringClass() != Object.class && !"getSkyWalkingDynamicField".equals(
|
||||
m.getName()) && !"setSkyWalkingDynamicField"
|
||||
.equals(m.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String arg(Class<?> cl, String name) {
|
||||
if (cl.isPrimitive()) {
|
||||
if (cl == Boolean.TYPE)
|
||||
return "((Boolean)" + name + ").booleanValue()";
|
||||
if (cl == Byte.TYPE)
|
||||
return "((Byte)" + name + ").byteValue()";
|
||||
if (cl == Character.TYPE)
|
||||
return "((Character)" + name + ").charValue()";
|
||||
if (cl == Double.TYPE)
|
||||
return "((Number)" + name + ").doubleValue()";
|
||||
if (cl == Float.TYPE)
|
||||
return "((Number)" + name + ").floatValue()";
|
||||
if (cl == Integer.TYPE)
|
||||
return "((Number)" + name + ").intValue()";
|
||||
if (cl == Long.TYPE)
|
||||
return "((Number)" + name + ").longValue()";
|
||||
if (cl == Short.TYPE)
|
||||
return "((Number)" + name + ").shortValue()";
|
||||
throw new RuntimeException("Unknown primitive type: " + cl.getName());
|
||||
}
|
||||
return "(" + ReflectUtils.getName(cl) + ")" + name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.asf.dubbo3.patch;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
* The dubbo conflict plugin resolver the problem about the wrapper class generated by Dubbo core cannot be compiled
|
||||
* successfully. As we known, The wrapper class traverses all the methods. In usual, it works unless this class has been
|
||||
* enhanced by Skywalking. The javasist cannot found the `EnhanceInstance` method when generate.
|
||||
* <p>
|
||||
* The plugin excludes {@link org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance} methods
|
||||
* to ensure the correct compilation of the code.
|
||||
*/
|
||||
public class WrapperInstrumentation extends ClassStaticMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String CONTEXT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContext";
|
||||
|
||||
private static final String GET_SERVER_CONTEXT_METHOD_NAME = "getServerContext";
|
||||
|
||||
private static final String CONTEXT_ATTACHMENT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContextAttachment";
|
||||
|
||||
@Override
|
||||
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
|
||||
return new StaticMethodsInterceptPoint[] {
|
||||
new StaticMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("makeWrapper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return "org.apache.skywalking.apm.plugin.asf.dubbo3.patch.MakeWrapperInterceptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName("org.apache.dubbo.common.bytecode.Wrapper");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<WitnessMethod> witnessMethods() {
|
||||
return Collections.singletonList(
|
||||
new WitnessMethod(
|
||||
CONTEXT_TYPE_NAME,
|
||||
named(GET_SERVER_CONTEXT_METHOD_NAME).and(
|
||||
returns(named(CONTEXT_ATTACHMENT_TYPE_NAME)))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
dubbo-3.x=org.apache.skywalking.apm.plugin.asf.dubbo3.patch.WrapperInstrumentation
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>8.9.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-dubbo-3.x-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>dubbo-3.x-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<dubbo.version>3.0.0</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.asf.dubbo3;
|
||||
|
||||
public class DubboConsumerInstrumentation extends DubboInstrumentationBase {
|
||||
|
||||
public DubboConsumerInstrumentation() {
|
||||
super(CONSUMER_ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.asf.dubbo3;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
|
||||
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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
public class DubboInstrumentationBase extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
public static final String PROVIDER_ENHANCE_CLASS = "org.apache.dubbo.monitor.support.MonitorFilter";
|
||||
|
||||
public static final String CONSUMER_ENHANCE_CLASS = "org.apache.dubbo.monitor.support.MonitorClusterFilter";
|
||||
|
||||
public static final String INTERCEPT_POINT_METHOD = "invoke";
|
||||
|
||||
public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.asf.dubbo3.DubboInterceptor";
|
||||
|
||||
public static final String CONTEXT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContext";
|
||||
|
||||
public static final String GET_SERVER_CONTEXT_METHOD_NAME = "getServerContext";
|
||||
|
||||
public static final String CONTEXT_ATTACHMENT_TYPE_NAME = "org.apache.dubbo.rpc.RpcContextAttachment";
|
||||
|
||||
private final String enhanceClassName;
|
||||
|
||||
public DubboInstrumentationBase(String enhanceClassName) {
|
||||
this.enhanceClassName = enhanceClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(enhanceClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(INTERCEPT_POINT_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<WitnessMethod> witnessMethods() {
|
||||
return Collections.singletonList(
|
||||
new WitnessMethod(
|
||||
CONTEXT_TYPE_NAME,
|
||||
named(GET_SERVER_CONTEXT_METHOD_NAME).and(
|
||||
returns(named(CONTEXT_ATTACHMENT_TYPE_NAME)))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* 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.asf.dubbo3;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcContextAttachment;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcServiceContext;
|
||||
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.Tags;
|
||||
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.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.util.StringUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link DubboInterceptor} define how to enhance class {@link org.apache.dubbo.monitor.support.MonitorFilter#invoke(Invoker,
|
||||
* Invocation)}. the trace context transport to the provider side by {@link RpcContext#getServerAttachment}.but all the
|
||||
* version of dubbo framework below 3.0.0 don't support {@link RpcContext#getClientAttachment}, we support another way
|
||||
* to support it.
|
||||
*/
|
||||
public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
public static final String ARGUMENTS = "arguments";
|
||||
|
||||
/**
|
||||
* <h2>Consumer:</h2> The serialized trace context data will
|
||||
* inject to the {@link RpcContext#getClientAttachment} for transport to provider side.
|
||||
* <p>
|
||||
* <h2>Provider:</h2> The serialized trace context data will extract from
|
||||
* {@link RpcContext#getServerAttachment}. current trace segment will ref if the serialize context data is not
|
||||
* null.
|
||||
*/
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
Invoker invoker = (Invoker) allArguments[0];
|
||||
Invocation invocation = (Invocation) allArguments[1];
|
||||
|
||||
RpcServiceContext serviceContext = RpcContext.getServiceContext();
|
||||
boolean isConsumer;
|
||||
URL url = serviceContext.getUrl();
|
||||
if (url == null) {
|
||||
url = serviceContext.getConsumerUrl();
|
||||
isConsumer = url != null;
|
||||
} else {
|
||||
isConsumer = serviceContext.isConsumerSide();
|
||||
}
|
||||
|
||||
RpcContextAttachment attachment = isConsumer ? RpcContext.getClientAttachment() : RpcContext.getServerAttachment();
|
||||
URL requestURL = invoker.getUrl();
|
||||
|
||||
AbstractSpan span;
|
||||
|
||||
final String host = requestURL.getHost();
|
||||
final int port = requestURL.getPort();
|
||||
|
||||
boolean needCollectArguments;
|
||||
int argumentsLengthThreshold;
|
||||
if (isConsumer) {
|
||||
final ContextCarrier contextCarrier = new ContextCarrier();
|
||||
span = ContextManager.createExitSpan(
|
||||
generateOperationName(requestURL, invocation), contextCarrier, host + ":" + port);
|
||||
//invocation.getAttachments().put("contextData", contextDataStr);
|
||||
//@see https://github.com/alibaba/dubbo/blob/dubbo-2.5.3/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java#L154-L161
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
attachment.setAttachment(next.getHeadKey(), next.getHeadValue());
|
||||
if (invocation.getAttachments().containsKey(next.getHeadKey())) {
|
||||
invocation.getAttachments().remove(next.getHeadKey());
|
||||
}
|
||||
}
|
||||
needCollectArguments = DubboPluginConfig.Plugin.Dubbo.COLLECT_CONSUMER_ARGUMENTS;
|
||||
argumentsLengthThreshold = DubboPluginConfig.Plugin.Dubbo.CONSUMER_ARGUMENTS_LENGTH_THRESHOLD;
|
||||
} else {
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
next.setHeadValue(attachment.getAttachment(next.getHeadKey()));
|
||||
}
|
||||
|
||||
span = ContextManager.createEntrySpan(generateOperationName(requestURL, invocation), contextCarrier);
|
||||
span.setPeer(attachment.getRemoteAddressString());
|
||||
needCollectArguments = DubboPluginConfig.Plugin.Dubbo.COLLECT_PROVIDER_ARGUMENTS;
|
||||
argumentsLengthThreshold = DubboPluginConfig.Plugin.Dubbo.PROVIDER_ARGUMENTS_LENGTH_THRESHOLD;
|
||||
}
|
||||
|
||||
Tags.URL.set(span, generateRequestURL(requestURL, invocation));
|
||||
collectArguments(needCollectArguments, argumentsLengthThreshold, span, invocation);
|
||||
span.setComponent(ComponentsDefine.DUBBO);
|
||||
SpanLayer.asRPCFramework(span);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
Result result = (Result) ret;
|
||||
try {
|
||||
if (result != null && result.getException() != null) {
|
||||
dealException(result.getException());
|
||||
}
|
||||
} catch (RpcException e) {
|
||||
dealException(e);
|
||||
}
|
||||
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
dealException(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the throwable, which occurs in Dubbo RPC service.
|
||||
*/
|
||||
private void dealException(Throwable throwable) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
span.log(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format operation name. e.g. org.apache.skywalking.apm.plugin.test.Test.test(String)
|
||||
*
|
||||
* @return operation name.
|
||||
*/
|
||||
private String generateOperationName(URL requestURL, Invocation invocation) {
|
||||
StringBuilder operationName = new StringBuilder();
|
||||
String groupStr = requestURL.getParameter(CommonConstants.GROUP_KEY);
|
||||
groupStr = StringUtil.isEmpty(groupStr) ? "" : groupStr + "/";
|
||||
operationName.append(groupStr);
|
||||
operationName.append(requestURL.getPath());
|
||||
operationName.append("." + invocation.getMethodName() + "(");
|
||||
for (Class<?> classes : invocation.getParameterTypes()) {
|
||||
operationName.append(classes.getSimpleName() + ",");
|
||||
}
|
||||
|
||||
if (invocation.getParameterTypes().length > 0) {
|
||||
operationName.delete(operationName.length() - 1, operationName.length());
|
||||
}
|
||||
|
||||
operationName.append(")");
|
||||
|
||||
return operationName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format request url. e.g. dubbo://127.0.0.1:20880/org.apache.skywalking.apm.plugin.test.Test.test(String).
|
||||
*
|
||||
* @return request url.
|
||||
*/
|
||||
private String generateRequestURL(URL url, Invocation invocation) {
|
||||
StringBuilder requestURL = new StringBuilder();
|
||||
requestURL.append(url.getProtocol() + "://");
|
||||
requestURL.append(url.getHost());
|
||||
requestURL.append(":" + url.getPort() + "/");
|
||||
requestURL.append(generateOperationName(url, invocation));
|
||||
return requestURL.toString();
|
||||
}
|
||||
|
||||
private void collectArguments(boolean needCollectArguments,
|
||||
int argumentsLengthThreshold,
|
||||
AbstractSpan span,
|
||||
Invocation invocation) {
|
||||
if (needCollectArguments && argumentsLengthThreshold > 0) {
|
||||
Object[] parameters = invocation.getArguments();
|
||||
if (parameters != null && parameters.length > 0) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Object parameter : parameters) {
|
||||
if (!first) {
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
stringBuilder.append(parameter);
|
||||
if (stringBuilder.length() > argumentsLengthThreshold) {
|
||||
stringBuilder.append("...");
|
||||
break;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
span.tag(ARGUMENTS, stringBuilder.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.asf.dubbo3;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
|
||||
|
||||
public class DubboPluginConfig {
|
||||
|
||||
public static class Plugin {
|
||||
|
||||
@PluginConfig(root = DubboPluginConfig.class)
|
||||
public static class Dubbo {
|
||||
|
||||
public static boolean COLLECT_CONSUMER_ARGUMENTS = false;
|
||||
|
||||
public static int CONSUMER_ARGUMENTS_LENGTH_THRESHOLD = 256;
|
||||
|
||||
public static boolean COLLECT_PROVIDER_ARGUMENTS = false;
|
||||
|
||||
public static int PROVIDER_ARGUMENTS_LENGTH_THRESHOLD = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.asf.dubbo3;
|
||||
|
||||
public class DubboProviderInstrumentation extends DubboInstrumentationBase {
|
||||
|
||||
public DubboProviderInstrumentation() {
|
||||
super(PROVIDER_ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
dubbo-3.x=org.apache.skywalking.apm.plugin.asf.dubbo3.DubboProviderInstrumentation
|
||||
dubbo-3.x=org.apache.skywalking.apm.plugin.asf.dubbo3.DubboConsumerInstrumentation
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.dubbo3;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.OverrideImplementor;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService;
|
||||
|
||||
@OverrideImplementor(ContextManagerExtendService.class)
|
||||
public class ContextManagerExtendOverrideService extends ContextManagerExtendService {
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* 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.dubbo3;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.dubbo.rpc.RpcContextAttachment;
|
||||
import org.apache.dubbo.rpc.RpcServiceContext;
|
||||
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService;
|
||||
import org.apache.skywalking.apm.agent.core.context.SW8CarrierItem;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
|
||||
import org.apache.skywalking.apm.agent.core.context.util.TagValuePair;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentRefHelper;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
|
||||
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
|
||||
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
|
||||
import org.apache.skywalking.apm.plugin.asf.dubbo3.DubboInterceptor;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
@PrepareForTest({RpcContext.class})
|
||||
public class DubboInterceptorTest {
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule agentServiceRule = new AgentServiceRule();
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
||||
private DubboInterceptor dubboInterceptor;
|
||||
|
||||
@Mock
|
||||
private RpcServiceContext serviceContext;
|
||||
@Mock
|
||||
private RpcContextAttachment contextAttachment;
|
||||
@Mock
|
||||
private Invoker invoker;
|
||||
@Mock
|
||||
private Invocation invocation;
|
||||
@Mock
|
||||
private MethodInterceptResult methodInterceptResult;
|
||||
@Mock
|
||||
private Result result;
|
||||
|
||||
private Object[] allArguments;
|
||||
private Class[] argumentTypes;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dubboInterceptor = new DubboInterceptor();
|
||||
|
||||
PowerMockito.mockStatic(RpcContext.class);
|
||||
URL url = URL.valueOf("dubbo://127.0.0.1:20880/org.apache.skywalking.apm.test.TestDubboService");
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
when(invocation.getMethodName()).thenReturn("test");
|
||||
when(invocation.getParameterTypes()).thenReturn(new Class[] {String.class});
|
||||
when(invocation.getArguments()).thenReturn(new Object[] {"abc"});
|
||||
when(RpcContext.getServiceContext()).thenReturn(serviceContext);
|
||||
when(serviceContext.getUrl()).thenReturn(null);
|
||||
when(serviceContext.getConsumerUrl()).thenReturn(url);
|
||||
when(RpcContext.getClientAttachment()).thenReturn(contextAttachment);
|
||||
|
||||
allArguments = new Object[] {
|
||||
invoker,
|
||||
invocation
|
||||
};
|
||||
argumentTypes = new Class[] {
|
||||
invoker.getClass(),
|
||||
invocation.getClass()
|
||||
};
|
||||
Config.Agent.SERVICE_NAME = "DubboTestCases-APP";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceFromPlugin() {
|
||||
PluginBootService service = ServiceManager.INSTANCE.findService(PluginBootService.class);
|
||||
|
||||
Assert.notNull(service);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceOverrideFromPlugin() {
|
||||
ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class);
|
||||
|
||||
Assert.isInstanceOf(ContextManagerExtendOverrideService.class, service);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithAttachment() throws Throwable {
|
||||
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertConsumerSpan(spans.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithException() throws Throwable {
|
||||
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
dubboInterceptor.handleMethodException(
|
||||
enhancedInstance, null, allArguments, argumentTypes, new RuntimeException());
|
||||
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertConsumerTraceSegmentInErrorCase(traceSegment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithResultHasException() throws Throwable {
|
||||
when(result.getException()).thenReturn(new RuntimeException());
|
||||
|
||||
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertConsumerTraceSegmentInErrorCase(traceSegment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderWithAttachment() throws Throwable {
|
||||
when(serviceContext.getUrl()).thenReturn(
|
||||
URL.valueOf("dubbo://127.0.0.1:20880/org.apache.skywalking.apm.test.TestDubboService"));
|
||||
when(serviceContext.getConsumerUrl()).thenReturn(null);
|
||||
when(RpcContext.getServerAttachment()).thenReturn(contextAttachment);
|
||||
when(contextAttachment.getAttachment(
|
||||
SW8CarrierItem.HEADER_NAME)).thenReturn(
|
||||
"1-My40LjU=-MS4yLjM=-3-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=");
|
||||
|
||||
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
|
||||
assertProvider();
|
||||
}
|
||||
|
||||
private void assertConsumerTraceSegmentInErrorCase(TraceSegment traceSegment) {
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertConsumerSpan(spans.get(0));
|
||||
AbstractTracingSpan span = spans.get(0);
|
||||
assertThat(SpanHelper.getLogs(span).size(), is(1));
|
||||
assertErrorLog(SpanHelper.getLogs(span).get(0));
|
||||
}
|
||||
|
||||
private void assertErrorLog(LogDataEntity logData) {
|
||||
assertThat(logData.getLogs().size(), is(4));
|
||||
assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.<Object>is("error"));
|
||||
assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(RuntimeException.class.getName()));
|
||||
assertNull(logData.getLogs().get(2).getValue());
|
||||
}
|
||||
|
||||
private void assertProvider() {
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertThat(SegmentHelper.getSpans(traceSegment).size(), is(1));
|
||||
assertProviderSpan(SegmentHelper.getSpans(traceSegment).get(0));
|
||||
assertTraceSegmentRef(traceSegment.getRef());
|
||||
}
|
||||
|
||||
private void assertTraceSegmentRef(TraceSegmentRef actual) {
|
||||
assertThat(SegmentRefHelper.getSpanId(actual), is(3));
|
||||
assertThat(SegmentRefHelper.getParentServiceInstance(actual), is("instance"));
|
||||
assertThat(SegmentRefHelper.getTraceSegmentId(actual), is("3.4.5"));
|
||||
}
|
||||
|
||||
private void assertProviderSpan(AbstractTracingSpan span) {
|
||||
assertCommonsAttribute(span);
|
||||
assertTrue(span.isEntry());
|
||||
}
|
||||
|
||||
private void assertConsumerSpan(AbstractTracingSpan span) {
|
||||
assertCommonsAttribute(span);
|
||||
assertTrue(span.isExit());
|
||||
}
|
||||
|
||||
private void assertCommonsAttribute(AbstractTracingSpan span) {
|
||||
List<TagValuePair> tags = SpanHelper.getTags(span);
|
||||
assertThat(tags.size(), is(1));
|
||||
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.RPC_FRAMEWORK));
|
||||
assertThat(SpanHelper.getComponentId(span), is(3));
|
||||
assertThat(
|
||||
tags.get(0)
|
||||
.getValue(),
|
||||
is("dubbo://127.0.0.1:20880/org.apache.skywalking.apm.test.TestDubboService.test(String)")
|
||||
);
|
||||
assertThat(span.getOperationName(), is("org.apache.skywalking.apm.test.TestDubboService.test(String)"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.dubbo3;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.BootService;
|
||||
|
||||
public class PluginBootService implements BootService {
|
||||
@Override
|
||||
public void prepare() throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void boot() throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws Throwable {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
|
||||
org.apache.skywalking.apm.plugin.dubbo3.PluginBootService
|
||||
org.apache.skywalking.apm.plugin.dubbo3.ContextManagerExtendOverrideService
|
||||
|
|
@ -75,6 +75,8 @@
|
|||
<module>canal-1.x-plugin</module>
|
||||
<module>dubbo-2.7.x-plugin</module>
|
||||
<module>dubbo-2.7.x-conflict-patch</module>
|
||||
<module>dubbo-3.x-plugin</module>
|
||||
<module>dubbo-3.x-conflict-patch</module>
|
||||
<module>vertx-plugins</module>
|
||||
<module>resteasy-plugin</module>
|
||||
<module>solrj-7.x-plugin</module>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
- dbcp-2.x
|
||||
- druid-1.x
|
||||
- dubbo
|
||||
- dubbo-2.7.x
|
||||
- dubbo-3.x
|
||||
- ehcache-2.x
|
||||
- elastic-job-2.x
|
||||
- elasticjob-3.x
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ metrics based on the tracing data.
|
|||
* RPC Frameworks
|
||||
* [Dubbo](https://github.com/alibaba/dubbo) 2.5.4 -> 2.6.0
|
||||
* [Dubbox](https://github.com/dangdangdotcom/dubbox) 2.8.4
|
||||
* [Apache Dubbo](https://github.com/apache/dubbo) 2.7.0
|
||||
* [Apache Dubbo](https://github.com/apache/dubbo) 2.7.x -> 3.x
|
||||
* [Motan](https://github.com/weibocom/motan) 0.2.x -> 1.1.0
|
||||
* [gRPC](https://github.com/grpc/grpc-java) 1.x
|
||||
* [Apache ServiceComb Java Chassis](https://github.com/apache/servicecomb-java-chassis) 0.1 -> 0.5,1.x
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
#!/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 -Dskywalking.plugin.dubbo.collect_consumer_arguments=true \
|
||||
-Dskywalking.plugin.dubbo.collect_provider_arguments=true -jar ${agent_opts} ${home}/../libs/dubbo-3.x-scenario.jar &
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
segmentItems:
|
||||
- serviceName: dubbo-3.x-scenario
|
||||
segmentSize: ge 3
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: org.apache.skywalking.apm.testcase.dubbo3.services.GreetService.doBusiness(String)
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: RPCFramework
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 3
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: not null
|
||||
tags:
|
||||
- {key: url, value: not null}
|
||||
- {key: arguments, value: helloWorld}
|
||||
refs:
|
||||
- {parentEndpoint: GET:/dubbo-3.x-scenario/case/dubbo, networkAddress: not null,
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: dubbo-3.x-scenario, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: org.apache.skywalking.apm.testcase.dubbo3.services.GreetService.doBusiness(String)
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: RPCFramework
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 3
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
tags:
|
||||
- {key: url, value: not null}
|
||||
- {key: arguments, value: helloWorld}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: GET:/dubbo-3.x-scenario/case/dubbo
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 1
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/dubbo-3.x-scenario/case/dubbo'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
type: jvm
|
||||
entryService: http://localhost:8080/dubbo-3.x-scenario/case/dubbo
|
||||
healthCheck: http://localhost:8080/dubbo-3.x-scenario/case/healthCheck
|
||||
startScript: ./bin/startup.sh
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>dubbo-3.x-scenario</artifactId>
|
||||
<version>5.0.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<spring.boot.version>2.1.6.RELEASE</spring.boot.version>
|
||||
|
||||
<test.framework>dubbo</test.framework>
|
||||
<test.framework.version>3.0.0</test.framework.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-dubbo-3.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- dubbo -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-zookeeper</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>dubbo-3.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>./target/dubbo-3.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.dubbo3;
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.skywalking.apm.testcase.dubbo3.services.GreetService;
|
||||
import org.apache.skywalking.apm.testcase.dubbo3.services.impl.GreetServiceImpl;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new EmbeddedZooKeeper(2181, false).start();
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class DubboConfiguration {
|
||||
|
||||
private ApplicationConfig applicationConfig = new ApplicationConfig(Application.class.getSimpleName());
|
||||
|
||||
private RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181");
|
||||
|
||||
private ProtocolConfig protocolConfig = new ProtocolConfig("dubbo", 20080);
|
||||
|
||||
public DubboConfiguration() {
|
||||
ApplicationModel.getConfigManager().setApplication(applicationConfig);
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "unexport")
|
||||
public ServiceConfig<GreetService> service() {
|
||||
ServiceConfig<GreetService> serviceConfig = new ServiceConfig<>();
|
||||
serviceConfig.setRegistry(registryConfig);
|
||||
serviceConfig.setProtocol(protocolConfig);
|
||||
serviceConfig.setInterface(GreetService.class);
|
||||
serviceConfig.setRef(new GreetServiceImpl());
|
||||
serviceConfig.setTimeout(5000);
|
||||
serviceConfig.export();
|
||||
return serviceConfig;
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "destroy")
|
||||
public ReferenceConfig<GreetService> reference() {
|
||||
ReferenceConfig<GreetService> referenceConfig = new ReferenceConfig<>();
|
||||
referenceConfig.setRegistry(registryConfig);
|
||||
referenceConfig.setInterface(GreetService.class);
|
||||
referenceConfig.setScope("remote");
|
||||
return referenceConfig;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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.dubbo3;
|
||||
|
||||
import org.apache.zookeeper.server.ServerConfig;
|
||||
import org.apache.zookeeper.server.ZooKeeperServerMain;
|
||||
import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
|
||||
* <p>
|
||||
* Helper class to start an embedded instance of standalone (non clustered) ZooKeeper.
|
||||
* <p>
|
||||
* NOTE: at least an external standalone server (if not an ensemble) are recommended, even for {@link
|
||||
* org.springframework.xd.dirt.server.singlenode.SingleNodeApplication}
|
||||
*/
|
||||
public class EmbeddedZooKeeper implements SmartLifecycle {
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedZooKeeper.class);
|
||||
|
||||
/**
|
||||
* ZooKeeper client port. This will be determined dynamically upon startup.
|
||||
*/
|
||||
private final int clientPort;
|
||||
|
||||
/**
|
||||
* Whether to auto-start. Default is true.
|
||||
*/
|
||||
private boolean autoStartup = true;
|
||||
|
||||
/**
|
||||
* Lifecycle phase. Default is 0.
|
||||
*/
|
||||
private int phase = 0;
|
||||
|
||||
/**
|
||||
* Thread for running the ZooKeeper server.
|
||||
*/
|
||||
private volatile Thread zkServerThread;
|
||||
|
||||
/**
|
||||
* ZooKeeper server.
|
||||
*/
|
||||
private volatile ZooKeeperServerMain zkServer;
|
||||
|
||||
/**
|
||||
* {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread.
|
||||
*/
|
||||
private ErrorHandler errorHandler;
|
||||
|
||||
private boolean daemon = true;
|
||||
|
||||
/**
|
||||
* Construct an EmbeddedZooKeeper with a random port.
|
||||
*/
|
||||
public EmbeddedZooKeeper() {
|
||||
clientPort = SocketUtils.findAvailableTcpPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an EmbeddedZooKeeper with the provided port.
|
||||
*
|
||||
* @param clientPort port for ZooKeeper server to bind to
|
||||
*/
|
||||
public EmbeddedZooKeeper(int clientPort, boolean daemon) {
|
||||
this.clientPort = clientPort;
|
||||
this.daemon = daemon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port that clients should use to connect to this embedded server.
|
||||
*
|
||||
* @return dynamically determined client port
|
||||
*/
|
||||
public int getClientPort() {
|
||||
return this.clientPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether to start automatically. Default is true.
|
||||
*
|
||||
* @param autoStartup whether to start automatically
|
||||
*/
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
this.autoStartup = autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return this.autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the lifecycle phase for the embedded server.
|
||||
*
|
||||
* @param phase the lifecycle phase
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return zkServerThread != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the ZooKeeper server in a background thread.
|
||||
* <p>
|
||||
* Register an error handler via {@link #setErrorHandler} in order to handle any exceptions thrown during startup or
|
||||
* execution.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void start() {
|
||||
if (zkServerThread == null) {
|
||||
zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter");
|
||||
zkServerThread.setDaemon(daemon);
|
||||
zkServerThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the ZooKeeper server.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void stop() {
|
||||
if (zkServerThread != null) {
|
||||
// The shutdown method is protected...thus this hack to invoke it.
|
||||
// This will log an exception on shutdown; see
|
||||
// https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details.
|
||||
try {
|
||||
Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
|
||||
shutdown.setAccessible(true);
|
||||
shutdown.invoke(zkServer);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// It is expected that the thread will exit after
|
||||
// the server is shutdown; this will block until
|
||||
// the shutdown is complete.
|
||||
try {
|
||||
zkServerThread.join(5000);
|
||||
zkServerThread = null;
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOGGER.warn("Interrupted while waiting for embedded ZooKeeper to exit");
|
||||
// abandoning zk thread
|
||||
zkServerThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the server if running and invoke the callback when complete.
|
||||
*/
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
stop();
|
||||
callback.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none
|
||||
* is provided, only error-level logging will occur.
|
||||
*
|
||||
* @param errorHandler the {@link ErrorHandler} to be invoked
|
||||
*/
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runnable implementation that starts the ZooKeeper server.
|
||||
*/
|
||||
private class ServerRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
File file = new File(System.getProperty("java.io.tmpdir")
|
||||
+ File.separator + UUID.randomUUID());
|
||||
file.deleteOnExit();
|
||||
properties.setProperty("dataDir", file.getAbsolutePath());
|
||||
properties.setProperty("clientPort", String.valueOf(clientPort));
|
||||
|
||||
QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();
|
||||
quorumPeerConfig.parseProperties(properties);
|
||||
|
||||
zkServer = new ZooKeeperServerMain();
|
||||
ServerConfig configuration = new ServerConfig();
|
||||
configuration.readFrom(quorumPeerConfig);
|
||||
|
||||
zkServer.runFromConfig(configuration);
|
||||
} catch (Exception e) {
|
||||
if (errorHandler != null) {
|
||||
errorHandler.handleError(e);
|
||||
} else {
|
||||
LOGGER.error("Exception running embedded ZooKeeper", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.dubbo3.controller;
|
||||
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.skywalking.apm.testcase.dubbo3.services.GreetService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/case")
|
||||
public class CaseController {
|
||||
|
||||
private static final String SUCCESS = "Success";
|
||||
|
||||
@Autowired
|
||||
private ReferenceConfig<GreetService> referenceConfig;
|
||||
|
||||
@RequestMapping("/healthCheck")
|
||||
@ResponseBody
|
||||
public String healthCheck() {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@RequestMapping("/dubbo")
|
||||
@ResponseBody
|
||||
public String dubbo() {
|
||||
GreetService greetService = referenceConfig.get();
|
||||
greetService.doBusiness("helloWorld");
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.dubbo3.services;
|
||||
|
||||
public interface GreetService {
|
||||
String doBusiness(String s);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.dubbo3.services.impl;
|
||||
|
||||
import org.apache.skywalking.apm.testcase.dubbo3.services.GreetService;
|
||||
|
||||
public class GreetServiceImpl implements GreetService {
|
||||
|
||||
@Override
|
||||
public String doBusiness(String s) {
|
||||
return "{name:'" + s + "'}";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /dubbo-3.x-scenario
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
3.0.4
|
||||
Loading…
Reference in New Issue