This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-java.git
The following commit(s) were added to refs/heads/main by this push: new 5cd52658c6 Support for ActiveMQ-Artemis messaging tracing. (#670) 5cd52658c6 is described below commit 5cd52658c623241678f2196346a949bf6d35c655 Author: Chen Ziyan <clairelove.c...@gmail.com> AuthorDate: Mon Jan 29 16:01:20 2024 +0800 Support for ActiveMQ-Artemis messaging tracing. (#670) --- .github/workflows/plugins-jdk17-test.1.yaml | 1 + CHANGES.md | 1 + .../pom.xml | 48 ++++++ .../MessageConsumerConstructorInterceptor.java | 49 ++++++ .../jakarta/client/MessageConsumerInterceptor.java | 117 +++++++++++++ .../MessageProducerConstructorInterceptor.java | 49 ++++++ .../jakarta/client/MessageProducerInterceptor.java | 111 ++++++++++++ .../artemis/jakarta/client/define/EnhanceInfo.java | 89 ++++++++++ .../define/MessageConsumerInstrumentation.java | 80 +++++++++ .../define/MessageProducerInstrumentation.java | 80 +++++++++ .../src/main/resources/skywalking-plugin.def | 18 ++ apm-sniffer/apm-sdk-plugin/pom.xml | 1 + .../setup/service-agent/java-agent/Plugin-list.md | 1 + .../service-agent/java-agent/Supported-list.md | 1 + .../activemq-artemis-2.x-scenario/bin/startup.sh | 21 +++ .../config/expectedData.yaml | 192 +++++++++++++++++++++ .../configuration.yml | 31 ++++ .../activemq-artemis-2.x-scenario/pom.xml | 140 +++++++++++++++ .../src/main/assembly/assembly.xml | 41 +++++ .../apm/testcase/activemq/artemis/Application.java | 32 ++++ .../activemq/artemis/config/ActiveMQConfig.java | 36 ++++ .../artemis/controller/CaseController.java | 47 +++++ .../artemis/service/MessagingListener.java | 49 ++++++ .../activemq/artemis/service/MessagingService.java | 69 ++++++++ .../src/main/resources/application.yaml | 31 ++++ .../src/main/resources/log4j2.xml | 30 ++++ .../support-version.list | 32 ++++ 27 files changed, 1397 insertions(+) diff --git a/.github/workflows/plugins-jdk17-test.1.yaml b/.github/workflows/plugins-jdk17-test.1.yaml index 21449a7861..d469d4c2ef 100644 --- a/.github/workflows/plugins-jdk17-test.1.yaml +++ b/.github/workflows/plugins-jdk17-test.1.yaml @@ -59,6 +59,7 @@ jobs: - resteasy-6.x-scenario - gateway-4.x-scenario - httpexchange-scenario + - activemq-artemis-2.x-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index 9bdff5f5a7..14032134e8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Release Notes. * Support tracing for async producing, batch sync consuming, and batch async consuming in rocketMQ-client-java-5.x-plugin. * Convert the Redisson span into an async span. * Rename system env name from `sw_plugin_kafka_producer_config` to `SW_PLUGIN_KAFKA_PRODUCER_CONFIG`. +* Support for ActiveMQ-Artemis messaging tracing. #### Documentation diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/pom.xml new file mode 100644 index 0000000000..cc6a9f1ae2 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/pom.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>apm-sdk-plugin</artifactId> + <groupId>org.apache.skywalking</groupId> + <version>9.2.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>apm-activemq-artemis-jakarta-client-2.x-plugin</artifactId> + <name>activemq-artemis-jakarta-client-2.x-plugin</name> + <packaging>jar</packaging> + + <properties> + <java.version>1.8</java.version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <artemis-jakarta-client.version>2.31.2</artemis-jakarta-client.version> + </properties> + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-jakarta-client</artifactId> + <version>${artemis-jakarta-client.version}</version> + <scope>provided</scope> + <exclusions> + </exclusions> + </dependency> + </dependencies> +</project> diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerConstructorInterceptor.java new file mode 100644 index 0000000000..f8be4dad40 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerConstructorInterceptor.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client; + +import java.util.Map; +import org.apache.activemq.artemis.jms.client.ActiveMQConnection; +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.EnhanceInfo; + +/** + * {@link MessageConsumerConstructorInterceptor} get enhance data from the constructor of {@link org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer} + */ +public class MessageConsumerConstructorInterceptor implements InstanceConstructorInterceptor { + private static final String DEFAULT_HOST = "localhost"; + private static final String DEFAULT_PORT = "61616"; + private static final String HOST_KEY = "host"; + private static final String PORT_KEY = "port"; + + @Override + public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) throws Throwable { + ActiveMQConnection connection = (ActiveMQConnection) allArguments[1]; + ActiveMQDestination destination = (ActiveMQDestination) allArguments[5]; + Map<String, Object> paramMap = connection.getSessionFactory().getConnectorConfiguration().getParams(); + EnhanceInfo enhanceInfo = new EnhanceInfo(); + enhanceInfo.setBrokerUrl(paramMap.getOrDefault(HOST_KEY, DEFAULT_HOST) + ":" + paramMap.getOrDefault(PORT_KEY + , DEFAULT_PORT)); + enhanceInfo.setName(destination.getName()); + enhanceInfo.setAddress(destination.getAddress()); + enhanceInfo.setType(destination.getType()); + objInst.setSkyWalkingDynamicField(enhanceInfo); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerInterceptor.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerInterceptor.java new file mode 100644 index 0000000000..82f371221e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageConsumerInterceptor.java @@ -0,0 +1,117 @@ +/* + * 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.activemq.artemis.jakarta.client; + +import java.lang.reflect.Method; +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.apache.activemq.artemis.jms.client.ActiveMQMessage; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.StringTag; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.EnhanceInfo; + +/** + * {@link MessageConsumerInterceptor} create entry span when the method {@link org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer#getMessage(long, boolean)} execute + */ +public class MessageConsumerInterceptor implements InstanceMethodsAroundInterceptor { + private static final String OPERATION_NAME_PREFIX = "ActiveMQ/"; + private static final String CONSUMER_OPERATION_NAME_SUFFIX = "/Consumer"; + public static final StringTag MQ_MESSAGE_ID = new StringTag("mq.message.id"); + private static final String QUEUE = "Queue"; + private static final String TOPIC = "Topic"; + + @Override + public void beforeMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class<?>[] classes, + final MethodInterceptResult methodInterceptResult) throws Throwable { + } + + @Override + public Object afterMethod(final EnhancedInstance objInst, + final Method method, + final Object[] objects, + final Class<?>[] classes, + final Object ret) throws Throwable { + ActiveMQMessage message = (ActiveMQMessage) ret; + if (message == null) { + return ret; + } + ContextCarrier contextCarrier = getContextCarrierFromMessage(message); + EnhanceInfo enhanceInfo = (EnhanceInfo) objInst.getSkyWalkingDynamicField(); + boolean queue = isQueue(enhanceInfo.getType()); + AbstractSpan activeSpan = ContextManager.createEntrySpan( + buildOperationName(queue, enhanceInfo.getName()), + contextCarrier + ); + Tags.MQ_BROKER.set(activeSpan, enhanceInfo.getBrokerUrl()); + if (queue) { + Tags.MQ_QUEUE.set(activeSpan, enhanceInfo.getName()); + } else { + Tags.MQ_TOPIC.set(activeSpan, enhanceInfo.getName()); + } + activeSpan.tag(MQ_MESSAGE_ID, message.getJMSMessageID()); + activeSpan.setPeer(enhanceInfo.getBrokerUrl()); + activeSpan.setComponent(ComponentsDefine.ACTIVEMQ_CONSUMER); + SpanLayer.asMQ(activeSpan); + ContextManager.stopSpan(activeSpan); + return ret; + } + + @Override + public void handleMethodException(final EnhancedInstance enhancedInstance, + final Method method, + final Object[] objects, + final Class<?>[] classes, + final Throwable t) { + ContextManager.activeSpan().log(t); + } + + private ContextCarrier getContextCarrierFromMessage(ActiveMQMessage message) { + ContextCarrier contextCarrier = new ContextCarrier(); + + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(message.getCoreMessage().getStringProperty(next.getHeadKey().replace("-", "_"))); + } + + return contextCarrier; + } + + private boolean isQueue(ActiveMQDestination.TYPE type) { + return ActiveMQDestination.TYPE.QUEUE.equals(type) || ActiveMQDestination.TYPE.TEMP_QUEUE.equals(type); + } + + private String buildOperationName(boolean isQueue, String name) { + if (isQueue) { + return OPERATION_NAME_PREFIX + QUEUE + "/" + name + CONSUMER_OPERATION_NAME_SUFFIX; + } else { + return OPERATION_NAME_PREFIX + TOPIC + "/" + name + CONSUMER_OPERATION_NAME_SUFFIX; + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerConstructorInterceptor.java new file mode 100644 index 0000000000..4a8f548fd4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerConstructorInterceptor.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client; + +import java.util.Map; +import org.apache.activemq.artemis.jms.client.ActiveMQConnection; +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.EnhanceInfo; + +/** + * {@link MessageProducerConstructorInterceptor} get enhance data from the constructor of {@link org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer} + */ +public class MessageProducerConstructorInterceptor implements InstanceConstructorInterceptor { + private static final String DEFAULT_HOST = "localhost"; + private static final String DEFAULT_PORT = "61616"; + private static final String HOST_KEY = "host"; + private static final String PORT_KEY = "port"; + + @Override + public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) throws Throwable { + ActiveMQConnection connection = (ActiveMQConnection) allArguments[0]; + Map<String, Object> paramMap = connection.getSessionFactory().getConnectorConfiguration().getParams(); + ActiveMQDestination destination = (ActiveMQDestination) allArguments[2]; + EnhanceInfo enhanceInfo = new EnhanceInfo(); + enhanceInfo.setBrokerUrl(paramMap.getOrDefault(HOST_KEY, DEFAULT_HOST) + ":" + paramMap.getOrDefault(PORT_KEY + , DEFAULT_PORT)); + enhanceInfo.setName(destination.getName()); + enhanceInfo.setAddress(destination.getAddress()); + enhanceInfo.setType(destination.getType()); + objInst.setSkyWalkingDynamicField(enhanceInfo); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerInterceptor.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerInterceptor.java new file mode 100644 index 0000000000..08687d6e92 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/MessageProducerInterceptor.java @@ -0,0 +1,111 @@ +/* + * 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.activemq.artemis.jakarta.client; + +import jakarta.jms.Message; +import java.lang.reflect.Method; +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.StringTag; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.EnhanceInfo; + +/** + * {@link MessageProducerInterceptor} create exit span when the method {@link org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer#doSendx} + * execute + */ +public class MessageProducerInterceptor implements InstanceMethodsAroundInterceptor { + private static final String OPERATION_NAME_PREFIX = "ActiveMQ/"; + private static final String PRODUCER_OPERATION_NAME_SUFFIX = "/Producer"; + private static final StringTag MQ_MESSAGE_ID = new StringTag("mq.message.id"); + private static final String QUEUE = "Queue"; + private static final String TOPIC = "Topic"; + + @Override + public void beforeMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class<?>[] classes, + final MethodInterceptResult methodInterceptResult) throws Throwable { + ContextCarrier contextCarrier = new ContextCarrier(); + Message message = (Message) allArguments[1]; + EnhanceInfo enhanceInfo = (EnhanceInfo) objInst.getSkyWalkingDynamicField(); + boolean queue = isQueue(enhanceInfo.getType()); + AbstractSpan activeSpan = ContextManager.createExitSpan( + buildOperationName(queue, enhanceInfo.getName()), + contextCarrier, enhanceInfo.getBrokerUrl() + ); + contextCarrier.extensionInjector().injectSendingTimestamp(); + Tags.MQ_BROKER.set(activeSpan, enhanceInfo.getBrokerUrl()); + if (queue) { + Tags.MQ_QUEUE.set(activeSpan, enhanceInfo.getName()); + } else { + Tags.MQ_TOPIC.set(activeSpan, enhanceInfo.getName()); + } + SpanLayer.asMQ(activeSpan); + activeSpan.setComponent(ComponentsDefine.ACTIVEMQ_PRODUCER); + CarrierItem next = contextCarrier.items(); + + while (next.hasNext()) { + next = next.next(); + message.setStringProperty(next.getHeadKey().replace("-", "_"), next.getHeadValue()); + } + } + + @Override + public Object afterMethod(final EnhancedInstance enhancedInstance, + final Method method, + final Object[] allArguments, + final Class<?>[] classes, + final Object ret) throws Throwable { + AbstractSpan activeSpan = ContextManager.activeSpan(); + Message message = (Message) allArguments[1]; + activeSpan.tag(MQ_MESSAGE_ID, message.getJMSMessageID()); + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(final EnhancedInstance enhancedInstance, + final Method method, + final Object[] objects, + final Class<?>[] classes, + final Throwable t) { + ContextManager.activeSpan().log(t); + } + + private boolean isQueue(ActiveMQDestination.TYPE type) { + return ActiveMQDestination.TYPE.QUEUE.equals(type) || ActiveMQDestination.TYPE.TEMP_QUEUE.equals(type); + } + + private String buildOperationName(boolean isQueue, String name) { + if (isQueue) { + return OPERATION_NAME_PREFIX + QUEUE + "/" + name + PRODUCER_OPERATION_NAME_SUFFIX; + } else { + return OPERATION_NAME_PREFIX + TOPIC + "/" + name + PRODUCER_OPERATION_NAME_SUFFIX; + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/EnhanceInfo.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/EnhanceInfo.java new file mode 100644 index 0000000000..81ccc14576 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/EnhanceInfo.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.activemq.artemis.jakarta.client.define; + +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; + +/** + * {@link EnhanceInfo} saves the brokerUrl/name/address/TYPE properties. + */ +public class EnhanceInfo { + private String brokerUrl; + private String name; + private String address; + private ActiveMQDestination.TYPE type; + + public EnhanceInfo() { + } + + /** + * get the brokerUrl of ActiveMQ + */ + public String getBrokerUrl() { + return brokerUrl; + } + + /** + * set the brokerUrl of ActiveMQ + */ + public void setBrokerUrl(final String brokerUrl) { + this.brokerUrl = brokerUrl; + } + + /** + * get the type of destination(Queue/Topic) + */ + public ActiveMQDestination.TYPE getType() { + return type; + } + + /** + * set the type of destination(Queue/Topic) + */ + public void setType(final ActiveMQDestination.TYPE type) { + this.type = type; + } + + /** + * get the name of destination + */ + public String getName() { + return name; + } + + /** + * set the name of destination + */ + public void setName(final String name) { + this.name = name; + } + + /** + * get the address of destination + */ + public String getAddress() { + return address; + } + + /** + * set the address of destination + */ + public void setAddress(final String address) { + this.address = address; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageConsumerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageConsumerInstrumentation.java new file mode 100644 index 0000000000..e6e2c5d918 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageConsumerInstrumentation.java @@ -0,0 +1,80 @@ +/* + * 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.activemq.artemis.jakarta.client.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class MessageConsumerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer"; + private static final String ENHANCE_METHOD = "getMessage"; + private static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.MessageConsumerConstructorInterceptor"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.MessageConsumerInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getConstructorMatcher() { + return takesArguments(8); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_INTERCEPTOR_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(ENHANCE_METHOD).and(takesArguments(2)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageProducerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageProducerInstrumentation.java new file mode 100644 index 0000000000..b0fa3766b4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/artemis/jakarta/client/define/MessageProducerInstrumentation.java @@ -0,0 +1,80 @@ +/* + * 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.activemq.artemis.jakarta.client.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class MessageProducerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer"; + private static final String ENHANCE_METHOD = "doSendx"; + private static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.MessageProducerConstructorInterceptor"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.MessageProducerInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getConstructorMatcher() { + return takesArguments(5); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_INTERCEPTOR_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(ENHANCE_METHOD); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000..55ef5fd11b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.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. + +activemq-artemis-jakarta-client-2.x=org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.MessageProducerInstrumentation +activemq-artemis-jakarta-client-2.x=org.apache.skywalking.apm.plugin.activemq.artemis.jakarta.client.define.MessageConsumerInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 6300be177a..bfb4f47444 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -136,6 +136,7 @@ <module>websphere-liberty-23.x-plugin</module> <module>aerospike-plugin</module> <module>rocketMQ-client-java-5.x-plugin</module> + <module>activemq-artemis-jakarta-client-2.x-plugin</module> </modules> <packaging>pom</packaging> 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 3c0f2fed45..16136fce70 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -175,3 +175,4 @@ - spring-cloud-gateway-4.x - spring-webflux-6.x - spring-webflux-6.x-webclient +- activemq-artemis-jakarta-client-2.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 35ee22b092..9e69ad72b4 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -81,6 +81,7 @@ metrics based on the tracing data. * [RabbitMQ](https://www.rabbitmq.com/) 3.x-> 5.x * [Pulsar](http://pulsar.apache.org) 2.2.x -> 2.9.x * [NATS](https://github.com/nats-io/nats.java) 2.14.x -> 2.15.x + * [ActiveMQ-Artemis](https://github.com/apache/activemq) 2.30.0 -> 2.31.2 * Aliyun ONS 1.x (Optional¹) * NoSQL * [aerospike](https://github.com/aerospike/aerospike-client-java) 3.x -> 6.x diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/bin/startup.sh b/test/plugin/scenarios/activemq-artemis-2.x-scenario/bin/startup.sh new file mode 100644 index 0000000000..6282faed60 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.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 -Dspring.artemis.broker-url=${BROKERURL} -Dspring.artemis.user=${USER} -Dspring.artemis.password=${PASSWORD} -jar ${agent_opts} ${home}/../libs/activemq-artemis-2.x-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/config/expectedData.yaml new file mode 100644 index 0000000000..bf12411067 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/config/expectedData.yaml @@ -0,0 +1,192 @@ +# 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: activemq-artemis-2.x-scenario + segmentSize: ge 6 + segments: + - segmentId: not null + spans: + - operationName: ActiveMQ/Queue/QueueDemo/Consumer + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 46 + isError: false + spanType: Entry + peer: not blank + skipAnalysis: false + tags: + - {key: transmission.latency, value: ge 0} + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + refs: + - {parentEndpoint: 'GET:/activemq-artemis-scenario/testcase/activemq-artemis-scenario', + networkAddress: not blank, refType: CrossProcess, parentSpanId: 1, + parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: activemq-artemis-2.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: ActiveMQ/Topic/TopicDemo/Consumer + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 46 + isError: false + spanType: Entry + peer: not blank + skipAnalysis: false + tags: + - {key: transmission.latency, value: ge 0} + - {key: mq.broker, value: not blank} + - {key: mq.topic, value: not blank} + - {key: mq.message.id, value: not null} + refs: + - {parentEndpoint: 'GET:/activemq-artemis-scenario/testcase/activemq-artemis-scenario', + networkAddress: not blank, refType: CrossProcess, parentSpanId: 2, + parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: activemq-artemis-2.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: ActiveMQ/Queue/QueueDemo2/Consumer + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 46 + isError: false + spanType: Entry + peer: not blank + skipAnalysis: false + tags: + - {key: transmission.latency, value: ge 0} + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + refs: + - {parentEndpoint: 'GET:/activemq-artemis-scenario/testcase/activemq-artemis-scenario', + networkAddress: not blank, refType: CrossProcess, parentSpanId: 3, + parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: activemq-artemis-2.x-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: ActiveMQ/Queue/QueueDemo/Producer + parentSpanId: 0 + spanId: 1 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 45 + isError: false + spanType: Exit + peer: not blank + skipAnalysis: false + tags: + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + - operationName: ActiveMQ/Topic/TopicDemo/Producer + parentSpanId: 0 + spanId: 2 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 45 + isError: false + spanType: Exit + peer: not blank + skipAnalysis: false + tags: + - {key: mq.broker, value: not blank} + - {key: mq.topic, value: not blank} + - {key: mq.message.id, value: not null} + - operationName: ActiveMQ/Queue/QueueDemo2/Producer + parentSpanId: 0 + spanId: 3 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 45 + isError: false + spanType: Exit + peer: not blank + skipAnalysis: false + tags: + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + - operationName: ActiveMQ/Queue/QueueDemo3/Producer + parentSpanId: 0 + spanId: 4 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 45 + isError: false + spanType: Exit + peer: not blank + skipAnalysis: false + tags: + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + - operationName: GET:/activemq-artemis-scenario/testcase/activemq-artemis-scenario + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/activemq-artemis-scenario/testcase/activemq-artemis-scenario'} + - {key: http.method, value: GET} + - {key: http.status_code, value: '200'} + - segmentId: not null + spans: + - operationName: ActiveMQ/Queue/QueueDemo3/Consumer + parentSpanId: -1 + spanId: 0 + spanLayer: MQ + startTime: nq 0 + endTime: nq 0 + componentId: 46 + isError: false + spanType: Entry + peer: not blank + skipAnalysis: false + tags: + - {key: transmission.latency, value: ge 0} + - {key: mq.broker, value: not blank} + - {key: mq.queue, value: not blank} + - {key: mq.message.id, value: not null} + refs: + - {parentEndpoint: 'GET:/activemq-artemis-scenario/testcase/activemq-artemis-scenario', + networkAddress: not blank, refType: CrossProcess, parentSpanId: 4, + parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: activemq-artemis-2.x-scenario, + traceId: not null} \ No newline at end of file diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/configuration.yml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/configuration.yml new file mode 100644 index 0000000000..1ecda1486a --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/configuration.yml @@ -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. + +type: jvm +entryService: http://localhost:8080/activemq-artemis-scenario/testcase/activemq-artemis-scenario +healthCheck: http://localhost:8080/activemq-artemis-scenario/testcase/healthCheck +startScript: ./bin/startup.sh +environment: + - BROKERURL=tcp://activemq-server:61616 + - USER=artemis + - PASSWORD=artemis +dependencies: + activemq-server: + image: apache/activemq-artemis:2.31.2 + hostname: activemq-server + expose: + - 8161 + - 61616 \ No newline at end of file diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/pom.xml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/pom.xml new file mode 100644 index 0000000000..57fda8bf62 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/pom.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.example</groupId> + <artifactId>activemq-artemis-2.x-scenario</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>activemq-artemis-2.x-scenario</name> + <description>activemq-artemis-2.x-scenario</description> + <properties> + <java.version>17</java.version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <test.framework.version>2.31.2</test.framework.version> + <spring-boot.version>3.0.0</spring-boot.version> + <lombok.version>1.18.20</lombok.version> + <artemis.version>${test.framework.version}</artemis.version> + <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> + <jboss-logging.version>3.5.0.Final</jboss-logging.version> + <spring-jms.version>6.0.2</spring-jms.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <version>${spring-boot.version}</version> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-logging</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jms</artifactId> + <version>${spring-jms.version}</version> + </dependency> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-jakarta-client</artifactId> + <version>${test.framework.version}</version> + </dependency> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-core-client</artifactId> + <version>${test.framework.version}</version> + </dependency> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-commons</artifactId> + <version>${test.framework.version}</version> + </dependency> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-selector</artifactId> + <version>${test.framework.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-log4j2</artifactId> + <version>${spring-boot.version}</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.logging</groupId> + <artifactId>jboss-logging</artifactId> + <version>${jboss-logging.version}</version> + </dependency> + </dependencies> + + <build> + <finalName>activemq-artemis-2.x-scenario</finalName> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${spring-boot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin.version}</version> + <configuration> + <source>${java.version}</source> + <target>${java.version}</target> + <encoding>${project.build.sourceEncoding}</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>assemble</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/assembly.xml</descriptor> + </descriptors> + <outputDirectory>./target/</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000..d61a5c3cc1 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <formats> + <format>zip</format> + </formats> + + <fileSets> + <fileSet> + <directory>./bin</directory> + <fileMode>0775</fileMode> + </fileSet> + </fileSets> + + <files> + <file> + <source>${project.build.directory}/activemq-artemis-2.x-scenario.jar</source> + <outputDirectory>./libs</outputDirectory> + <fileMode>0775</fileMode> + </file> + </files> +</assembly> diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/Application.java b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/Application.java new file mode 100644 index 0000000000..81702b310b --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/Application.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.activemq.artemis; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.jms.annotation.EnableJms; + +@EnableJms +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/config/ActiveMQConfig.java b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/config/ActiveMQConfig.java new file mode 100644 index 0000000000..b2798b9ca3 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/config/ActiveMQConfig.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.activemq.artemis.config; + +import jakarta.jms.ConnectionFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jms.config.DefaultJmsListenerContainerFactory; +import org.springframework.jms.config.JmsListenerContainerFactory; + +@Configuration +public class ActiveMQConfig { + + @Bean + public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) { + DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory(); + bean.setPubSubDomain(true); + bean.setConnectionFactory(activeMQConnectionFactory); + return bean; + } +} diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/controller/CaseController.java b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/controller/CaseController.java new file mode 100644 index 0000000000..99a4418f6d --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/controller/CaseController.java @@ -0,0 +1,47 @@ +/* + * 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.activemq.artemis.controller; + +import org.apache.skywalking.apm.testcase.activemq.artemis.service.MessagingService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/testcase") +public class CaseController { + private static final String SUCCESS = "Success"; + + @Autowired + private MessagingService messagingService; + + @GetMapping("/activemq-artemis-scenario") + public String demo() throws Exception { + messagingService.sendMessage("hello world"); + messagingService.sendTopicMessage("hello world"); + messagingService.sendAndReceiveMessage("hello world"); + messagingService.convertAndSendMessage("hello world"); + return SUCCESS; + } + + @GetMapping("/healthCheck") + public String healthCheck() { + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingListener.java b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingListener.java new file mode 100644 index 0000000000..2052579930 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingListener.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.apm.testcase.activemq.artemis.service; + +import jakarta.jms.Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jms.annotation.JmsListener; +import org.springframework.stereotype.Component; + +@Component +public class MessagingListener { + final Logger logger = LoggerFactory.getLogger(getClass()); + + @JmsListener(destination = "QueueDemo", concurrency = "10") + public void onMessageReceived(Message message) throws Exception { + logger.info("received normal message: " + message); + } + + @JmsListener(destination = "TopicDemo", concurrency = "1", containerFactory = "jmsListenerContainerTopic") + public void onSelfMessageReceived(Message message) throws Exception { + logger.info("received self message: " + message); + } + + @JmsListener(destination = "QueueDemo2", concurrency = "1") + public void onSendReceiveMessageReceived(Message message) throws Exception { + logger.info("received send and receive message: " + message); + } + + @JmsListener(destination = "QueueDemo3", concurrency = "1") + public void onConvertSendMessageReceived(Message message) throws Exception { + logger.info("received convert and send message: " + message); + } +} diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingService.java b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingService.java new file mode 100644 index 0000000000..e4f5011342 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/activemq/artemis/service/MessagingService.java @@ -0,0 +1,69 @@ +/* + * 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.activemq.artemis.service; + +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.Session; +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.jms.core.MessageCreator; +import org.springframework.stereotype.Component; + +@Component +public class MessagingService { + @Autowired + private JmsTemplate jmsTemplate; + + public void sendMessage(String text) throws Exception { + jmsTemplate.send("QueueDemo", new MessageCreator() { + @Override + public Message createMessage(Session session) throws JMSException { + return session.createTextMessage(text); + } + }); + } + + public void sendTopicMessage(String text) throws Exception { + ActiveMQDestination destination = ActiveMQDestination.createDestination( + "TopicDemo", ActiveMQDestination.TYPE.TOPIC); + jmsTemplate.send(destination, new MessageCreator() { + @Override + public Message createMessage(final Session session) throws JMSException { + return session.createTextMessage(text); + } + }); + } + + public void sendAndReceiveMessage(String text) throws Exception { + jmsTemplate.setReceiveTimeout(500); + jmsTemplate.sendAndReceive("QueueDemo2", new MessageCreator() { + @Override + public Message createMessage(Session session) throws JMSException { + return session.createTextMessage(text); + } + }); + } + + public void convertAndSendMessage(String text) throws Exception { + ActiveMQDestination destination = ActiveMQDestination.createDestination( + "QueueDemo3", ActiveMQDestination.TYPE.QUEUE); + jmsTemplate.convertAndSend(destination, text); + } +} \ No newline at end of file diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/application.yaml new file mode 100644 index 0000000000..4298edec40 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/application.yaml @@ -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. +# +# +server: + port: 8080 + servlet: + context-path: /activemq-artemis-scenario +spring: + jms: + pub-sub-domain: false + artemis: + mode: native +logging: + config: classpath:log4j2.xml + + + diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..9849ed5a8a --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_ERR"> + <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/> + </Console> + </Appenders> + <Loggers> + <Root level="WARN"> + <AppenderRef ref="Console"/> + </Root> + </Loggers> +</Configuration> \ No newline at end of file diff --git a/test/plugin/scenarios/activemq-artemis-2.x-scenario/support-version.list b/test/plugin/scenarios/activemq-artemis-2.x-scenario/support-version.list new file mode 100644 index 0000000000..06a4c47be4 --- /dev/null +++ b/test/plugin/scenarios/activemq-artemis-2.x-scenario/support-version.list @@ -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. + +# lists your version here (Contains only the last version number of each minor version.) +2.17.0 +2.18.0 +2.19.1 +2.20.0 +2.21.0 +2.22.0 +2.23.1 +2.24.0 +2.25.0 +2.26.0 +2.27.1 +2.28.0 +2.29.0 +2.30.0 +2.31.2 \ No newline at end of file