diff --git a/azure-pipelines.yml b/azure-pipelines.yml index fa2327079b292..c6f11ad5bad3f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -24,7 +24,7 @@ pr: jobs: - job: Build_Native_Linux - timeoutInMinutes: 180 + timeoutInMinutes: 210 pool: vmImage: 'Ubuntu 16.04' diff --git a/bom/deployment/pom.xml b/bom/deployment/pom.xml index 16bcb6e2224d8..a44b0b50c8f20 100644 --- a/bom/deployment/pom.xml +++ b/bom/deployment/pom.xml @@ -96,6 +96,26 @@ quarkus-agroal-deployment ${project.version} + + io.quarkus + quarkus-artemis-core + ${project.version} + + + io.quarkus + quarkus-artemis-core-deployment + ${project.version} + + + io.quarkus + quarkus-artemis-jms + ${project.version} + + + io.quarkus + quarkus-artemis-jms-deployment + ${project.version} + io.quarkus quarkus-hibernate-validator-deployment diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml index a3669539b0de3..32798c6707109 100644 --- a/bom/runtime/pom.xml +++ b/bom/runtime/pom.xml @@ -150,6 +150,7 @@ 2.0.0-alpha03 3.10.2 1.11.0 + 2.9.0 3.1.0 6.0.1 @@ -277,6 +278,16 @@ quarkus-agroal ${project.version} + + io.quarkus + quarkus-artemis-core + ${project.version} + + + io.quarkus + quarkus-artemis-jms + ${project.version} + io.quarkus quarkus-elasticsearch-rest-client @@ -1069,6 +1080,16 @@ log4j ${log4j.version} + + org.apache.activemq + artemis-core-client + ${artemis.version} + + + org.apache.activemq + artemis-jms-client + ${artemis.version} + org.apache.httpcomponents httpclient @@ -2077,7 +2098,7 @@ jetty-webapp ${jetty.version} - + diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 8507feed43486..411b45acaac48 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -31,6 +31,7 @@ 3.3.0 0.0.7 3.7.1 + 2.9.0 2.3.28 diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java index 0c02f01f16cc4..896836b8a50e7 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java @@ -10,6 +10,8 @@ public final class FeatureBuildItem extends MultiBuildItem { public static final String AGROAL = "agroal"; + public static final String ARTEMIS_CORE = "artemis-core"; + public static final String ARTEMIS_JMS = "artemis-jms"; public static final String CDI = "cdi"; public static final String DYNAMODB = "dynamodb"; public static final String ELASTICSEARCH_REST_CLIENT = "elasticsearch-rest-client"; diff --git a/devtools/common/src/main/filtered/extensions.json b/devtools/common/src/main/filtered/extensions.json index 54f6769944232..707462898cc47 100644 --- a/devtools/common/src/main/filtered/extensions.json +++ b/devtools/common/src/main/filtered/extensions.json @@ -68,6 +68,24 @@ "groupId": "io.quarkus", "artifactId": "quarkus-amazon-lambda" }, + { + "name": "Artemis Core", + "labels": [ + "artemis-core", + "artemis" + ], + "groupId": "io.quarkus", + "artifactId": "quarkus-artemis-core" + }, + { + "name": "Artemis JMS", + "labels": [ + "artemis-jms", + "artemis" + ], + "groupId": "io.quarkus", + "artifactId": "quarkus-artemis-jms" + }, { "name": "Flyway", "labels": [ diff --git a/extensions/artemis-core/deployment/pom.xml b/extensions/artemis-core/deployment/pom.xml new file mode 100644 index 0000000000000..b5212a74ca088 --- /dev/null +++ b/extensions/artemis-core/deployment/pom.xml @@ -0,0 +1,54 @@ + + + + io.quarkus + quarkus-artemis-core-parent + 999-SNAPSHOT + + 4.0.0 + + quarkus-artemis-core-deployment + Quarkus - Artemis - Core - Deployment + + + + io.quarkus + quarkus-core-deployment + + + + io.quarkus + quarkus-arc-deployment + + + + io.quarkus + quarkus-netty-deployment + + + + io.quarkus + quarkus-artemis-core + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java b/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java new file mode 100644 index 0000000000000..4715c4bb72e8b --- /dev/null +++ b/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisCoreProcessor.java @@ -0,0 +1,100 @@ +package io.quarkus.artemis.core.deployment; + +import java.util.Collection; +import java.util.Optional; + +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.core.remoting.impl.netty.NettyConnectorFactory; +import org.apache.activemq.artemis.spi.core.remoting.ConnectorFactory; +import org.apache.commons.logging.impl.Jdk14Logger; +import org.apache.commons.logging.impl.LogFactoryImpl; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.logging.Logger; + +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.artemis.core.runtime.ArtemisCoreProducer; +import io.quarkus.artemis.core.runtime.ArtemisCoreRecorder; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; +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.substrate.ReflectiveClassBuildItem; + +public class ArtemisCoreProcessor { + + private static final Logger LOGGER = Logger.getLogger(ArtemisCoreProcessor.class); + + static final Class[] BUILTIN_CONNECTOR_FACTORIES = { + NettyConnectorFactory.class + }; + + static final Class[] BUILTIN_LOADBALANCING_POLICIES = { + FirstElementConnectionLoadBalancingPolicy.class, + RandomConnectionLoadBalancingPolicy.class, + RandomStickyConnectionLoadBalancingPolicy.class, + RoundRobinConnectionLoadBalancingPolicy.class + }; + + @BuildStep + void build(CombinedIndexBuildItem indexBuildItem, + BuildProducer reflectiveClass) { + + reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, + LogFactoryImpl.class.getName(), Jdk14Logger.class.getName())); + + 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)); + } + + 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)); + } + } + + @BuildStep + void load(BuildProducer additionalBean, BuildProducer feature, + Optional artemisJms) { + + if (artemisJms.isPresent()) { + return; + } + feature.produce(new FeatureBuildItem(FeatureBuildItem.ARTEMIS_CORE)); + additionalBean.produce(AdditionalBeanBuildItem.unremovableOf(ArtemisCoreProducer.class)); + } + + @Record(ExecutionTime.RUNTIME_INIT) + @BuildStep + void configure(ArtemisCoreRecorder recorder, ArtemisRuntimeConfig runtimeConfig, + BeanContainerBuildItem beanContainer, Optional artemisJms) { + + if (artemisJms.isPresent()) { + return; + } + recorder.setConfig(runtimeConfig, beanContainer.getValue()); + } +} diff --git a/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisJmsBuildItem.java b/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisJmsBuildItem.java new file mode 100644 index 0000000000000..71aaf27395ac9 --- /dev/null +++ b/extensions/artemis-core/deployment/src/main/java/io/quarkus/artemis/core/deployment/ArtemisJmsBuildItem.java @@ -0,0 +1,9 @@ +package io.quarkus.artemis.core.deployment; + +import io.quarkus.builder.item.SimpleBuildItem; + +/** + * Marker build item indicating that JMS is enabled + */ +public final class ArtemisJmsBuildItem extends SimpleBuildItem { +} diff --git a/extensions/artemis-core/pom.xml b/extensions/artemis-core/pom.xml new file mode 100644 index 0000000000000..6136f616664b2 --- /dev/null +++ b/extensions/artemis-core/pom.xml @@ -0,0 +1,21 @@ + + + + quarkus-build-parent + io.quarkus + 999-SNAPSHOT + ../../build-parent/pom.xml + + + 4.0.0 + quarkus-artemis-core-parent + Quarkus - Artemis - Core + pom + + + deployment + runtime + + diff --git a/extensions/artemis-core/runtime/pom.xml b/extensions/artemis-core/runtime/pom.xml new file mode 100644 index 0000000000000..cdf0130ac4ac4 --- /dev/null +++ b/extensions/artemis-core/runtime/pom.xml @@ -0,0 +1,64 @@ + + + + io.quarkus + quarkus-artemis-core-parent + 999-SNAPSHOT + + 4.0.0 + + quarkus-artemis-core + Quarkus - Artemis - Core - Runtime + + + + io.quarkus + quarkus-core + + + + io.quarkus + quarkus-arc + + + + io.quarkus + quarkus-netty + + + + org.apache.activemq + artemis-core-client + + + + com.oracle.substratevm + svm + + + + + + + + io.quarkus + quarkus-bootstrap-maven-plugin + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreProducer.java b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreProducer.java new file mode 100644 index 0000000000000..44fa7a1d580d6 --- /dev/null +++ b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreProducer.java @@ -0,0 +1,26 @@ +package io.quarkus.artemis.core.runtime; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +import org.apache.activemq.artemis.api.core.client.ActiveMQClient; +import org.apache.activemq.artemis.api.core.client.ServerLocator; + +@ApplicationScoped +public class ArtemisCoreProducer { + + private ArtemisRuntimeConfig config; + + @Produces + public ServerLocator produceServerLocator() throws Exception { + return ActiveMQClient.createServerLocator(config.url); + } + + public ArtemisRuntimeConfig getConfig() { + return config; + } + + public void setConfig(ArtemisRuntimeConfig config) { + this.config = config; + } +} diff --git a/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java new file mode 100644 index 0000000000000..654e08d7c6a04 --- /dev/null +++ b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisCoreRecorder.java @@ -0,0 +1,12 @@ +package io.quarkus.artemis.core.runtime; + +import io.quarkus.arc.runtime.BeanContainer; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class ArtemisCoreRecorder { + + public void setConfig(ArtemisRuntimeConfig config, BeanContainer container) { + container.instance(ArtemisCoreProducer.class).setConfig(config); + } +} diff --git a/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java new file mode 100644 index 0000000000000..848597a230d99 --- /dev/null +++ b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/ArtemisRuntimeConfig.java @@ -0,0 +1,29 @@ +package io.quarkus.artemis.core.runtime; + +import java.util.Optional; + +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) +public class ArtemisRuntimeConfig { + + /** + * Artemis connection url + */ + @ConfigItem + public String url; + + /** + * Username for authentication, only used with JMS + */ + @ConfigItem + public Optional username; + + /** + * Password for authentication, only used with JMS + */ + @ConfigItem + public Optional password; +} diff --git a/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/graal/CheckDependenciesSubstitutions.java b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/graal/CheckDependenciesSubstitutions.java new file mode 100644 index 0000000000000..7d3879bfc1b58 --- /dev/null +++ b/extensions/artemis-core/runtime/src/main/java/io/quarkus/artemis/core/runtime/graal/CheckDependenciesSubstitutions.java @@ -0,0 +1,20 @@ +package io.quarkus.artemis.core.runtime.graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + +// Epoll and Kqueue are not supported on SVM +@Substitute +@TargetClass(org.apache.activemq.artemis.core.remoting.impl.netty.CheckDependencies.class) +final class CheckDependenciesSubstitutions { + + @Substitute + public static final boolean isEpollAvailable() { + return false; + } + + @Substitute + public static final boolean isKQueueAvailable() { + return false; + } +} diff --git a/extensions/artemis-jms/deployment/pom.xml b/extensions/artemis-jms/deployment/pom.xml new file mode 100644 index 0000000000000..039f864fb8cce --- /dev/null +++ b/extensions/artemis-jms/deployment/pom.xml @@ -0,0 +1,44 @@ + + + + io.quarkus + quarkus-artemis-jms-parent + 999-SNAPSHOT + + 4.0.0 + + quarkus-artemis-jms-deployment + Quarkus - Artemis - JMS - Deployment + + + + io.quarkus + quarkus-artemis-core-deployment + + + + io.quarkus + quarkus-artemis-jms + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/artemis-jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java b/extensions/artemis-jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java new file mode 100644 index 0000000000000..9890871e44af2 --- /dev/null +++ b/extensions/artemis-jms/deployment/src/main/java/io/quarkus/artemis/jms/deployment/ArtemisJmsProcessor.java @@ -0,0 +1,33 @@ +package io.quarkus.artemis.jms.deployment; + +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.artemis.core.deployment.ArtemisJmsBuildItem; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; +import io.quarkus.artemis.jms.runtime.ArtemisJmsProducer; +import io.quarkus.artemis.jms.runtime.ArtemisJmsRecorder; +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; + +public class ArtemisJmsProcessor { + + @BuildStep + void load(BuildProducer additionalBean, BuildProducer feature, + BuildProducer artemisJms) { + + artemisJms.produce(new ArtemisJmsBuildItem()); + feature.produce(new FeatureBuildItem(FeatureBuildItem.ARTEMIS_JMS)); + additionalBean.produce(AdditionalBeanBuildItem.unremovableOf(ArtemisJmsProducer.class)); + } + + @Record(ExecutionTime.RUNTIME_INIT) + @BuildStep + void configure(ArtemisJmsRecorder recorder, ArtemisRuntimeConfig runtimeConfig, + BeanContainerBuildItem beanContainer) { + + recorder.setConfig(runtimeConfig, beanContainer.getValue()); + } +} diff --git a/extensions/artemis-jms/pom.xml b/extensions/artemis-jms/pom.xml new file mode 100644 index 0000000000000..73b6fa958f5d1 --- /dev/null +++ b/extensions/artemis-jms/pom.xml @@ -0,0 +1,21 @@ + + + + quarkus-build-parent + io.quarkus + 999-SNAPSHOT + ../../build-parent/pom.xml + + + 4.0.0 + quarkus-artemis-jms-parent + Quarkus - Artemis - JMS + pom + + + deployment + runtime + + diff --git a/extensions/artemis-jms/runtime/pom.xml b/extensions/artemis-jms/runtime/pom.xml new file mode 100644 index 0000000000000..dd998a08444dc --- /dev/null +++ b/extensions/artemis-jms/runtime/pom.xml @@ -0,0 +1,49 @@ + + + + io.quarkus + quarkus-artemis-jms-parent + 999-SNAPSHOT + + 4.0.0 + + quarkus-artemis-jms + Quarkus - Artemis - JMS - Runtime + + + + io.quarkus + quarkus-artemis-core + + + + org.apache.activemq + artemis-jms-client + + + + + + + + io.quarkus + quarkus-bootstrap-maven-plugin + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsProducer.java b/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsProducer.java new file mode 100644 index 0000000000000..a02a085871013 --- /dev/null +++ b/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsProducer.java @@ -0,0 +1,29 @@ +package io.quarkus.artemis.jms.runtime; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.jms.ConnectionFactory; + +import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory; + +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; + +@ApplicationScoped +public class ArtemisJmsProducer { + + private ArtemisRuntimeConfig config; + + @Produces + public ConnectionFactory producesConnectionFactory() { + return new ActiveMQJMSConnectionFactory(config.url, + config.username.orElse(null), config.password.orElse(null)); + } + + public ArtemisRuntimeConfig getConfig() { + return config; + } + + public void setConfig(ArtemisRuntimeConfig config) { + this.config = config; + } +} diff --git a/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java b/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java new file mode 100644 index 0000000000000..fffef19ee8396 --- /dev/null +++ b/extensions/artemis-jms/runtime/src/main/java/io/quarkus/artemis/jms/runtime/ArtemisJmsRecorder.java @@ -0,0 +1,13 @@ +package io.quarkus.artemis.jms.runtime; + +import io.quarkus.arc.runtime.BeanContainer; +import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfig; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class ArtemisJmsRecorder { + + public void setConfig(ArtemisRuntimeConfig config, BeanContainer container) { + container.instance(ArtemisJmsProducer.class).setConfig(config); + } +} diff --git a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java index 13200477c7679..62b8131f2d4b3 100644 --- a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java +++ b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java @@ -48,6 +48,7 @@ import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem; import io.quarkus.deployment.builditem.SystemPropertyBuildItem; import io.quarkus.deployment.builditem.substrate.ReflectiveClassBuildItem; +import io.quarkus.deployment.builditem.substrate.SubstrateConfigBuildItem; import io.quarkus.infinispan.client.runtime.InfinispanClientBuildTimeConfig; import io.quarkus.infinispan.client.runtime.InfinispanClientProducer; import io.quarkus.infinispan.client.runtime.InfinispanClientRuntimeConfig; @@ -73,6 +74,7 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch BuildProducer feature, BuildProducer additionalBeans, BuildProducer sslNativeSupport, + BuildProducer substrateConfig, ApplicationIndexBuildItem applicationIndexBuildItem) throws ClassNotFoundException, IOException { feature.produce(new FeatureBuildItem(FeatureBuildItem.INFINISPAN_CLIENT)); @@ -154,6 +156,9 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch // This is required for netty to work properly reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, "io.netty.channel.socket.nio.NioSocketChannel")); + substrateConfig.produce(SubstrateConfigBuildItem.builder() + .addRuntimeInitializedClass("org.infinispan.client.hotrod.impl.transport.netty.TransportHelper") + .build()); // We use reflection to have continuous queries work reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, "org.infinispan.client.hotrod.event.impl.ContinuousQueryImpl$ClientEntryListener")); diff --git a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java index ea17730947fa2..33946a8b60c1e 100644 --- a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java +++ b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java @@ -13,6 +13,7 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.JniBuildItem; import io.quarkus.deployment.builditem.substrate.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.substrate.SubstrateConfigBuildItem; import io.quarkus.netty.BossGroup; @@ -26,7 +27,9 @@ class NettyProcessor { private static final Logger log = Logger.getLogger(NettyProcessor.class); @BuildStep - SubstrateConfigBuildItem build() { + SubstrateConfigBuildItem build(BuildProducer jni) { + boolean enableJni = false; + reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, "io.netty.channel.socket.nio.NioSocketChannel")); reflectiveClass .produce(new ReflectiveClassBuildItem(false, false, "io.netty.channel.socket.nio.NioServerSocketChannel")); @@ -48,6 +51,47 @@ SubstrateConfigBuildItem build() { //ignore log.debug("Not registering Netty HTTP classes as they were not found"); } + + try { + Class.forName("io.netty.channel.unix.UnixChannel"); + enableJni = true; + builder.addRuntimeInitializedClass("io.netty.channel.unix.Errors") + .addRuntimeInitializedClass("io.netty.channel.unix.FileDescriptor") + .addRuntimeInitializedClass("io.netty.channel.unix.IovArray") + .addRuntimeInitializedClass("io.netty.channel.unix.Limits"); + } catch (ClassNotFoundException e) { + //ignore + log.debug("Not registering Netty native unix classes as they were not found"); + } + + try { + Class.forName("io.netty.channel.epoll.EpollMode"); + enableJni = true; + builder.addRuntimeInitializedClass("io.netty.channel.epoll.Epoll") + .addRuntimeInitializedClass("io.netty.channel.epoll.EpollEventArray") + .addRuntimeInitializedClass("io.netty.channel.epoll.EpollEventLoop") + .addRuntimeInitializedClass("io.netty.channel.epoll.Native"); + } catch (ClassNotFoundException e) { + //ignore + log.debug("Not registering Netty native epoll classes as they were not found"); + } + + try { + Class.forName("io.netty.channel.kqueue.AcceptFilter"); + enableJni = true; + builder.addRuntimeInitializedClass("io.netty.channel.kqueue.KQueue") + .addRuntimeInitializedClass("io.netty.channel.kqueue.KQueueEventArray") + .addRuntimeInitializedClass("io.netty.channel.kqueue.KQueueEventLoop") + .addRuntimeInitializedClass("io.netty.channel.kqueue.Native"); + } catch (ClassNotFoundException e) { + //ignore + log.debug("Not registering Netty native kqueue classes as they were not found"); + } + + if (enableJni) { + jni.produce(new JniBuildItem()); + } + return builder //TODO: make configurable .build(); } diff --git a/extensions/pom.xml b/extensions/pom.xml index a13ac3afce6c2..ba0c56d0fa191 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -74,6 +74,8 @@ tika neo4j mongodb-client + artemis-core + artemis-jms spring-di diff --git a/integration-tests/artemis-core/pom.xml b/integration-tests/artemis-core/pom.xml new file mode 100644 index 0000000000000..9a204f4d6e7c4 --- /dev/null +++ b/integration-tests/artemis-core/pom.xml @@ -0,0 +1,127 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-integration-test-artemis-core + Quarkus - Integration Tests - Artemis - Core + The Apache ActiveMQ Artemis Core integration tests module + + + true + + + + + + io.quarkus + quarkus-resteasy + + + + + io.quarkus + quarkus-artemis-core + + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + org.apache.activemq + artemis-server + ${artemis.version} + test + + + org.jboss.logmanager + jboss-logmanager + + + + + + + + + ${project.groupId} + quarkus-maven-plugin + + + + build + + + + + + + + + + native-image + + + native + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + + + + + + ${project.groupId} + quarkus-maven-plugin + + + native-image + + native-image + + + true + true + + ${graalvmHome} + + + + + + + + + + diff --git a/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java new file mode 100644 index 0000000000000..3f0bcff7408cf --- /dev/null +++ b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java @@ -0,0 +1,36 @@ +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.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(); + ClientMessage message = session.createConsumer("test-core").receive(1000L); + message.acknowledge(); + return message.getBodyBuffer().readString(); + } catch (ActiveMQException e) { + throw new RuntimeException("Could not receive message", e); + } + } +} diff --git a/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java new file mode 100644 index 0000000000000..09fcc62d76fd6 --- /dev/null +++ b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java @@ -0,0 +1,26 @@ +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/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java new file mode 100644 index 0000000000000..c2dc9f9db748f --- /dev/null +++ b/integration-tests/artemis-core/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java @@ -0,0 +1,35 @@ +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.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); + session.createProducer("test-core").send(message); + } catch (ActiveMQException e) { + throw new RuntimeException("Could not send message", e); + } + } +} diff --git a/integration-tests/artemis-core/src/main/resources/application.properties b/integration-tests/artemis-core/src/main/resources/application.properties new file mode 100644 index 0000000000000..d7f1552f7a3ae --- /dev/null +++ b/integration-tests/artemis-core/src/main/resources/application.properties @@ -0,0 +1 @@ +quarkus.artemis.url=tcp://localhost:61616 diff --git a/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java new file mode 100644 index 0000000000000..062348efe2579 --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java @@ -0,0 +1,8 @@ +package io.quarkus.it.artemis; + +import io.quarkus.test.junit.SubstrateTest; + +@SubstrateTest +public class ArtemisConsumerITCase extends ArtemisConsumerTest { + +} diff --git a/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java new file mode 100644 index 0000000000000..6c1bee7d93462 --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java @@ -0,0 +1,31 @@ +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 org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import io.restassured.response.Response; +import io.undertow.httpcore.StatusCodes; + +@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(StatusCodes.OK, response.statusCode()); + Assertions.assertEquals(body, response.getBody().asString()); + } +} diff --git a/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java new file mode 100644 index 0000000000000..da1b14a8a2566 --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java @@ -0,0 +1,17 @@ +package io.quarkus.it.artemis; + +import java.util.Random; + +import org.apache.activemq.artemis.api.core.client.ActiveMQClient; +import org.apache.activemq.artemis.api.core.client.ClientSession; + +public interface ArtemisHelper { + + default String createBody() { + return Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 16); + } + + default ClientSession createSession() throws Exception { + return ActiveMQClient.createServerLocator("tcp://localhost:61616").createSessionFactory().createSession(); + } +} diff --git a/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java new file mode 100644 index 0000000000000..d8aea4c888df5 --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java @@ -0,0 +1,8 @@ +package io.quarkus.it.artemis; + +import io.quarkus.test.junit.SubstrateTest; + +@SubstrateTest +public class ArtemisProducerITCase extends ArtemisProducerTest { + +} diff --git a/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java new file mode 100644 index 0000000000000..609b1d2567f93 --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java @@ -0,0 +1,31 @@ +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 org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import io.restassured.response.Response; +import io.undertow.httpcore.StatusCodes; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +public class ArtemisProducerTest implements ArtemisHelper { + + @Test + public void test() throws Exception { + String body = createBody(); + Response response = RestAssured.with().body(body).post("/artemis"); + Assertions.assertEquals(StatusCodes.NO_CONTENT, 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/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java new file mode 100644 index 0000000000000..581cde9b6f67d --- /dev/null +++ b/integration-tests/artemis-core/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java @@ -0,0 +1,36 @@ +package io.quarkus.it.artemis; + +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Map; + +import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; +import org.apache.commons.io.FileUtils; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class ArtemisTestResource implements QuarkusTestResourceLifecycleManager { + + private EmbeddedActiveMQ embedded; + + @Override + public Map start() { + try { + FileUtils.deleteDirectory(Paths.get("./target/artemis").toFile()); + embedded = new EmbeddedActiveMQ(); + embedded.start(); + } catch (Exception e) { + throw new RuntimeException("Could not start embedded ActiveMQ server", e); + } + return Collections.emptyMap(); + } + + @Override + public void stop() { + try { + embedded.stop(); + } catch (Exception e) { + throw new RuntimeException("Could not stop embedded ActiveMQ server", e); + } + } +} diff --git a/integration-tests/artemis-core/src/test/resources/broker.xml b/integration-tests/artemis-core/src/test/resources/broker.xml new file mode 100644 index 0000000000000..ebc7ccd91575d --- /dev/null +++ b/integration-tests/artemis-core/src/test/resources/broker.xml @@ -0,0 +1,25 @@ + + + ./target/artemis/paging + ./target/artemis/bindings + ./target/artemis/journal + ./target/artemis/large-messages + + + tcp://localhost:61616 + + + tcp://localhost:61616 + + + false + + +
+ + + +
+
+
+
diff --git a/integration-tests/artemis-jms/pom.xml b/integration-tests/artemis-jms/pom.xml new file mode 100644 index 0000000000000..54483c49c58c1 --- /dev/null +++ b/integration-tests/artemis-jms/pom.xml @@ -0,0 +1,127 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-integration-test-artemis-jms + Quarkus - Integration Tests - Artemis - JMS + The Apache ActiveMQ Artemis JMS integration tests module + + + true + + + + + + io.quarkus + quarkus-resteasy + + + + + io.quarkus + quarkus-artemis-jms + + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + org.apache.activemq + artemis-server + ${artemis.version} + test + + + org.jboss.logmanager + jboss-logmanager + + + + + + + + + ${project.groupId} + quarkus-maven-plugin + + + + build + + + + + + + + + + native-image + + + native + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + + + + + + ${project.groupId} + quarkus-maven-plugin + + + native-image + + native-image + + + true + true + + ${graalvmHome} + + + + + + + + + + diff --git a/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java new file mode 100644 index 0000000000000..5452a493cd0a7 --- /dev/null +++ b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisConsumerManager.java @@ -0,0 +1,34 @@ +package io.quarkus.it.artemis; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageConsumer; +import javax.jms.Session; + +@ApplicationScoped +public class ArtemisConsumerManager { + + @Inject + ConnectionFactory connectionFactory; + + private Connection connection; + + @PostConstruct + public void init() throws JMSException { + connection = connectionFactory.createConnection(); + connection.start(); + } + + public String receive() { + try (Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) { + MessageConsumer consumer = session.createConsumer(session.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/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java new file mode 100644 index 0000000000000..09fcc62d76fd6 --- /dev/null +++ b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisEndpoint.java @@ -0,0 +1,26 @@ +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/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java new file mode 100644 index 0000000000000..edd8016e1030c --- /dev/null +++ b/integration-tests/artemis-jms/src/main/java/io/quarkus/it/artemis/ArtemisProducerManager.java @@ -0,0 +1,33 @@ +package io.quarkus.it.artemis; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; + +@ApplicationScoped +public class ArtemisProducerManager { + + @Inject + ConnectionFactory connectionFactory; + + private Connection connection; + + @PostConstruct + public void init() throws JMSException { + connection = connectionFactory.createConnection(); + } + + public void send(String body) { + try (Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) { + MessageProducer producer = session.createProducer(session.createQueue("test-jms")); + producer.send(session.createTextMessage(body)); + } catch (JMSException e) { + throw new RuntimeException("Could not send message", e); + } + } +} diff --git a/integration-tests/artemis-jms/src/main/resources/application.properties b/integration-tests/artemis-jms/src/main/resources/application.properties new file mode 100644 index 0000000000000..d7f1552f7a3ae --- /dev/null +++ b/integration-tests/artemis-jms/src/main/resources/application.properties @@ -0,0 +1 @@ +quarkus.artemis.url=tcp://localhost:61616 diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java new file mode 100644 index 0000000000000..062348efe2579 --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerITCase.java @@ -0,0 +1,8 @@ +package io.quarkus.it.artemis; + +import io.quarkus.test.junit.SubstrateTest; + +@SubstrateTest +public class ArtemisConsumerITCase extends ArtemisConsumerTest { + +} diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java new file mode 100644 index 0000000000000..d7e6aee554a2b --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisConsumerTest.java @@ -0,0 +1,29 @@ +package io.quarkus.it.artemis; + +import javax.jms.Session; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import io.restassured.response.Response; +import io.undertow.httpcore.StatusCodes; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +public class ArtemisConsumerTest implements ArtemisHelper { + + @Test + public void test() throws Exception { + String body = createBody(); + try (Session session = createSession()) { + session.createProducer(session.createQueue("test-jms")).send(session.createTextMessage(body)); + } + + Response response = RestAssured.with().body(body).get("/artemis"); + Assertions.assertEquals(StatusCodes.OK, response.statusCode()); + Assertions.assertEquals(body, response.getBody().asString()); + } +} diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java new file mode 100644 index 0000000000000..33dd8511cb72f --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisHelper.java @@ -0,0 +1,22 @@ +package io.quarkus.it.artemis; + +import java.util.Random; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Session; + +import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory; + +public interface ArtemisHelper { + + default String createBody() { + return Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 16); + } + + default Session createSession() throws JMSException { + Connection connection = new ActiveMQJMSConnectionFactory("tcp://localhost:61616").createConnection(); + connection.start(); + return connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + } +} diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java new file mode 100644 index 0000000000000..d8aea4c888df5 --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerITCase.java @@ -0,0 +1,8 @@ +package io.quarkus.it.artemis; + +import io.quarkus.test.junit.SubstrateTest; + +@SubstrateTest +public class ArtemisProducerITCase extends ArtemisProducerTest { + +} diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java new file mode 100644 index 0000000000000..11238b6bc4107 --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisProducerTest.java @@ -0,0 +1,32 @@ +package io.quarkus.it.artemis; + +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.Session; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import io.restassured.response.Response; +import io.undertow.httpcore.StatusCodes; + +@QuarkusTest +@QuarkusTestResource(ArtemisTestResource.class) +public class ArtemisProducerTest implements ArtemisHelper { + + @Test + public void test() throws Exception { + String body = createBody(); + Response response = RestAssured.with().body(body).post("/artemis"); + Assertions.assertEquals(StatusCodes.NO_CONTENT, response.statusCode()); + + try (Session session = createSession()) { + MessageConsumer consumer = session.createConsumer(session.createQueue("test-jms")); + Message message = consumer.receive(1000L); + Assertions.assertEquals(body, message.getBody(String.class)); + } + } +} diff --git a/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java new file mode 100644 index 0000000000000..581cde9b6f67d --- /dev/null +++ b/integration-tests/artemis-jms/src/test/java/io/quarkus/it/artemis/ArtemisTestResource.java @@ -0,0 +1,36 @@ +package io.quarkus.it.artemis; + +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Map; + +import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; +import org.apache.commons.io.FileUtils; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class ArtemisTestResource implements QuarkusTestResourceLifecycleManager { + + private EmbeddedActiveMQ embedded; + + @Override + public Map start() { + try { + FileUtils.deleteDirectory(Paths.get("./target/artemis").toFile()); + embedded = new EmbeddedActiveMQ(); + embedded.start(); + } catch (Exception e) { + throw new RuntimeException("Could not start embedded ActiveMQ server", e); + } + return Collections.emptyMap(); + } + + @Override + public void stop() { + try { + embedded.stop(); + } catch (Exception e) { + throw new RuntimeException("Could not stop embedded ActiveMQ server", e); + } + } +} diff --git a/integration-tests/artemis-jms/src/test/resources/broker.xml b/integration-tests/artemis-jms/src/test/resources/broker.xml new file mode 100644 index 0000000000000..b3e4ec0d49861 --- /dev/null +++ b/integration-tests/artemis-jms/src/test/resources/broker.xml @@ -0,0 +1,23 @@ + + + ./target/artemis/paging + ./target/artemis/bindings + ./target/artemis/journal + ./target/artemis/large-messages + + + tcp://localhost:61616 + + + tcp://localhost:61616 + + + false + + + +
test-jms
+
+
+
+
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index dc81db73ae607..840f9c654eaf7 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -54,6 +54,8 @@ resteasy-jackson jgit virtual-http + artemis-core + artemis-jms