From 37dc3122f387ec76ab09f7fdc2b3acc304055e82 Mon Sep 17 00:00:00 2001 From: Marco Bungart Date: Wed, 5 Oct 2022 03:27:54 +0200 Subject: [PATCH] #20: allow configuration of multiple named connection factories --- .all-contributorsrc | 9 + .../ArtemisBootstrappedBuildItem.java | 18 + .../deployment/ArtemisBuildTimeConfig.java | 27 -- .../core/deployment/ArtemisCoreProcessor.java | 142 +++++--- .../DevServicesArtemisProcessor.java | 184 +++++++--- .../health/ArtemisHealthProcessor.java | 58 +++ .../health/ArtemisHealthSupportBuildItem.java | 6 + .../core/runtime/ArtemisBuildTimeConfig.java | 44 +++ .../core/runtime/ArtemisBuildTimeConfigs.java | 52 +++ .../core/runtime/ArtemisCoreRecorder.java | 23 +- .../ArtemisDevServicesBuildTimeConfig.java | 56 ++- .../core/runtime/ArtemisRuntimeConfig.java | 43 ++- .../core/runtime/ArtemisRuntimeConfigs.java | 41 +++ .../artemis/core/runtime/ArtemisUtil.java | 27 ++ .../core/runtime/ShadowRunTimeConfig.java | 41 +++ .../runtime/health/ArtemisHealthSupport.java | 21 ++ .../health/ArtemisHealthSupportRecorder.java | 38 ++ .../health/ServerLocatorHealthCheck.java | 38 +- .../ROOT/pages/includes/attributes.adoc | 2 +- .../pages/includes/quarkus-artemis-core.adoc | 341 ++++++++++++++++-- .../it/artemis/ArtemisConsumerManager.java | 39 -- .../quarkus/it/artemis/ArtemisEndpoint.java | 26 -- .../it/artemis/ArtemisProducerManager.java | 38 -- .../artemis/core/ArtemisConsumerManager.java | 53 +++ .../it/artemis/core/ArtemisEndpoint.java | 49 +++ .../artemis/core/ArtemisProducerManager.java | 52 +++ .../src/main/resources/application.properties | 2 + .../it/artemis/ArtemisConsumerITCase.java | 8 - .../it/artemis/ArtemisConsumerTest.java | 33 -- .../it/artemis/ArtemisHealthCheckITCase.java | 8 - .../it/artemis/ArtemisHealthCheckTest.java | 36 -- .../it/artemis/ArtemisProducerITCase.java | 8 - .../it/artemis/ArtemisProducerTest.java | 17 - .../it/artemis/BaseArtemisProducerTest.java | 24 -- .../DevServiceArtemisProducerTest.java | 16 - .../it/artemis/{ => core}/ArtemisHelper.java | 9 +- .../artemis/core/BaseArtemisConsumerTest.java | 36 ++ .../core/BaseArtemisHealthCheckTest.java | 48 +++ .../artemis/core/BaseArtemisProducerTest.java | 35 ++ .../DevServiceArtemisEnabled.java | 7 +- .../devservices/DevservicesConsumerTest.java | 10 + .../DevservicesHealthCheckTest.java | 10 + .../devservices/DevservicesProducerTest.java | 10 + .../core/embedded/EmbeddedConsumerITCase.java | 7 + .../core/embedded/EmbeddedConsumerTest.java | 12 + .../embedded/EmbeddedHealthCheckITCase.java | 7 + .../embedded/EmbeddedHealthCheckTest.java | 12 + .../core/embedded/EmbeddedProducerITCase.java | 7 + .../core/embedded/EmbeddedProducerTest.java | 12 + .../embedded/NamedOneArtemisTestResource.java | 9 + .../src/test/resources/broker-named-1.xml | 26 ++ .../core/src/test/resources/broker.xml | 12 +- .../it/artemis/ArtemisConsumerManager.java | 24 -- .../quarkus/it/artemis/ArtemisEndpoint.java | 34 -- .../it/artemis/ArtemisProducerManager.java | 55 --- .../artemis/jms/ArtemisConsumerManager.java | 46 +++ .../it/artemis/jms/ArtemisEndpoint.java | 64 ++++ .../artemis/jms/ArtemisProducerManager.java | 88 +++++ .../src/main/resources/application.properties | 5 +- .../it/artemis/ArtemisConsumerITCase.java | 8 - .../it/artemis/ArtemisConsumerTest.java | 30 -- .../it/artemis/ArtemisHealthCheckITCase.java | 8 - .../it/artemis/ArtemisHealthCheckTest.java | 36 -- .../it/artemis/ArtemisProducerITCase.java | 8 - .../it/artemis/ArtemisProducerTest.java | 16 - .../it/artemis/ArtemisProducerXAITCase.java | 7 - .../it/artemis/ArtemisProducerXATest.java | 49 --- .../it/artemis/BaseArtemisProducerTest.java | 25 -- .../it/artemis/DevServiceArtemisEnabled.java | 21 -- .../DevServiceArtemisProducerTest.java | 15 - .../it/artemis/{ => jms}/ArtemisHelper.java | 10 +- .../artemis/jms/BaseArtemisConsumerTest.java | 32 ++ .../jms/BaseArtemisHealthCheckTest.java | 48 +++ .../artemis/jms/BaseArtemisProducerTest.java | 36 ++ .../jms/BaseArtemisProducerXATest.java | 57 +++ .../DevservicesArtemisEnabled.java | 24 ++ .../devservices/DevservicesConsumerTest.java | 10 + .../DevservicesHealthCheckTest.java | 10 + .../devservices/DevservicesProducerTest.java | 10 + .../DevservicesProducerXATest.java | 10 + .../jms/embedded/EmbeddedConsumerITCase.java | 7 + .../jms/embedded/EmbeddedConsumerTest.java | 12 + .../embedded/EmbeddedHealthCheckITCase.java | 7 + .../jms/embedded/EmbeddedHealthCheckTest.java | 12 + .../jms/embedded/EmbeddedProducerITCase.java | 8 + .../jms/embedded/EmbeddedProducerTest.java | 12 + .../embedded/EmbeddedProducerXAITCase.java | 7 + .../jms/embedded/EmbeddedProducerXATest.java | 12 + .../embedded/NamedOneArtemisTestResource.java | 9 + .../jms/src/test/resources/broker-named-1.xml | 26 ++ .../jms/src/test/resources/broker.xml | 12 +- .../jms/deployment/ArtemisJmsProcessor.java | 80 ++-- .../ConnectorFactoryHealthCheckProcessor.java | 13 + .../jms/runtime/ArtemisJmsRecorder.java | 75 +++- .../health/ConnectionFactoryHealthCheck.java | 43 ++- .../artemis/test/ArtemisTestResource.java | 50 ++- 96 files changed, 2192 insertions(+), 868 deletions(-) create mode 100644 core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBootstrappedBuildItem.java delete mode 100644 core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBuildTimeConfig.java create mode 100644 core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthProcessor.java create mode 100644 core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthSupportBuildItem.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfig.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfigs.java rename core/{deployment/src/main/java/io/quarkus/artemis/core/deployment => runtime/src/main/java/io/quarkus/artemis/core/runtime}/ArtemisDevServicesBuildTimeConfig.java (67%) create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfigs.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisUtil.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ShadowRunTimeConfig.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupport.java create mode 100644 core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupportRecorder.java delete mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java delete mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java delete mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java create mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisConsumerManager.java create mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisEndpoint.java create mode 100644 integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisProducerManager.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java delete mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java rename integration-tests/core/src/test/java/io/quarkus/it/artemis/{ => core}/ArtemisHelper.java (60%) create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisConsumerTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisHealthCheckTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisProducerTest.java rename integration-tests/core/src/test/java/io/quarkus/it/artemis/{ => core/devservices}/DevServiceArtemisEnabled.java (67%) create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesConsumerTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesHealthCheckTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesProducerTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerITCase.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckITCase.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerITCase.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerTest.java create mode 100644 integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/NamedOneArtemisTestResource.java create mode 100644 integration-tests/core/src/test/resources/broker-named-1.xml delete mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java delete mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java delete mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java create mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisConsumerManager.java create mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisEndpoint.java create mode 100644 integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisProducerManager.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXAITCase.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXATest.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java delete mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java rename integration-tests/jms/src/test/java/io/quarkus/it/artemis/{ => jms}/ArtemisHelper.java (61%) create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisConsumerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisHealthCheckTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerXATest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesArtemisEnabled.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesConsumerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesHealthCheckTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerXATest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerITCase.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckITCase.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerITCase.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerTest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXAITCase.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXATest.java create mode 100644 integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/NamedOneArtemisTestResource.java create mode 100644 integration-tests/jms/src/test/resources/broker-named-1.xml create mode 100644 jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/health/ConnectorFactoryHealthCheckProcessor.java diff --git a/.all-contributorsrc b/.all-contributorsrc index 486e63d5..0b783041 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -14,6 +14,15 @@ "code", "maintenance" ] + }, + { + "login": "turing85", + "name": "Marco Bungart", + "avatar_url": "https://avatars.githubusercontent.com/u/32584495?v=4", + "profile": "https://github.com/turing85", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBootstrappedBuildItem.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBootstrappedBuildItem.java new file mode 100644 index 00000000..5d0a32fc --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBootstrappedBuildItem.java @@ -0,0 +1,18 @@ +package io.quarkus.artemis.core.deployment; + +import java.util.Collections; +import java.util.Set; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class ArtemisBootstrappedBuildItem extends SimpleBuildItem { + private final Set connectionNames; + + public ArtemisBootstrappedBuildItem(Set connectionNames) { + this.connectionNames = Collections.unmodifiableSet(connectionNames); + } + + public Set getConnectionNames() { + return connectionNames; + } +} diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBuildTimeConfig.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBuildTimeConfig.java deleted file mode 100644 index 19617765..00000000 --- a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisBuildTimeConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.quarkus.artemis.core.deployment; - -import io.quarkus.runtime.annotations.ConfigItem; -import io.quarkus.runtime.annotations.ConfigPhase; -import io.quarkus.runtime.annotations.ConfigRoot; - -@ConfigRoot(name = "artemis", phase = ConfigPhase.BUILD_TIME) -public class ArtemisBuildTimeConfig { - - /** - * Whether or not an health check is published in case the smallrye-health extension is present - */ - @ConfigItem(name = "health.enabled", defaultValue = "true") - public boolean healthEnabled; - - /** - * Support to expose {@link javax.jms.XAConnectionFactory} - */ - @ConfigItem(name = "xa.enabled", defaultValue = "false") - public boolean xaEnabled; - - /** - * Configuration for DevServices. DevServices allows Quarkus to automatically start ActiveMQ Artemis in dev and test mode. - */ - @ConfigItem - public ArtemisDevServicesBuildTimeConfig devservices; -} diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java index 23960fc6..a06bd209 100644 --- a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java @@ -1,113 +1,153 @@ package io.quarkus.artemis.core.deployment; -import java.util.Collection; -import java.util.Optional; +import java.util.*; +import java.util.function.Supplier; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Default; +import org.apache.activemq.artemis.api.core.ActiveMQBuffers; import org.apache.activemq.artemis.api.core.client.ServerLocator; -import org.apache.activemq.artemis.api.core.client.loadbalance.ConnectionLoadBalancingPolicy; -import org.apache.activemq.artemis.api.core.client.loadbalance.FirstElementConnectionLoadBalancingPolicy; -import org.apache.activemq.artemis.api.core.client.loadbalance.RandomConnectionLoadBalancingPolicy; -import org.apache.activemq.artemis.api.core.client.loadbalance.RandomStickyConnectionLoadBalancingPolicy; -import org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy; +import org.apache.activemq.artemis.api.core.client.loadbalance.*; import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory; import org.apache.activemq.artemis.spi.core.remoting.ConnectorFactory; +import org.apache.activemq.artemis.utils.RandomUtil; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.logging.Logger; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; -import io.quarkus.artemis.core.runtime.ArtemisCoreRecorder; +import io.quarkus.artemis.core.runtime.*; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; +import io.smallrye.common.annotation.Identifier; public class ArtemisCoreProcessor { - private static final Logger LOGGER = Logger.getLogger(ArtemisCoreProcessor.class); + private static final String FEATURE = "artemis-core"; - static final Class[] BUILTIN_CONNECTOR_FACTORIES = { + static final Class[] BUILTIN_CONNECTOR_FACTORIES = { NettyConnectorFactory.class }; - static final Class[] BUILTIN_LOADBALANCING_POLICIES = { + static final Class[] BUILTIN_LOADBALANCING_POLICIES = { FirstElementConnectionLoadBalancingPolicy.class, RandomConnectionLoadBalancingPolicy.class, RandomStickyConnectionLoadBalancingPolicy.class, RoundRobinConnectionLoadBalancingPolicy.class }; + @SuppressWarnings("unused") + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + + @SuppressWarnings("unused") @BuildStep NativeImageConfigBuildItem config() { return NativeImageConfigBuildItem.builder() - .addRuntimeInitializedClass("org.apache.activemq.artemis.api.core.ActiveMQBuffers") - .addRuntimeInitializedClass("org.apache.activemq.artemis.utils.RandomUtil").build(); + .addRuntimeInitializedClass(ActiveMQBuffers.class.getCanonicalName()) + .addRuntimeInitializedClass(RandomUtil.class.getCanonicalName()) + .build(); } + @SuppressWarnings("unused") @BuildStep - void build(CombinedIndexBuildItem indexBuildItem, - BuildProducer reflectiveClass) { - + ArtemisBootstrappedBuildItem build( + CombinedIndexBuildItem indexBuildItem, + BuildProducer reflectiveClass, + ShadowRunTimeConfig shadowRunTimeConfig, + ArtemisBuildTimeConfigs buildTimeConfigs) { Collection connectorFactories = indexBuildItem.getIndex() .getAllKnownImplementors(DotName.createSimple(ConnectorFactory.class.getName())); - - for (ClassInfo ci : connectorFactories) { - LOGGER.debug("Adding reflective class " + ci); - reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, ci.toString())); - } - - for (Class c : BUILTIN_CONNECTOR_FACTORIES) { - reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, c)); - } + addDynamicReflectiveBuildItems(reflectiveClass, connectorFactories); + addBuiltinReflectiveBuiltitems(reflectiveClass, BUILTIN_CONNECTOR_FACTORIES); Collection loadBalancers = indexBuildItem.getIndex() .getAllKnownImplementors(DotName.createSimple(ConnectionLoadBalancingPolicy.class.getName())); - - for (ClassInfo ci : loadBalancers) { - LOGGER.debug("Adding reflective class " + ci); - reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, ci.toString())); - } - - for (Class c : BUILTIN_LOADBALANCING_POLICIES) { - reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, c)); + addDynamicReflectiveBuildItems(reflectiveClass, loadBalancers); + addBuiltinReflectiveBuiltitems(reflectiveClass, BUILTIN_LOADBALANCING_POLICIES); + HashSet names = new HashSet<>(shadowRunTimeConfig.getNames()); + HashSet disabled = new HashSet<>(); + for (var entry : shadowRunTimeConfig.getAllConfigs().entrySet()) { + if (entry.getValue().isDisabled()) { + disabled.add(entry.getKey()); + } } + names.addAll(buildTimeConfigs.getAllConfigs().keySet()); + names.removeAll(disabled); + return new ArtemisBootstrappedBuildItem(names); } + @SuppressWarnings("unused") + @Record(ExecutionTime.RUNTIME_INIT) @BuildStep - HealthBuildItem health(ArtemisBuildTimeConfig buildConfig, Optional artemisJms) { + ArtemisCoreConfiguredBuildItem configure( + ArtemisCoreRecorder recorder, + ArtemisRuntimeConfigs runtimeConfigs, + ArtemisBuildTimeConfigs buildTimeConfigs, + ArtemisBootstrappedBuildItem bootstrap, + BuildProducer syntheticBeanProducer, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional artemisJms) { if (artemisJms.isPresent()) { return null; } - return new HealthBuildItem( - "io.quarkus.artemis.core.runtime.health.ServerLocatorHealthCheck", - buildConfig.healthEnabled); + for (String name : bootstrap.getConnectionNames()) { + Supplier supplier = recorder.getServerLocatorSupplier( + name, + runtimeConfigs, + buildTimeConfigs); + SyntheticBeanBuildItem serverLocator = toSyntheticBeanBuildItem(name, supplier); + syntheticBeanProducer.produce(serverLocator); + } + return new ArtemisCoreConfiguredBuildItem(); } - @Record(ExecutionTime.RUNTIME_INIT) - @BuildStep - ArtemisCoreConfiguredBuildItem configure(ArtemisCoreRecorder recorder, - BuildProducer syntheticBeanProducer, Optional artemisJms) { + private static void addDynamicReflectiveBuildItems( + BuildProducer reflectiveClass, + Collection connectorFactories) { + for (ClassInfo ci : connectorFactories) { + LOGGER.debug("Adding reflective class " + ci); + reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, ci.toString())); + } + } - if (artemisJms.isPresent()) { - return null; + private static void addBuiltinReflectiveBuiltitems( + BuildProducer reflectiveClass, + Class[] builtinConnectorFactories) { + for (Class c : builtinConnectorFactories) { + reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, c)); } + } - SyntheticBeanBuildItem serverLocator = SyntheticBeanBuildItem.configure(ServerLocator.class) - .supplier(recorder.getServerLocatorSupplier()) - .scope(ApplicationScoped.class) - .defaultBean() - .unremovable() + private SyntheticBeanBuildItem toSyntheticBeanBuildItem( + String name, + Supplier supplier) { + SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem + .configure(ServerLocator.class) + .supplier(supplier) + .scope(ApplicationScoped.class); + return addQualifiers(configurator, name) .setRuntimeInit() .done(); - syntheticBeanProducer.produce(serverLocator); + } - return new ArtemisCoreConfiguredBuildItem(); + public static SyntheticBeanBuildItem.ExtendedBeanConfigurator addQualifiers( + SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator, + String name) { + if (ArtemisUtil.isDefault(name)) { + configurator + .addQualifier().annotation(Default.class).done(); + } + return configurator + .addQualifier().annotation(Identifier.class).addValue("value", name).done(); } } diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/DevServicesArtemisProcessor.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/DevServicesArtemisProcessor.java index 43ff3805..9109104b 100644 --- a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/DevServicesArtemisProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/DevServicesArtemisProcessor.java @@ -1,9 +1,11 @@ package io.quarkus.artemis.core.deployment; import java.time.Duration; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import org.jboss.logging.Logger; @@ -12,6 +14,10 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfig; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs; +import io.quarkus.artemis.core.runtime.ArtemisDevServicesBuildTimeConfig; +import io.quarkus.artemis.core.runtime.ArtemisUtil; import io.quarkus.deployment.IsNormal; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem; @@ -35,6 +41,7 @@ public class DevServicesArtemisProcessor { private static final Logger LOGGER = Logger.getLogger(DevServicesArtemisProcessor.class); private static final String QUARKUS_ARTEMIS_URL = "quarkus.artemis.url"; + private static final String QUARKUS_ARTEMIS_NAMED_URL_TEMPLATE = "quarkus.artemis.%s.url"; /** * Label to add to shared Dev Service for ActiveMQ Artemis running in containers. @@ -45,49 +52,91 @@ public class DevServicesArtemisProcessor { private static final ContainerLocator artemisContainerLocator = new ContainerLocator(DEV_SERVICE_LABEL, ARTEMIS_PORT); - static volatile RunningDevService devService; - static volatile ArtemisDevServiceCfg cfg; + static final ConcurrentHashMap devServices = new ConcurrentHashMap<>(); + static final ConcurrentHashMap cfgs = new ConcurrentHashMap<>(); static volatile boolean first = true; + @SuppressWarnings("unused") @BuildStep(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class) - public DevServicesResultBuildItem startArtemisDevService( + public List startArtemisDevService( DockerStatusBuildItem dockerStatusBuildItem, LaunchModeBuildItem launchMode, - ArtemisBuildTimeConfig artemisBuildTimeConfig, + ArtemisBootstrappedBuildItem bootstrap, + ArtemisBuildTimeConfigs buildConfigs, List devServicesSharedNetworkBuildItem, - Optional consoleInstalledBuildItem, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional consoleInstalledBuildItem, CuratedApplicationShutdownBuildItem closeBuildItem, - LoggingSetupBuildItem loggingSetupBuildItem, GlobalDevServicesConfig devServicesConfig) { + LoggingSetupBuildItem loggingSetupBuildItem, + GlobalDevServicesConfig devServicesConfig) { + ArrayList results = new ArrayList<>(); + for (String name : bootstrap.getConnectionNames()) { + ArtemisDevServiceCfg configuration = getConfiguration( + buildConfigs.getAllConfigs().getOrDefault(name, new ArtemisBuildTimeConfig()), + name); + DevServicesResultBuildItem result = start( + configuration, + name, + dockerStatusBuildItem, + launchMode, + devServicesSharedNetworkBuildItem, + consoleInstalledBuildItem, + closeBuildItem, + loggingSetupBuildItem, + devServicesConfig); + if (result != null) { + results.add(result); + } + } - ArtemisDevServiceCfg configuration = getConfiguration(artemisBuildTimeConfig); + return results; + } - if (devService != null) { - boolean shouldShutdownTheBroker = !configuration.equals(cfg); + private static DevServicesResultBuildItem start( + ArtemisDevServiceCfg configuration, + String name, + DockerStatusBuildItem dockerStatusBuildItem, + LaunchModeBuildItem launchMode, + List devServicesSharedNetworkBuildItem, + Optional consoleInstalledBuildItem, + CuratedApplicationShutdownBuildItem closeBuildItem, + LoggingSetupBuildItem loggingSetupBuildItem, + GlobalDevServicesConfig devServicesConfig) { + if (devServices.get(name) != null && configuration != null) { + boolean shouldShutdownTheBroker = !configuration.equals(cfgs.get(name)); if (!shouldShutdownTheBroker) { - return devService.toBuildItem(); + return devServices.get(name).toBuildItem(); } - shutdownBroker(); - cfg = null; + shutdownBroker(name); + cfgs.clear(); } StartupLogCompressor compressor = new StartupLogCompressor( (launchMode.isTest() ? "(test) " : "") + "ActiveMQ Artemis Dev Services Starting:", consoleInstalledBuildItem, loggingSetupBuildItem); - try { - devService = startArtemis(dockerStatusBuildItem, configuration, launchMode, - !devServicesSharedNetworkBuildItem.isEmpty(), - devServicesConfig.timeout); - if (devService == null) { + if (configuration != null) { + try { + // devServices + RunningDevService service = startArtemis( + name, + dockerStatusBuildItem, + configuration, + launchMode, + devServicesConfig.timeout); + if (service != null) { + devServices.put(name, service); + } + if (devServices.get(name) == null) { + compressor.closeAndDumpCaptured(); + } else { + compressor.close(); + } + } catch (Throwable t) { compressor.closeAndDumpCaptured(); - } else { - compressor.close(); + throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } - } catch (Throwable t) { - compressor.closeAndDumpCaptured(); - throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } - if (devService == null) { + if (devServices.get(name) == null) { return null; } @@ -95,42 +144,56 @@ public DevServicesResultBuildItem startArtemisDevService( if (first) { first = false; Runnable closeTask = () -> { - if (devService != null) { - shutdownBroker(); + for (String serviceName : devServices.keySet()) { + shutdownBroker(serviceName); } first = true; - devService = null; - cfg = null; + devServices.clear(); + cfgs.clear(); }; closeBuildItem.addCloseTask(closeTask, true); } - cfg = configuration; + cfgs.put(name, configuration); - if (devService.isOwner()) { - LOGGER.infof("Dev Services for ActiveMQ Artemis started on %s", getArtemisUrl()); + if (devServices.get(name).isOwner()) { + LOGGER.infof( + "Dev Services for ActiveMQ Artemis and named connection %s started on %s", + name, + getArtemisUrl(name)); } + return devServices.get(name).toBuildItem(); + } - return devService.toBuildItem(); + private static String getArtemisUrl(String name) { + return devServices.get(name).getConfig().get(getUrlPropertyName(name)); } - public static String getArtemisUrl() { - return devService.getConfig().get(QUARKUS_ARTEMIS_URL); + private static String getUrlPropertyName(String name) { + if (Objects.equals(ArtemisUtil.DEFAULT_CONFIG_NAME, name)) { + return QUARKUS_ARTEMIS_URL; + } else { + return String.format(QUARKUS_ARTEMIS_NAMED_URL_TEMPLATE, name); + } } - private void shutdownBroker() { - if (devService != null) { + private static void shutdownBroker(String name) { + if (devServices.get(name) != null) { try { - devService.close(); + devServices.get(name).close(); } catch (Throwable e) { LOGGER.error("Failed to stop the ActiveMQ Artemis broker", e); } finally { - devService = null; + devServices.remove(name); } } } - private RunningDevService startArtemis(DockerStatusBuildItem dockerStatusBuildItem, ArtemisDevServiceCfg config, - LaunchModeBuildItem launchMode, boolean useSharedNetwork, Optional timeout) { + private static RunningDevService startArtemis( + String name, + DockerStatusBuildItem dockerStatusBuildItem, + ArtemisDevServiceCfg config, + LaunchModeBuildItem launchMode, + Optional timeout) { if (!config.devServicesEnabled) { // explicitly disabled LOGGER.debug("Not starting dev services for ActiveMQ Artemis, as it has been disabled in the config."); @@ -138,7 +201,8 @@ private RunningDevService startArtemis(DockerStatusBuildItem dockerStatusBuildIt } // Check if quarkus.artemis.url is set - if (ConfigUtils.isPropertyPresent(QUARKUS_ARTEMIS_URL)) { + String urlPropertyName = getUrlPropertyName(name); + if (ConfigUtils.isPropertyPresent(urlPropertyName)) { LOGGER.debug("Not starting dev services for ActiveMQ Artemis, the quarkus.artemis.url is configured."); return null; } @@ -154,7 +218,8 @@ private RunningDevService startArtemis(DockerStatusBuildItem dockerStatusBuildIt launchMode.getLaunchMode()); // Starting the broker - final Supplier defaultArtemisBrokerSupplier = () -> { + String containerName = "ActiveMQ-Artemis " + name; + Supplier defaultArtemisBrokerSupplier = () -> { ArtemisContainer container = new ArtemisContainer( DockerImageName.parse(config.imageName), config.fixedExposedPort, @@ -171,24 +236,29 @@ private RunningDevService startArtemis(DockerStatusBuildItem dockerStatusBuildIt timeout.ifPresent(container::withStartupTimeout); container.start(); - return new RunningDevService("ActiveMQ-Artemis", + return new RunningDevService( + containerName, container.getContainerId(), container::close, - QUARKUS_ARTEMIS_URL, + urlPropertyName, String.format("tcp://%s:%d", container.getHost(), container.getPort())); }; return maybeContainerAddress - .map(containerAddress -> new RunningDevService("ActiveMQ-Artemis", + .map(containerAddress -> new RunningDevService( + containerName, containerAddress.getId(), null, - QUARKUS_ARTEMIS_URL, containerAddress.getUrl())) + urlPropertyName, + containerAddress.getUrl())) .orElseGet(defaultArtemisBrokerSupplier); } - private ArtemisDevServiceCfg getConfiguration(ArtemisBuildTimeConfig cfg) { - ArtemisDevServicesBuildTimeConfig devServicesConfig = cfg.devservices; - return new ArtemisDevServiceCfg(devServicesConfig); + private ArtemisDevServiceCfg getConfiguration(ArtemisBuildTimeConfig config, String name) { + if (config.getDevservices() != null) { + return new ArtemisDevServiceCfg(config.getDevservices(), name); + } + return null; } private static final class ArtemisDevServiceCfg { @@ -201,15 +271,15 @@ private static final class ArtemisDevServiceCfg { private final String password; private final String extraArgs; - public ArtemisDevServiceCfg(ArtemisDevServicesBuildTimeConfig config) { - this.devServicesEnabled = config.enabled.orElse(true); - this.imageName = config.imageName; - this.fixedExposedPort = config.port.orElse(0); - this.shared = config.shared; - this.serviceName = config.serviceName; - this.user = config.user; - this.password = config.password; - this.extraArgs = config.extraArgs; + public ArtemisDevServiceCfg(ArtemisDevServicesBuildTimeConfig config, String name) { + this.devServicesEnabled = config.isEnabled(); + this.imageName = config.getImageName(); + this.fixedExposedPort = config.getPort(); + this.shared = config.isShared(); + this.serviceName = config.getServiceName() + "-" + name; + this.user = config.getUser(); + this.password = config.getPassword(); + this.extraArgs = config.getExtraArgs(); } @Override diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthProcessor.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthProcessor.java new file mode 100644 index 00000000..2a11c479 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthProcessor.java @@ -0,0 +1,58 @@ +package io.quarkus.artemis.core.deployment.health; + +import java.util.Optional; + +import javax.enterprise.context.ApplicationScoped; + +import io.quarkus.arc.deployment.SyntheticBeanBuildItem; +import io.quarkus.artemis.core.deployment.ArtemisBootstrappedBuildItem; +import io.quarkus.artemis.core.deployment.ArtemisJmsBuildItem; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs; +import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupport; +import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupportRecorder; +import io.quarkus.artemis.core.runtime.health.ServerLocatorHealthCheck; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; + +public class ArtemisHealthProcessor { + @SuppressWarnings("unused") + @Record(ExecutionTime.RUNTIME_INIT) + @BuildStep + ArtemisHealthSupportBuildItem healthSupport( + Capabilities capabilities, + ArtemisBootstrappedBuildItem bootstrap, + ArtemisBuildTimeConfigs buildTimeConfigs, + BuildProducer syntheticBeanProducer, + ArtemisHealthSupportRecorder recorder) { + if (capabilities.isPresent(Capability.SMALLRYE_HEALTH) && buildTimeConfigs.isHealthEnabled()) { + syntheticBeanProducer.produce(SyntheticBeanBuildItem + .configure(ArtemisHealthSupport.class) + .supplier(recorder.getArtemisSupportBuilder(bootstrap.getConnectionNames(), buildTimeConfigs)) + .scope(ApplicationScoped.class) + .defaultBean() + .setRuntimeInit() + .done()); + return new ArtemisHealthSupportBuildItem(); + } + return null; + } + + @SuppressWarnings("unused") + @BuildStep + HealthBuildItem healthChecks( + Capabilities capabilities, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional artemisJms, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional artemisHealthSupportBuildItem) { + if (artemisJms.isEmpty() + && capabilities.isPresent(Capability.SMALLRYE_HEALTH) + && artemisHealthSupportBuildItem.isPresent()) { + return new HealthBuildItem(ServerLocatorHealthCheck.class.getCanonicalName(), true); + } + return null; + } +} diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthSupportBuildItem.java b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthSupportBuildItem.java new file mode 100644 index 00000000..427f04dc --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/health/ArtemisHealthSupportBuildItem.java @@ -0,0 +1,6 @@ +package io.quarkus.artemis.core.deployment.health; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class ArtemisHealthSupportBuildItem extends SimpleBuildItem { +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfig.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfig.java new file mode 100644 index 00000000..987a7727 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfig.java @@ -0,0 +1,44 @@ +package io.quarkus.artemis.core.runtime; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class ArtemisBuildTimeConfig { + + /** + * Configuration for DevServices. DevServices allows Quarkus to automatically start ActiveMQ Artemis in dev and test mode. + */ + @ConfigItem + public ArtemisDevServicesBuildTimeConfig devservices = new ArtemisDevServicesBuildTimeConfig(); + + /** + * Whether this particular data source should be excluded from the health check if + * the general health check for data sources is enabled. + *

