diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index a5781788f..e26c10857 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -63,6 +63,7 @@ jobs: - spring-4.1.x-scenario - spring-4.3.x-scenario - spring-async-scenario + - vertx-core-4.x-scenario - vertx-eventbus-3.x-scenario - vertx-web-3.54minus-scenario - vertx-web-3.6plus-scenario diff --git a/CHANGES.md b/CHANGES.md index 6e7639cbf..44d13b5f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Release Notes. * Ignore the synthetic constructor created by the agent in the Spring patch plugin. * Add witness class for vertx-core-3.x plugin. * Add witness class for graphql plugin. +* Add vertx-core-4.x plugin. #### Documentation * Add link about java agent injector. diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/vertx-plugins/pom.xml index 8070ce6ce..8680bf9c4 100644 --- a/apm-sniffer/apm-sdk-plugin/vertx-plugins/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/pom.xml @@ -28,6 +28,7 @@ vertx-plugins + vertx-core-4.x-plugin vertx-core-3.x-plugin pom diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/pom.xml new file mode 100644 index 000000000..344330c3f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/pom.xml @@ -0,0 +1,45 @@ + + + + + vertx-plugins + org.apache.skywalking + 8.10.0-SNAPSHOT + + 4.0.0 + + apm-vertx-core-4.x-plugin + jar + + vertx-core-4.x-plugin + http://maven.apache.org + + + 4.2.5 + + + + + io.vertx + vertx-core + ${vertx.version} + provided + + + diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/ClusteredMessageConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/ClusteredMessageConstructorInterceptor.java new file mode 100644 index 000000000..c9177fe7f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/ClusteredMessageConstructorInterceptor.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.vertx4; + +import io.vertx.core.eventbus.impl.clustered.ClusteredEventBus; +import io.vertx.core.spi.cluster.NodeInfo; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +import java.lang.reflect.Field; + +public class ClusteredMessageConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Exception { + for (Object arg : allArguments) { + if (arg instanceof ClusteredEventBus) { + Field nodeInfoField = ClusteredEventBus.class.getDeclaredField("nodeInfo"); + nodeInfoField.setAccessible(true); + NodeInfo nodeInfo = (NodeInfo) nodeInfoField.get(arg); + + objInst.setSkyWalkingDynamicField(nodeInfo.host() + ":" + nodeInfo.port()); + break; + } + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/SWVertxTracer.java b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/SWVertxTracer.java new file mode 100644 index 000000000..aeb782a3e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/SWVertxTracer.java @@ -0,0 +1,203 @@ +/* + * 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.vertx4; + +import io.vertx.core.Context; +import io.vertx.core.eventbus.Message; +import io.vertx.core.eventbus.impl.clustered.ClusteredMessage; +import io.vertx.core.impl.ContextInternal; +import io.vertx.core.spi.observability.HttpRequest; +import io.vertx.core.spi.observability.HttpResponse; +import io.vertx.core.spi.tracing.SpanKind; +import io.vertx.core.spi.tracing.TagExtractor; +import io.vertx.core.spi.tracing.VertxTracer; +import io.vertx.core.tracing.TracingPolicy; +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.ContextSnapshot; +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.network.trace.component.ComponentsDefine; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +public class SWVertxTracer implements VertxTracer { + + @Override + public AbstractSpan receiveRequest(Context context, SpanKind kind, TracingPolicy policy, R request, + String operation, Iterable> headers, + TagExtractor tagExtractor) { + if (TracingPolicy.IGNORE.equals(policy)) { + return null; + } + + if (request instanceof HttpRequest) { + HttpRequest serverRequest = (HttpRequest) request; + + ContextCarrier contextCarrier = getContextCarrier(headers); + AbstractSpan span = toEntrySpan( + String.join(":", serverRequest.method().name(), serverRequest.uri()), + contextCarrier, + context + ); + SpanLayer.asHttp(span); + Tags.HTTP.METHOD.set(span, serverRequest.method().toString()); + Tags.URL.set(span, serverRequest.absoluteURI()); + + return toAsyncSpan(context, span, false); + } else if (request instanceof Message) { + Message serverRequest = (Message) request; + + ContextCarrier contextCarrier = getContextCarrier(headers); + AbstractSpan span = toEntrySpan(serverRequest.address(), contextCarrier, context); + SpanLayer.asRPCFramework(span); + + return toAsyncSpan(context, span, false); + } + + return null; + } + + @Override + public void sendResponse(Context context, R response, AbstractSpan payload, Throwable failure, + TagExtractor tagExtractor) { + if (payload != null) { + if (failure != null) { + payload.log(failure); + } + + if (response instanceof HttpResponse) { + Tags.HTTP_RESPONSE_STATUS_CODE.set(payload, ((HttpResponse) response).statusCode()); + } + payload.asyncFinish(); + } + } + + @Override + public AbstractSpan sendRequest(Context context, SpanKind kind, TracingPolicy policy, R request, + String operation, BiConsumer headers, + TagExtractor tagExtractor) { + if (TracingPolicy.IGNORE.equals(policy) || request == null) { + return null; + } + + if (request instanceof HttpRequest) { + HttpRequest clientRequest = (HttpRequest) request; + + ContextCarrier contextCarrier = new ContextCarrier(); + AbstractSpan span = toExitSpan( + clientRequest.uri(), + clientRequest.remoteAddress().host() + ":" + clientRequest.remoteAddress().port(), + contextCarrier, + context + ); + SpanLayer.asHttp(span); + Tags.HTTP.METHOD.set(span, clientRequest.method().name()); + Tags.URL.set(span, clientRequest.absoluteURI()); + + return toExitAsyncSpan(context, headers, contextCarrier, span); + } else if (request instanceof Message) { + Message clientRequest = (Message) request; + + String remotePeer = "localhost"; + if (clientRequest instanceof ClusteredMessage) { + EnhancedInstance enhancedInstance = (EnhancedInstance) clientRequest; + if (enhancedInstance.getSkyWalkingDynamicField() != null) { + remotePeer = (String) enhancedInstance.getSkyWalkingDynamicField(); + } + } + ContextCarrier contextCarrier = new ContextCarrier(); + AbstractSpan span = toExitSpan(clientRequest.address(), remotePeer, contextCarrier, context); + SpanLayer.asRPCFramework(span); + + return toExitAsyncSpan(context, headers, contextCarrier, span); + } + return null; + } + + @Override + public void receiveResponse(Context context, R response, AbstractSpan payload, Throwable failure, + TagExtractor tagExtractor) { + this.sendResponse(context, response, payload, failure, tagExtractor); + } + + private void continueContextIfNecessary(Context context) { + //Context.getLocal(String) changes to Context.getLocal(Object) from 4.0.x to 4.1.x, so direct access local map + Map contextMap = ((ContextInternal) context).localContextData(); + ContextSnapshot contextSnapshot = (ContextSnapshot) contextMap.get("sw.context-snapshot"); + + if (contextSnapshot != null) { + ContextManager.continued(contextSnapshot); + } + } + + private ContextCarrier getContextCarrier(Iterable> headers) { + Map headerMap = new HashMap<>(); + headers.forEach(it -> headerMap.put(it.getKey(), it.getValue())); + ContextCarrier contextCarrier = new ContextCarrier(); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(headerMap.get(next.getHeadKey())); + } + return contextCarrier; + } + + private AbstractSpan toAsyncSpan(Context context, AbstractSpan span, boolean isExitSpan) { + //Context.putLocal(String) changes to Context.putLocal(Object) from 4.0.x to 4.1.x, so direct access local map + Map contextMap = ((ContextInternal) context).localContextData(); + if (!isExitSpan) { + contextMap.put("sw.context-snapshot", ContextManager.capture()); + } + + AbstractSpan asyncSpan = span.prepareForAsync(); + ContextManager.stopSpan(); + return asyncSpan; + } + + private AbstractSpan toExitAsyncSpan(Context context, BiConsumer headers, + ContextCarrier contextCarrier, AbstractSpan span) { + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + headers.accept(next.getHeadKey(), next.getHeadValue()); + } + return toAsyncSpan(context, span, true); + } + + private AbstractSpan toEntrySpan(String operationName, ContextCarrier contextCarrier, Context context) { + AbstractSpan span = ContextManager.createEntrySpan(operationName, contextCarrier); + continueContextIfNecessary(context); + span.setComponent(ComponentsDefine.VERTX); + return span; + } + + private AbstractSpan toExitSpan(String operationName, String remotePeer, ContextCarrier contextCarrier, + Context context) { + AbstractSpan span = ContextManager.createExitSpan(operationName, contextCarrier, remotePeer); + continueContextIfNecessary(context); + span.setComponent(ComponentsDefine.VERTX); + return span; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/VertxBuilderConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/VertxBuilderConstructorInterceptor.java new file mode 100644 index 000000000..9d8794ab3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/VertxBuilderConstructorInterceptor.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.plugin.vertx4; + +import io.vertx.core.impl.VertxBuilder; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +public class VertxBuilderConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + VertxBuilder vertxBuilder = (VertxBuilder) objInst; + vertxBuilder.tracer(new SWVertxTracer()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/ClusteredMessageConstructorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/ClusteredMessageConstructorInstrumentation.java new file mode 100644 index 000000000..b493896f9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/ClusteredMessageConstructorInstrumentation.java @@ -0,0 +1,72 @@ +/* + * 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.vertx4.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.isPublic; + +/** + * {@link ClusteredMessageConstructorInstrumentation} enhance the constructor in + * io.vertx.core.eventbus.impl.clustered.ClusteredMessage class by + * ClusteredMessageConstructorInterceptor class. + */ +public class ClusteredMessageConstructorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "io.vertx.core.eventbus.impl.clustered.ClusteredMessage"; + private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.vertx4.ClusteredMessageConstructorInterceptor"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return isPublic(); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPT_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + protected String[] witnessClasses() { + return new String[] { "io.vertx.core.impl.VertxBuilder" }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/VertxBuilderConstructorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/VertxBuilderConstructorInstrumentation.java new file mode 100644 index 000000000..d1bb8452d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/vertx4/define/VertxBuilderConstructorInstrumentation.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.vertx4.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.any; + +/** + * {@link VertxBuilderConstructorInstrumentation} enhance the constructor in + * io.vertx.core.impl.VertxBuilder class by + * VertxBuilderConstructorInterceptor class. + */ +public class VertxBuilderConstructorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "io.vertx.core.impl.VertxBuilder"; + private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.vertx4.VertxBuilderConstructorInterceptor"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPT_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..ad30dc8de --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +vertx-core-4.x=org.apache.skywalking.apm.plugin.vertx4.define.ClusteredMessageConstructorInstrumentation +vertx-core-4.x=org.apache.skywalking.apm.plugin.vertx4.define.VertxBuilderConstructorInstrumentation \ No newline at end of file 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 6b535cacf..dc238ec5b 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -117,6 +117,7 @@ - toolkit-exception - undertow-2.x-plugin - vertx-core-3.x +- vertx-core-4.x - xxl-job-2.x - zookeeper-3.4.x - mssql-jtds-1.x 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 98e8edf2e..51e6c6ccf 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -112,8 +112,8 @@ metrics based on the tracing data. * [Fastjson](https://github.com/alibaba/fastjson) 1.2.x (Optional²) * [Jackson](https://github.com/FasterXML/jackson) 2.x (Optional²) * Vert.x Ecosystem - * Vert.x Eventbus 3.2+ - * Vert.x Web 3.x + * Vert.x Eventbus 3.2 -> 4.x + * Vert.x Web 3.x -> 4.x * Thread Schedule Framework * [Spring @Async](https://github.com/spring-projects/spring-framework) 4.x and 5.x * [Quasar](https://github.com/puniverse/quasar) 0.7.x diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/bin/startup.sh b/test/plugin/scenarios/vertx-core-4.x-scenario/bin/startup.sh new file mode 100644 index 000000000..58d6bf6fa --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.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/vertx-core-4.x-scenario.jar & diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/vertx-core-4.x-scenario/config/expectedData.yaml new file mode 100644 index 000000000..48f853332 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/config/expectedData.yaml @@ -0,0 +1,177 @@ +# 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: vertx-core-4.x-scenario + segmentSize: 8 + segments: + - segmentId: not null + spans: + - operationName: HEAD:/vertx-core-4-scenario/case/healthCheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: http.method, value: HEAD} + - {key: url, value: 'http://localhost:8080/vertx-core-4-scenario/case/healthCheck'} + - {key: http.status_code, value: '200'} + - segmentId: not null + spans: + - operationName: local-message-receiver + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + refs: + - {parentEndpoint: local-message-receiver, networkAddress: not null, + refType: CrossProcess, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: local-message-receiver + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Exit + peer: not null + skipAnalysis: false + refs: + - {parentEndpoint: 'GET:/vertx-core-4-scenario/case/executeTest', networkAddress: '', + refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: cluster-message-receiver + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + refs: + - {parentEndpoint: cluster-message-receiver, networkAddress: not null, + refType: CrossProcess, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: GET:/vertx-core-4-scenario/case/executeTest + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: http.method, value: GET} + - {key: url, value: 'http://localhost:8080/vertx-core-4-scenario/case/executeTest'} + - {key: http.status_code, value: '200'} + refs: + - {parentEndpoint: /vertx-core-4-scenario/case/executeTest, networkAddress: 'localhost:8080', + refType: CrossProcess, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: GET:/vertx-core-4-scenario/case/core-case + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: http.method, value: GET} + - {key: url, value: 'http://localhost:8080/vertx-core-4-scenario/case/core-case'} + - {key: http.status_code, value: '200'} + - segmentId: not null + spans: + - operationName: /vertx-core-4-scenario/case/executeTest + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: http.method, value: GET} + - {key: url, value: 'http://localhost:8080/vertx-core-4-scenario/case/executeTest'} + - {key: http.status_code, value: '200'} + refs: + - {parentEndpoint: 'GET:/vertx-core-4-scenario/case/core-case', networkAddress: '', + refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: cluster-message-receiver + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 59 + isError: false + spanType: Exit + peer: not null + skipAnalysis: false + refs: + - {parentEndpoint: 'GET:/vertx-core-4-scenario/case/executeTest', networkAddress: '', + refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: vertx-core-4.x-scenario, + traceId: not null} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/configuration.yml b/test/plugin/scenarios/vertx-core-4.x-scenario/configuration.yml new file mode 100644 index 000000000..7d3d6663f --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.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/vertx-core-4-scenario/case/core-case +healthCheck: http://localhost:8080/vertx-core-4-scenario/case/healthCheck +startScript: ./bin/startup.sh diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/pom.xml b/test/plugin/scenarios/vertx-core-4.x-scenario/pom.xml new file mode 100644 index 000000000..5e33cc7de --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/pom.xml @@ -0,0 +1,107 @@ + + + + + org.apache.skywalking.apm.testcase + vertx-core-4.x-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 4.2.5 + 2.1.6.RELEASE + 2.9.4 + + + skywalking-vertx-core-4.x-scenario + + + + io.vertx + vertx-core + ${test.framework.version} + + + io.vertx + vertx-web + ${test.framework.version} + + + io.vertx + vertx-hazelcast + ${test.framework.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + vertx-core-4.x-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + 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/ + + + + + + + diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..742ca00a7 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/vertx-core-4.x-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/Application.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/Application.java new file mode 100644 index 000000000..44d1a4a36 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/Application.java @@ -0,0 +1,60 @@ +/* + * 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.vertxcore; + +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.spi.cluster.ClusterManager; +import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager; + +import org.apache.skywalking.apm.testcase.vertxcore.controller.ClusterReceiver; +import org.apache.skywalking.apm.testcase.vertxcore.controller.VertxCoreController; + +public class Application { + + public static void main(String[] args) { + System.setProperty("vertx.disableFileCPResolving", "true"); + ClusterManager mgr = new HazelcastClusterManager(); + VertxOptions options = new VertxOptions().setClusterManager(mgr); + Vertx.clusteredVertx(options, cluster -> { + if (cluster.succeeded()) { + cluster.result().deployVerticle(new ClusterReceiver(), deploy -> { + if (deploy.succeeded()) { + ClusterManager mgr2 = new HazelcastClusterManager(); + VertxOptions options2 = new VertxOptions().setClusterManager(mgr2); + Vertx.clusteredVertx(options2, cluster2 -> { + if (cluster2.succeeded()) { + cluster2.result().deployVerticle(new VertxCoreController()); + } else { + cluster2.cause().printStackTrace(); + System.exit(-1); + } + }); + } else { + deploy.cause().printStackTrace(); + System.exit(-1); + } + }); + } else { + cluster.cause().printStackTrace(); + System.exit(-1); + } + }); + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/ClusterReceiver.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/ClusterReceiver.java new file mode 100644 index 000000000..a59ce6a05 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/ClusterReceiver.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.vertxcore.controller; + +import io.vertx.core.AbstractVerticle; +import io.vertx.core.eventbus.EventBus; +import org.apache.skywalking.apm.testcase.vertxcore.util.CustomMessage; +import org.apache.skywalking.apm.testcase.vertxcore.util.CustomMessageCodec; + +public class ClusterReceiver extends AbstractVerticle { + + @Override + public void start() { + EventBus eventBus = vertx.eventBus(); + eventBus.registerDefaultCodec(CustomMessage.class, new CustomMessageCodec()); + + eventBus.consumer("cluster-message-receiver", + message -> message.reply(new CustomMessage("cluster-message-receiver reply"))); + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/LocalReceiver.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/LocalReceiver.java new file mode 100644 index 000000000..bc05481eb --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/LocalReceiver.java @@ -0,0 +1,31 @@ +/* + * 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.vertxcore.controller; + +import io.vertx.core.AbstractVerticle; +import org.apache.skywalking.apm.testcase.vertxcore.util.CustomMessage; + +public class LocalReceiver extends AbstractVerticle { + + @Override + public void start() { + vertx.eventBus().consumer("local-message-receiver", + message -> message.reply(new CustomMessage("local-message-receiver reply"))); + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/VertxCoreController.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/VertxCoreController.java new file mode 100644 index 000000000..5193035ef --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/controller/VertxCoreController.java @@ -0,0 +1,101 @@ +/* + * 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.vertxcore.controller; + +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Promise; +import io.vertx.core.http.HttpMethod; +import io.vertx.core.json.Json; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; +import org.apache.skywalking.apm.testcase.vertxcore.util.CustomMessage; +import org.apache.skywalking.apm.testcase.vertxcore.util.CustomMessageCodec; + +public class VertxCoreController extends AbstractVerticle { + + @Override + public void start() { + Router router = Router.router(vertx); + router.get("/vertx-core-4-scenario/case/core-case").handler(this::handleCoreCase); + router.get("/vertx-core-4-scenario/case/executeTest").handler(this::executeTest); + router.head("/vertx-core-4-scenario/case/healthCheck").handler(this::healthCheck); + vertx.createHttpServer().requestHandler(router).listen(8080); + + vertx.eventBus().registerDefaultCodec(CustomMessage.class, new CustomMessageCodec()); + vertx.deployVerticle(LocalReceiver.class.getName()); + } + + private void handleCoreCase(RoutingContext routingContext) { + vertx.createHttpClient().request(HttpMethod.GET, 8080, "localhost", + "/vertx-core-4-scenario/case/executeTest").onComplete(it -> { + if (it.succeeded()) { + it.result().end(); + it.result().response().onComplete(it2 -> { + if (it2.succeeded()) { + routingContext.response().setStatusCode(it2.result().statusCode()).end(); + } + }); + } + }); + } + + private void executeTest(RoutingContext routingContext) { + Promise localMessageFuture = Promise.promise(); + CustomMessage localMessage = new CustomMessage("local-message-receiver request"); + vertx.eventBus().request("local-message-receiver", localMessage, reply -> { + if (reply.succeeded()) { + CustomMessage replyMessage = (CustomMessage) reply.result().body(); + replyMessage.getMessage(); + localMessageFuture.complete(); + } else { + localMessageFuture.fail(reply.cause()); + } + }); + + Promise clusterMessageFuture = Promise.promise(); + CustomMessage clusterWideMessage = new CustomMessage("cluster-message-receiver request"); + vertx.eventBus().request("cluster-message-receiver", clusterWideMessage, reply -> { + if (reply.succeeded()) { + CustomMessage replyMessage = (CustomMessage) reply.result().body(); + replyMessage.getMessage(); + clusterMessageFuture.complete(); + } else { + clusterMessageFuture.fail(reply.cause()); + } + }); + + localMessageFuture.future().onComplete(localHandler -> { + if (localHandler.succeeded()) { + clusterMessageFuture.future().onComplete(clusterHandler -> { + if (clusterHandler.succeeded()) { + routingContext.response().setStatusCode(200).end(); + } else { + routingContext.response().setStatusCode(500).end(Json.encodePrettily(clusterHandler.cause())); + } + }); + } else { + routingContext.response().setStatusCode(500).end(Json.encodePrettily(localHandler.cause())); + } + }); + } + + private void healthCheck(RoutingContext routingContext) { + routingContext.response().setStatusCode(200).end("Success"); + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessage.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessage.java new file mode 100644 index 000000000..d55fa6d90 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessage.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.vertxcore.util; + +public class CustomMessage { + + private final String message; + + public CustomMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessageCodec.java b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessageCodec.java new file mode 100644 index 000000000..7ed0394dc --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/vertxcore/util/CustomMessageCodec.java @@ -0,0 +1,57 @@ +/* + * 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.vertxcore.util; + +import io.vertx.core.buffer.Buffer; +import io.vertx.core.eventbus.MessageCodec; +import io.vertx.core.json.Json; +import io.vertx.core.json.JsonObject; + +public class CustomMessageCodec implements MessageCodec { + + @Override + public void encodeToWire(Buffer buffer, CustomMessage customMessage) { + String jsonStr = Json.encode(customMessage); + int length = jsonStr.getBytes().length; + buffer.appendInt(length); + buffer.appendString(jsonStr); + } + + @Override + public CustomMessage decodeFromWire(int position, Buffer buffer) { + int length = buffer.getInt(position); + JsonObject jsonMessage = new JsonObject(buffer.getString(position += 4, position + length)); + return new CustomMessage(jsonMessage.getString("message")); + } + + @Override + public CustomMessage transform(CustomMessage customMessage) { + return customMessage; + } + + @Override + public String name() { + return getClass().getSimpleName(); + } + + @Override + public byte systemCodecID() { + return -1; + } +} diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/resources/log4j2.xml new file mode 100644 index 000000000..ca19f179c --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/vertx-core-4.x-scenario/support-version.list b/test/plugin/scenarios/vertx-core-4.x-scenario/support-version.list new file mode 100644 index 000000000..7bda3b736 --- /dev/null +++ b/test/plugin/scenarios/vertx-core-4.x-scenario/support-version.list @@ -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. + +4.2.5 +4.1.8 +4.0.3