wildfly-proposals icon indicating copy to clipboard operation
wildfly-proposals copied to clipboard

WFLY-13793 Allow for a remote jms queue / topic not to use legacy amq…

Open soul2zimate opened this issue 4 years ago • 12 comments

…1 prefix

EAP7 issue: https://issues.redhat.com/browse/EAP7-1559 WFLY issue: https://issues.redhat.com/browse/WFLY-13793

WFLY PR: https://github.com/wildfly/wildfly/pull/14412

soul2zimate avatar Sep 24 '20 11:09 soul2zimate

@tommaso-borgato I have added some more information about this RFE desired outcome and test expected result. @ehsavoie please feel free to add anything else missing here and correct if I am wrong. Thanks,

soul2zimate avatar Aug 25 '21 09:08 soul2zimate

Release Note Content section is missing here, see the details in comments in the template

marekkopecky avatar Aug 30 '21 09:08 marekkopecky

Release Note Content section is missing here, see the details in comments in the template

I have added the missing Release Note Content part at the end.

soul2zimate avatar Aug 30 '21 09:08 soul2zimate

@tommaso-borgato this concerns only 'external" queues and topics as the internal EAP broker enforces the use of the legacy prefixes for locally defined destinations. We need to enable this at the model and at the deployment level.

You have different ways to access an external broker that's why we need the attribute at different level. It all depends on how you are obtaining the destination:

  • locally defined and injected: here you need it at the communication level and at the destination level
  • remote JNDI call on the broker: here you need it at the communication level
  • usage of Artemis API and destination address: here you need it at the communication level

The legacy prefix is here to ensure retro-compatibility with the destination addresses defined in HornetQ and Artemis 1.x. See Fully Qualified Queue Names to understand the impact of those prefixes. Setting the attribute at the communication level isn't sufficient as WildFly is enforcing the use of the legacy prefixes on the destination address. We can configure the broker to 'ignore' the prefixes automatically but this won't be applied at the creation of the destinations by WildFly. So while we would be using the JMS queue myqueue we would still create a jms.queue.myqueue*. A queue can be autocreated by the broker depending on the broker configuration, by WildFly can do it also if the broker won't allow it. We need to ensure that the address that WildFly is using matches that of the broker. The setting of the prefix is not only done by Wildfly but also by the Artemis client and resource adapter.

ehsavoie avatar Aug 28 '23 16:08 ehsavoie

@ehsavoie the internal EAP broker enforces the use of the legacy prefixes for locally defined destinations. why is it configured this way? IIUC, always adding the prefix means that both jms.queue.SomeQueue and SomeQueue in EAP would be translated to jms.queue.SomeQueue when sent to Artemis; since Artemis is forces using compatibility mode, then it would always strip the prefix; result is that jms.queue.SomeQueue and SomeQueue in EAP would always map to address SomeQueue in Artemis;

Is that correct?

tommaso-borgato avatar Aug 28 '23 17:08 tommaso-borgato

@tommaso-borgato Artemis compatibility mode doesn't apply to Artemis management messages: when WildFly is creating the destination it forces the prefix in the destination address. This is what this is all about: changing the create message WildFly sends to have the prefix or not. All those changes are targeting destination used for a remote broker. Also you are wrong here: embedded Artemis 2.x in WildFly forces legacy mode: the prefixes are always present. There is no broker.xml in embedded mode. Documentation doesn't state that because it has always been the case in WildFly or EAP: will create a queue at address jms.queue.foo. Also things a re bit more complex than that as we also need to be able to have address matching on the client side and not only on the server side. We need a way to configure both the client and the remote broker. Until now this was coarse grained. The goal is to be able to define that at the destination level.

ehsavoie avatar Aug 29 '23 07:08 ehsavoie

@ehsavoie I try and summarize here the outcome from our chat and experiments;

