diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index 68be94eb2e34b2337777991caeb780f951ab0483..edada49a2b61937af79ae510f8838911aaca66fc 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -71,6 +71,7 @@ jobs: - xxl-job-2.x-scenario - thrift-scenario - dbcp-2.x-scenario + - jsonrpc4j-1.x-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index 1239be9fe35e0106257daecd78e5d636916d8435..d644bf881f77c2a6ea76ab7efe0cff9b3e64dc20 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Release Notes. * Add `trace_segment_ref_limit_per_span` configuration mechanism to avoid OOM. * Improve `GlobalIdGenerator` performance. * Add an agent plugin to support elasticsearch7. +* Add `jsonrpc4j` agent plugin. #### OAP-Backend * BugFix: filter invalid Envoy access logs whose socket address is empty. 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 efcb4a1f4df46a3324aefce50e64b025e54dcc46..d004d099a6721b66ec455d2fb02ec22c72afeaf1 100755 --- 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 @@ -194,4 +194,6 @@ public class ComponentsDefine { public static final OfficialComponent APACHE_CXF = new OfficialComponent(105, "Apache-CXF"); public static final OfficialComponent DOLPHIN_SCHEDULER = new OfficialComponent(106, "dolphinscheduler"); + + public static final OfficialComponent JSON_RPC = new OfficialComponent(107, "JsonRpc"); } diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a72fa840b38ac858f37f5fdc58336ba1dd5a12f3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/pom.xml @@ -0,0 +1,57 @@ + + + + + + apm-sdk-plugin + org.apache.skywalking + 8.6.0-SNAPSHOT + + 4.0.0 + + jsonrpc4j-1.x-plugin + + + 1.5.3 + 3.0.1 + + + jar + + + + + com.github.briandilley.jsonrpc4j + jsonrpc4j + ${jsonrpc4j.version} + provided + + + + javax.servlet + javax.servlet-api + ${javax-servlet-api.version} + provided + + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcBasicServerInvokeInterceptor.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcBasicServerInvokeInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..569dc01fede4aca2b33c917deaa9870f336d21ff --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcBasicServerInvokeInterceptor.java @@ -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. + * + */ + +package org.apache.skywalking.apm.plugin.jsonrpc4j; + +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; + +import java.lang.reflect.Method; + +public class JsonRpcBasicServerInvokeInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, MethodInterceptResult result) throws Throwable { + Method rpcMethod = (Method) objects[1]; + AbstractSpan span = ContextManager.activeSpan(); + JsonRpcConstants.JSON_RPC_METHOD_TAG.set(span, rpcMethod.getName()); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Throwable throwable) { + ContextManager.activeSpan().log(throwable); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcConstants.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..191c211dea5c2be91e8825b9addba172c0b5af7c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcConstants.java @@ -0,0 +1,25 @@ +/* + * 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.jsonrpc4j; + +import org.apache.skywalking.apm.agent.core.context.tag.StringTag; + +public class JsonRpcConstants { + public static final StringTag JSON_RPC_METHOD_TAG = new StringTag(1, "jsonrpc.method"); +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..8c64b43f7e81ebef152f3e89e8b7ea24af1432c9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientInterceptor.java @@ -0,0 +1,82 @@ +/* + * 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.jsonrpc4j; + +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.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; +import java.net.URL; + +@SuppressWarnings("unused") +public class JsonRpcHttpClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] objects) { + URL url = (URL) objects[1]; + JsonRpcPeerInfo clientDto = new JsonRpcPeerInfo(); + int port = url.getPort(); + if (port < 0) { + if (isHttps(url)) { + port = 443; + } else { + port = 80; + } + } + + clientDto.setPort(port); + clientDto.setServiceUrl(url); + objInst.setSkyWalkingDynamicField(clientDto); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, MethodInterceptResult result) throws Throwable { + JsonRpcPeerInfo clientDto = (JsonRpcPeerInfo) objInst.getSkyWalkingDynamicField(); + String methodName = objects[0].toString(); + String operationName = clientDto.getServiceUrl().getPath() + "." + methodName; + AbstractSpan span = ContextManager.createExitSpan(operationName, new ContextCarrier(), clientDto.getServiceUrl().getHost() + ":" + clientDto.getPort()); + span.setComponent(ComponentsDefine.JSON_RPC); + Tags.HTTP.METHOD.set(span, "POST"); + Tags.URL.set(span, clientDto.getServiceUrlString()); + SpanLayer.asRPCFramework(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Object o) throws Throwable { + ContextManager.stopSpan(); + return o; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Throwable throwable) { + ContextManager.activeSpan().log(throwable); + } + + private boolean isHttps(URL url) { + return url.getProtocol().equals("https"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientPrepareConnectionInterceptor.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientPrepareConnectionInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..b2d49f1d78b4993d6de6e3ec0e2cfb35bb57db60 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientPrepareConnectionInterceptor.java @@ -0,0 +1,62 @@ +/* + * 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.jsonrpc4j; + +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; + +import java.lang.reflect.Method; +import java.net.HttpURLConnection; + +@SuppressWarnings("unused") +public class JsonRpcHttpClientPrepareConnectionInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, MethodInterceptResult result) { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Object retObj) { + HttpURLConnection connection = (HttpURLConnection) retObj; + AbstractSpan span = ContextManager.activeSpan(); + if (span == null) { + return retObj; + } + + ContextCarrier carrier = new ContextCarrier(); + ContextManager.inject(carrier); + CarrierItem item = carrier.items(); + if (item.hasNext()) { + item = item.next(); + connection.setRequestProperty(item.getHeadKey(), item.getHeadValue()); + } + + return retObj; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Throwable throwable) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcPeerInfo.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcPeerInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..bb59a12fb2d349d98a1eff06f9141a5f66d58af5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcPeerInfo.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.jsonrpc4j; + +import java.net.URL; + +public class JsonRpcPeerInfo { + + private URL serviceUrl; + + private String serviceUrlString; + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + private int port; + + public URL getServiceUrl() { + return serviceUrl; + } + + public void setServiceUrl(URL serviceUrl) { + this.serviceUrl = serviceUrl; + this.serviceUrlString = serviceUrl.toString(); + } + + public String getServiceUrlString() { + return serviceUrlString; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonServiceExporterInterceptor.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonServiceExporterInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..ebd5add5d60d6bbaec7d0331d93fa6fe106ea749 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonServiceExporterInterceptor.java @@ -0,0 +1,82 @@ +/* + * 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.jsonrpc4j; + +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.agent.core.util.MethodUtil; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +public class JsonServiceExporterInterceptor implements InstanceMethodsAroundInterceptor { + + private static boolean IS_SERVLET_GET_STATUS_METHOD_EXIST; + private static final String SERVLET_RESPONSE_CLASS = "javax.servlet.http.HttpServletResponse"; + private static final String GET_STATUS_METHOD = "getStatus"; + + static { + IS_SERVLET_GET_STATUS_METHOD_EXIST = MethodUtil.isMethodExist(JsonServiceExporterInterceptor.class.getClassLoader(), SERVLET_RESPONSE_CLASS, GET_STATUS_METHOD); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, MethodInterceptResult result) throws Throwable { + + HttpServletRequest request = (HttpServletRequest) objects[0]; + ContextCarrier contextCarrier = new ContextCarrier(); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(request.getHeader(next.getHeadKey())); + } + + AbstractSpan span = ContextManager.createEntrySpan(request.getRequestURI(), contextCarrier); + Tags.HTTP.METHOD.set(span, request.getMethod()); + Tags.URL.set(span, request.getRequestURL().toString()); + span.setComponent(ComponentsDefine.JSON_RPC); + SpanLayer.asRPCFramework(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Object ret) throws Throwable { + + HttpServletResponse response = (HttpServletResponse) objects[1]; + AbstractSpan span = ContextManager.activeSpan(); + if (IS_SERVLET_GET_STATUS_METHOD_EXIST) { + Tags.STATUS_CODE.set(span, String.valueOf(response.getStatus())); + } + + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] objects, Class[] classes, Throwable throwable) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcBasicServerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcBasicServerInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..606237e81952cdf96e94cd55c0a15e61be4e0ca5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcBasicServerInstrumentation.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jsonrpc4j.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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class JsonRpcBasicServerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.googlecode.jsonrpc4j.JsonRpcBasicServer"; + public static final String INVOKE_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jsonrpc4j.JsonRpcBasicServerInvokeInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("invoke"); + } + + @Override + public String getMethodsInterceptor() { + return INVOKE_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcHttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcHttpClientInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..212e6b8971deee81d25d06403de7aef7e9f0a1b7 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonRpcHttpClientInstrumentation.java @@ -0,0 +1,116 @@ +/* + * 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.jsonrpc4j.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import java.net.URL; + +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; + +@SuppressWarnings("unused") +public class JsonRpcHttpClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.googlecode.jsonrpc4j.JsonRpcHttpClient"; + + public static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jsonrpc4j.JsonRpcHttpClientInterceptor"; + + public static final String PER_CONNECTION_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jsonrpc4j.JsonRpcHttpClientPrepareConnectionInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return ElementMatchers.takesArguments(6).and(ElementMatchers.takesArgument(1, URL.class)); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPTOR_CLASS; + } + }, + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return ElementMatchers.takesArguments(5).and(ElementMatchers.takesArgument(1, URL.class)); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPTOR_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + + return ElementMatchers.named("invoke").and(ElementMatchers.takesArguments(4)) + .and(takesArgumentWithType(2, "java.lang.reflect.Type")); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return ElementMatchers.named("prepareConnection"); + } + + @Override + public String getMethodsInterceptor() { + return PER_CONNECTION_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonServiceExporterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonServiceExporterInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..4cee21b6ea900fc0d2761ee69598f734c9b710d4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jsonrpc4j/define/JsonServiceExporterInstrumentation.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jsonrpc4j.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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class JsonServiceExporterInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.googlecode.jsonrpc4j.spring.JsonServiceExporter"; + public static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jsonrpc4j.JsonServiceExporterInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("handleRequest"); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..5fb503472ad2b749e9c590d5d39200b3750645ea --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,19 @@ +# 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. + +jsonrpc4j=org.apache.skywalking.apm.plugin.jsonrpc4j.define.JsonRpcHttpClientInstrumentation +jsonrpc4j=org.apache.skywalking.apm.plugin.jsonrpc4j.define.JsonRpcBasicServerInstrumentation +jsonrpc4j=org.apache.skywalking.apm.plugin.jsonrpc4j.define.JsonServiceExporterInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientTests.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientTests.java new file mode 100644 index 0000000000000000000000000000000000000000..9296391c28344883da68d8cfe59eb62d9c2777d9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcHttpClientTests.java @@ -0,0 +1,121 @@ +/* + * 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.jsonrpc4j; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.googlecode.jsonrpc4j.JsonRpcHttpClient; +import org.apache.skywalking.apm.agent.core.boot.OverrideImplementor; +import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.TagValuePair; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +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.TracingSegmentRunner; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class JsonRpcHttpClientTests { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private MockJsonRpcHttpClient enhancedInstance; + private ObjectMapper objectMapper = new ObjectMapper(); + + private JsonRpcHttpClientInterceptor httpClientInterceptor; + private JsonRpcHttpClientPrepareConnectionInterceptor jsonRpcHttpClientPrepareConnectionInterceptor; + private URL url; + private HttpURLConnection httpURLConnection; + + @Before + public void setUp() throws Exception { + url = new URL("HTTP://localhost:8080/test"); + enhancedInstance = new MockJsonRpcHttpClient(objectMapper, url, new HashMap<>(), false, false); + httpClientInterceptor = new JsonRpcHttpClientInterceptor(); + jsonRpcHttpClientPrepareConnectionInterceptor = new JsonRpcHttpClientPrepareConnectionInterceptor(); + httpURLConnection = (HttpURLConnection) url.openConnection(); + } + + @Test + public void testMethodAround() throws Throwable { + Object[] objects = new Object[]{"OperationKey", url}; + httpClientInterceptor.onConstruct(enhancedInstance, objects); + httpClientInterceptor.beforeMethod(enhancedInstance, null, objects, null, null); + jsonRpcHttpClientPrepareConnectionInterceptor.afterMethod(enhancedInstance, null, null, null, httpURLConnection); + httpClientInterceptor.afterMethod(enhancedInstance, null, objects, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + Assert.assertEquals(1, SegmentHelper.getSpans(traceSegment).size()); + AbstractTracingSpan finishedSpan = SegmentHelper.getSpans(traceSegment).get(0); + + List tags = SpanHelper.getTags(finishedSpan); + assertThat(tags.size(), is(2)); + assertThat(tags.get(0).getValue(), is("POST")); + assertThat(tags.get(1).getValue(), is(url.toString())); + Assert.assertEquals(false, SpanHelper.getErrorOccurred(finishedSpan)); + } + + private class MockJsonRpcHttpClient extends JsonRpcHttpClient implements EnhancedInstance { + + private Object object; + + public MockJsonRpcHttpClient(ObjectMapper mapper, URL serviceUrl, Map headers, boolean gzipRequests, boolean acceptGzipResponses) { + super(mapper, serviceUrl, headers, gzipRequests, acceptGzipResponses); + } + + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + object = value; + } + } + + @OverrideImplementor(ContextManagerExtendService.class) + public static class ContextManagerExtendOverrideService extends ContextManagerExtendService { + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcServerTests.java b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcServerTests.java new file mode 100644 index 0000000000000000000000000000000000000000..e50b7d389ba82fa3def08ded5eda2638ad5d7508 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jsonrpc4j/JsonRpcServerTests.java @@ -0,0 +1,136 @@ +/* + * 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.jsonrpc4j; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.googlecode.jsonrpc4j.JsonRpcBasicServer; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.TagValuePair; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +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.TracingSegmentRunner; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.List; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class JsonRpcServerTests { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private MockJsonRpcBasicServer mockJsonRpcBasicServer; + + private MockJsonServiceExporterInterceptor mockJsonServiceExporterInterceptor; + + private JsonServiceExporterInterceptor jsonServiceExporterInterceptor; + + private JsonRpcBasicServerInvokeInterceptor jsonRpcBasicServerInvokeInterceptor; + + private ObjectMapper objectMapper = new ObjectMapper(); + + private HttpServletRequest httpServletRequest; + + private HttpServletResponse httpServletResponse; + + @Before + public void setUp() throws Exception { + httpServletRequest = mock(HttpServletRequest.class); + httpServletResponse = mock(HttpServletResponse.class); + when(httpServletRequest.getRequestURI()).thenReturn("/test"); + when(httpServletRequest.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080")); + when(httpServletResponse.getStatus()).thenReturn(200); + httpServletResponse = mock(HttpServletResponse.class); + jsonRpcBasicServerInvokeInterceptor = new JsonRpcBasicServerInvokeInterceptor(); + jsonServiceExporterInterceptor = new JsonServiceExporterInterceptor(); + mockJsonRpcBasicServer = new MockJsonRpcBasicServer(objectMapper, null); + mockJsonServiceExporterInterceptor = new MockJsonServiceExporterInterceptor(); + } + + @Test + public void testJsonRpcServerMethodAround() throws Throwable { + Object[] objects = new Object[]{httpServletRequest}; + jsonServiceExporterInterceptor.beforeMethod(mockJsonServiceExporterInterceptor, null, objects, null, null); + objects = new Object[]{null, JsonRpcServerTests.class.getMethod("testJsonRpcServerMethodAround")}; + jsonRpcBasicServerInvokeInterceptor.beforeMethod(mockJsonRpcBasicServer, null, objects, null, null); + objects = new Object[]{null, httpServletResponse}; + jsonServiceExporterInterceptor.afterMethod(mockJsonServiceExporterInterceptor, null, objects, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + Assert.assertEquals(1, SegmentHelper.getSpans(traceSegment).size()); + AbstractTracingSpan finishedSpan = SegmentHelper.getSpans(traceSegment).get(0); + + List tags = SpanHelper.getTags(finishedSpan); + assertThat(tags.size(), is(4)); + Assert.assertEquals(false, SpanHelper.getErrorOccurred(finishedSpan)); + } + + private class MockJsonRpcBasicServer extends JsonRpcBasicServer implements EnhancedInstance { + + public MockJsonRpcBasicServer(ObjectMapper mapper, Object handler) { + super(mapper, handler); + } + + @Override + public Object getSkyWalkingDynamicField() { + return null; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + } + } + + private class MockJsonServiceExporterInterceptor extends JsonServiceExporterInterceptor implements EnhancedInstance { + + @Override + public Object getSkyWalkingDynamicField() { + return null; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 8bbca4a930d6f0f2230b272f6eee0fdc1961cf61..57464edad0c1c67460c83f7e31be0719d904e1a4 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -109,6 +109,7 @@ mssql-jtds-1.x-plugin mssql-jdbc-plugin cxf-3.x-plugin + jsonrpc4j-1.x-plugin pom diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index 07ee1511e13c234f84001a8373fe59e481c1b41a..c082e232bcf4c67c88e1230cfa971df6f207d896 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -114,3 +114,4 @@ - mssql-jtds-1.x - mssql-jdbc - apache-cxf-3.x +- jsonrpc4j diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml index 892a18a88bc82a122789ec7a870e08c37ad7d42b..7bfaaf3b3d0d71caf005d2e7b79ced4fb9358007 100755 --- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml +++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml @@ -350,6 +350,9 @@ Apache-CXF: dolphinscheduler: id: 106 languages: Java +JsonRpc: + id: 107 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml index a6939e6aaacaf364e41a09a4a9fee06701b6ff78..898b7feed2c66392fd0c3db3ae0aa5d04c01e565 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml @@ -13,6 +13,7 @@ # 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-2.7.x-scenario segmentSize: ge 3 diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/bin/startup.sh b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/bin/startup.sh new file mode 100644 index 0000000000000000000000000000000000000000..d7548dd340c3be3564630b1f0db755705693fa5a --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/jsonrpc4j-1.x-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/config/expectedData.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3d4a45238138b64e14abf349542d88815cc9ddca --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/config/expectedData.yaml @@ -0,0 +1,91 @@ +# 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: jsonrpc4j-1.x-scenario + segmentSize: ge 2 + segments: + - segmentId: not null + spans: + - operationName: /jsonrpc4j-1.x-scenario/path/to/demo-service.sayHello + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 107 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - { key: http.method, value: POST } + - { + key: url, + value: 'http://localhost:8080/jsonrpc4j-1.x-scenario/path/to/demo-service', + } + - operationName: /jsonrpc4j-1.x-scenario/case/json-rpc + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - { + key: url, + value: 'http://localhost:8080/jsonrpc4j-1.x-scenario/case/json-rpc', + } + - { key: http.method, value: GET } + - segmentId: not null + spans: + - operationName: /jsonrpc4j-1.x-scenario/path/to/demo-service + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 107 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - { key: http.method, value: POST } + - { + key: url, + value: 'http://localhost:8080/jsonrpc4j-1.x-scenario/path/to/demo-service', + } + - { key: jsonrpc.method, value: sayHello } + - { key: status_code, value: '200' } + refs: + - { + parentEndpoint: /jsonrpc4j-1.x-scenario/case/json-rpc, + networkAddress: 'localhost:8080', + refType: CrossProcess, + parentSpanId: 1, + parentTraceSegmentId: not null, + parentServiceInstance: not null, + parentService: jsonrpc4j-1.x-scenario, + traceId: not null, + } diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/configuration.yml b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/configuration.yml new file mode 100644 index 0000000000000000000000000000000000000000..33541449b193cc881bf4d3e09a3a3e33bbee2e7f --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/configuration.yml @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: jvm +entryService: http://localhost:8080/jsonrpc4j-1.x-scenario/case/json-rpc +healthCheck: http://localhost:8080/jsonrpc4j-1.x-scenario/case/healthCheck +startScript: ./bin/startup.sh diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/pom.xml b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4579d75f1ef936fc2f7ab3e39a3ab20643fb5aae --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/pom.xml @@ -0,0 +1,119 @@ + + + + + 4.0.0 + + org.apache.skywalking + jsonrpc4j-1.x-scenario + 5.0.0 + jar + + + 8 + 8 + UTF-8 + 1.8 + 2.1.6.RELEASE + 1.5.3 + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.github.briandilley.jsonrpc4j + jsonrpc4j + ${jsonrpc.version} + + + + + jsonrpc4j-1.x-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + + + + spring-snapshots + https://repo.spring.io/snapshot + + + spring-milestones + https://repo.spring.io/milestone + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000000000000000000000000000000000..5cbaa119042cd8f5113867cefbd030cf5e726340 --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ./target/jsonrpc4j-1.x-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/Application.java b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..d9955df121707195c7557ffc4ec98385a8b61afd --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/Application.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.jsonrpc4j; + +import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public AutoJsonRpcServiceImplExporter serviceImplExporter() { + return new AutoJsonRpcServiceImplExporter(); + } +} diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/controller/CaseController.java b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/controller/CaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..ed14c9b01213943b0dd40c11f793ac2e4afdebaf --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/controller/CaseController.java @@ -0,0 +1,52 @@ +/* + * 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.jsonrpc4j.controller; + +import com.googlecode.jsonrpc4j.JsonRpcHttpClient; +import com.googlecode.jsonrpc4j.ProxyUtil; +import org.apache.skywalking.apm.testcase.jsonrpc4j.services.DemoService; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.net.MalformedURLException; +import java.net.URL; + +@RestController +@RequestMapping("/case") +public class CaseController { + + private static final String SUCCESS = "Success"; + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } + + @RequestMapping("/json-rpc") + @ResponseBody + public String jsonRpc() throws MalformedURLException { + JsonRpcHttpClient client = new JsonRpcHttpClient( + new URL("http://localhost:8080/jsonrpc4j-1.x-scenario/path/to/demo-service")); + DemoService demoService = ProxyUtil.createClientProxy(getClass().getClassLoader(), DemoService.class, client); + demoService.sayHello(); + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoService.java b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoService.java new file mode 100644 index 0000000000000000000000000000000000000000..05378fc390b00a1a151042b4d6e3cf6b110a9047 --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoService.java @@ -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.testcase.jsonrpc4j.services; + +import com.googlecode.jsonrpc4j.JsonRpcService; + +@JsonRpcService("/path/to/demo-service") +public interface DemoService { + + String sayHello(); +} diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoServiceImp.java b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoServiceImp.java new file mode 100644 index 0000000000000000000000000000000000000000..5323cc2e81f145bf20a0beed762f7b244559eea1 --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jsonrpc4j/services/DemoServiceImp.java @@ -0,0 +1,32 @@ +/* + * 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.jsonrpc4j.services; + +import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl; +import org.springframework.stereotype.Service; + +@AutoJsonRpcServiceImpl +@Service +public class DemoServiceImp implements DemoService { + + @Override + public String sayHello() { + return "hello"; + } +} diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/resources/application.yml b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..b756cca3f5331da3930fd034c74e37cc3921953d --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/src/main/resources/application.yml @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +server: + port: 8080 + servlet: + context-path: /jsonrpc4j-1.x-scenario diff --git a/test/plugin/scenarios/jsonrpc4j-1.x-scenario/support-version.list b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/support-version.list new file mode 100644 index 0000000000000000000000000000000000000000..b54a46899ff8da3e74807fcbaed17cc894f97668 --- /dev/null +++ b/test/plugin/scenarios/jsonrpc4j-1.x-scenario/support-version.list @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 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. + +1.6 +1.5.3 +1.4.6 +1.3.3