This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new f193379  [ARTEMIS-2545]: Auto queue creation does not work with MDBs.
f193379 is described below

commit f19337901a45e3437d1b944a5c60fb975754ab88
Author: Emmanuel Hugonnet <[email protected]>
AuthorDate: Thu Sep 16 09:57:07 2021 +0200

    [ARTEMIS-2545]: Auto queue creation does not work with MDBs.
    
    * Adding support for queue autocreation from the resource adapter.
    
    Issue: https://issues.apache.org/jira/browse/ARTEMIS-2545
---
 .../activemq/artemis/utils/AutoCreateUtil.java     | 90 ++++++++++++++++++++++
 .../artemis/jms/client/ActiveMQSession.java        | 64 +++------------
 .../artemis/ra/inflow/ActiveMQMessageHandler.java  |  2 +
 .../tests/integration/ra/ResourceAdapterTest.java  | 29 +++++++
 4 files changed, 133 insertions(+), 52 deletions(-)

diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/AutoCreateUtil.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/AutoCreateUtil.java
new file mode 100644
index 0000000..48e98ed
--- /dev/null
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/AutoCreateUtil.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.utils;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import static 
org.apache.activemq.artemis.api.core.ActiveMQExceptionType.QUEUE_DOES_NOT_EXIST;
+import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
+import org.apache.activemq.artemis.api.core.QueueConfiguration;
+import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSession.AddressQuery;
+import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
+import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
+
+/**
+ * Utility class to create queues 'automatically'.
+ */
+public class AutoCreateUtil {
+
+   public static  void autoCreateQueue(ClientSession session, SimpleString 
destAddress, SimpleString selectorString) throws ActiveMQException {
+      AddressQuery response = session.addressQuery(destAddress);
+      /* The address query will send back exists=true even if the node only 
has a REMOTE binding for the destination.
+       * Therefore, we must check if the queue names list contains the exact 
name of the address to know whether or
+       * not a LOCAL binding for the address exists. If no LOCAL binding 
exists then it should be created here.
+       */
+      SimpleString queueName = getCoreQueueName(session, destAddress);
+      if (!response.isExists() || 
!response.getQueueNames().contains(queueName)) {
+         if (response.isAutoCreateQueues()) {
+            try {
+               QueueConfiguration queueConfiguration = new 
QueueConfiguration(queueName)
+                     .setAutoCreated(true)
+                     .setAddress(destAddress);
+               
setRequiredQueueConfigurationIfNotSet(queueConfiguration,response, 
RoutingType.ANYCAST, selectorString, true);
+               session.createQueue(queueConfiguration);
+               ActiveMQClientLogger.LOGGER.debug("The queue " + destAddress + 
" was created automatically");
+            } catch (ActiveMQQueueExistsException e) {
+               // The queue was created by another client/admin between the 
query check and send create queue packet
+            }
+         } else {
+            throw new ActiveMQException("Destination " + destAddress + " does 
not exist", QUEUE_DOES_NOT_EXIST);
+         }
+      }
+   }
+
+   /**
+    * Set the non nullable (CreateQueueMessage_V2) queue attributes (all 
others have static defaults or get defaulted if null by address settings server 
side).
+    *
+    * @param queueConfiguration the provided queue configuration the client 
wants to set
+    * @param addressQuery the address settings query information (this could 
be removed if max consumers and purge on no consumers were null-able in 
CreateQueueMessage_V2)
+    * @param routingType of the queue (multicast or anycast)
+    * @param filter to apply on the queue
+    * @param durable if queue is durable
+    */
+   public static void setRequiredQueueConfigurationIfNotSet(QueueConfiguration 
queueConfiguration, ClientSession.AddressQuery addressQuery, RoutingType 
routingType, SimpleString filter, boolean durable) {
+      if (queueConfiguration.getRoutingType() == null) {
+         queueConfiguration.setRoutingType(routingType);
+      }
+      if (queueConfiguration.getFilterString() == null) {
+         queueConfiguration.setFilterString(filter);
+      }
+      if (queueConfiguration.getMaxConsumers() == null) {
+         
queueConfiguration.setMaxConsumers(addressQuery.getDefaultMaxConsumers());
+      }
+      if (queueConfiguration.isPurgeOnNoConsumers() == null) {
+         
queueConfiguration.setPurgeOnNoConsumers(addressQuery.isDefaultPurgeOnNoConsumers());
+      }
+      queueConfiguration.setDurable(durable);
+   }
+
+   public static SimpleString getCoreQueueName(ClientSession session, 
SimpleString destAddress) {
+      if (session.getVersion() < PacketImpl.FQQN_CHANGE_VERSION) {
+         return destAddress;
+      }
+      return CompositeAddress.extractQueueName(destAddress);
+   }
+}
diff --git 
a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
 
b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
index 6ec2225..1b2d619 100644
--- 
a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
+++ 
b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
@@ -16,6 +16,8 @@
  */
 package org.apache.activemq.artemis.jms.client;
 
+import static 
org.apache.activemq.artemis.api.core.ActiveMQExceptionType.QUEUE_DOES_NOT_EXIST;
+
 import javax.jms.BytesMessage;
 import javax.jms.Destination;
 import javax.jms.IllegalStateException;
@@ -72,6 +74,7 @@ import 
org.apache.activemq.artemis.jms.client.compatible1X.ActiveMQStreamCompati
 import 
org.apache.activemq.artemis.jms.client.compatible1X.ActiveMQTextCompatibleMessage;
 import org.apache.activemq.artemis.selector.filter.FilterException;
 import org.apache.activemq.artemis.selector.impl.SelectorParser;
+import org.apache.activemq.artemis.utils.AutoCreateUtil;
 import org.apache.activemq.artemis.utils.CompositeAddress;
 import org.apache.activemq.artemis.utils.SelectorTranslator;
 
@@ -802,22 +805,13 @@ public class ActiveMQSession implements QueueSession, 
TopicSession {
          SimpleString autoDeleteQueueName = null;
 
          if (dest.isQueue()) {
-            AddressQuery response = 
session.addressQuery(dest.getSimpleAddress());
-
-            /* The address query will send back exists=true even if the node 
only has a REMOTE binding for the destination.
-             * Therefore, we must check if the queue names list contains the 
exact name of the address to know whether or
-             * not a LOCAL binding for the address exists. If no LOCAL binding 
exists then it should be created here.
-             */
-            if (!response.isExists() || 
!response.getQueueNames().contains(getCoreQueueName(dest))) {
-               if (response.isAutoCreateQueues()) {
-                  try {
-                     createQueue(dest, RoutingType.ANYCAST, 
dest.getSimpleAddress(), null, true, true, response);
-                  } catch (ActiveMQQueueExistsException e) {
-                     // The queue was created by another client/admin between 
the query check and send create queue packet
-                  }
-               } else {
+            try {
+               AutoCreateUtil.autoCreateQueue(session, 
dest.getSimpleAddress(), null);
+            } catch (ActiveMQException ex) {
+               if (ex.getType() == QUEUE_DOES_NOT_EXIST) {
                   throw new InvalidDestinationException("Destination " + 
dest.getName() + " does not exist");
                }
+               throw ex;
             }
 
             dest.setCreated(true);
@@ -848,7 +842,7 @@ public class ActiveMQSession implements QueueSession, 
TopicSession {
                if (!CompositeAddress.isFullyQualified(dest.getAddress())) {
                   createTemporaryQueue(dest, RoutingType.MULTICAST, queueName, 
coreFilterString, response);
                } else {
-                  if (!response.isExists() || 
!response.getQueueNames().contains(getCoreQueueName(dest))) {
+                  if (!response.isExists() || 
!response.getQueueNames().contains(AutoCreateUtil.getCoreQueueName(session, 
dest.getSimpleAddress()))) {
                      if (response.isAutoCreateQueues()) {
                         try {
                            createQueue(dest, RoutingType.MULTICAST, 
dest.getSimpleAddress(), null, true, true, response);
@@ -931,14 +925,6 @@ public class ActiveMQSession implements QueueSession, 
TopicSession {
       }
    }
 
-   private SimpleString getCoreQueueName(ActiveMQDestination dest) {
-      if (session.getVersion() < PacketImpl.FQQN_CHANGE_VERSION) {
-         return dest.getSimpleAddress();
-      } else {
-         return CompositeAddress.extractQueueName(dest.getSimpleAddress());
-      }
-   }
-
    private ClientConsumer createClientConsumer(ActiveMQDestination 
destination, SimpleString queueName, SimpleString coreFilterString) throws 
ActiveMQException {
       QueueAttributes queueAttributes = destination.getQueueAttributes() == 
null ? new QueueAttributes() : destination.getQueueAttributes();
       int priority = queueAttributes.getConsumerPriority() == null ? 
ActiveMQDefaultConfiguration.getDefaultConsumerPriority() : 
queueAttributes.getConsumerPriority();
@@ -1278,19 +1264,19 @@ public class ActiveMQSession implements QueueSession, 
TopicSession {
 
    void createTemporaryQueue(ActiveMQDestination destination, RoutingType 
routingType, SimpleString queueName, SimpleString filter, 
ClientSession.AddressQuery addressQuery) throws ActiveMQException {
       QueueConfiguration queueConfiguration = 
destination.getQueueConfiguration() == null ? new QueueConfiguration(queueName) 
: destination.getQueueConfiguration();
-      setRequiredQueueConfigurationIfNotSet(queueConfiguration, addressQuery, 
routingType, filter, false);
+      AutoCreateUtil.setRequiredQueueConfigurationIfNotSet(queueConfiguration, 
addressQuery, routingType, filter, false);
       
session.createQueue(queueConfiguration.setName(queueName).setAddress(destination.getAddress()).setDurable(false).setTemporary(true));
    }
 
    void createSharedQueue(ActiveMQDestination destination, RoutingType 
routingType, SimpleString queueName, SimpleString filter, boolean durable, 
ClientSession.AddressQuery addressQuery) throws ActiveMQException {
       QueueConfiguration queueConfiguration = 
destination.getQueueConfiguration() == null ? new QueueConfiguration(queueName) 
: destination.getQueueConfiguration();
-      setRequiredQueueConfigurationIfNotSet(queueConfiguration, addressQuery, 
routingType, filter, durable);
+      AutoCreateUtil.setRequiredQueueConfigurationIfNotSet(queueConfiguration, 
addressQuery, routingType, filter, durable);
       
session.createSharedQueue(queueConfiguration.setName(queueName).setAddress(destination.getAddress()).setDurable(durable));
    }
 
    void createQueue(ActiveMQDestination destination, RoutingType routingType, 
SimpleString queueName, SimpleString filter, boolean durable, boolean 
autoCreated, ClientSession.AddressQuery addressQuery) throws ActiveMQException {
       QueueConfiguration queueConfiguration = 
destination.getQueueConfiguration() == null ? new QueueConfiguration(queueName) 
: destination.getQueueConfiguration();
-      setRequiredQueueConfigurationIfNotSet(queueConfiguration, addressQuery, 
routingType, filter, durable);
+      AutoCreateUtil.setRequiredQueueConfigurationIfNotSet(queueConfiguration, 
addressQuery, routingType, filter, durable);
       
session.createQueue(queueConfiguration.setName(queueName).setAddress(destination.getAddress()).setAutoCreated(autoCreated).setDurable(durable));
    }
 
@@ -1351,32 +1337,6 @@ public class ActiveMQSession implements QueueSession, 
TopicSession {
          return topic;
       }
    }
-
-   /**
-    * Set the non nullable (CreateQueueMessage_V2) queue attributes (all 
others have static defaults or get defaulted if null by address settings server 
side).
-    *
-    * @param queueConfiguration the provided queue configuration the client 
wants to set
-    * @param addressQuery the address settings query information (this could 
be removed if max consumers and purge on no consumers were null-able in 
CreateQueueMessage_V2)
-    * @param routingType of the queue (multicast or anycast)
-    * @param filter to apply on the queue
-    * @param durable if queue is durable
-    */
-   private void setRequiredQueueConfigurationIfNotSet(QueueConfiguration 
queueConfiguration, ClientSession.AddressQuery addressQuery, RoutingType 
routingType, SimpleString filter, boolean durable) {
-      if (queueConfiguration.getRoutingType() == null) {
-         queueConfiguration.setRoutingType(routingType);
-      }
-      if (queueConfiguration.getFilterString() == null) {
-         queueConfiguration.setFilterString(filter);
-      }
-      if (queueConfiguration.getMaxConsumers() == null) {
-         
queueConfiguration.setMaxConsumers(addressQuery.getDefaultMaxConsumers());
-      }
-      if (queueConfiguration.isPurgeOnNoConsumers() == null) {
-         
queueConfiguration.setPurgeOnNoConsumers(addressQuery.isDefaultPurgeOnNoConsumers());
-      }
-   }
-
-
    // Inner classes -------------------------------------------------
 
 }
diff --git 
a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
 
b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
index 714277f..0ee7043 100644
--- 
a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
+++ 
b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
@@ -50,6 +50,7 @@ import org.apache.activemq.artemis.ra.ActiveMQRALogger;
 import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter;
 import org.apache.activemq.artemis.service.extensions.ServiceUtils;
 import 
org.apache.activemq.artemis.service.extensions.xa.ActiveMQXAResourceWrapper;
+import org.apache.activemq.artemis.utils.AutoCreateUtil;
 import org.apache.activemq.artemis.utils.FutureLatch;
 import org.apache.activemq.artemis.utils.VersionLoader;
 import org.jboss.logging.Logger;
@@ -172,6 +173,7 @@ public class ActiveMQMessageHandler implements 
MessageHandler, FailoverEventList
             }
          } else {
             tempQueueName = activation.getAddress();
+            AutoCreateUtil.autoCreateQueue(session, tempQueueName, 
selectorString);
          }
          consumer = (ClientConsumerInternal) 
session.createConsumer(tempQueueName, selectorString);
       }
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ResourceAdapterTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ResourceAdapterTest.java
index 7689a02..7b6f1b1 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ResourceAdapterTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ResourceAdapterTest.java
@@ -136,6 +136,35 @@ public class ResourceAdapterTest extends 
ActiveMQRATestBase {
    }
 
    @Test
+   public void testAutoCreateQueuePrefixWhenUseJndiIsFalse() throws Exception {
+      final String prefix = "jms.queue.";
+      final String destinationName = "autocreatedtest";
+      final SimpleString prefixedDestinationName = 
SimpleString.toSimpleString(prefix + destinationName);
+      ActiveMQResourceAdapter ra = new ActiveMQResourceAdapter();
+      ra.setConnectorClassName(INVM_CONNECTOR_FACTORY);
+      ra.start(new BootstrapContext());
+      Connection conn = 
ra.getDefaultActiveMQConnectionFactory().createConnection();
+      conn.close();
+
+      ActiveMQActivationSpec spec = new ActiveMQActivationSpec();
+      spec.setResourceAdapter(ra);
+      spec.setUseJNDI(false);
+      spec.setDestinationType("javax.jms.Queue");
+      spec.setDestination(destinationName);
+      spec.setQueuePrefix(prefix);
+      spec.setMaxSession(1);
+      spec.setSetupAttempts(1);
+
+      ActiveMQActivation activation = new ActiveMQActivation(ra, new 
MessageEndpointFactory(), spec);
+
+      activation.start();
+
+      assertEquals(1, 
server.locateQueue(prefixedDestinationName).getConsumerCount());
+
+      activation.stop();
+   }
+
+   @Test
    public void testTopicPrefixWhenUseJndiIsFalse() throws Exception {
       final String prefix = "jms.topic.";
       final String destinationName = "test";

Reply via email to