diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index e02e8b22e2a4..5da616f20594 100644 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -125,6 +125,9 @@ public class ComponentsDefine { public static final OfficialComponent SOLRJ = new OfficialComponent(63, "solrj"); public static final OfficialComponent SPRING_ASYNC = new OfficialComponent(65, "SpringAsync"); + + public static final OfficialComponent HESSIAN = new OfficialComponent(66, "Hessian"); + private static ComponentsDefine INSTANCE = new ComponentsDefine(); @@ -184,6 +187,7 @@ public ComponentsDefine() { addComponent(SPRING_CLOUD_GATEWAY); addComponent(RESTEASY); addComponent(SOLRJ); + addComponent(HESSIAN); } private void addComponent(OfficialComponent component) { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index 48418d2d29e6..7977ab820edc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java @@ -232,5 +232,12 @@ public static class SolrJ { public static boolean TRACE_OPS_PARAMS = false; } + public static class Hessian { + /** + * If true, the request uri name will be used as the operation name instead of the interface class name, default is false. + */ + public static boolean USE_URL_AS_OPERATION_NAME = false; + } + } } diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/pom.xml new file mode 100644 index 000000000000..a9d08225cc48 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/pom.xml @@ -0,0 +1,54 @@ + + + + + + org.apache.skywalking + apm-sdk-plugin + 6.3.0-SNAPSHOT + + 4.0.0 + + apm-hessian-4.0.x-plugin + + hessian-4.0.x-plugin + + + 4.0.38 + + + + + com.caucho + hessian + ${hessian.version} + provided + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + + + diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/Constants.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/Constants.java new file mode 100644 index 000000000000..b491743c31d3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/Constants.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.hessian.v4; + +/** + * Constant field for hessian plugin + * + * @author Alan Lau + */ +public class Constants { + + public static final String ENHANCE_CLASS = "com.caucho.hessian.client.HessianProxy"; + + public static final String HESSIAN_SERVICE_EXPORTER_CLASS = "org.springframework.remoting.caucho.HessianServiceExporter"; + + public static final String ADDHEADER_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.hessian.v4.HessianAddHeaderInterceptor"; + + public static final String HESSIAN_SENDREQUEST_CLASS = "org.apache.skywalking.apm.plugin.hessian.v4.HessianProxySendRequestInterceptor"; + + public static final String HESSIAN_SERVLET_ENHANCE_CLASS = "com.caucho.hessian.server.HessianSkeleton"; + + public static final String SKELETON_INTERCPTOR_CLASS = "org.apache.skywalking.apm.plugin.hessian.v4.HessianSkeletonInterceptor"; + + public static final String CONSTRUCT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.hessian.v4.HessianProxyConstructorInterceptor"; + + public static final String SKELETON_CONSTRUCT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.hessian.v4.HessianSkeletonConstructorInterceptor"; + +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptor.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptor.java new file mode 100644 index 000000000000..ce60bc4862b4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptor.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.hessian.v4; + +import com.caucho.hessian.client.HessianURLConnection; +import java.lang.reflect.Method; +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.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +/** + * intercept method {@link HessianURLConnection#addHeader}. + * + * @author Alan Lau + */ +public class HessianAddHeaderInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + HessianURLConnection conn = (HessianURLConnection)allArguments[0]; + ContextCarrier carrier = new ContextCarrier(); + ContextManager.inject(carrier); + + CarrierItem next = carrier.items(); + while (next.hasNext()) { + next = next.next(); + conn.addHeader(next.getHeadKey(), next.getHeadValue()); + } + + } + + @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) { + dealException(t); + } + + public void dealException(Throwable t) { + AbstractSpan activeSpan = ContextManager.activeSpan(); + activeSpan.errorOccurred(); + activeSpan.log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxyConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxyConstructorInterceptor.java new file mode 100644 index 000000000000..55d8ec63988a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxyConstructorInterceptor.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.hessian.v4; + +import java.net.URL; +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.hessian.v4.define.HessianEnhanceCache; + +/** + * intercept HessianProxy + * + * @author Alan Lau + */ +public class HessianProxyConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + + if (allArguments.length < 3) { + return; + } + + if (allArguments[0] == null) { + return; + } + + URL url = (URL)allArguments[0]; + Class clazz = (Class)allArguments[2]; + HessianEnhanceCache cache = new HessianEnhanceCache(); + cache.setUrl(url); + cache.setObj(clazz); + objInst.setSkyWalkingDynamicField(cache); + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptor.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptor.java new file mode 100644 index 000000000000..2e9c97916f95 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptor.java @@ -0,0 +1,104 @@ +/* + * 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.hessian.v4; + +import java.lang.reflect.Method; +import java.net.URL; +import org.apache.skywalking.apm.agent.core.conf.Config; +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.plugin.hessian.v4.define.HessianEnhanceCache; + +/** + * intercept sendRequest of HessianProxy + * + * @author Alan Lau + */ +public class HessianProxySendRequestInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + if (allArguments.length < 0) { + return; + } + + if (allArguments.length < 0) { + return; + } + HessianEnhanceCache cache = (HessianEnhanceCache)objInst.getSkyWalkingDynamicField(); + URL url = cache.getUrl(); + AbstractSpan span; + final ContextCarrier contextCarrier = new ContextCarrier(); + String operateName; + + if (Config.Plugin.Hessian.USE_URL_AS_OPERATION_NAME) { + operateName = url.getPath(); + span = ContextManager.createExitSpan(operateName, contextCarrier, String.format(":", url.getHost(), url.getPort())); + Tags.URL.set(span, url.getPath()); + } else { + Object clazz = cache.getObj(); + if (clazz == null) { + return; + } + operateName = ((Class)clazz).getName(); + span = ContextManager.createExitSpan(operateName, contextCarrier, String.format(":", url.getHost(), url.getPort())); + Tags.URL.set(span, operateName); + } + + span.setOperationName(operateName); + span.setComponent(ComponentsDefine.HESSIAN); + span.start(System.currentTimeMillis()); + SpanLayer.asRPCFramework(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + if (allArguments.length < 0) { + return ret; + } + + if (allArguments.length < 0) { + return ret; + } + + ContextManager.stopSpan(); + return ret; + } + + @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + dealException(t); + } + + public void dealException(Throwable t) { + AbstractSpan activeSpan = ContextManager.activeSpan(); + activeSpan.errorOccurred(); + activeSpan.log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonConstructorInterceptor.java new file mode 100644 index 000000000000..32750c74063f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonConstructorInterceptor.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.hessian.v4; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +/** + * @author Alan Lau + */ +public class HessianSkeletonConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + + if (allArguments[0] == null) { + return; + } + + Object service = allArguments[1]; + objInst.setSkyWalkingDynamicField(service); + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptor.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptor.java new file mode 100644 index 000000000000..aaaaec8812e4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptor.java @@ -0,0 +1,102 @@ +/* + * 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.hessian.v4; + +import com.caucho.hessian.io.AbstractHessianInput; +import java.lang.reflect.Method; +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; + +/** + * intercept invoke of HessianSkeleton + * + * @author Alan Lau + */ +public class HessianSkeletonInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + Object service = allArguments[0]; + + if (service == null) { + return; + } + + AbstractHessianInput in = (AbstractHessianInput)allArguments[1]; + + final ContextCarrier contextCarrier = new ContextCarrier(); + + Object realService = objInst.getSkyWalkingDynamicField(); + String operationName = ((Class)realService).getName(); + + AbstractSpan span = ContextManager.createEntrySpan(operationName, contextCarrier); + + span.start(System.currentTimeMillis()); + span.setComponent(ComponentsDefine.HESSIAN); + Tags.URL.set(span, operationName); + SpanLayer.asRPCFramework(span); + + CarrierItem next = contextCarrier.items(); + while (next.hasNext() && in.readHeader() != null) { + next = next.next(); + next.setHeadValue((String)in.readObject()); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + Object service = allArguments[0]; + + if (service == null) { + return ret; + } + + 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 Hessian RPC service. + * + * @param throwable + */ + public void dealException(Throwable throwable) { + AbstractSpan span = ContextManager.activeSpan(); + span.errorOccurred(); + span.log(throwable); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianEnhanceCache.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianEnhanceCache.java new file mode 100644 index 000000000000..32eeb7dd5eaa --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianEnhanceCache.java @@ -0,0 +1,49 @@ +/* + * 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.hessian.v4.define; + +import java.net.URL; + +/** + * cache field for EnhanceInstance, using for create Trace Spans. + * + * @author Alan Lau + */ +public class HessianEnhanceCache { + + private Object obj; + + private URL url; + + public Object getObj() { + return obj; + } + + public void setObj(Object obj) { + this.obj = obj; + } + + public URL getUrl() { + return url; + } + + public void setUrl(URL url) { + this.url = url; + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianProxyInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianProxyInstrumentation.java new file mode 100644 index 000000000000..94f8e570f648 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianProxyInstrumentation.java @@ -0,0 +1,94 @@ +/* + * 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.hessian.v4.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.ADDHEADER_INTERCEPTOR_CLASS; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.CONSTRUCT_INTERCEPTOR; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.ENHANCE_CLASS; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.HESSIAN_SENDREQUEST_CLASS; + +/** + * enhance method addRequestHeaders + * + * @author Alan Lau + */ +public class HessianProxyInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override public String getConstructorInterceptor() { + return CONSTRUCT_INTERCEPTOR; + } + } + }; + } + + @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("addRequestHeaders"); + } + + @Override public String getMethodsInterceptor() { + return ADDHEADER_INTERCEPTOR_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("sendRequest"); + } + + @Override public String getMethodsInterceptor() { + return HESSIAN_SENDREQUEST_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + }, + + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianSkeletonInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianSkeletonInstrumentation.java new file mode 100644 index 000000000000..baaf599f5426 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hessian/v4/define/HessianSkeletonInstrumentation.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.hessian.v4.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 static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.HESSIAN_SERVLET_ENHANCE_CLASS; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.SKELETON_CONSTRUCT_INTERCEPTOR; +import static org.apache.skywalking.apm.plugin.hessian.v4.Constants.SKELETON_INTERCPTOR_CLASS; + +/** + * enhance method invoke of HessianSkeleton + * + * @author Alan Lau + */ +public class HessianSkeletonInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return ElementMatchers.takesArguments(2); + } + + @Override public String getConstructorInterceptor() { + return SKELETON_CONSTRUCT_INTERCEPTOR; + } + } + }; + } + + @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("invoke").and(ElementMatchers.takesArguments(3)).and(takesArgumentWithType(1, "com.caucho.hessian.io.AbstractHessianInput")).and(takesArgumentWithType(2, "com.caucho.hessian.io.AbstractHessianOutput")); + } + + @Override public String getMethodsInterceptor() { + return SKELETON_INTERCPTOR_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(HESSIAN_SERVLET_ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000000..03dc375cf6a0 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +hessian-4.0.x=org.apache.skywalking.apm.plugin.hessian.v4.define.HessianProxyInstrumentation +hessian-4.0.x=org.apache.skywalking.apm.plugin.hessian.v4.define.HessianSkeletonInstrumentation +hessian-4.0.x=org.apache.skywalking.apm.plugin.hessian.v4.define.HessianServiceExporterInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptorTest.java new file mode 100644 index 000000000000..255240c1d66e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianAddHeaderInterceptorTest.java @@ -0,0 +1,120 @@ +/* + * 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.hessian.v4; + +import com.caucho.hessian.client.HessianConnection; +import com.caucho.hessian.client.HessianProxy; +import com.caucho.hessian.client.HessianURLConnection; +import java.net.URL; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +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.hessian.v4.define.HessianEnhanceCache; +import org.junit.Assert; +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 static org.hamcrest.CoreMatchers.is; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +@PrepareForTest(value = {HessianProxy.class, ContextManager.class}) +public class HessianAddHeaderInterceptorTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Mock + private HessianProxy hessianProxy; + + @Mock + private String methodName; + + @Mock + private ContextCarrier carrier; + + private HessianAddHeaderInterceptor interceptor; + + @Mock + private AbstractSpan span; + + @Mock + private MethodInterceptResult methodInterceptResult; + + private Object[] allArguments; + private Class[] argumentTypes; + + private EnhancedInstance enhancedInstance = new EnhancedInstance() { + + private Object object; + + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + }; + + @Before + public void setUp() throws Exception { + interceptor = new HessianAddHeaderInterceptor(); + PowerMockito.when(hessianProxy.getURL()).thenReturn(new URL("http://127.0.0.1:8080/TestHessian")); + HessianEnhanceCache cache = new HessianEnhanceCache(); + cache.setUrl(hessianProxy.getURL()); + enhancedInstance.setSkyWalkingDynamicField(cache); + + HessianConnection huc = PowerMockito.mock(HessianURLConnection.class); + + PowerMockito.when(huc.getStatusCode()).thenReturn(200); + + PowerMockito.mockStatic(ContextManager.class); + PowerMockito.when(ContextManager.activeSpan()).thenReturn(span); + + allArguments = new Object[] {huc}; + argumentTypes = new Class[] {HessianConnection.class}; + } + + @Test + public void testAddHeader() throws Throwable { + interceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(0)); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptorTest.java new file mode 100644 index 000000000000..d45f84e17e71 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianProxySendRequestInterceptorTest.java @@ -0,0 +1,124 @@ +/* + * 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.hessian.v4; + +import com.caucho.hessian.client.HessianConnection; +import com.caucho.hessian.client.HessianProxy; +import com.caucho.hessian.client.HessianURLConnection; +import java.net.URL; +import java.util.List; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.apache.skywalking.apm.plugin.hessian.v4.define.HessianEnhanceCache; +import org.junit.Assert; +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 static org.hamcrest.CoreMatchers.is; + +/** + * @author Alan Lau + */ + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +@PrepareForTest(HessianProxy.class) +public class HessianProxySendRequestInterceptorTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Mock + private HessianProxy hessianProxy; + + @Mock + private String methodName; + + + private Class object = new Object().getClass(); + + private HessianProxySendRequestInterceptor interceptor; + + private HessianConnection hessianConnection; + + @Mock + private MethodInterceptResult methodInterceptResult; + + private Object[] allArguments; + private Class[] argumentTypes; + + private EnhancedInstance enhancedInstance = new EnhancedInstance() { + + private Object object; + + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + }; + + @Before + public void setUp() throws Exception { + interceptor = new HessianProxySendRequestInterceptor(); + PowerMockito.when(hessianProxy.getURL()).thenReturn(new URL("http://127.0.0.1:8080/TestHessian")); + HessianEnhanceCache cache = new HessianEnhanceCache(); + cache.setUrl(hessianProxy.getURL()); + cache.setObj(object); + enhancedInstance.setSkyWalkingDynamicField(cache); + + HessianConnection huc = PowerMockito.mock(HessianURLConnection.class); + + PowerMockito.when(huc.getStatusCode()).thenReturn(200); + + allArguments = new Object[] {huc}; + argumentTypes = new Class[] {HessianConnection.class}; + } + + @Test + public void testSendRequest() throws Throwable { + interceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + Assert.assertThat(spans.size(), is(1)); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptorTest.java new file mode 100644 index 000000000000..b5b784b25207 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hessian-4.0.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/hessian/v4/HessianSkeletonInterceptorTest.java @@ -0,0 +1,168 @@ +/* + * 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.hessian.v4; + +import com.caucho.hessian.io.AbstractHessianInput; +import com.caucho.hessian.io.AbstractHessianOutput; +import com.caucho.hessian.server.HessianSkeleton; +import java.util.List; +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.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.helper.SpanHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.SpanAssert; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.junit.Assert; +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 static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * unit tests for hessian plugin + * + * @author Alan Lau + */ +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +@PrepareForTest(HessianSkeleton.class) +public class HessianSkeletonInterceptorTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Mock + private String methodName; + + private HessianSkeletonInterceptor interceptor; + + @Mock + private AbstractHessianInput input; + + @Mock + private AbstractHessianOutput out; + + @Mock + private MethodInterceptResult methodInterceptResult; + + private Object[] allArguments; + private Class[] argumentTypes; + + @Mock + private Object service; + + private EnhancedInstance enhancedInstance = new EnhancedInstance() { + + private Object object; + + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + }; + + @Before + public void setUp() throws Exception { + interceptor = new HessianSkeletonInterceptor(); + + input = PowerMockito.mock(AbstractHessianInput.class); + out = PowerMockito.mock(AbstractHessianOutput.class); + + service = PowerMockito.mock(Object.class); + enhancedInstance.setSkyWalkingDynamicField(service.getClass()); + allArguments = new Object[] {service, input, out}; + argumentTypes = new Class[] {Object.class, AbstractHessianInput.class, AbstractHessianOutput.class}; + } + + @Test + public void testWithoutSerializedContextData() throws Throwable { + interceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertHessianSpan(spans.get(0)); + } + + @Test + public void testWithSerializedContextData() throws Throwable { +// when(request.getHeader(SW3CarrierItem.HEADER_NAME)).thenReturn("1.234.111|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*"); + + interceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + Assert.assertThat(spans.size(), is(1)); + + assertHessianSpan(spans.get(0)); + } + + @Test + public void testWithErrorException() throws Throwable { + interceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult); + interceptor.handleMethodException(enhancedInstance, null, allArguments, argumentTypes, new RuntimeException()); + interceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, null); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHessianSpan(spans.get(0)); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertThat(logDataEntities.size(), is(1)); + SpanAssert.assertException(logDataEntities.get(0), RuntimeException.class); + } + + private void assertHessianSpan(AbstractTracingSpan span) { + assertThat(span.getOperationName(), is(service.getClass().getName())); + assertComponent(span, ComponentsDefine.HESSIAN); + SpanAssert.assertTag(span, 0, service.getClass().getName()); + assertThat(span.isEntry(), is(true)); + SpanAssert.assertLayer(span, SpanLayer.RPC_FRAMEWORK); + } + +} + + diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 9a60778216a9..ce6124e0683f 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -75,6 +75,7 @@ vertx-plugins resteasy-plugin solrj-7.x-plugin + hessian-4.0.x-plugin pom diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index 3b5838b34e86..09ddafa5acbf 100644 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -90,6 +90,7 @@ property key | Description | Default | `plugin.mysql.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`| `plugin.solrj.trace_statement`|If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.|`false`| `plugin.solrj.trace_ops_params`|If true, trace all the operation parameters in Solr request, default is false.|`false`| +`plugin.hessian.use_url_as_operation_name`|If true, the request url name will be used as the operation name instead of the interface class name, default is false.|`false`| ## Optional Plugins Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositories. diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index 1f52dffdddaa..aa1121aaacb4 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -37,6 +37,7 @@ * [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.0.x * [SOFARPC](https://github.com/alipay/sofa-rpc) 5.4.0 + * [Hessian](http://hessian.caucho.com) 4.0.x * MQ * [RocketMQ](https://github.com/apache/rocketmq) 4.x * [Kafka](http://kafka.apache.org) 0.11.0.0 -> 1.0 diff --git a/oap-server/server-core/src/test/resources/component-libraries.yml b/oap-server/server-core/src/test/resources/component-libraries.yml index f8347e144286..a7d281e4cf19 100644 --- a/oap-server/server-core/src/test/resources/component-libraries.yml +++ b/oap-server/server-core/src/test/resources/component-libraries.yml @@ -207,6 +207,10 @@ Solr: SpringAsync: id: 65 languages: Java +Hessian: + id: 66 + languages: Java + # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/oap-server/server-starter/src/main/resources/component-libraries.yml b/oap-server/server-starter/src/main/resources/component-libraries.yml index e4200c26f013..35de86e347ae 100644 --- a/oap-server/server-starter/src/main/resources/component-libraries.yml +++ b/oap-server/server-starter/src/main/resources/component-libraries.yml @@ -225,7 +225,9 @@ Solr: SpringAsync: id: 65 languages: Java - +Hessian: + id: 66 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only