Description
Use case:
Artemis 1.5.x Resource adapter that connects to a remote HornetQ broker.
The RA is configured to use the protocol-manager-factory for HornetQ (protocol-manager-factory="org.apache.activemq.artemis.core.protocol.hornetq.client.HornetQClientProtocolManagerFactory") and use Artemis remote connector to connect to HornetQ.
When the RA is activated and its JMS resources are setup, it creates 15 ClientSessions.
The first one is created without any issue and manage to connect to HornetQ broker.
However in org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl#getConnection, it will subscribes to cluster topology from the remote HornetQ broker.
The HornetQ boker will send back its topology with the remote connector information (that uses the org.hornetq.core.remoting.impl.netty.NettyConnectorFactory).
The ServerLocator will be updated to use this topology info instead of the initialConnectors and
subsequent creations of Connection will fail because of the ClassCastException at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl#instantiateConnectorFactory:
2017-09-18 09:05:14,006 ERROR [org.apache.activemq.artemis.ra] (default-threads - 1) AMQ154003: Unable to reconnect org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec(ra=org.apache.activemq.artemis.ra.ActiveMQResourceAdapter@3ca2957 destination=inQueue destinationType=javax.jms.Queue ack=Auto-acknowledge durable=false clientID=null user=null maxSession=15): java.lang.ClassCastException: org.hornetq.core.remoting.impl.netty.NettyConnectorFactory cannot be cast to org.apache.activemq.artemis.spi.core.remoting.ConnectorFactory at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl$2.run(ClientSessionFactoryImpl.java:952) at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl$2.run(ClientSessionFactoryImpl.java:950) at java.security.AccessController.doPrivileged(Native Method) at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.instantiateConnectorFactory(ClientSessionFactoryImpl.java:950) at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.<init>(ClientSessionFactoryImpl.java:179) at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:757) at org.apache.activemq.artemis.ra.inflow.ActiveMQActivation.setup(ActiveMQActivation.java:316) at org.apache.activemq.artemis.ra.inflow.ActiveMQActivation.reconnect(ActiveMQActivation.java:681) at org.apache.activemq.artemis.ra.inflow.ActiveMQActivation$SetupActivation.run(ActiveMQActivation.java:725) at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:223) at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33) at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:808) at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45) at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:828) at java.lang.Thread.run(Thread.java:748) at org.jboss.threads.JBossThread.run(JBossThread.java:320)
I propose that we enhance the ClientProtocolManagerFactory to handle this case. When it receives topology (and TransportConfiguration), it should be possible to "adapt" the transport configuration.
This would be a no-op for Artemis ClientProtocolManagerFactory but it would allow the HornetQClientProtocolManagerFactory to adapt its transport configuration to replace the use of the HornetQ NettyConnectorFactory by the use of the Netty one.