diff --git a/.github/workflows/plugins-test.0.yaml b/.github/workflows/plugins-test.0.yaml index d21190329..24fba53bf 100644 --- a/.github/workflows/plugins-test.0.yaml +++ b/.github/workflows/plugins-test.0.yaml @@ -84,6 +84,7 @@ jobs: - elasticjob-3.x-scenario - springmvc-reactive-scenario - springmvc-reactive-devtools-scenario + - fastjson-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index 2ab1ca89c..a7197926f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Release Notes. * Add benchmark result for `exception-ignore` plugin and polish plugin guide. * Provide Alibaba Druid database connection pool plugin. * Provide HikariCP database connection pool plugin. +* Provide Alibaba Fastjson parser/generator plugin. * Fix a tracing context leak of SpringMVC plugin, when an internal exception throws due to response can't be found. * Make GRPC log reporter sharing GRPC channel with other reporters of agent. Remove config items of `agent.conf`, `plugin.toolkit.log.grpc.reporter.server_host`, `plugin.toolkit.log.grpc.reporter.server_port`, and `plugin.toolkit.log.grpc.reporter.upstream_timeout`. rename `plugin.toolkit.log.grpc.reporter.max_message_size` to `log.max_message_size`. 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 cc9ebd3e9..8f8796117 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 @@ -211,4 +211,6 @@ public class ComponentsDefine { public static final OfficialComponent HIKARI_CP = new OfficialComponent(116, "HikariCP"); + public static final OfficialComponent FASTJSON = new OfficialComponent(117, "Fastjson"); + } diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/pom.xml b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/pom.xml new file mode 100644 index 000000000..c6b56efdd --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/pom.xml @@ -0,0 +1,45 @@ + + + + + 4.0.0 + + org.apache.skywalking + optional-plugins + 8.8.0-SNAPSHOT + + + apm-fastjson-1.x-plugin + fastjson-1.2.x-plugin + jar + + + UTF-8 + 1.2.62 + + + + + com.alibaba + fastjson + ${fastjson.version} + provided + + + diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptor.java new file mode 100644 index 000000000..ea7f3768b --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptor.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ParseArrayInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_FROM_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_FROM_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + + if (allArguments[0] instanceof String) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((String) allArguments[0]).length())); + } + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptor.java new file mode 100644 index 000000000..858a9cd5e --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptor.java @@ -0,0 +1,58 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ParseInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_FROM_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_FROM_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + + if (allArguments[0] instanceof String) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((String) allArguments[0]).length())); + } else if (allArguments[0] instanceof byte[]) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((byte[]) allArguments[0]).length)); + } + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptor.java new file mode 100644 index 000000000..2fa751d9b --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptor.java @@ -0,0 +1,71 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.io.InputStream; +import java.lang.reflect.Method; + +public class ParseObjectInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_FROM_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_FROM_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + + if (allArguments[0] instanceof String) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((String) allArguments[0]).length())); + } else if (allArguments[0] instanceof byte[]) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((byte[]) allArguments[0]).length)); + } else if (allArguments[0] instanceof char[]) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((char[]) allArguments[0]).length)); + } else if (allArguments[0] instanceof InputStream) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(inputStreamAvailable(allArguments[0]))); + } + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } + + private int inputStreamAvailable(Object in) { + try { + return ((InputStream) in).available(); + } catch (Throwable e) { + throw new RuntimeException(e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptor.java new file mode 100644 index 000000000..c26b2fa24 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptor.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ToJavaObjectInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_TO_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_OBJECT = "object"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_TO_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + + if (allArguments.length > 1 && allArguments[1] instanceof Class) { + span.tag(Tags.ofKey(SPAN_TAG_KEY_OBJECT), ((Class) allArguments[1]).getTypeName()); + } + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptor.java new file mode 100644 index 000000000..c495a8151 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptor.java @@ -0,0 +1,59 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ToJsonBytesInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_TO_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_TO_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + + if (!ContextManager.isActive()) { + return ret; + } + if (ret instanceof byte[]) { + ContextManager.activeSpan().tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((byte[]) ret).length)); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptor.java new file mode 100644 index 000000000..35acaa314 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptor.java @@ -0,0 +1,59 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ToJsonInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_TO_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_OBJECT = "object"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_TO_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + + if (!ContextManager.isActive()) { + return ret; + } + if (ret != null) { + ContextManager.activeSpan().tag(Tags.ofKey(SPAN_TAG_KEY_OBJECT), String.valueOf(ret.getClass().getTypeName())); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptor.java new file mode 100644 index 000000000..b916ae8d5 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptor.java @@ -0,0 +1,59 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class ToJsonStringInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_TO_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_TO_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + + if (!ContextManager.isActive()) { + return ret; + } + if (ret instanceof String) { + ContextManager.activeSpan().tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((String) ret).length())); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptor.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptor.java new file mode 100644 index 000000000..2bd584895 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptor.java @@ -0,0 +1,59 @@ +/* + * 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.fastjson; + +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.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; + +public class WriteJsonStringInterceptor implements StaticMethodsAroundInterceptor { + + public static final String OPERATION_NAME_TO_JSON = "Fastjson/"; + public static final String SPAN_TAG_KEY_LENGTH = "length"; + + @Override + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { + + AbstractSpan span = ContextManager.createLocalSpan(OPERATION_NAME_TO_JSON + method.getName()); + span.setComponent(ComponentsDefine.FASTJSON); + } + + @Override + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { + + if (!ContextManager.isActive()) { + return ret; + } + if (ret instanceof Integer) { + ContextManager.activeSpan().tag(Tags.ofKey(SPAN_TAG_KEY_LENGTH), Integer.toString(((Integer) ret).intValue())); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/define/FastjsonInstrumentation.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/define/FastjsonInstrumentation.java new file mode 100644 index 000000000..00d23c071 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/fastjson/define/FastjsonInstrumentation.java @@ -0,0 +1,93 @@ +/* + * 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.fastjson.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * Fastjson A fast JSON parser/generator for Java from Alibaba inc. + *

