[jira] [Comment Edited] (ARTEMIS-4416) Client can't use anycast without FQQN

2023-09-07 Thread Justin Bertram (Jira)


[ 
https://issues.apache.org/jira/browse/ARTEMIS-4416?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17762861#comment-17762861
 ] 

Justin Bertram edited comment on ARTEMIS-4416 at 9/7/23 8:33 PM:
-

As noted in [the 
documentation|https://activemq.apache.org/components/artemis/documentation/latest/jms-core-mapping.html]:

bq. ...a JMS queue is implemented as an address with name=(the JMS queue name) 
with an ANYCAST routing type associated with it.

Therefore, when an application uses the core JMS client to send a message to a 
JMS queue then the implementation will check if there is an address and anycast 
queue with the proper name. If there isn't then it will attempt to auto-create 
one or both as necessary. If auto-creation of the address or queue is not 
possible then the implementation will thrown an exception indicating that the 
destination is invalid. This is to fulfill the expectation that sending a 
message to a JMS queue will actually result in the message being stored.

This is in contrast to sending a message to a JMS _topic_ where it's perfectly 
acceptable for the message not be stored (i.e. if there are no subscriptions).

In your case, your application is sending a message to a JMS queue named 
{{myAddress}}. On the broker you have defined an address named {{myAddress}}, 
but you _don't_ have a corresponding anycast queue named {{myAddress}} and 
since auto-creation for queues is also disabled you receive an invalid 
destination exception since the client has no expectation that the message will 
actually be stored on the broker.

bq. It's the server's responsibility to forward the message to the correct 
queue, if the queue doesn't exist, it will send the message to DLQ or elsewhere.

This is incorrect. If there is no queue on an address or if there are queues 
with filters and the sent message doesn't match then the message _will be 
dropped_ by default.

Prior to 2.7.0 the client wouldn't even attempt to auto-create the queue so it 
was possible for messages to essentially be lost (i.e. sent to the broker 
"successfully" but dropped).

If you want to keep your existing semantics you just need to use a JMS topic & 
multicast, e.g.:
{code:java}
ActiveMQConnectionFactory connectionFactory = new 
ActiveMQConnectionFactory("tcp://localhost:61616");

JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setDefaultDestination(new ActiveMQTopic("myAddress")); // use a JMS 
topic

jmsTemplate.send(msg -> {
  TextMessage textMessage = msg.createTextMessage("body-content-text");
  textMessage.setStringProperty("foo", "3");
  return textMessage;
});{code}
{code:xml}
  
 

   
  
   
   
  
   
   
  
   

 
  {code}

It's worth noting that having multiple _anycast_ queues on an address is rather 
uncommon. In your case the only reason it's working is because all the filters 
are mutually exclusive. I would definitely recommend using a JMS topic and 
multicast configuration as it actually fits your use-case.

Also, I recommend you keep your broker more up-to-date. This change was 
introduced over 4 years ago now.


was (Author: jbertram):
As noted in [the 
documentation|https://activemq.apache.org/components/artemis/documentation/latest/jms-core-mapping.html]:

bq. ...a JMS queue is implemented as an address with name=(the JMS queue name) 
with an ANYCAST routing type associated with it.

Therefore, when an application uses the core JMS client to send a message to a 
JMS queue then the implementation will check if there is an address and anycast 
queue with the proper name. If there isn't then it will attempt to auto-create 
one or both as necessary. If auto-creation of the address or queue is not 
possible then the implementation will thrown an exception indicating that the 
destination is invalid. This is to fulfill the expectation that sending a 
message to a JMS queue will actually result in the message being stored.

This is in contrast to sending a message to a JMS _topic_ where it's perfectly 
acceptable for the message not be stored (i.e. if there are no subscriptions).

In your case, your application is sending a message to a JMS queue named 
{{myAddress}}. On the broker you have defined an address named {{myAddress}}, 
but you _don't_ have a corresponding anycast queue named {{myAddress}} and 
since auto-creation for queues is also disabled you receive an invalid 
destination exception since the client has no expectation that the message will 
actually be stored on the broker.

bq. It's the server's responsibility to forward the message to the correct 
queue, if the queue doesn't exist, it will send the message to DLQ or elsewhere.

This is incorrect. If there is no queue on an address or if there are queues 

[jira] [Comment Edited] (ARTEMIS-4416) Client can't use anycast without FQQN

2023-09-07 Thread Damien Picard (Jira)


[ 
https://issues.apache.org/jira/browse/ARTEMIS-4416?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17762767#comment-17762767
 ] 

Damien Picard edited comment on ARTEMIS-4416 at 9/7/23 2:41 PM:


 

In this file 
[ActiveMQSession.java|https://github.com/apache/activemq-artemis/blob/91debf25dbf0f3924d511ee615c6f9b0545e2a5f/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java#L413C12-L440C14],
 _checkDestination_ function: 
{code:java}
// Second we create the queue, the address would have existed or 
successfully created.
            if (destination.isQueue()) {
               ClientSession.QueueQuery queueQuery = 
session.queueQuery(address);
               if (!queueQuery.isExists()) {
                  if (addressQuery.isAutoCreateQueues()) {
                     if (destination.isTemporary()) {
                        createTemporaryQueue(destination, RoutingType.ANYCAST, 
address, null, addressQuery);
                     } else {
                        createQueue(destination, RoutingType.ANYCAST, address, 
null, true, true, addressQuery);
                     }
                  } else {
                     throw new InvalidDestinationException("Destination " + 
address + " does not exist, address exists but autoCreateQueues=" + 
addressQuery.isAutoCreateQueues());
                  }
               }
            } else if (CompositeAddress.isFullyQualified(address)) { // it 
could be a topic using FQQN
               ClientSession.QueueQuery queueQuery = 
session.queueQuery(address);
               if (!queueQuery.isExists()) {
                  if (addressQuery.isAutoCreateQueues()) {
                     if (destination.isTemporary()) {
                        createTemporaryQueue(destination, 
RoutingType.MULTICAST, address, null, addressQuery);
                     } else {
                        createQueue(destination, RoutingType.MULTICAST, 
address, null, true, true, addressQuery);
                     }
                  } else {
                     throw new InvalidDestinationException("Destination " + 
address + " does not exist, address exists but autoCreateQueues=" + 
addressQuery.isAutoCreateQueues());
                  }
               }
            } {code}
When we don't use a fully qualified address (FQQN), I don't understand why the 
client needs to check if the queue exists. It's the server's responsibility to 
forward the message to the correct queue, if the queue doesn't exist, it will 
send the message to DLQ or elsewhere.


was (Author: JIRAUSER302079):
 

In this file 
[ActiveMQSession.java|https://github.com/apache/activemq-artemis/blob/91debf25dbf0f3924d511ee615c6f9b0545e2a5f/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java#L413C12-L440C14],
 _checkDestination_ function: 
{code:java}
// Second we create the queue, the address would have existed or 
successfully created.
            if (destination.isQueue()) {
               ClientSession.QueueQuery queueQuery = 
session.queueQuery(address);
               if (!queueQuery.isExists()) {
                  if (addressQuery.isAutoCreateQueues()) {
                     if (destination.isTemporary()) {
                        createTemporaryQueue(destination, RoutingType.ANYCAST, 
address, null, addressQuery);
                     } else {
                        createQueue(destination, RoutingType.ANYCAST, address, 
null, true, true, addressQuery);
                     }
                  } else {
                     throw new InvalidDestinationException("Destination " + 
address + " does not exist, address exists but autoCreateQueues=" + 
addressQuery.isAutoCreateQueues());
                  }
               }
            } else if (CompositeAddress.isFullyQualified(address)) { // it 
could be a topic using FQQN
               ClientSession.QueueQuery queueQuery = 
session.queueQuery(address);
               if (!queueQuery.isExists()) {
                  if (addressQuery.isAutoCreateQueues()) {
                     if (destination.isTemporary()) {
                        createTemporaryQueue(destination, 
RoutingType.MULTICAST, address, null, addressQuery);
                     } else {
                        createQueue(destination, RoutingType.MULTICAST, 
address, null, true, true, addressQuery);
                     }
                  } else {
                     throw new InvalidDestinationException("Destination " + 
address + " does not exist, address exists but autoCreateQueues=" + 
addressQuery.isAutoCreateQueues());
                  }
               }
            } {code}
 

When we don't use a fully qualified address (FQQN), I don't understand why the 
client needs to check if the queue exists. It's the server's responsibility to 
forward the message to the correct queue, if the queue doesn't exist, it will 

[jira] [Comment Edited] (ARTEMIS-4416) Client can't use anycast without FQQN

2023-09-01 Thread Justin Bertram (Jira)


[ 
https://issues.apache.org/jira/browse/ARTEMIS-4416?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17761348#comment-17761348
 ] 

Justin Bertram edited comment on ARTEMIS-4416 at 9/1/23 4:43 PM:
-

Can you include example configuration to demonstrate your use-case?

For example, are you using something like this?
{code:xml}
  
 

   
  
   
   
  
   
   
  
   

 
  {code}


was (Author: jbertram):
Can you include example configuration to demonstrate your use-case?

> Client can't use anycast without FQQN
> -
>
> Key: ARTEMIS-4416
> URL: https://issues.apache.org/jira/browse/ARTEMIS-4416
> Project: ActiveMQ Artemis
>  Issue Type: Bug
>Affects Versions: 2.7.0, 2.28.0
>Reporter: Damien Picard
>Priority: Major
>
> Since artemis-jms-client@2.7.0, it's no longer possible to create an 
> ActiveMQQueue object with an address (only FQQN). 
> Use case:
> 1. We have an address with one or more queues (declare with an anycast 
> router).
> 2. We create filters to distribute our messages to the correct queue
> 3. A producer sends a message to an address and the server is responsible for 
> forwarding it to the correct queue.
> This use case works in 2.6.4. Since 2.7.0, we have an error raised by the 
> "checkDestination" method ("Destination xxx does not exist, address exists 
> but autoCreateQueues=false").
> ActiveMQ Artemis lets you do this, but the client prevents it.
> If we're using ActiveMQTopic, it works exclusively in multicast mode, so the 
> above use case doesn't work either.
> Also, we could use FQQN exclusively, but we didn't design our architecture 
> that way.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)