+ * By default, the health check includes all configured data sources (if it is enabled). + */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + @ConfigItem + public Optional healthExclude = Optional.empty(); + + /** + * Support to expose {@link javax.jms.XAConnectionFactory} + */ + @ConfigItem(defaultValue = "false") + public boolean xaEnabled; + + public ArtemisDevServicesBuildTimeConfig getDevservices() { + return devservices; + } + + public boolean isHealthExclude() { + return healthExclude.orElse(false); + } + + public boolean isXaEnabled() { + return xaEnabled; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfigs.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfigs.java new file mode 100644 index 00000000..9576fa9c --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisBuildTimeConfigs.java @@ -0,0 +1,52 @@ +package io.quarkus.artemis.core.runtime; + +import java.util.HashMap; +import java.util.Map; + +import io.quarkus.runtime.annotations.*; + +@ConfigRoot(name = "artemis", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public class ArtemisBuildTimeConfigs { + + /** + * The default config + */ + @ConfigItem(name = ConfigItem.PARENT) + public ArtemisBuildTimeConfig defaultConfig = new ArtemisBuildTimeConfig(); + + /** + * Additional named configs + */ + @ConfigDocSection + @ConfigDocMapKey("configuration-name") + @ConfigItem(name = ConfigItem.PARENT) + public Map namedConfigs = new HashMap<>(); + + /** + * Whether a health check is published in case the smallrye-health extension is present. + *

+ * This is a global setting and is not specific to a datasource. + */ + @ConfigItem(name = "health.enabled", defaultValue = "true") + public boolean healthEnabled = true; + + public ArtemisBuildTimeConfig getDefaultConfig() { + return defaultConfig; + } + + public Map getNamedConfigs() { + return namedConfigs; + } + + public Map getAllConfigs() { + HashMap allConfigs = new HashMap<>(getNamedConfigs()); + if (getDefaultConfig() != null) { + allConfigs.put(ArtemisUtil.DEFAULT_CONFIG_NAME, getDefaultConfig()); + } + return allConfigs; + } + + public boolean isHealthEnabled() { + return healthEnabled; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java index 07bb1150..cc1cdea9 100644 --- a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java @@ -9,23 +9,24 @@ @Recorder public class ArtemisCoreRecorder { - - final ArtemisRuntimeConfig config; - - public ArtemisCoreRecorder(ArtemisRuntimeConfig config) { - this.config = config; - } - - public Supplier getServerLocatorSupplier() { - return new Supplier() { + public Supplier getServerLocatorSupplier( + String name, + ArtemisRuntimeConfigs runtimeConfigs, + ArtemisBuildTimeConfigs buildTimeConfigs) { + ArtemisRuntimeConfig runtimeConfig = runtimeConfigs.getAllConfigs().getOrDefault(name, new ArtemisRuntimeConfig()); + ArtemisBuildTimeConfig buildTimeConfig = buildTimeConfigs.getAllConfigs().getOrDefault(name, + new ArtemisBuildTimeConfig()); + ArtemisUtil.validateIntegrity(runtimeConfig, buildTimeConfig, name); + return new Supplier<>() { @Override public ServerLocator get() { try { - return ActiveMQClient.createServerLocator(config.url); + return ActiveMQClient.createServerLocator(runtimeConfig.getUrl()); } catch (Exception e) { - throw new RuntimeException("Could not create ServerLocator", e); + throw new RuntimeException(e); } } }; } + } diff --git a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisDevServicesBuildTimeConfig.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisDevServicesBuildTimeConfig.java similarity index 67% rename from core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisDevServicesBuildTimeConfig.java rename to core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisDevServicesBuildTimeConfig.java index 5c4b7606..70f4ef23 100644 --- a/core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisDevServicesBuildTimeConfig.java +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisDevServicesBuildTimeConfig.java @@ -1,4 +1,4 @@ -package io.quarkus.artemis.core.deployment; +package io.quarkus.artemis.core.runtime; import java.util.Optional; @@ -9,25 +9,27 @@ public class ArtemisDevServicesBuildTimeConfig { /** - * Enable or disable Dev Services explicitly. Dev Services are automatically enabled unless {@code quarkus.artemis.url} is - * set. + * Enable or disable Dev Services explicitly. Dev Services are automatically enabled unless + * {@code quarkus.artemis.url} is set. */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ConfigItem - public Optional enabled = Optional.empty(); + Optional enabled = Optional.empty(); /** * Optional fixed port the dev service will listen to. *

* If not defined, the port will be chosen randomly. */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ConfigItem - public Optional port; + Optional port = Optional.empty(); /** * The ActiveMQ Artemis container image to use. */ @ConfigItem(defaultValue = "quay.io/artemiscloud/activemq-artemis-broker:1.0.5") - public String imageName; + String imageName = "quay.io/artemiscloud/activemq-artemis-broker:1.0.5"; /** * Indicates if the ActiveMQ Artemis broker managed by Quarkus Dev Services is shared. @@ -41,7 +43,7 @@ public class ArtemisDevServicesBuildTimeConfig { * Container sharing is only used in dev mode. */ @ConfigItem(defaultValue = "true") - public boolean shared; + boolean shared = true; /** * The value of the {@code quarkus-dev-service-artemis} label attached to the started container. @@ -54,23 +56,55 @@ public class ArtemisDevServicesBuildTimeConfig { * This property is used when you need multiple shared ActiveMQ Artemis brokers. */ @ConfigItem(defaultValue = "artemis") - public String serviceName; + String serviceName = "artemis"; /** * User to start artemis broker */ @ConfigItem(defaultValue = "admin") - public String user; + String user = "admin"; /** * Password to start artemis broker */ @ConfigItem(defaultValue = "admin") - public String password; + String password = "admin"; /** * The value of the {@code AMQ_EXTRA_ARGS} environment variable to pass to the container. */ @ConfigItem(defaultValue = "--no-autotune --mapped --no-fsync") - public String extraArgs; + String extraArgs = "--no-autotune --mapped --no-fsync"; + + public boolean isEnabled() { + return enabled.orElse(true); + } + + public int getPort() { + return port.orElse(0); + } + + public String getImageName() { + return imageName; + } + + public boolean isShared() { + return shared; + } + + public String getServiceName() { + return serviceName; + } + + public String getUser() { + return user; + } + + public String getPassword() { + return password; + } + + public String getExtraArgs() { + return extraArgs; + } } diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java index 848597a2..f88fe7f8 100644 --- a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java @@ -2,28 +2,59 @@ import java.util.Optional; +import io.quarkus.runtime.annotations.ConfigGroup; import io.quarkus.runtime.annotations.ConfigItem; -import io.quarkus.runtime.annotations.ConfigPhase; -import io.quarkus.runtime.annotations.ConfigRoot; -@ConfigRoot(name = "artemis", phase = ConfigPhase.RUN_TIME) +@ConfigGroup public class ArtemisRuntimeConfig { + /** + * Whether to enable this connection. + *

+ * Is enabled by default. + */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + @ConfigItem + public Optional enabled = Optional.empty(); + /** * Artemis connection url */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ConfigItem - public String url; + public Optional url = Optional.empty(); /** * Username for authentication, only used with JMS */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ConfigItem - public Optional username; + public Optional username = Optional.empty(); /** * Password for authentication, only used with JMS */ + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ConfigItem - public Optional password; + public Optional password = Optional.empty(); + + public boolean isEnabled() { + return enabled.orElse(true); + } + + public boolean isDisabled() { + return !isEnabled(); + } + + public String getUrl() { + return url.orElse(null); + } + + public String getUsername() { + return username.orElse(null); + } + + public String getPassword() { + return password.orElse(null); + } } diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfigs.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfigs.java new file mode 100644 index 00000000..1d1daf2e --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfigs.java @@ -0,0 +1,41 @@ +package io.quarkus.artemis.core.runtime; + +import java.util.HashMap; +import java.util.Map; + +import io.quarkus.runtime.annotations.*; + +@ConfigGroup +@ConfigRoot(name = "artemis", phase = ConfigPhase.RUN_TIME) +public class ArtemisRuntimeConfigs { + + /** + * The default configuration + */ + @ConfigItem(name = ConfigItem.PARENT) + public ArtemisRuntimeConfig defaultConfig; + + /** + * Additional named configuration + */ + @ConfigDocSection + @ConfigDocMapKey("configuration-name") + @ConfigItem(name = ConfigItem.PARENT) + public Map namedConfigs = new HashMap<>(); + + public ArtemisRuntimeConfig getDefaultConfig() { + return defaultConfig; + } + + public Map getNamedConfigs() { + return namedConfigs; + } + + public Map getAllConfigs() { + HashMap allConfigs = new HashMap<>(getNamedConfigs()); + if (getDefaultConfig() != null) { + allConfigs.put(ArtemisUtil.DEFAULT_CONFIG_NAME, getDefaultConfig()); + } + return allConfigs; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisUtil.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisUtil.java new file mode 100644 index 00000000..7efbcfcf --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisUtil.java @@ -0,0 +1,27 @@ +package io.quarkus.artemis.core.runtime; + +public class ArtemisUtil { + public static final String DEFAULT_CONFIG_NAME = ""; + + private ArtemisUtil() { + } + + public static boolean isDefault(String configName) { + return DEFAULT_CONFIG_NAME.equals(configName); + } + + public static void validateIntegrity( + ArtemisRuntimeConfig runtimeConfig, + ArtemisBuildTimeConfig buildTimeConfig, + String name) { + final boolean devServiceEnabled = buildTimeConfig.getDevservices().isEnabled(); + if (runtimeConfig.getUrl() == null && devServiceEnabled) { + throw new IllegalStateException(String.format("Connection %s: url is not set and devservices is " + + "activated. This is a bug. Please report it.", name)); + } + if (runtimeConfig.getUrl() == null && !devServiceEnabled) { + throw new IllegalStateException(String.format("Connection %s: url is not set and devservices are not " + + "activated. Please set either the url or activate devservices.", name)); + } + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ShadowRunTimeConfig.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ShadowRunTimeConfig.java new file mode 100644 index 00000000..2365611c --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ShadowRunTimeConfig.java @@ -0,0 +1,41 @@ +package io.quarkus.artemis.core.runtime; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; + +@ConfigRoot(name = "artemis", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public class ShadowRunTimeConfig { + + @ConfigItem(name = ConfigItem.PARENT, generateDocumentation = false) + public ArtemisRuntimeConfigs delegate = new ArtemisRuntimeConfigs(); + + public ArtemisRuntimeConfig getDefaultConfig() { + return delegate.getDefaultConfig(); + } + + public Map getNamedConfigs() { + return delegate.getNamedConfigs(); + } + + public Map getAllConfigs() { + return delegate.getAllConfigs(); + } + + public Set getNames() { + HashSet names = new HashSet<>(); + if (getDefaultConfig().isEnabled()) { + names.add(ArtemisUtil.DEFAULT_CONFIG_NAME); + } + for (var item : getNamedConfigs().entrySet()) { + if (item.getValue().isEnabled()) { + names.add(item.getKey()); + } + } + return names; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupport.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupport.java new file mode 100644 index 00000000..f463e309 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupport.java @@ -0,0 +1,21 @@ +package io.quarkus.artemis.core.runtime.health; + +import java.util.Set; + +public class ArtemisHealthSupport { + private final Set configuredNames; + private final Set excludedNames; + + public ArtemisHealthSupport(Set configuredNames, Set excludedNames) { + this.configuredNames = configuredNames; + this.excludedNames = excludedNames; + } + + public Set getConfiguredNames() { + return configuredNames; + } + + public Set getExcludedNames() { + return excludedNames; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupportRecorder.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupportRecorder.java new file mode 100644 index 00000000..66abf644 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ArtemisHealthSupportRecorder.java @@ -0,0 +1,38 @@ +package io.quarkus.artemis.core.runtime.health; + +import java.util.*; +import java.util.function.Supplier; + +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfig; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class ArtemisHealthSupportRecorder { + public Supplier getArtemisSupportBuilder( + Set names, + ArtemisBuildTimeConfigs buildTimeConfigs) { + Set excludedNames = processConfigs(names, buildTimeConfigs); + return new Supplier<>() { + @Override + public ArtemisHealthSupport get() { + return new ArtemisHealthSupport(names, excludedNames); + } + }; + } + + private static Set processConfigs( + Set names, + ArtemisBuildTimeConfigs buildTimeConfigs) { + Set excluded = new HashSet<>(); + Map allBuildTimeConfigs = Optional.ofNullable(buildTimeConfigs.getAllConfigs()) + .orElse(Map.of()); + for (String name : names) { + ArtemisBuildTimeConfig buildTimeConfig = allBuildTimeConfigs.getOrDefault(name, new ArtemisBuildTimeConfig()); + if (buildTimeConfig.isHealthExclude()) { + excluded.add(name); + } + } + return excluded; + } +} diff --git a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ServerLocatorHealthCheck.java b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ServerLocatorHealthCheck.java index 9eed5dac..5d2376f3 100644 --- a/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ServerLocatorHealthCheck.java +++ b/core/runtime/src/main/java/io/quarkus/artemis/core/runtime/health/ServerLocatorHealthCheck.java @@ -1,7 +1,10 @@ package io.quarkus.artemis.core.runtime.health; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; @@ -10,20 +13,39 @@ import org.eclipse.microprofile.health.HealthCheckResponseBuilder; import org.eclipse.microprofile.health.Readiness; +import io.quarkus.arc.Arc; +import io.smallrye.common.annotation.Identifier; + @Readiness @ApplicationScoped public class ServerLocatorHealthCheck implements HealthCheck { + private final Map serverLocators = new HashMap<>(); - @Inject - ServerLocator serverLocator; + public ServerLocatorHealthCheck(@SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support) { + Set names = support.getConfiguredNames(); + Set excludedNames = support.getExcludedNames(); + for (String name : names) { + ServerLocator locator = Arc.container().instance(ServerLocator.class, Identifier.Literal.of(name)).get(); + if (!excludedNames.contains(name) && locator != null) { + serverLocators.put(name, locator); + } + } + } @Override public HealthCheckResponse call() { - HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis Core health check"); - try (ClientSessionFactory factory = serverLocator.createSessionFactory()) { - builder.up(); - } catch (Exception e) { - builder.down(); + if (serverLocators.isEmpty()) { + return null; + } + HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis Core health check").up(); + for (var entry : serverLocators.entrySet()) { + String name = entry.getKey(); + ServerLocator serverLocator = entry.getValue(); + try (ClientSessionFactory ignored = serverLocator.createSessionFactory()) { + builder.withData(name, "UP"); + } catch (Exception e) { + builder.withData(name, "DOWN").down(); + } } return builder.build(); } diff --git a/docs/modules/ROOT/pages/includes/attributes.adoc b/docs/modules/ROOT/pages/includes/attributes.adoc index a4b681c1..dcb1b27a 100644 --- a/docs/modules/ROOT/pages/includes/attributes.adoc +++ b/docs/modules/ROOT/pages/includes/attributes.adoc @@ -1,4 +1,4 @@ -:quarkus-version: 2.13.0.Final +:quarkus-version: 2.13.1.Final :quarkus-artemis-version: 1.3.0 :quarkus-org-url: https://github.com/quarkusio diff --git a/docs/modules/ROOT/pages/includes/quarkus-artemis-core.adoc b/docs/modules/ROOT/pages/includes/quarkus-artemis-core.adoc index 0efaa71d..b5f959a6 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-artemis-core.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-artemis-core.adoc @@ -10,38 +10,6 @@ h|[[quarkus-artemis-core_configuration]]link:#quarkus-artemis-core_configuration h|Type h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.health.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.health.enabled[quarkus.artemis.health.enabled]` - -[.description] --- -Whether or not an health check is published in case the smallrye-health extension is present - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_HEALTH_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_ARTEMIS_HEALTH_ENABLED+++` -endif::add-copy-button-to-env-var[] ---|boolean -|`true` - - -a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.xa.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.xa.enabled[quarkus.artemis.xa.enabled]` - -[.description] --- -Support to expose `javax.jms.XAConnectionFactory` - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_XA_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_ARTEMIS_XA_ENABLED+++` -endif::add-copy-button-to-env-var[] ---|boolean -|`false` - - a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.devservices.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.devservices.enabled[quarkus.artemis.devservices.enabled]` [.description] @@ -174,6 +142,73 @@ endif::add-copy-button-to-env-var[] |`--no-autotune --mapped --no-fsync` +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.health-exclude]]`link:#quarkus-artemis-core_quarkus.artemis.health-exclude[quarkus.artemis.health-exclude]` + +[.description] +-- +Whether this particular data source should be excluded from the health check if the general health check for data sources is enabled. +By default, the health check includes all configured data sources (if it is enabled). + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_HEALTH_EXCLUDE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS_HEALTH_EXCLUDE+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.xa-enabled]]`link:#quarkus-artemis-core_quarkus.artemis.xa-enabled[quarkus.artemis.xa-enabled]` + +[.description] +-- +Support to expose `javax.jms.XAConnectionFactory` + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_XA_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS_XA_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +|`false` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.health.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.health.enabled[quarkus.artemis.health.enabled]` + +[.description] +-- +Whether a health check is published in case the smallrye-health extension is present. +This is a global setting and is not specific to a datasource. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_HEALTH_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS_HEALTH_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +|`true` + + +a| [[quarkus-artemis-core_quarkus.artemis.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.enabled[quarkus.artemis.enabled]` + +[.description] +-- +Whether to enable this connection. +Is enabled by default. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + a| [[quarkus-artemis-core_quarkus.artemis.url]]`link:#quarkus-artemis-core_quarkus.artemis.url[quarkus.artemis.url]` [.description] @@ -187,7 +222,7 @@ ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_ARTEMIS_URL+++` endif::add-copy-button-to-env-var[] --|string -|required icon:exclamation-circle[title=Configuration property is required] +| a| [[quarkus-artemis-core_quarkus.artemis.username]]`link:#quarkus-artemis-core_quarkus.artemis.username[quarkus.artemis.username]` @@ -221,4 +256,244 @@ endif::add-copy-button-to-env-var[] --|string | + +h|[[quarkus-artemis-core_quarkus.artemis.named-configs-additional-named-configs]]link:#quarkus-artemis-core_quarkus.artemis.named-configs-additional-named-configs[Additional named configs] + +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.enabled[quarkus.artemis."configuration-name".devservices.enabled]` + +[.description] +-- +Enable or disable Dev Services explicitly. Dev Services are automatically enabled unless `quarkus.artemis.url` is set. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.port]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.port[quarkus.artemis."configuration-name".devservices.port]` + +[.description] +-- +Optional fixed port the dev service will listen to. +If not defined, the port will be chosen randomly. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_PORT+++` +endif::add-copy-button-to-env-var[] +--|int +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.image-name]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.image-name[quarkus.artemis."configuration-name".devservices.image-name]` + +[.description] +-- +The ActiveMQ Artemis container image to use. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_IMAGE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_IMAGE_NAME+++` +endif::add-copy-button-to-env-var[] +--|string +|`quay.io/artemiscloud/activemq-artemis-broker:1.0.5` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.shared]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.shared[quarkus.artemis."configuration-name".devservices.shared]` + +[.description] +-- +Indicates if the ActiveMQ Artemis broker managed by Quarkus Dev Services is shared. When shared, Quarkus looks for running containers using label-based service discovery. If a matching container is found, it is used, and so a second one is not started. Otherwise, Dev Services for ActiveMQ Artemis starts a new container. +The discovery uses the `quarkus-dev-service-artemis` label. The value is configured using the `service-name` property. +Container sharing is only used in dev mode. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_SHARED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_SHARED+++` +endif::add-copy-button-to-env-var[] +--|boolean +|`true` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.service-name]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.service-name[quarkus.artemis."configuration-name".devservices.service-name]` + +[.description] +-- +The value of the `quarkus-dev-service-artemis` label attached to the started container. This property is used when `shared` is set to `true`. In this case, before starting a container, Dev Services for ActiveMQ Artemis looks for a container with the `quarkus-dev-service-artemis` label set to the configured value. If found, it will use this container instead of starting a new one. Otherwise it starts a new container with the `quarkus-dev-service-artemis` label set to the specified value. +This property is used when you need multiple shared ActiveMQ Artemis brokers. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_SERVICE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_SERVICE_NAME+++` +endif::add-copy-button-to-env-var[] +--|string +|`artemis` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.user]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.user[quarkus.artemis."configuration-name".devservices.user]` + +[.description] +-- +User to start artemis broker + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_USER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_USER+++` +endif::add-copy-button-to-env-var[] +--|string +|`admin` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.password]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.password[quarkus.artemis."configuration-name".devservices.password]` + +[.description] +-- +Password to start artemis broker + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_PASSWORD+++` +endif::add-copy-button-to-env-var[] +--|string +|`admin` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.extra-args]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.devservices.extra-args[quarkus.artemis."configuration-name".devservices.extra-args]` + +[.description] +-- +The value of the `AMQ_EXTRA_ARGS` environment variable to pass to the container. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_EXTRA_ARGS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__DEVSERVICES_EXTRA_ARGS+++` +endif::add-copy-button-to-env-var[] +--|string +|`--no-autotune --mapped --no-fsync` + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.health-exclude]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.health-exclude[quarkus.artemis."configuration-name".health-exclude]` + +[.description] +-- +Whether this particular data source should be excluded from the health check if the general health check for data sources is enabled. +By default, the health check includes all configured data sources (if it is enabled). + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__HEALTH_EXCLUDE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__HEALTH_EXCLUDE+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + +a|icon:lock[title=Fixed at build time] [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.xa-enabled]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.xa-enabled[quarkus.artemis."configuration-name".xa-enabled]` + +[.description] +-- +Support to expose `javax.jms.XAConnectionFactory` + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__XA_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__XA_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +|`false` + + +h|[[quarkus-artemis-core_quarkus.artemis.named-configs-additional-named-configuration]]link:#quarkus-artemis-core_quarkus.artemis.named-configs-additional-named-configuration[Additional named configuration] + +h|Type +h|Default + +a| [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.enabled]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.enabled[quarkus.artemis."configuration-name".enabled]` + +[.description] +-- +Whether to enable this connection. +Is enabled by default. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + +a| [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.url]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.url[quarkus.artemis."configuration-name".url]` + +[.description] +-- +Artemis connection url + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__URL+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__URL+++` +endif::add-copy-button-to-env-var[] +--|string +| + + +a| [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.username]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.username[quarkus.artemis."configuration-name".username]` + +[.description] +-- +Username for authentication, only used with JMS + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__USERNAME+++` +endif::add-copy-button-to-env-var[] +--|string +| + + +a| [[quarkus-artemis-core_quarkus.artemis.-configuration-name-.password]]`link:#quarkus-artemis-core_quarkus.artemis.-configuration-name-.password[quarkus.artemis."configuration-name".password]` + +[.description] +-- +Password for authentication, only used with JMS + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_ARTEMIS__CONFIGURATION_NAME__PASSWORD+++` +endif::add-copy-button-to-env-var[] +--|string +| + |=== \ No newline at end of file diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java deleted file mode 100644 index 6b9204ee..00000000 --- a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.apache.activemq.artemis.api.core.ActiveMQException; -import org.apache.activemq.artemis.api.core.client.ClientConsumer; -import org.apache.activemq.artemis.api.core.client.ClientMessage; -import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; -import org.apache.activemq.artemis.api.core.client.ServerLocator; - -@ApplicationScoped -public class ArtemisConsumerManager { - - @Inject - ServerLocator serverLocator; - - private ClientSessionFactory connection; - - @PostConstruct - public void init() throws Exception { - connection = serverLocator.createSessionFactory(); - } - - public String receive() { - try (ClientSession session = connection.createSession()) { - session.start(); - try (ClientConsumer consumer = session.createConsumer("test-core")) { - ClientMessage message = consumer.receive(1000L); - message.acknowledge(); - return message.getBodyBuffer().readString(); - } - } catch (ActiveMQException e) { - throw new RuntimeException("Could not receive message", e); - } - } -} diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java deleted file mode 100644 index 09fcc62d..00000000 --- a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -@Path("/artemis") -public class ArtemisEndpoint { - - @Inject - ArtemisProducerManager producer; - - @Inject - ArtemisConsumerManager consumer; - - @POST - public void post(String message) { - producer.send(message); - } - - @GET - public String get() { - return consumer.receive(); - } -} diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java deleted file mode 100644 index 62fc0d7c..00000000 --- a/integration-tests/core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.apache.activemq.artemis.api.core.ActiveMQException; -import org.apache.activemq.artemis.api.core.client.ClientMessage; -import org.apache.activemq.artemis.api.core.client.ClientProducer; -import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; -import org.apache.activemq.artemis.api.core.client.ServerLocator; - -@ApplicationScoped -public class ArtemisProducerManager { - - @Inject - ServerLocator serverLocator; - - private ClientSessionFactory connection; - - @PostConstruct - public void init() throws Exception { - connection = serverLocator.createSessionFactory(); - } - - public void send(String body) { - try (ClientSession session = connection.createSession()) { - ClientMessage message = session.createMessage(true); - message.getBodyBuffer().writeString(body); - try (ClientProducer producer = session.createProducer("test-core")) { - producer.send(message); - } - } catch (ActiveMQException e) { - throw new RuntimeException("Could not send message", e); - } - } -} diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisConsumerManager.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisConsumerManager.java new file mode 100644 index 00000000..ddf49527 --- /dev/null +++ b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisConsumerManager.java @@ -0,0 +1,53 @@ +package io.quarkus.it.artemis.core; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.client.*; + +import io.smallrye.common.annotation.Identifier; + +public class ArtemisConsumerManager { + static class Producer { + @Produces + @ApplicationScoped + ArtemisConsumerManager defaultConsumer(@SuppressWarnings("CdiInjectionPointsInspection") ServerLocator serverLocator) + throws Exception { + return new ArtemisConsumerManager(serverLocator, "test-core-default"); + } + + @Produces + @ApplicationScoped + @Identifier("named-1") + ArtemisConsumerManager namedOneConsumer( + @SuppressWarnings("CdiInjectionPointsInspection") @Identifier("named-1") ServerLocator namedOneServerLocator) + throws Exception { + return new ArtemisConsumerManager(namedOneServerLocator, "test-core-named-1"); + } + + Producer() { + } + } + + private final ClientSessionFactory sessionFactory; + private final String queueName; + + private ArtemisConsumerManager(ServerLocator serverLocator, String queueName) throws Exception { + sessionFactory = serverLocator.createSessionFactory(); + this.queueName = queueName; + } + + public String receive() { + try (ClientSession session = sessionFactory.createSession()) { + session.start(); + try (ClientConsumer consumer = session.createConsumer(queueName)) { + ClientMessage message = consumer.receive(1000L); + message.acknowledge(); + return message.getBodyBuffer().readString(); + } + } catch (ActiveMQException e) { + throw new RuntimeException("Could not receive message", e); + } + } +} diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisEndpoint.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisEndpoint.java new file mode 100644 index 00000000..9d1ad624 --- /dev/null +++ b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisEndpoint.java @@ -0,0 +1,49 @@ +package io.quarkus.it.artemis.core; + +import javax.inject.Inject; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +import io.smallrye.common.annotation.Identifier; + +@Path("/artemis") +@Consumes(MediaType.TEXT_PLAIN) +@Produces(MediaType.TEXT_PLAIN) +public class ArtemisEndpoint { + + @Inject + ArtemisProducerManager defaultProducer; + + @Inject + ArtemisConsumerManager defaultConsumer; + + @Inject + @Identifier("named-1") + ArtemisProducerManager namedOneProducer; + + @Inject + @Identifier("named-1") + ArtemisConsumerManager namedOneConsumer; + + @POST + public void defaultPost(String message) { + defaultProducer.send(message); + } + + @GET + public String defaultGet() { + return defaultConsumer.receive(); + } + + @POST + @Path("named-1") + public void namedOnePost(String message) { + namedOneProducer.send(message); + } + + @GET + @Path("named-1") + public String namedOneGet(String message) { + return namedOneConsumer.receive(); + } +} diff --git a/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisProducerManager.java b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisProducerManager.java new file mode 100644 index 00000000..10f22002 --- /dev/null +++ b/integration-tests/core/src/main/java/io/quarkus/it/artemis/core/ArtemisProducerManager.java @@ -0,0 +1,52 @@ +package io.quarkus.it.artemis.core; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.client.*; + +import io.smallrye.common.annotation.Identifier; + +public class ArtemisProducerManager { + static class Producer { + @Produces + @ApplicationScoped + public static ArtemisProducerManager defaultProducer( + @SuppressWarnings("CdiInjectionPointsInspection") ServerLocator serverLocator) throws Exception { + return new ArtemisProducerManager(serverLocator, "test-core-default"); + } + + @Produces + @ApplicationScoped + @Identifier("named-1") + public static ArtemisProducerManager namedOneProducer( + @SuppressWarnings("CdiInjectionPointsInspection") @Identifier("named-1") ServerLocator namedOneServerLocator) + throws Exception { + return new ArtemisProducerManager(namedOneServerLocator, "test-core-named-1"); + } + + Producer() { + } + } + + private final ClientSessionFactory sessionFactory; + private final String queueName; + + private ArtemisProducerManager(ServerLocator serverLocator, String queueName) throws Exception { + this.sessionFactory = serverLocator.createSessionFactory(); + this.queueName = queueName; + } + + public void send(String body) { + try (ClientSession session = sessionFactory.createSession()) { + ClientMessage message = session.createMessage(true); + message.getBodyBuffer().writeString(body); + try (ClientProducer producer = session.createProducer(queueName)) { + producer.send(message); + } + } catch (ActiveMQException e) { + throw new RuntimeException("Could not send message", e); + } + } +} diff --git a/integration-tests/core/src/main/resources/application.properties b/integration-tests/core/src/main/resources/application.properties index 6b27fee5..d74730bf 100644 --- a/integration-tests/core/src/main/resources/application.properties +++ b/integration-tests/core/src/main/resources/application.properties @@ -1 +1,3 @@ quarkus.artemis.devservices.enabled=false +quarkus.artemis."named-1".devservices.enabled=false +quarkus.artemis."named-2".enabled=false diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java deleted file mode 100644 index b09ca3be..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisConsumerITCase extends ArtemisConsumerTest { - -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java deleted file mode 100644 index 05bfa017..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.ws.rs.core.Response.Status; - -import org.apache.activemq.artemis.api.core.client.ClientMessage; -import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.response.Response; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisConsumerTest implements ArtemisHelper { - - @Test - public void test() throws Exception { - String body = createBody(); - try (ClientSession session = createSession()) { - ClientMessage message = session.createMessage(true); - message.getBodyBuffer().writeString(body); - session.createProducer("test-core").send(message); - } - - Response response = RestAssured.with().body(body).get("/artemis"); - Assertions.assertEquals(Status.OK.getStatusCode(), response.statusCode()); - Assertions.assertEquals(body, response.getBody().asString()); - } -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java deleted file mode 100644 index 11ce2d1b..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisHealthCheckITCase extends ArtemisHealthCheckTest { - -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java deleted file mode 100644 index 131c0521..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.quarkus.it.artemis; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.core.Response.Status; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.common.mapper.TypeRef; -import io.restassured.response.Response; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisHealthCheckTest { - - @Test - public void test() { - Response response = RestAssured.with().get("/q/health/ready"); - Assertions.assertEquals(Status.OK.getStatusCode(), response.statusCode()); - - Map body = response.as(new TypeRef>() { - }); - Assertions.assertEquals("UP", body.get("status")); - - @SuppressWarnings("unchecked") - List> checks = (List>) body.get("checks"); - Assertions.assertEquals(1, checks.size()); - Assertions.assertEquals("Artemis Core health check", checks.get(0).get("name")); - } -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java deleted file mode 100644 index aac9133a..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisProducerITCase extends ArtemisProducerTest { - -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java deleted file mode 100644 index 72372aa3..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.quarkus.it.artemis; - -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisProducerTest extends BaseArtemisProducerTest { - - @Test - public void test() throws Exception { - super.test(); - } -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java deleted file mode 100644 index 425c4859..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.quarkus.it.artemis; - -import org.apache.activemq.artemis.api.core.client.ClientMessage; -import org.apache.activemq.artemis.api.core.client.ClientSession; -import org.junit.jupiter.api.Assertions; - -import io.restassured.RestAssured; -import io.restassured.response.Response; - -public abstract class BaseArtemisProducerTest implements ArtemisHelper { - - public void test() throws Exception { - String body = createBody(); - Response response = RestAssured.with().body(body).post("/artemis"); - Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); - - try (ClientSession session = createSession()) { - session.start(); - ClientMessage message = session.createConsumer("test-core").receive(1000L); - message.acknowledge(); - Assertions.assertEquals(body, message.getBodyBuffer().readString()); - } - } -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java deleted file mode 100644 index 3687695a..00000000 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.quarkus.it.artemis; - -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.TestProfile; - -@QuarkusTest -@TestProfile(DevServiceArtemisEnabled.class) -public class DevServiceArtemisProducerTest extends BaseArtemisProducerTest { - - @Test - public void test() throws Exception { - super.test(); - } -} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/ArtemisHelper.java similarity index 60% rename from integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java rename to integration-tests/core/src/test/java/io/quarkus/it/artemis/core/ArtemisHelper.java index 99fe1b2b..fa847a77 100644 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/ArtemisHelper.java @@ -1,4 +1,4 @@ -package io.quarkus.it.artemis; +package io.quarkus.it.artemis.core; import java.util.Random; @@ -12,8 +12,13 @@ default String createBody() { return Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 16); } - default ClientSession createSession() throws Exception { + default ClientSession createDefaultSession() throws Exception { String url = ConfigProvider.getConfig().getValue("quarkus.artemis.url", String.class); return ActiveMQClient.createServerLocator(url).createSessionFactory().createSession(); } + + default ClientSession createNamedOneSession() throws Exception { + String url = ConfigProvider.getConfig().getValue("quarkus.artemis.named-1.url", String.class); + return ActiveMQClient.createServerLocator(url).createSessionFactory().createSession(); + } } diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisConsumerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisConsumerTest.java new file mode 100644 index 00000000..7ddfb429 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisConsumerTest.java @@ -0,0 +1,36 @@ +package io.quarkus.it.artemis.core; + +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.client.ClientSession; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +public abstract class BaseArtemisConsumerTest implements ArtemisHelper { + + @Test + void testDefault() throws Exception { + test(createDefaultSession(), "test-core-default", "/artemis"); + } + + @Test + void testNamedOne() throws Exception { + test(createNamedOneSession(), "test-core-named-1", "/artemis/named-1"); + } + + private void test(ClientSession session, String addressName, String endpoint) throws ActiveMQException { + String body = createBody(); + try (ClientSession autoClosedSession = session) { + ClientMessage message = autoClosedSession.createMessage(true); + message.getBodyBuffer().writeString(body); + autoClosedSession.createProducer(addressName).send(message); + } + + Response response = RestAssured.with().body(body).get(endpoint); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.statusCode()); + Assertions.assertEquals(body, response.getBody().asString()); + } +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisHealthCheckTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisHealthCheckTest.java new file mode 100644 index 00000000..19bffeac --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisHealthCheckTest.java @@ -0,0 +1,48 @@ +package io.quarkus.it.artemis.core; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.common.mapper.TypeRef; +import io.restassured.response.Response; + +public abstract class BaseArtemisHealthCheckTest { + @Test + void testHealth() { + test("/q/health"); + } + + @Test + void testReady() { + test("/q/health/ready"); + } + + private static void test(String address) { + Response response = RestAssured.with().get(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.statusCode()); + + Map body = response.as(new TypeRef<>() { + }); + Assertions.assertEquals("UP", body.get("status")); + + @SuppressWarnings("unchecked") + List> checks = (List>) body.get("checks"); + Assertions.assertEquals(1, checks.size()); + Map check = checks.get(0); + Assertions.assertEquals("Artemis Core health check", check.get("name")); + + @SuppressWarnings("unchecked") + Map data = (Map) check.get("data"); + Assertions.assertEquals(2, data.size()); + Set namedConnections = Set.of("", "named-1"); + Assertions.assertEquals(namedConnections, data.keySet()); + for (String namedConnection : namedConnections) { + Assertions.assertEquals("UP", data.get(namedConnection)); + } + } +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisProducerTest.java new file mode 100644 index 00000000..11b5cf36 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/BaseArtemisProducerTest.java @@ -0,0 +1,35 @@ +package io.quarkus.it.artemis.core; + +import org.apache.activemq.artemis.api.core.ActiveMQException; +import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.client.ClientSession; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +public abstract class BaseArtemisProducerTest implements ArtemisHelper { + @Test + void testDefault() throws Exception { + test(createDefaultSession(), "/artemis", "test-core-default"); + } + + @Test + void testNamedOne() throws Exception { + test(createNamedOneSession(), "/artemis/named-1", "test-core-named-1"); + } + + private void test(ClientSession session, String address, String queueName) throws ActiveMQException { + String body = createBody(); + Response response = RestAssured.with().body(body).post(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); + + try (ClientSession autoClosedSession = session) { + session.start(); + ClientMessage message = autoClosedSession.createConsumer(queueName).receive(1000L); + message.acknowledge(); + Assertions.assertEquals(body, message.getBodyBuffer().readString()); + } + } +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevServiceArtemisEnabled.java similarity index 67% rename from integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java rename to integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevServiceArtemisEnabled.java index ddc945ac..2609538e 100644 --- a/integration-tests/core/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevServiceArtemisEnabled.java @@ -1,4 +1,4 @@ -package io.quarkus.it.artemis; +package io.quarkus.it.artemis.core.devservices; import java.util.HashMap; import java.util.Map; @@ -13,8 +13,9 @@ public DevServiceArtemisEnabled() { public Map getConfigOverrides() { Map props = new HashMap<>(); props.put("quarkus.artemis.devservices.enabled", "true"); - props.put("quarkus.artemis.devservices.extra-args", "--no-autotune --queues test-core"); - + props.put("quarkus.artemis.devservices.extra-args", "--no-autotune --queues test-core-default"); + props.put("quarkus.artemis.\"named-1\".devservices.enabled", "true"); + props.put("quarkus.artemis.\"named-1\".devservices.extra-args", "--no-autotune --queues test-core-named-1"); return props; } diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesConsumerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesConsumerTest.java new file mode 100644 index 00000000..b8d50e2f --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesConsumerTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.core.devservices; + +import io.quarkus.it.artemis.core.BaseArtemisConsumerTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevServiceArtemisEnabled.class) +class DevservicesConsumerTest extends BaseArtemisConsumerTest { +} \ No newline at end of file diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesHealthCheckTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesHealthCheckTest.java new file mode 100644 index 00000000..ec429333 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesHealthCheckTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.core.devservices; + +import io.quarkus.it.artemis.core.BaseArtemisHealthCheckTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevServiceArtemisEnabled.class) +class DevservicesHealthCheckTest extends BaseArtemisHealthCheckTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesProducerTest.java new file mode 100644 index 00000000..2d76b21d --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/devservices/DevservicesProducerTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.core.devservices; + +import io.quarkus.it.artemis.core.BaseArtemisProducerTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevServiceArtemisEnabled.class) +class DevservicesProducerTest extends BaseArtemisProducerTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerITCase.java new file mode 100644 index 00000000..757f5144 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedConsumerITCase extends EmbeddedConsumerTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerTest.java new file mode 100644 index 00000000..05f420dc --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedConsumerTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.core.BaseArtemisConsumerTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedConsumerTest extends BaseArtemisConsumerTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckITCase.java new file mode 100644 index 00000000..8bb274a3 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedHealthCheckITCase extends EmbeddedHealthCheckTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckTest.java new file mode 100644 index 00000000..f386e5e0 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedHealthCheckTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.core.BaseArtemisHealthCheckTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedHealthCheckTest extends BaseArtemisHealthCheckTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerITCase.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerITCase.java new file mode 100644 index 00000000..e2167644 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedProducerITCase extends EmbeddedProducerTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerTest.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerTest.java new file mode 100644 index 00000000..982c8402 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/EmbeddedProducerTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.core.BaseArtemisProducerTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedProducerTest extends BaseArtemisProducerTest { +} diff --git a/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/NamedOneArtemisTestResource.java b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/NamedOneArtemisTestResource.java new file mode 100644 index 00000000..5d206757 --- /dev/null +++ b/integration-tests/core/src/test/java/io/quarkus/it/artemis/core/embedded/NamedOneArtemisTestResource.java @@ -0,0 +1,9 @@ +package io.quarkus.it.artemis.core.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; + +public class NamedOneArtemisTestResource extends ArtemisTestResource { + public NamedOneArtemisTestResource() { + super("named-1"); + } +} diff --git a/integration-tests/core/src/test/resources/broker-named-1.xml b/integration-tests/core/src/test/resources/broker-named-1.xml new file mode 100644 index 00000000..4abe4191 --- /dev/null +++ b/integration-tests/core/src/test/resources/broker-named-1.xml @@ -0,0 +1,26 @@ + + + ./target/artemis/named-1/paging + ./target/artemis/named-1/bindings + ./target/artemis/named-1/journal + ./target/artemis/named-1/large-messages + + + tcp://localhost:61617 + + + tcp://localhost:61617 + + + -1 + false + + +

+ + + +
+ + + diff --git a/integration-tests/core/src/test/resources/broker.xml b/integration-tests/core/src/test/resources/broker.xml index c180db24..560fd565 100644 --- a/integration-tests/core/src/test/resources/broker.xml +++ b/integration-tests/core/src/test/resources/broker.xml @@ -1,9 +1,9 @@ - ./target/artemis/paging - ./target/artemis/bindings - ./target/artemis/journal - ./target/artemis/large-messages + ./target/artemis/default/paging + ./target/artemis/default/bindings + ./target/artemis/default/journal + ./target/artemis/default/large-messages tcp://localhost:61616 @@ -16,9 +16,9 @@ false -
+
- +
diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java deleted file mode 100644 index 197994e4..00000000 --- a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.jms.ConnectionFactory; -import javax.jms.JMSConsumer; -import javax.jms.JMSContext; -import javax.jms.JMSException; - -@ApplicationScoped -public class ArtemisConsumerManager { - - @Inject - ConnectionFactory connectionFactory; - - public String receive() { - try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE); - JMSConsumer consumer = context.createConsumer(context.createQueue("test-jms"))) { - return consumer.receive(1000L).getBody(String.class); - } catch (JMSException e) { - throw new RuntimeException("Could not receive message", e); - } - } -} diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java deleted file mode 100644 index 5c800f37..00000000 --- a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.inject.Inject; -import javax.transaction.Transactional; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -@Path("/artemis") -public class ArtemisEndpoint { - - @Inject - ArtemisProducerManager producer; - - @Inject - ArtemisConsumerManager consumer; - - @POST - public void post(String message) { - producer.send(message); - } - - @POST - @Path("/xa") - @Transactional - public void postXA(String message) throws Exception { - producer.sendXA(message); - } - - @GET - public String get() { - return consumer.receive(); - } -} diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java deleted file mode 100644 index 31f08efd..00000000 --- a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.jms.ConnectionFactory; -import javax.jms.JMSContext; -import javax.jms.JMSProducer; -import javax.jms.XAConnectionFactory; -import javax.jms.XAJMSContext; -import javax.transaction.Synchronization; -import javax.transaction.TransactionManager; - -@ApplicationScoped -public class ArtemisProducerManager { - - @Inject - ConnectionFactory connectionFactory; - - @Inject - XAConnectionFactory xaConnectionFactory; - - @Inject - TransactionManager tm; - - private void _send(JMSContext context, String body) { - JMSProducer producer = context.createProducer(); - producer.send(context.createQueue("test-jms"), body); - } - - public void send(String body) { - try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) { - _send(context, body); - } - } - - public void sendXA(String body) throws Exception { - XAJMSContext context = xaConnectionFactory.createXAContext(); - tm.getTransaction().enlistResource(context.getXAResource()); - tm.getTransaction().registerSynchronization(new Synchronization() { - @Override - public void beforeCompletion() { - - } - - @Override - public void afterCompletion(int i) { - context.close(); - } - }); - _send(context, body); - if (body.equals("fail")) { - tm.setRollbackOnly(); - } - } -} diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisConsumerManager.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisConsumerManager.java new file mode 100644 index 00000000..b6e6de99 --- /dev/null +++ b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisConsumerManager.java @@ -0,0 +1,46 @@ +package io.quarkus.it.artemis.jms; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.jms.ConnectionFactory; +import javax.jms.JMSConsumer; +import javax.jms.JMSContext; +import javax.jms.JMSException; + +import io.smallrye.common.annotation.Identifier; + +public class ArtemisConsumerManager { + static class Producer { + @Produces + @ApplicationScoped + ArtemisConsumerManager defaultConsumerManager( + @SuppressWarnings("CdiInjectionPointsInspection") ConnectionFactory connectionFactory) { + return new ArtemisConsumerManager(connectionFactory, "test-jms-default"); + } + + @Produces + @ApplicationScoped + @Identifier("named-1") + ArtemisConsumerManager namedOneConsumerManager( + @SuppressWarnings("CdiInjectionPointsInspection") @Identifier("named-1") ConnectionFactory namedOneConnectionFactory) { + return new ArtemisConsumerManager(namedOneConnectionFactory, "test-jms-named-1"); + } + } + + private final ConnectionFactory connectionFactory; + private final String queueName; + + public ArtemisConsumerManager(ConnectionFactory connectionFactory, String queueName) { + this.connectionFactory = connectionFactory; + this.queueName = queueName; + } + + public String receive() { + try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE); + JMSConsumer consumer = context.createConsumer(context.createQueue(queueName))) { + return consumer.receive(1000L).getBody(String.class); + } catch (JMSException e) { + throw new RuntimeException("Could not receive message", e); + } + } +} diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisEndpoint.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisEndpoint.java new file mode 100644 index 00000000..0e542a3c --- /dev/null +++ b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisEndpoint.java @@ -0,0 +1,64 @@ +package io.quarkus.it.artemis.jms; + +import javax.inject.Inject; +import javax.transaction.Transactional; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +import io.smallrye.common.annotation.Identifier; + +@Path("/artemis") +@Consumes(MediaType.TEXT_PLAIN) +@Produces(MediaType.TEXT_PLAIN) +public class ArtemisEndpoint { + + @Inject + ArtemisProducerManager defaultProducer; + + @Inject + ArtemisConsumerManager defaultConsumer; + + @Inject + @Identifier("named-1") + ArtemisProducerManager namedOneProducer; + + @Inject + @Identifier("named-1") + ArtemisConsumerManager namedOneConsumer; + + @POST + public void defaultPost(String message) { + defaultProducer.send(message); + } + + @POST + @Path("/xa") + @Transactional + public void defaultPostXA(String message) throws Exception { + defaultProducer.sendXA(message); + } + + @GET + public String defaultGet() { + return defaultConsumer.receive(); + } + + @POST + @Path("named-1") + public void namedOnePost(String message) { + namedOneProducer.send(message); + } + + @POST + @Path("named-1/xa") + @Transactional + public void namedOnePostXA(String message) throws Exception { + namedOneProducer.sendXA(message); + } + + @GET + @Path("named-1") + public String namedOneGet() { + return namedOneConsumer.receive(); + } +} diff --git a/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisProducerManager.java b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisProducerManager.java new file mode 100644 index 00000000..f1991335 --- /dev/null +++ b/integration-tests/jms/src/main/java/io/quarkus/it/artemis/jms/ArtemisProducerManager.java @@ -0,0 +1,88 @@ +package io.quarkus.it.artemis.jms; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.jms.*; +import javax.transaction.RollbackException; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.TransactionManager; + +import io.smallrye.common.annotation.Identifier; + +public class ArtemisProducerManager { + static class Producer { + @Produces + @ApplicationScoped + ArtemisProducerManager defaultProducer( + @SuppressWarnings("CdiInjectionPointsInspection") ConnectionFactory defaultConnectionFactory, + @SuppressWarnings("CdiInjectionPointsInspection") XAConnectionFactory defaultXaConnectionFactory, + @SuppressWarnings("CdiInjectionPointsInspection") TransactionManager tm) { + return new ArtemisProducerManager(defaultConnectionFactory, defaultXaConnectionFactory, tm, "test-jms-default"); + } + + @Produces + @ApplicationScoped + @Identifier("named-1") + ArtemisProducerManager namedOneProducer( + @SuppressWarnings("CdiInjectionPointsInspection") @Identifier("named-1") ConnectionFactory namedOneConnectionFactory, + @SuppressWarnings("CdiInjectionPointsInspection") @Identifier("named-1") XAConnectionFactory namedOneXaConnectionFactory, + @SuppressWarnings("CdiInjectionPointsInspection") TransactionManager tm) { + return new ArtemisProducerManager( + namedOneConnectionFactory, + namedOneXaConnectionFactory, + tm, + "test-jms-named-1"); + } + + Producer() { + } + } + + private final ConnectionFactory connectionFactory; + private final XAConnectionFactory xaConnectionFactory; + private final TransactionManager tm; + private final String queueName; + + private ArtemisProducerManager( + ConnectionFactory connectionFactory, + XAConnectionFactory xaConnectionFactory, + TransactionManager tm, + String queueName) { + this.connectionFactory = connectionFactory; + this.xaConnectionFactory = xaConnectionFactory; + this.tm = tm; + this.queueName = queueName; + } + + private void send(JMSContext context, String body) { + JMSProducer producer = context.createProducer(); + producer.send(context.createQueue(queueName), body); + } + + public void send(String body) { + try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) { + send(context, body); + } + } + + public void sendXA(String body) throws SystemException, RollbackException { + XAJMSContext context = xaConnectionFactory.createXAContext(); + tm.getTransaction().enlistResource(context.getXAResource()); + tm.getTransaction().registerSynchronization(new Synchronization() { + @Override + public void beforeCompletion() { + + } + + @Override + public void afterCompletion(int i) { + context.close(); + } + }); + send(context, body); + if (body.equals("fail")) { + tm.setRollbackOnly(); + } + } +} diff --git a/integration-tests/jms/src/main/resources/application.properties b/integration-tests/jms/src/main/resources/application.properties index 65e531c5..e3fbeaee 100644 --- a/integration-tests/jms/src/main/resources/application.properties +++ b/integration-tests/jms/src/main/resources/application.properties @@ -1,2 +1,5 @@ quarkus.artemis.devservices.enabled=false -quarkus.artemis.xa.enabled=true \ No newline at end of file +quarkus.artemis.xa-enabled=true +quarkus.artemis."named-1".devservices.enabled=false +quarkus.artemis."named-1".xa-enabled=true +quarkus.artemis."named-2".enabled=false \ No newline at end of file diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java deleted file mode 100644 index b09ca3be..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisConsumerITCase extends ArtemisConsumerTest { - -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java deleted file mode 100644 index e05003e6..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.jms.JMSContext; -import javax.ws.rs.core.Response.Status; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.response.Response; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisConsumerTest implements ArtemisHelper { - - @Test - public void test() throws Exception { - String body = createBody(); - try (JMSContext context = createContext()) { - context.createProducer().send(context.createQueue("test-jms"), body); - } - - Response response = RestAssured.with().body(body).get("/artemis"); - Assertions.assertEquals(Status.OK.getStatusCode(), response.statusCode()); - Assertions.assertEquals(body, response.getBody().asString()); - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java deleted file mode 100644 index 11ce2d1b..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisHealthCheckITCase extends ArtemisHealthCheckTest { - -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java deleted file mode 100644 index 26c266fc..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHealthCheckTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.quarkus.it.artemis; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.core.Response.Status; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.common.mapper.TypeRef; -import io.restassured.response.Response; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisHealthCheckTest { - - @Test - public void test() { - Response response = RestAssured.with().get("/q/health/ready"); - Assertions.assertEquals(Status.OK.getStatusCode(), response.statusCode()); - - Map body = response.as(new TypeRef>() { - }); - Assertions.assertEquals("UP", body.get("status")); - - @SuppressWarnings("unchecked") - List> checks = (List>) body.get("checks"); - Assertions.assertEquals(1, checks.size()); - Assertions.assertEquals("Artemis JMS health check", checks.get(0).get("name")); - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java deleted file mode 100644 index aac9133a..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisProducerITCase extends ArtemisProducerTest { - -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java deleted file mode 100644 index d42bcebc..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.quarkus.it.artemis; - -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisProducerTest extends BaseArtemisProducerTest { - @Test - public void test() throws Exception { - super.test(); - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXAITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXAITCase.java deleted file mode 100644 index 07610ab5..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXAITCase.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.artemis; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ArtemisProducerXAITCase extends ArtemisProducerXATest { -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXATest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXATest.java deleted file mode 100644 index 404f0c7f..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerXATest.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.jms.JMSConsumer; -import javax.jms.JMSContext; -import javax.jms.Message; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import io.quarkus.artemis.test.ArtemisTestResource; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.response.Response; - -@QuarkusTest -@QuarkusTestResource(ArtemisTestResource.class) -public class ArtemisProducerXATest extends BaseArtemisProducerTest { - @Test - public void test() throws Exception { - super.test(); - } - - @Test - public void testXA() throws Exception { - String body = createBody(); - Response response = RestAssured.with().body(body).post("/artemis/xa"); - Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); - - try (JMSContext context = createContext()) { - JMSConsumer consumer = context.createConsumer(context.createQueue("test-jms")); - Message message = consumer.receive(1000L); - Assertions.assertEquals(body, message.getBody(String.class)); - } - } - - @Test - public void testRollback() throws Exception { - String body = "fail"; - Response response = RestAssured.with().body(body).post("/artemis/xa"); - Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); - - try (JMSContext context = createContext()) { - JMSConsumer consumer = context.createConsumer(context.createQueue("test-jms")); - Message message = consumer.receive(1000L); - Assertions.assertNull(message); - } - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java deleted file mode 100644 index 8294f3d2..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/BaseArtemisProducerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.it.artemis; - -import javax.jms.JMSConsumer; -import javax.jms.JMSContext; -import javax.jms.Message; - -import org.junit.jupiter.api.Assertions; - -import io.restassured.RestAssured; -import io.restassured.response.Response; - -abstract public class BaseArtemisProducerTest implements ArtemisHelper { - - public void test() throws Exception { - String body = createBody(); - Response response = RestAssured.with().body(body).post("/artemis"); - Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); - - try (JMSContext context = createContext()) { - JMSConsumer consumer = context.createConsumer(context.createQueue("test-jms")); - Message message = consumer.receive(1000L); - Assertions.assertEquals(body, message.getBody(String.class)); - } - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java deleted file mode 100644 index 378e5a54..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisEnabled.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.quarkus.it.artemis; - -import java.util.Collections; -import java.util.Map; - -import io.quarkus.test.junit.QuarkusTestProfile; - -public class DevServiceArtemisEnabled implements QuarkusTestProfile { - public DevServiceArtemisEnabled() { - } - - @Override - public Map getConfigOverrides() { - return Collections.singletonMap("quarkus.artemis.devservices.enabled", "true"); - } - - @Override - public boolean disableGlobalTestResources() { - return true; - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java deleted file mode 100644 index 5b7cd1e5..00000000 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/DevServiceArtemisProducerTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkus.it.artemis; - -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.TestProfile; - -@QuarkusTest -@TestProfile(DevServiceArtemisEnabled.class) -public class DevServiceArtemisProducerTest extends BaseArtemisProducerTest { - @Test - public void test() throws Exception { - super.test(); - } -} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/ArtemisHelper.java similarity index 61% rename from integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java rename to integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/ArtemisHelper.java index 96b12d5d..08fd3b32 100644 --- a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/ArtemisHelper.java @@ -1,9 +1,8 @@ -package io.quarkus.it.artemis; +package io.quarkus.it.artemis.jms; import java.util.Random; import javax.jms.JMSContext; -import javax.jms.JMSException; import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory; import org.eclipse.microprofile.config.ConfigProvider; @@ -14,8 +13,13 @@ default String createBody() { return Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 16); } - default JMSContext createContext() throws JMSException { + default JMSContext createDefaultContext() { String url = ConfigProvider.getConfig().getValue("quarkus.artemis.url", String.class); return new ActiveMQJMSConnectionFactory(url).createContext(JMSContext.AUTO_ACKNOWLEDGE); } + + default JMSContext createNamedOnContext() { + String url = ConfigProvider.getConfig().getValue("quarkus.artemis.named-1.url", String.class); + return new ActiveMQJMSConnectionFactory(url).createContext(JMSContext.AUTO_ACKNOWLEDGE); + } } diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisConsumerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisConsumerTest.java new file mode 100644 index 00000000..438047cd --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisConsumerTest.java @@ -0,0 +1,32 @@ +package io.quarkus.it.artemis.jms; + +import javax.jms.JMSContext; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +public abstract class BaseArtemisConsumerTest implements ArtemisHelper { + @Test + void testDefault() { + test(createDefaultContext(), "test-jms-default", "/artemis"); + } + + @Test + void testNamedOne() { + test(createNamedOnContext(), "test-jms-named-1", "/artemis/named-1"); + } + + private void test(JMSContext context, String queueName, String address) { + String body = createBody(); + try (JMSContext ignored = context) { + context.createProducer().send(context.createQueue(queueName), body); + } + + Response response = RestAssured.with().body(body).get(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.statusCode()); + Assertions.assertEquals(body, response.getBody().asString()); + } +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisHealthCheckTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisHealthCheckTest.java new file mode 100644 index 00000000..8e9e9332 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisHealthCheckTest.java @@ -0,0 +1,48 @@ +package io.quarkus.it.artemis.jms; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.common.mapper.TypeRef; +import io.restassured.response.Response; + +public abstract class BaseArtemisHealthCheckTest { + @Test + void testHealth() { + test("/q/health"); + } + + @Test + void testReady() { + test("/q/health/ready"); + } + + private static void test(String address) { + Response response = RestAssured.with().get(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.statusCode()); + + Map body = response.as(new TypeRef<>() { + }); + Assertions.assertEquals("UP", body.get("status")); + + @SuppressWarnings("unchecked") + List> checks = (List>) body.get("checks"); + Assertions.assertEquals(1, checks.size()); + Map check = checks.get(0); + Assertions.assertEquals("Artemis JMS health check", check.get("name")); + + @SuppressWarnings("unchecked") + Map data = (Map) check.get("data"); + Assertions.assertEquals(2, data.size()); + Set namedConnections = Set.of("", "named-1"); + Assertions.assertEquals(namedConnections, data.keySet()); + for (String namedConnection : namedConnections) { + Assertions.assertEquals("UP", data.get(namedConnection)); + } + } +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerTest.java new file mode 100644 index 00000000..432421d3 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerTest.java @@ -0,0 +1,36 @@ +package io.quarkus.it.artemis.jms; + +import javax.jms.JMSConsumer; +import javax.jms.JMSContext; +import javax.jms.JMSException; +import javax.jms.Message; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +abstract public class BaseArtemisProducerTest implements ArtemisHelper { + @Test + void testDefault() throws Exception { + test(createDefaultContext(), "/artemis", "test-jms-default"); + } + + @Test + void testNamedOne() throws Exception { + test(createNamedOnContext(), "/artemis/named-1", "test-jms-named-1"); + } + + private void test(JMSContext context, String address, String queueName) throws JMSException { + String body = createBody(); + Response response = RestAssured.with().body(body).post(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); + + try (JMSContext autoClosedContext = context) { + JMSConsumer consumer = autoClosedContext.createConsumer(autoClosedContext.createQueue(queueName)); + Message message = consumer.receive(1000L); + Assertions.assertEquals(body, message.getBody(String.class)); + } + } +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerXATest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerXATest.java new file mode 100644 index 00000000..1e05577d --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/BaseArtemisProducerXATest.java @@ -0,0 +1,57 @@ +package io.quarkus.it.artemis.jms; + +import javax.jms.JMSConsumer; +import javax.jms.JMSContext; +import javax.jms.JMSException; +import javax.jms.Message; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +public abstract class BaseArtemisProducerXATest extends BaseArtemisProducerTest { + @Test + void testXADefault() throws Exception { + testXA(createDefaultContext(), "/artemis/xa", "test-jms-default"); + } + + @Test + void testXANamedOne() throws Exception { + testXA(createNamedOnContext(), "/artemis/named-1/xa", "test-jms-named-1"); + } + + private void testXA(JMSContext context, String address, String queueName) throws JMSException { + String body = createBody(); + Response response = RestAssured.with().body(body).post(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); + + try (JMSContext autoClosedContext = context) { + JMSConsumer consumer = autoClosedContext.createConsumer(autoClosedContext.createQueue(queueName)); + Message message = consumer.receive(1000L); + Assertions.assertEquals(body, message.getBody(String.class)); + } + } + + @Test + public void testRollbackDefault() { + testRollback(createDefaultContext(), "/artemis/xa", "test-jms-default"); + } + + @Test + public void testRollbackNamedOne() { + testRollback(createNamedOnContext(), "/artemis/named-1/xa", "test-jms-named-1"); + } + + private void testRollback(JMSContext context, String address, String queueName) { + Response response = RestAssured.with().body("fail").post(address); + Assertions.assertEquals(javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.statusCode()); + + try (JMSContext autoClosedContext = context) { + JMSConsumer consumer = autoClosedContext.createConsumer(autoClosedContext.createQueue(queueName)); + Message message = consumer.receive(1000L); + Assertions.assertNull(message); + } + } +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesArtemisEnabled.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesArtemisEnabled.java new file mode 100644 index 00000000..c576e76d --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesArtemisEnabled.java @@ -0,0 +1,24 @@ +package io.quarkus.it.artemis.jms.devservices; + +import java.util.HashMap; +import java.util.Map; + +import io.quarkus.test.junit.QuarkusTestProfile; + +public class DevservicesArtemisEnabled implements QuarkusTestProfile { + public DevservicesArtemisEnabled() { + } + + @Override + public Map getConfigOverrides() { + Map props = new HashMap<>(); + props.put("quarkus.artemis.devservices.enabled", "true"); + props.put("quarkus.artemis.\"named-1\".devservices.enabled", "true"); + return props; + } + + @Override + public boolean disableGlobalTestResources() { + return true; + } +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesConsumerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesConsumerTest.java new file mode 100644 index 00000000..65c549b7 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesConsumerTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.jms.devservices; + +import io.quarkus.it.artemis.jms.BaseArtemisConsumerTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevservicesArtemisEnabled.class) +class DevservicesConsumerTest extends BaseArtemisConsumerTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesHealthCheckTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesHealthCheckTest.java new file mode 100644 index 00000000..0c92b0b7 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesHealthCheckTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.jms.devservices; + +import io.quarkus.it.artemis.jms.BaseArtemisHealthCheckTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevservicesArtemisEnabled.class) +class DevservicesHealthCheckTest extends BaseArtemisHealthCheckTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerTest.java new file mode 100644 index 00000000..2034c612 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerTest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.jms.devservices; + +import io.quarkus.it.artemis.jms.BaseArtemisProducerTest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevservicesArtemisEnabled.class) +class DevservicesProducerTest extends BaseArtemisProducerTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerXATest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerXATest.java new file mode 100644 index 00000000..7f2b1fa7 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/devservices/DevservicesProducerXATest.java @@ -0,0 +1,10 @@ +package io.quarkus.it.artemis.jms.devservices; + +import io.quarkus.it.artemis.jms.BaseArtemisProducerXATest; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(DevservicesArtemisEnabled.class) +class DevservicesProducerXATest extends BaseArtemisProducerXATest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerITCase.java new file mode 100644 index 00000000..701d07ad --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedConsumerITCase extends EmbeddedConsumerTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerTest.java new file mode 100644 index 00000000..541b50b3 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedConsumerTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.jms.BaseArtemisConsumerTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedConsumerTest extends BaseArtemisConsumerTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckITCase.java new file mode 100644 index 00000000..44e98df9 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedHealthCheckITCase extends EmbeddedHealthCheckTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckTest.java new file mode 100644 index 00000000..3b5b701a --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedHealthCheckTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.jms.BaseArtemisHealthCheckTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedHealthCheckTest extends BaseArtemisHealthCheckTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerITCase.java new file mode 100644 index 00000000..3f1cd62b --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerITCase.java @@ -0,0 +1,8 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedProducerITCase extends EmbeddedProducerTest { + +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerTest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerTest.java new file mode 100644 index 00000000..8d2d5ebb --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerTest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.jms.BaseArtemisProducerTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedProducerTest extends BaseArtemisProducerTest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXAITCase.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXAITCase.java new file mode 100644 index 00000000..d60686c2 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXAITCase.java @@ -0,0 +1,7 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class EmbeddedProducerXAITCase extends EmbeddedProducerXATest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXATest.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXATest.java new file mode 100644 index 00000000..0810cde6 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/EmbeddedProducerXATest.java @@ -0,0 +1,12 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; +import io.quarkus.it.artemis.jms.BaseArtemisProducerXATest; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +@QuarkusTestResource(NamedOneArtemisTestResource.class) +class EmbeddedProducerXATest extends BaseArtemisProducerXATest { +} diff --git a/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/NamedOneArtemisTestResource.java b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/NamedOneArtemisTestResource.java new file mode 100644 index 00000000..01f83d09 --- /dev/null +++ b/integration-tests/jms/src/test/java/io/quarkus/it/artemis/jms/embedded/NamedOneArtemisTestResource.java @@ -0,0 +1,9 @@ +package io.quarkus.it.artemis.jms.embedded; + +import io.quarkus.artemis.test.ArtemisTestResource; + +public class NamedOneArtemisTestResource extends ArtemisTestResource { + public NamedOneArtemisTestResource() { + super("named-1"); + } +} diff --git a/integration-tests/jms/src/test/resources/broker-named-1.xml b/integration-tests/jms/src/test/resources/broker-named-1.xml new file mode 100644 index 00000000..ea7f4e39 --- /dev/null +++ b/integration-tests/jms/src/test/resources/broker-named-1.xml @@ -0,0 +1,26 @@ + + + ./target/artemis/named-1/paging + ./target/artemis/named-1/bindings + ./target/artemis/named-1/journal + ./target/artemis/named-1/large-messages + + + tcp://localhost:61617 + + + tcp://localhost:61617 + + + -1 + false + + +
+ + + +
+
+
+
diff --git a/integration-tests/jms/src/test/resources/broker.xml b/integration-tests/jms/src/test/resources/broker.xml index 7a71d2d7..c777d4d6 100644 --- a/integration-tests/jms/src/test/resources/broker.xml +++ b/integration-tests/jms/src/test/resources/broker.xml @@ -1,9 +1,9 @@ - ./target/artemis/paging - ./target/artemis/bindings - ./target/artemis/journal - ./target/artemis/large-messages + ./target/artemis/default/paging + ./target/artemis/default/bindings + ./target/artemis/default/journal + ./target/artemis/default/large-messages tcp://localhost:61616 @@ -16,9 +16,9 @@ false -
+
- +
diff --git a/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java b/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java index 134c0a79..980b415c 100644 --- a/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java +++ b/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java @@ -1,6 +1,9 @@ package io.quarkus.artemis.jms.deployment; +import java.util.HashSet; import java.util.Optional; +import java.util.Set; +import java.util.function.Supplier; import javax.enterprise.context.ApplicationScoped; import javax.jms.ConnectionFactory; @@ -9,45 +12,86 @@ import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; -import io.quarkus.artemis.core.deployment.ArtemisBuildTimeConfig; +import io.quarkus.artemis.core.deployment.ArtemisBootstrappedBuildItem; +import io.quarkus.artemis.core.deployment.ArtemisCoreProcessor; import io.quarkus.artemis.core.deployment.ArtemisJmsBuildItem; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfig; +import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfigs; import io.quarkus.artemis.jms.runtime.ArtemisJmsRecorder; +import io.quarkus.artemis.jms.runtime.ArtemisJmsWrapper; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; public class ArtemisJmsProcessor { private static final String FEATURE = "artemis-jms"; + @SuppressWarnings("unused") @BuildStep FeatureBuildItem feature() { return new FeatureBuildItem(FEATURE); } + @SuppressWarnings("unused") @BuildStep void load(BuildProducer artemisJms) { artemisJms.produce(new ArtemisJmsBuildItem()); } - @BuildStep - HealthBuildItem health(ArtemisBuildTimeConfig buildConfig) { - return new HealthBuildItem( - "io.quarkus.artemis.jms.runtime.health.ConnectionFactoryHealthCheck", - buildConfig.healthEnabled); - } - + @SuppressWarnings("unused") @Record(ExecutionTime.RUNTIME_INIT) @BuildStep - ArtemisJmsConfiguredBuildItem configure(ArtemisJmsRecorder recorder, ArtemisBuildTimeConfig config, - Optional wrapper, + ArtemisJmsConfiguredBuildItem configure( + ArtemisJmsRecorder recorder, + ArtemisRuntimeConfigs runtimeConfigs, + ArtemisBuildTimeConfigs buildTimeConfigs, + ArtemisBootstrappedBuildItem bootstrap, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional wrapperItem, BuildProducer syntheticBeanProducer) { + ArtemisJmsWrapper wrapper = getWrapper(recorder, wrapperItem); + final Set connectionNames = bootstrap.getConnectionNames(); + recorder.init(runtimeConfigs, buildTimeConfigs, new HashSet<>(connectionNames)); + for (String name : connectionNames) { + Supplier connectionFactorySupplier = recorder.getConnectionFactoryProducer(name, wrapper); + syntheticBeanProducer.produce(toSyntheticBeanBuildItem( + name, + connectionFactorySupplier, + buildTimeConfigs.getAllConfigs().getOrDefault(name, new ArtemisBuildTimeConfig()).isXaEnabled())); + } + return new ArtemisJmsConfiguredBuildItem(); + } + + private static ArtemisJmsWrapper getWrapper( + ArtemisJmsRecorder recorder, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional wrapperItem) { + ArtemisJmsWrapper wrapper; + if (wrapperItem.isPresent()) { + wrapper = wrapperItem.get().getWrapper(); + } else { + wrapper = new ArtemisJmsWrapperBuildItem(recorder.getDefaultWrapper()).getWrapper(); + } + return wrapper; + } + + private static SyntheticBeanBuildItem toSyntheticBeanBuildItem( + String name, + Supplier connectionFactorySupplier, + boolean isXaEnable) { + SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = initializeConfigurator(isXaEnable) + .supplier(connectionFactorySupplier) + .scope(ApplicationScoped.class); + return ArtemisCoreProcessor.addQualifiers(configurator, name) + .setRuntimeInit() + .done(); + } + private static SyntheticBeanBuildItem.ExtendedBeanConfigurator initializeConfigurator(boolean isXaEnable) { SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator; - if (config.xaEnabled) { + if (isXaEnable) { configurator = SyntheticBeanBuildItem.configure(ActiveMQConnectionFactory.class); /** * Since {@link ActiveMQConnectionFactory} implements both {@link ConnectionFactory} and @@ -60,16 +104,6 @@ ArtemisJmsConfiguredBuildItem configure(ArtemisJmsRecorder recorder, ArtemisBuil } else { configurator = SyntheticBeanBuildItem.configure(ConnectionFactory.class); } - - configurator.supplier(recorder.getConnectionFactorySupplier( - wrapper.orElseGet(() -> new ArtemisJmsWrapperBuildItem(recorder.getDefaultWrapper())).getWrapper())) - .scope(ApplicationScoped.class) - .defaultBean() - .unremovable() - .setRuntimeInit(); - - syntheticBeanProducer.produce(configurator.done()); - - return new ArtemisJmsConfiguredBuildItem(); + return configurator; } } diff --git a/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/health/ConnectorFactoryHealthCheckProcessor.java b/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/health/ConnectorFactoryHealthCheckProcessor.java new file mode 100644 index 00000000..2d7130a2 --- /dev/null +++ b/jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/health/ConnectorFactoryHealthCheckProcessor.java @@ -0,0 +1,13 @@ +package io.quarkus.artemis.jms.deployment.health; + +import io.quarkus.artemis.core.deployment.health.ArtemisHealthSupportBuildItem; +import io.quarkus.artemis.jms.runtime.health.ConnectionFactoryHealthCheck; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; + +public class ConnectorFactoryHealthCheckProcessor { + @BuildStep() + HealthBuildItem healthChecks(ArtemisHealthSupportBuildItem artemisHealthSupportBuildItem) { + return new HealthBuildItem(ConnectionFactoryHealthCheck.class.getCanonicalName(), true); + } +} diff --git a/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java b/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java index eef3a302..9a1163ae 100644 --- a/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java +++ b/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java @@ -1,21 +1,33 @@ package io.quarkus.artemis.jms.runtime; +import java.util.Collection; +import java.util.HashMap; import java.util.function.Supplier; import javax.jms.ConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; -import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; +import io.quarkus.artemis.core.runtime.*; import io.quarkus.runtime.annotations.Recorder; @Recorder public class ArtemisJmsRecorder { + private HashMap connectionFactoryConfigs; - final ArtemisRuntimeConfig config; - - public ArtemisJmsRecorder(ArtemisRuntimeConfig config) { - this.config = config; + public void init( + ArtemisRuntimeConfigs runtimeConfigs, + ArtemisBuildTimeConfigs buildTimeConfigs, + Collection connectionNames) { + connectionFactoryConfigs = new HashMap<>(); + for (String name : connectionNames) { + connectionFactoryConfigs.put( + name, + new ConnectionFactoryConfig( + name, + runtimeConfigs.getAllConfigs().getOrDefault(name, new ArtemisRuntimeConfig()), + buildTimeConfigs.getAllConfigs().getOrDefault(name, new ArtemisBuildTimeConfig()))); + } } public ArtemisJmsWrapper getDefaultWrapper() { @@ -27,15 +39,56 @@ public ConnectionFactory wrapConnectionFactory(ActiveMQConnectionFactory cf) { }; } - public Supplier getConnectionFactorySupplier(ArtemisJmsWrapper wrapper) { - return new Supplier() { + public Supplier getConnectionFactoryProducer( + String name, + ArtemisJmsWrapper wrapper) { + ConnectionFactoryConfig config = connectionFactoryConfigs.get(name); + ConnectionFactory connectionFactory; + connectionFactory = extractConnectionFactory(wrapper, config); + return new Supplier<>() { @Override public ConnectionFactory get() { - ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(config.url, - config.username.orElse(null), - config.password.orElse(null)); - return wrapper.wrapConnectionFactory(connectionFactory); + return connectionFactory; } }; } + + private static ConnectionFactory extractConnectionFactory(ArtemisJmsWrapper wrapper, ConnectionFactoryConfig config) { + if (config.getUrl() != null) { + return wrapper.wrapConnectionFactory(new ActiveMQConnectionFactory( + config.getUrl(), + config.getUsername(), + config.getPassword())); + } + return null; + } + + private static class ConnectionFactoryConfig { + final String url; + final ArtemisRuntimeConfig runtimeConfig; + + private ConnectionFactoryConfig( + String name, + ArtemisRuntimeConfig runtimeConfig, + ArtemisBuildTimeConfig buildTimeConfig) { + this.runtimeConfig = runtimeConfig; + if (buildTimeConfig == null) { + buildTimeConfig = new ArtemisBuildTimeConfig(); + } + ArtemisUtil.validateIntegrity(runtimeConfig, buildTimeConfig, name); + this.url = runtimeConfig.getUrl(); + } + + public String getUrl() { + return runtimeConfig.getUrl(); + } + + public String getUsername() { + return runtimeConfig.getUsername(); + } + + public String getPassword() { + return runtimeConfig.getPassword(); + } + } } diff --git a/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/health/ConnectionFactoryHealthCheck.java b/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/health/ConnectionFactoryHealthCheck.java index c171de77..ceec12b0 100644 --- a/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/health/ConnectionFactoryHealthCheck.java +++ b/jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/health/ConnectionFactoryHealthCheck.java @@ -1,7 +1,10 @@ package io.quarkus.artemis.jms.runtime.health; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; import javax.jms.Connection; import javax.jms.ConnectionFactory; @@ -10,20 +13,44 @@ import org.eclipse.microprofile.health.HealthCheckResponseBuilder; import org.eclipse.microprofile.health.Readiness; +import io.quarkus.arc.Arc; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfigs; +import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupport; +import io.smallrye.common.annotation.Identifier; + @Readiness @ApplicationScoped public class ConnectionFactoryHealthCheck implements HealthCheck { - @Inject - ConnectionFactory connectionFactory; + private final Map connectionFactories = new HashMap<>(); + + public ConnectionFactoryHealthCheck( + @SuppressWarnings("CdiInjectionPointsInspection") ArtemisRuntimeConfigs runtimeConfigs, + @SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support) { + Set names = support.getConfiguredNames(); + Set excludedNames = support.getExcludedNames(); + for (String name : names) { + if (runtimeConfigs.getAllConfigs().getOrDefault(name, new ArtemisRuntimeConfig()).getUrl() != null) { + ConnectionFactory connectionFactory = Arc.container() + .instance(ConnectionFactory.class, Identifier.Literal.of(name)).get(); + if (!excludedNames.contains(name) && connectionFactory != null) { + connectionFactories.put(name, connectionFactory); + } + } + } + } @Override public HealthCheckResponse call() { - HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis JMS health check"); - try (Connection connection = connectionFactory.createConnection()) { - builder.up(); - } catch (Exception e) { - builder.down(); + HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis JMS health check").up(); + for (var entry : connectionFactories.entrySet()) { + String name = entry.getKey(); + try (Connection ignored = entry.getValue().createConnection()) { + builder.withData(name, "UP"); + } catch (Exception e) { + builder.withData(name, "DOWN").down(); + } } return builder.build(); } diff --git a/test-framework/src/main/java/io/quarkus/artemis/test/ArtemisTestResource.java b/test-framework/src/main/java/io/quarkus/artemis/test/ArtemisTestResource.java index ca50bf51..675a1473 100644 --- a/test-framework/src/main/java/io/quarkus/artemis/test/ArtemisTestResource.java +++ b/test-framework/src/main/java/io/quarkus/artemis/test/ArtemisTestResource.java @@ -3,6 +3,7 @@ import java.nio.file.Paths; import java.util.Collections; import java.util.Map; +import java.util.Objects; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; @@ -11,22 +12,36 @@ import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class ArtemisTestResource implements QuarkusTestResourceLifecycleManager { + private static final String DEFAULT_CONNECTION_NAME = ""; + private final String connectionName; private EmbeddedActiveMQ embedded; + @SuppressWarnings("unused") + public ArtemisTestResource() { + this(DEFAULT_CONNECTION_NAME); + } + + protected ArtemisTestResource(String connectionName) { + this.connectionName = Objects.requireNonNull(connectionName); + } + @Override public Map start() { try { - FileUtils.deleteDirectory(Paths.get("./target/artemis").toFile()); - embedded = new EmbeddedActiveMQ(); + final String artemisPath = String.format("./target/artemis/%s", connectionName); + FileUtils.deleteDirectory(Paths.get(artemisPath).toFile()); + embedded = new EmbeddedActiveMQ() + .setConfigResourcePath(getConfigurationFileName()); embedded.start(); } catch (Exception e) { - throw new RuntimeException("Could not start embedded ActiveMQ server", e); + throw new RuntimeException("Could not start embedded ActiveMQ server for connection " + connectionName, e); } for (TransportConfiguration config : embedded.getConfiguration().getAcceptorConfigurations()) { if (config.getName().equals("activemq")) { - return Collections.singletonMap("quarkus.artemis.url", + return Collections.singletonMap( + getUrlConfigKey(), String.format("tcp://%s:%s", config.getParams().get("host"), config.getParams().get("port"))); } } @@ -34,15 +49,28 @@ public Map start() { return Collections.emptyMap(); } + private String getConfigurationFileName() { + if (connectionName.equals(DEFAULT_CONNECTION_NAME)) { + return "broker.xml"; + } + return String.format("broker-%s.xml", connectionName); + } + + private String getUrlConfigKey() { + if (connectionName.equals(DEFAULT_CONNECTION_NAME)) { + return "quarkus.artemis.url"; + } + return String.format("quarkus.artemis.%s.url", connectionName); + } + @Override public void stop() { - if (embedded == null) { - return; - } - try { - embedded.stop(); - } catch (Exception e) { - throw new RuntimeException("Could not stop embedded ActiveMQ server", e); + if (embedded != null) { + try { + embedded.stop(); + } catch (Exception e) { + throw new RuntimeException("Could not stop embedded ActiveMQ server for connection" + connectionName, e); + } } } }