+ * JSON provides a "one stop" solution for json parser/generator solution + * basic requirements. + *

+ * json2x: JSON#parse()/JSON#parseArray()/JSON#parseObject()/JSON#toJavaObject() + * x2json: JSON#toJSON()/JSON#toJSONBytes()/JSON#toJSONString()/JSON#writeJSONString() + */ +public class FastjsonInstrumentation extends ClassStaticMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.alibaba.fastjson.JSON"; + + private static final Map ENHANCE_METHODS = new HashMap() { + { + put("parseArray", "org.apache.skywalking.apm.plugin.fastjson.ParseArrayInterceptor"); + put("parse", "org.apache.skywalking.apm.plugin.fastjson.ParseInterceptor"); + put("parseObject", "org.apache.skywalking.apm.plugin.fastjson.ParseObjectInterceptor"); + put("toJavaObject", "org.apache.skywalking.apm.plugin.fastjson.ToJavaObjectInterceptor"); + put("toJSONBytes", "org.apache.skywalking.apm.plugin.fastjson.ToJsonBytesInterceptor"); + put("toJSON", "org.apache.skywalking.apm.plugin.fastjson.ToJsonInterceptor"); + put("toJSONString", "org.apache.skywalking.apm.plugin.fastjson.ToJsonStringInterceptor"); + put("writeJSONString", "org.apache.skywalking.apm.plugin.fastjson.WriteJsonStringInterceptor"); + } + }; + + @Override + public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + + final List points = new ArrayList(ENHANCE_METHODS.size()); + + for (Map.Entry entry : ENHANCE_METHODS.entrySet()) { + final StaticMethodsInterceptPoint point = new StaticMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(entry.getKey()); + } + + @Override + public String getMethodsInterceptor() { + return entry.getValue(); + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }; + points.add(point); + } + + return points.toArray(new StaticMethodsInterceptPoint[points.size()]); + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..69b4fd0da --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +fastjson-1.2.x=org.apache.skywalking.apm.plugin.fastjson.define.FastjsonInstrumentation \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptorTest.java new file mode 100644 index 000000000..783822a6a --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseArrayInterceptorTest.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.fastjson; + +import com.alibaba.fastjson.JSON; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ParseArrayInterceptorTest { + + private ParseArrayInterceptor parseArrayInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Class[] argumentType; + + @Before + public void setUp() { + parseArrayInterceptor = new ParseArrayInterceptor(); + arguments = new Object[]{"[{\"key\": 123}]"}; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("parseArray", String.class); + parseArrayInterceptor.beforeMethod(null, method, arguments, null, null); + parseArrayInterceptor.afterMethod(null, method, arguments, null, null); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptorTest.java new file mode 100644 index 000000000..dc924bbaf --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseInterceptorTest.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.fastjson; + +import com.alibaba.fastjson.JSON; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ParseInterceptorTest { + + private ParseInterceptor parseInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Class[] argumentType; + + @Before + public void setUp() { + parseInterceptor = new ParseInterceptor(); + arguments = new Object[]{"{\"key\": 123}"}; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("parse", String.class); + parseInterceptor.beforeMethod(null, method, arguments, null, null); + parseInterceptor.afterMethod(null, method, arguments, null, null); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptorTest.java new file mode 100644 index 000000000..a5ab570e0 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ParseObjectInterceptorTest.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.fastjson; + +import com.alibaba.fastjson.JSON; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ParseObjectInterceptorTest { + + private ParseObjectInterceptor parseObjectInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Class[] argumentType; + + @Before + public void setUp() { + parseObjectInterceptor = new ParseObjectInterceptor(); + arguments = new Object[]{"{\"key\": 123}"}; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("parseObject", String.class); + parseObjectInterceptor.beforeMethod(null, method, arguments, null, null); + parseObjectInterceptor.afterMethod(null, method, arguments, null, null); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptorTest.java new file mode 100644 index 000000000..16b547ce9 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJavaObjectInterceptorTest.java @@ -0,0 +1,85 @@ +/* + * 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.fastjson; + +import com.alibaba.fastjson.JSON; +import lombok.Data; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ToJavaObjectInterceptorTest { + + private ToJavaObjectInterceptor toJavaObjectInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Class[] argumentType; + + @Data + private class TestBean { + private int key; + } + + @Before + public void setUp() { + toJavaObjectInterceptor = new ToJavaObjectInterceptor(); + arguments = new Object[]{JSON.parseObject("{\"key\": 123}"), TestBean.class}; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("toJavaObject", JSON.class, Class.class); + toJavaObjectInterceptor.beforeMethod(null, method, arguments, null, null); + toJavaObjectInterceptor.afterMethod(null, method, arguments, null, null); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptorTest.java new file mode 100644 index 000000000..375b2fb0d --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonBytesInterceptorTest.java @@ -0,0 +1,89 @@ +/* + * 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.fastjson; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.Data; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ToJsonBytesInterceptorTest { + + private ToJsonBytesInterceptor toJsonBytesInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Object result; + + private Class[] argumentType; + + @Data + private class TestBean { + private int key; + } + + @Before + public void setUp() { + toJsonBytesInterceptor = new ToJsonBytesInterceptor(); + arguments = new Object[]{new TestBean(), new SerializerFeature[0]}; + result = new byte[0]; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("toJSONBytes", Object.class, SerializerFeature[].class); + toJsonBytesInterceptor.beforeMethod(null, method, arguments, null, null); + toJsonBytesInterceptor.afterMethod(null, method, arguments, null, result); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptorTest.java new file mode 100644 index 000000000..bab818138 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonInterceptorTest.java @@ -0,0 +1,89 @@ +/* + * 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.fastjson; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ToJsonInterceptorTest { + + private ToJsonInterceptor toJsonInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Object result; + + private Class[] argumentType; + + @Data + private class TestBean { + private int key; + } + + @Before + public void setUp() { + toJsonInterceptor = new ToJsonInterceptor(); + arguments = new Object[]{new TestBean()}; + result = new JSONObject(); + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("toJSON", Object.class); + toJsonInterceptor.beforeMethod(null, method, arguments, null, null); + toJsonInterceptor.afterMethod(null, method, arguments, null, result); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptorTest.java new file mode 100644 index 000000000..3c10a50f9 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/ToJsonStringInterceptorTest.java @@ -0,0 +1,89 @@ +/* + * 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.fastjson; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +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.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.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.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class ToJsonStringInterceptorTest { + + private ToJsonStringInterceptor toJsonStringInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private Object result; + + private Class[] argumentType; + + @Data + private class TestBean { + private int key; + } + + @Before + public void setUp() { + toJsonStringInterceptor = new ToJsonStringInterceptor(); + arguments = new Object[]{new TestBean()}; + result = new JSONObject().toJSONString(); + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("toJSONString", Object.class); + toJsonStringInterceptor.beforeMethod(null, method, arguments, null, null); + toJsonStringInterceptor.afterMethod(null, method, arguments, null, result); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptorTest.java b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptorTest.java new file mode 100644 index 000000000..5ebf84228 --- /dev/null +++ b/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/fastjson/WriteJsonStringInterceptorTest.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.fastjson; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.Data; +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.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.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.io.OutputStream; +import java.lang.reflect.Method; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class WriteJsonStringInterceptorTest { + + private WriteJsonStringInterceptor writeJsonStringInterceptor; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private Object[] arguments; + + private int result; + + private Class[] argumentType; + + @Data + private class TestBean { + private int key; + } + + @Before + public void setUp() { + writeJsonStringInterceptor = new WriteJsonStringInterceptor(); + arguments = new Object[]{null, new TestBean(), new SerializerFeature[0]}; + result = 1; + } + + @Test + public void testSendMessage() throws Throwable { + + Method method = JSON.class.getMethod("writeJSONString", OutputStream.class, Object.class, SerializerFeature[].class); + writeJsonStringInterceptor.beforeMethod(null, method, arguments, null, null); + writeJsonStringInterceptor.afterMethod(null, method, arguments, null, result); + + List traceSegmentList = segmentStorage.getTraceSegments(); + assertThat(traceSegmentList.size(), is(1)); + + TraceSegment segment = traceSegmentList.get(0); + List spans = SegmentHelper.getSpans(segment); + assertThat(spans.size(), is(1)); + } + +} \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/pom.xml b/apm-sniffer/optional-plugins/pom.xml index aaa2fe83b..8bef01907 100644 --- a/apm-sniffer/optional-plugins/pom.xml +++ b/apm-sniffer/optional-plugins/pom.xml @@ -53,6 +53,7 @@ sentinel-1.x-plugin ehcache-2.x-plugin guava-cache-plugin + fastjson-1.2.x-plugin 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 b4a67d461..44ad25aed 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -18,6 +18,7 @@ - elasticsearch-5.x - elasticsearch-6.x - elasticsearch-7.x +- fastjson-1.2.x - feign-default-http-9.x - feign-pathvar-9.x - finagle diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index d43224030..8f60dcba2 100755 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -87,6 +87,7 @@ Now, we have the following known optional plugins. * Plugin of sentinel-1.x in the optional plugin folder. The reason for being an optional plugin is, the sentinel plugin generates a large number of local spans, which have a potential performance impact. * Plugin of ehcache-2.x in the optional plugin folder. The reason for being an optional plugin is, this plugin enhanced cache framework, generates large number of local spans, which have a potential performance impact. * Plugin of guava-cache in the optional plugin folder. The reason for being an optional plugin is, this plugin enhanced cache framework, generates large number of local spans, which have a potential performance impact. +* Plugin of fastjson serialization lib in optional plugin folder. ## Bootstrap class plugins All bootstrap plugins are optional, due to unexpected risk. Bootstrap plugins are provided in `bootstrap-plugins` folder. 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 2bf88984d..c7bf9f9d4 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -106,6 +106,7 @@ metrics based on the tracing data. * [Canal: Alibaba mysql database binlog incremental subscription & consumer components](https://github.com/alibaba/canal) 1.0.25 -> 1.1.2 * JSON * [GSON](https://github.com/google/gson) 2.8.x (Optional²) + * [Fastjson](https://github.com/alibaba/fastjson) 1.2.x (Optional²) * Vert.x Ecosystem * Vert.x Eventbus 3.2+ * Vert.x Web 3.x diff --git a/test/plugin/scenarios/fastjson-scenario/bin/startup.sh b/test/plugin/scenarios/fastjson-scenario/bin/startup.sh new file mode 100644 index 000000000..3f83aafab --- /dev/null +++ b/test/plugin/scenarios/fastjson-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/fastjson-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/fastjson-scenario/config/expectedData.yaml b/test/plugin/scenarios/fastjson-scenario/config/expectedData.yaml new file mode 100644 index 000000000..d535a587e --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/config/expectedData.yaml @@ -0,0 +1,130 @@ +# 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: fastjson-scenario + segmentSize: ge 2 + segments: + - segmentId: nq 0 + spans: + - operationName: Fastjson/parse + parentSpanId: 0 + spanId: 1 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '11'} + - operationName: Fastjson/parseArray + parentSpanId: 0 + spanId: 2 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '25'} + - operationName: Fastjson/parseObject + parentSpanId: 0 + spanId: 3 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '24'} + - operationName: Fastjson/toJavaObject + parentSpanId: 0 + spanId: 4 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: object, value: org.apache.skywalking.apm.testcase.fastjson.entity.CaseEntity} + - operationName: Fastjson/toJSON + parentSpanId: 0 + spanId: 5 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: object, value: com.alibaba.fastjson.JSONObject} + - operationName: Fastjson/toJSONBytes + parentSpanId: 0 + spanId: 6 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '24'} + - operationName: Fastjson/toJSONString + parentSpanId: 0 + spanId: 7 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '24'} + - operationName: Fastjson/writeJSONString + parentSpanId: 0 + spanId: 8 + spanLayer: Unknown + startTime: nq 0 + endTime: nq 0 + componentId: 117 + isError: false + spanType: Local + peer: '' + tags: + - {key: length, value: '24'} + - operationName: /fastjson-scenario/case/fastjson-scenario + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + tags: + - {key: url, value: 'http://localhost:8080/fastjson-scenario/case/fastjson-scenario'} + - {key: http.method, value: GET} diff --git a/test/plugin/scenarios/fastjson-scenario/configuration.yml b/test/plugin/scenarios/fastjson-scenario/configuration.yml new file mode 100644 index 000000000..f83bb98b1 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/configuration.yml @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: jvm +entryService: http://localhost:8080/fastjson-scenario/case/fastjson-scenario +healthCheck: http://localhost:8080/fastjson-scenario/case/healthCheck +startScript: ./bin/startup.sh +runningMode: with_optional +withPlugins: apm-fastjson-1.x-plugin-*.jar +environment: +dependencies: diff --git a/test/plugin/scenarios/fastjson-scenario/pom.xml b/test/plugin/scenarios/fastjson-scenario/pom.xml new file mode 100644 index 000000000..5a2330228 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/pom.xml @@ -0,0 +1,119 @@ + + + + + org.apache.skywalking.apm.testcase + fastjson-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 2.1.6.RELEASE + 1.2.62 + ${test.framework.version} + 2.6.2 + 4.3.8.RELEASE + + + skywalking-fastjson-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot-version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + com.alibaba + fastjson + ${test.framework.version} + + + + + fastjson-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/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/fastjson-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..eb282b476 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/fastjson-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/Application.java b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/Application.java new file mode 100644 index 000000000..3f2abf32a --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/Application.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.fastjson; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/controller/CaseController.java b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/controller/CaseController.java new file mode 100644 index 000000000..a395aaf00 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/controller/CaseController.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.testcase.fastjson.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.skywalking.apm.testcase.fastjson.service.CaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; + +@RestController +@RequestMapping("/case") +public class CaseController { + + @Autowired + CaseService caseService; + + private static final Logger LOGGER = LogManager.getLogger(CaseController.class); + + private static final String SUCCESS = "Success"; + + @RequestMapping("/fastjson-scenario") + @ResponseBody + public String testcase() throws IOException { + try { + caseService.parseCase(); + caseService.parseArrayCase(); + caseService.parseObjectCase(); + caseService.toJavaObjectCase(); + caseService.toJsonCase(); + caseService.toJsonBytesCase(); + caseService.toJsonStringCase(); + caseService.writeJsonStringCase(); + } catch (IOException e) { + LOGGER.error("Failed to parse json.", e); + throw e; + } + return SUCCESS; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } + +} diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/entity/CaseEntity.java b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/entity/CaseEntity.java new file mode 100644 index 000000000..4fe4a5920 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/entity/CaseEntity.java @@ -0,0 +1,41 @@ +/* + * 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.fastjson.entity; + +public class CaseEntity { + + private int key; + private String msg; + + public int getKey() { + return key; + } + + public void setKey(int key) { + this.key = key; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/service/CaseService.java b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/service/CaseService.java new file mode 100644 index 000000000..35367e982 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/java/org/apache/skywalking/apm/testcase/fastjson/service/CaseService.java @@ -0,0 +1,96 @@ +/* + * 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.fastjson.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.util.IOUtils; +import org.apache.skywalking.apm.testcase.fastjson.entity.CaseEntity; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +@Service +public class CaseService { + + public void parseCase() { + String jsonStr = "{\"key\":123}"; + Object jsonObj = JSON.parse(jsonStr, ParserConfig.getGlobalInstance(), JSON.DEFAULT_GENERATE_FEATURE); + assert jsonObj instanceof JSONObject; + } + + public void parseArrayCase() { + String jsonStr = "[{\"key\":123},{\"key\":456}]"; + Object jsonObj = JSON.parseArray(jsonStr); + assert jsonObj instanceof JSONArray; + } + + public void parseObjectCase() { + String jsonStr = "{\"key\":123,\"msg\":\"test\"}"; + Object jsonObj = JSON.parseObject(jsonStr, CaseEntity.class, ParserConfig.global, null, JSON.DEFAULT_PARSER_FEATURE, new Feature[0]); + assert jsonObj instanceof CaseEntity; + } + + public void toJavaObjectCase() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("key", 123); + jsonObject.put("msg", "test"); + Object jsonObj = JSON.toJavaObject(jsonObject, CaseEntity.class); + assert jsonObj instanceof CaseEntity; + } + + public void toJsonCase() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("key", 123); + jsonObject.put("msg", "test"); + Object jsonObj = JSON.toJSON(jsonObject, SerializeConfig.globalInstance); + assert jsonObj instanceof JSONObject; + } + + public void toJsonBytesCase() { + CaseEntity caseEntity = new CaseEntity(); + caseEntity.setKey(123); + caseEntity.setMsg("test"); + Object jsonObj = JSON.toJSONBytes(IOUtils.UTF8, caseEntity, SerializeConfig.globalInstance, new SerializeFilter[0], null, JSON.DEFAULT_GENERATE_FEATURE); + assert jsonObj instanceof byte[]; + } + + public void toJsonStringCase() { + CaseEntity caseEntity = new CaseEntity(); + caseEntity.setKey(123); + caseEntity.setMsg("test"); + Object jsonObj = JSON.toJSONString(caseEntity, SerializeConfig.globalInstance, new SerializeFilter[0], null, JSON.DEFAULT_GENERATE_FEATURE); + assert jsonObj instanceof String; + } + + public void writeJsonStringCase() throws IOException { + ByteArrayOutputStream outnew = new ByteArrayOutputStream(); + CaseEntity caseEntity = new CaseEntity(); + caseEntity.setKey(123); + caseEntity.setMsg("test"); + Object jsonObj = JSON.writeJSONString(outnew, IOUtils.UTF8, caseEntity, SerializeConfig.globalInstance, new SerializeFilter[0], null, JSON.DEFAULT_GENERATE_FEATURE); + assert jsonObj instanceof Integer; + } +} diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/fastjson-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..247f82400 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/resources/application.yaml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +server: + port: 8080 + servlet: + context-path: /fastjson-scenario +logging: + config: classpath:log4j2.xml \ No newline at end of file diff --git a/test/plugin/scenarios/fastjson-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/fastjson-scenario/src/main/resources/log4j2.xml new file mode 100644 index 000000000..9849ed5a8 --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/fastjson-scenario/support-version.list b/test/plugin/scenarios/fastjson-scenario/support-version.list new file mode 100644 index 000000000..fdd67757a --- /dev/null +++ b/test/plugin/scenarios/fastjson-scenario/support-version.list @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +1.2.62