We start by following the procedure described in https://github.com/wildfly/quickstart/tree/main/remote-helloworld-mdb; Basically what's relevant here is:

  • we start a remote Artemis Broker which is NOT running in compatibility mode (= it doesn't try to add prefixes for all incoming queue/topic names)
  • we create a connection on WildFly to the remote Artemis Broker (called pooled-connection-factory) which overrides the default value of enable-amq1-prefix (which is true) by setting it to enable-amq1-prefix=false: this means also the WildFly Artemis client won't try to add prefixes to all queue/topic names
  • we create an application which defines a queue named HelloWorldMDBQueue which overrides the default behavior by setting properties = {"enable-amq1-prefix=false"} (default would be true) on the queue definition:
@JMSDestinationDefinition(
            name = "java:/queue/HELLOWORLDMDBQueue",
            interfaceName = "jakarta.jms.Queue",
            destinationName = "HelloWorldMDBQueue",
            properties = {"enable-amq1-prefix=false"} // if you remove this, a useless jms.queue.HelloWorldMDBQueue is created
        )

This results in a destination named HelloWorldMDBQueue containing a single anycast queue named HelloWorldMDBQueue being created on the remote Artemis Broker;

Everything is consistent: our java annotation defines a destination named HelloWorldMDBQueue and the remote Artemis Broker, contains a destination with the same name, no prefix added;

This is what happens after the feature provided by this RFE has been used: it is setting properties = {"enable-amq1-prefix=false"};

Now, remove properties = {"enable-amq1-prefix=false"} from @JMSDestinationDefinition and redeploy the application: you'll notice that:

  • everything continues to work: messages are routed to Artemis destination HelloWorldMDBQueue
  • **a useless destination named jms.queue.HelloWorldMDBQueue is created on the remote Artemis Broker

Summary: with the feature provided by this RFE we can get rid of that useless destination

@ehsavoie why don't we add the former example to the AD? it would help understanding what it's all about

tommaso-borgato avatar Aug 30 '23 14:08 tommaso-borgato

@ehsavoie I also tried using queues defined in model:

I you define an external queue in WildFly model without setting enable-amq1-prefix:

/subsystem=messaging-activemq/external-jms-queue=myExternalQueue:add(entries=[java:jboss/exported/jms/queue/myExternalQueue])

When you later use that queue in your Java code:

@Resource(lookup = "java:jboss/exported/jms/queue/myExternalQueue")
    private transient Queue queue5;

Here is what happens:

  • a useless myExternalQueue destination is created on the remote Artemis broker
  • a destination named jms.queue.myExternalQueue is created on the remote Artemis broker: messages are correctly routed to this destination

Thanks to the feature provided by this RFE, we can get rid of the useless myExternalQueue destination by setting enable-amq1-prefix either to true or false:

/subsystem=messaging-activemq/external-jms-queue=myExternalQueue:add(entries=[java:jboss/exported/jms/queue/myExternalQueue], enable-amq1-prefix=true)

in this case, just a destination named jms.queue.myExternalQueue is created on the remote Artemis broker: messages are correctly routed to this destination

or, when set to false:

/subsystem=messaging-activemq/external-jms-queue=myExternalQueue:add(entries=[java:jboss/exported/jms/queue/myExternalQueue], enable-amq1-prefix=false)

in this case, just a destination named myExternalQueue is created on the remote Artemis broker: messages are correctly routed to this destination

@ehsavoie do you think we can add also this scenario to the AD? this way we cover both annotation and model defined destinations;

tommaso-borgato avatar Aug 30 '23 16:08 tommaso-borgato

@tommaso-borgato I going to put those details in the AD. Note that the quickstart didn't exist at the tile the AD was written :)

ehsavoie avatar Aug 31 '23 07:08 ehsavoie

@ehsavoie yet another thing for some future (feel free to ignore it in case it doesn't make sense):

Proposal for a future RFE

Given:

  • Artemis Remote Brokers don't run in compatibility mode (compatibility mode off = don't add legacy prefixes to names - generally enabled by adding "anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to any acceptor url) by default both on bare metal and on OpenShift
  • Artemis Broker Embedded in WildFly, by default runs in compatibility mode (compatibility mode on = add legacy prefixes to names)

We could make the behavior of the Artemis Broker Embedded in WildFly consistent with bare metal and OpenShift: the Artemis Broker Embedded in WildFly would not run in compatibility mode anymore;

This might be also the occasion to adjust the behavior of the other related components accordingly in order to streamline the user experience and make it simpler and consistent across different Artemis options (embedded, remote on bare metal, remote on OpenShift):

  • @jakarta.jms.JMSDestinationDefinition annotation
  • external-jms-queue model object
  • pooled-connection-factory model object

tommaso-borgato avatar Aug 31 '23 08:08 tommaso-borgato

@soul2zimate after you give a look at my latest 2 comments I think we can finally approve this AD

tommaso-borgato avatar Sep 25 '23 14:09 tommaso-borgato

updated as per the last QE comment. Thank you.

soul2zimate avatar Sep 26 '23 07:09 soul2zimate