1 2 Previous Next 22 Replies Latest reply on Apr 21, 2010 9:26 AM by jesper.pedersen

    HornetQ RA integration

    jmesnil

      Hi,

       

      As you probably know, we are integrating HornetQ in AS 6 (and the clock is ticking!).

      HornetQ now has its own resource adapter and no longer use the generic JMS RA.

      However, I've some difficulties to understand how it fits with *-ds.xml connection factories.

       

         <tx-connection-factory>

            <jndi-name>DURABLE_SUB_CONNECTION_FACTORY</jndi-name>

            <rar-name>jms-ra.rar</rar-name>

            <connection-definition>org.hornetq.ra.HornetQRAConnectionFactory</connection-definition>

            <xa-transaction/>

            <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property>

            <config-property name="ClientID" type="java.lang.String">cts</config-property>

            <max-pool-size>1</max-pool-size>

         </tx-connection-factory>

       

      I don't understand how I can find whether the managed connection factory will use XA or not when I effectively create the JMS resources in HornetQRAConnectionFactory class.

      Is there a way to know whether a connection factory is using <xa-transaction /> or <local-transaction /> from the SPI or am I missing something obvious?

       

      Thanks for the help,

      jeff

        • 1. Re: HornetQ RA integration
          vickyk

           

          I don't understand how I can find whether the managed connection factory will use XA or not when I effectively create the JMS resources in HornetQRAConnectionFactory class.


          I don't understand why you need to do so, the ConnectionManager should identify if it is localtx or xatx and accordingly enlist the XAResource.

          The client application will get the ConnectionFactory which will call the ConnectionManager::allocateConnection() and further invoke createManagedConnection Or matchManagedConnection.

           

          The createManagedConnection will basically invoke the MCF::createConnection().

           

          PS: If you could explain the details then I could take a deeper look at the specs and corresponding details, right now I am putting all what is there in top of my mind.

           

          Regards,

          Vicky

          • 2. Re: HornetQ RA integration
            jmesnil

            vickyk wrote:

             

            The client application will get the ConnectionFactory which will call the ConnectionManager::allocateConnection() and further invoke createManagedConnection Or matchManagedConnection.

             

            The createManagedConnection will basically invoke the MCF::createConnection().

             

            PS: If you could explain the details then I could take a deeper look at the specs and corresponding details, right now I am putting all what is there in top of my mind.

            In HornetQRAManagedConnectionFactory.createConnection(), I create the ManagedConnection which in turn create the underlying HornetQ JMS resources.

            At that time, I need to know if I should create a XASession (if <xa-transaction /> was specified), a transacted Session (if <local-transaction />) or a non-transacted Session (if in a <no-tx-connection-factory> element).

            This created session will be returned later by ManagedConnection.getConnection(). Is that correct?

             

            I'm diving into the JCA spec to have a better picture of this...

             

            thanks for the help

            • 3. Re: HornetQ RA integration
              vickyk

              jmesnil wrote:

               

              At that time, I need to know if I should create a XASession (if <xa-transaction /> was specified), a transacted Session (if <local-transaction />) or a non-transacted Session (if in a <no-tx-connection-factory> element).

              This created session will be returned later by ManagedConnection.getConnection(). Is that 

               

              If xa-transaction is specified the ConnectionManager implementation i.e org.jboss.resource.connectionmanager.TxConnectionManager::createConnectionListerner(..) will get the XAResource from the MC::getXAResource

               

              Here is the code

               

               public ConnectionListener createConnectionListener(ManagedConnection mc, Object context)
                    throws ResourceException
                 {
                    XAResource xaResource = null;
                    
                    if (localTransactions)
                    {
                       xaResource = new LocalXAResource(log);
                       if (xaResourceTimeout != 0)
                          log.debug("XAResource transaction timeout cannot be set for local transactions: " + getJndiName());
                    }
                    else
                    {
                       xaResource = JcaXAResourceWrapperFactory.getResourceWrapper(mc.getXAResource(), isSameRMOverrideValue);
                       
                       if (xaResourceTimeout != 0)
                       {
                          try
                          {
                             if (xaResource.setTransactionTimeout(xaResourceTimeout) == false)
                                log.debug("XAResource does not support transaction timeout configuration: " + getJndiName());
                          }
                          catch (XAException e)
                          {
                             throw new JBossResourceException("Unable to set XAResource transaction timeout: " + getJndiName(), e);
                          }
                       }
                    }
              
                    ConnectionListener cli = new TxConnectionEventListener(mc, poolingStrategy, context, log, xaResource);
                    mc.addConnectionEventListener(cli);
                    return cli;
                 }
              
              

               

               

              The ConnectionListener/ConnectionManager creates the XASession and non XASession, you will have to implement the getXAResource and getLocalTransaction appropriately.

               

              The JCA CM will call these methods approprately during the execution.

              You can find more from JCA specs CM chapter.

               

              HTH !

              • 4. Re: HornetQ RA integration
                jmesnil

                yeah, I see now.

                 

                Indeed HornetQ RA must defer the creation of its JMS resources until the ConnectionManager calls getXAResource(), getLocalTransaction() or getConnection(). Then we have all the informations we need to create them.

                 

                Thanks for the help!

                • 5. Re: HornetQ RA integration
                  jmesnil

                  I still have an issu even when I defer the creation of the JMS resources.

                   

                  19:02:54,257 TRACE [org.hornetq.ra.HornetQRAManagedConnection] getXAResource()

                  19:02:54,637 TRACE [org.hornetq.ra.HornetQRAManagedConnection] XAResource=org.hornetq.core.client.impl.ClientSessionImpl@e10de4c

                  19:02:54,641 TRACE [org.hornetq.ra.HornetQRAXAResource] constructor(org.hornetq.ra.HornetQRAManagedConnection@16fe8172, org.hornetq.core.client.impl.ClientSessionImpl@e10de4c)

                  19:02:54,642 TRACE [org.hornetq.ra.HornetQRAManagedConnection] addConnectionEventListener(org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener@1ee46f29[state=NORMAL mc=org.hornetq.ra.HornetQRAManagedConnection@16fe8172 handles=0 lastUse=1268848974642 permit=false trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$PoolByCri@273dfc97 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@569231a1 xaResource=org.hornetq.ra.HornetQRAXAResource@17f86d6e txSync=null])

                  19:02:54,643 TRACE [org.jboss.resource.connectionmanager.JBossManagedConnectionPool] supplying new ManagedConnection: org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener@1ee46f29[state=NORMAL mc=org.hornetq.ra.HornetQRAManagedConnection@16fe8172 handles=0 lastUse=1268848974642 permit=false trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$PoolByCri@273dfc97 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@569231a1 xaResource=org.hornetq.ra.HornetQRAXAResource@17f86d6e txSync=null]

                  19:02:54,644 TRACE [org.jboss.resource.connectionmanager.TxConnectionManager] No transaction, no need to enlist: org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener@1ee46f29[state=NORMAL mc=org.hornetq.ra.HornetQRAManagedConnection@16fe8172 handles=0 lastUse=1268848974642 permit=true trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$PoolByCri@273dfc97 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@569231a1 xaResource=org.hornetq.ra.HornetQRAXAResource@17f86d6e txSync=null]

                  19:02:54,645 TRACE [org.hornetq.ra.HornetQRAManagedConnection] getConnection(null, HornetQRAConnectionRequestInfo[type=1, useXA=false, transacted=false, acknowledgeMode=1, clientID=null, userName=j2ee, password=j2ee])

                  According to the log, getXAResource() is called on the ManagedConnection

                  -> I create the underlying JMS XA Session

                  Then the tm realizes there is no TX and does not enlist the xaresource

                  Finally getConnection() is called on the ManagedConnection

                  -> It will return the JMS XA session

                   

                  In the TCK, I have a lot of failures because the tests call methods which are not allowed on XA Session (e.g. Session.recover()).

                  And the issues is that different tests use the same connection-factory settings either inside or outside a transaction.

                   

                  It's not clear to me but this seems to imply that a ManagedConnection with XA transaction has to accept doing work outside a transaction.

                  I don't find the relevant section in the JCA spec. wdyt?

                  • 6. Re: HornetQ RA integration
                    vickyk
                    According to the log, getXAResource() is called on the ManagedConnection

                    -> I create the underlying JMS XA Session

                    Then the tm realizes there is no TX and does not enlist the xaresource

                    Finally getConnection() is called on the ManagedConnection

                    -> It will return the JMS XA session

                    yes this flow is in the CM::allocateConnection(), you can see the implementation here

                    http://anonsvn.jboss.org/repos/jbossas/trunk/connector/src/main/java/org/jboss/resource/connectionmanager/BaseConnectionManager2.java

                     

                    jmesnil wrote:

                    It's not clear to me but this seems to imply that a ManagedConnection with XA transaction has to accept doing work outside a transaction.

                    I don't find the relevant section in the JCA spec. wdyt?

                    It does work outside the transaction, you will only get the pooling functionality and not the transparent TX enlistment since this is not called in the TX context.

                     

                    Check "7.6.4 Scenario: Transactional Setup for a ManagedConnection" of JCA1.5 specs, this talks about the case when the TX propagation is there.

                     


                      If the application server decides that the transaction manager will manage the

                      current transaction, it conducts the following transactional setup on the
                      ManagedConnection instance:

                     

                     

                    Using the xa resource with transaction context does not make any sense as there is no tx propagation, in such cases no-tx resource could be used.

                     

                    I don't understand how the Session.recovery would be called in tests where there is no tx propagation, if the TX  is not being present in the usecases then i don't see recovery being called ,  therefore the TX recovey mechanism will not call Session::recovery.

                    The recovery will come in picture in case of TX only.

                     

                    I may need to understand the TCK testcase to provide more details.

                    • 7. Re: HornetQ RA integration
                      jmesnil

                      vickyk wrote:

                       

                      Using the xa resource with transaction context does not make any sense as there is no tx propagation, in such cases no-tx resource could be used.

                      I agree. Unfortunately, this is to pass TCK tests and some of them uses the same ConnectionFactory with transactions and others don't.

                       

                      I don't understand how the Session.recovery would be called in tests where there is no tx propagation, if the TX  is not being present in the usecases then i don't see recovery being called ,  therefore the TX recovey mechanism will not call Session::recovery.

                      The recovery will come in picture in case of TX only.

                       

                      I may need to understand the TCK testcase to provide more details.

                      I was talking about JMS Session.recover(), not XAResource.recover().

                      Session.recover() is used to recover message acknowledgementswhen the JMS session is not transacted. Sorry for the confusion.

                       

                      thanks for the clarification,

                      jeff

                      • 8. Re: HornetQ RA integration
                        vickyk

                        jmesnil wrote:

                         

                        Session.recover() is used to recover message acknowledgementswhen the JMS session is not transacted. Sorry for the confusion.

                         

                        thanks for the clarification,

                        jeff

                        Not sure if I understood this, it seems that Session.recovery is not the part of the jms API.

                        Would you explain the failure cause in details, your earlier description wasn't that clear to me?

                        Also you could take a look at the older implementation for some reference, since this implementation would have passed the TCK tests

                        http://anonsvn.jboss.org/repos/jbossas/trunk/connector/src/main/java/org/jboss/resource/adapter/jms/

                         

                        AFAIR the tx enlistment will not happen if the xa specific RA if it is not used in tx context, it should not pose any issues. I don't know how the recovery() call as pointed by you is being made after the session is retrieved from the jms RA.

                        • 9. Re: HornetQ RA integration
                          timfox

                          We're discussing this here:

                           

                          http://community.jboss.org/message/532625#532625

                           

                          AIUI (Jeff please correct me if I am wrong), the JBoss JCA impl is calling getXAResource() even though no work is being done as part of an XA tx, which seems incorrect to me.

                           

                          This causes the HQ RA to use an XA session, which never gets enlisted in a tx, and the JBoss JCA impl then expects that xa session that's not enlisted to behave like a non transacted session - again an incorrect assumption.

                           

                          The only reason JBM worked is due to a hack we put it in to work around this strange JCA impl behaviour. We don't want to have to put the same hack in HornetQ.

                          • 10. Re: HornetQ RA integration
                            vickyk

                            timfox wrote:

                             

                            We're discussing this here:

                             

                            http://community.jboss.org/message/532625#532625

                             

                            AIUI (Jeff please correct me if I am wrong), the JBoss JCA impl is calling getXAResource() even though no work is being done as part of an XA tx, which seems incorrect to me

                             

                            Yes it does call the getXAReosource() on the MC even if there is not TX propagation. Here is the code which does it

                            org.jboss.resource.connectionmanager.TxConnectionManager::createConnectionListener()

                            http://anonsvn.jboss.org/repos/jbossas/trunk/connector/src/main/java/org/jboss/resource/connectionmanager/TxConnectionManager.java

                             

                            Also the JCA interacts with the XASession's i.e which I assume are the XAResource via the TM, the TM could interact with the XAResources only when it is enlisted.If the TX is not propagated and JCA getting the XAResource and not making it available(by enlisting it in TX) should not have any effect AFAIU, I don't know how it is affecting TCK.

                             

                            Yes as per the JCA specs we should not be calling the getXAResource on MC if there is not a TX propagation, this looks a bug to me also.

                             

                            Jeff, are you able to get things working as it had been done in jboss messaing.

                            I could try making the changes in JCA but it might need more time for testing etc, I will raise a discussion about it in design forums too so that we hear more from otheres.

                            • 11. Re: HornetQ RA integration
                              vickyk

                              Here is the related link in JCA development forums

                              http://community.jboss.org/thread/149602

                              • 12. Re: HornetQ RA integration
                                timfox

                                Thanks Vicky,

                                 

                                Jeff, one workaround we could do for now:

                                 

                                When returning the XAResource to the applpication server via getXAResource we could actually return a thin wrapper around the real XAResource, in this thin wrapper we could maintain a flag isEnlisted which keeps track of whether the XAResource has actually been used or not.

                                 

                                We could then only create the real XAResource and XA session when the enlistment actually occurs.

                                 

                                I do believe though this should be fixed in the JCA impl as a proper solution, otherwise for one thing it means JBoss JCA impl won't work with other non JBoss JCA adaptors which don't have the "hacks" in place to workaround the current JCA impl behaviour.

                                • 13. Re: HornetQ RA integration

                                  Tim Fox wrote:

                                  I do believe though this should be fixed in the JCA impl as a proper solution, otherwise for one thing it means JBoss JCA impl won't work with other non JBoss JCA adaptors which don't have the "hacks" in place to workaround the current JCA impl behaviour.

                                  What are you on about?

                                   

                                  The problem is one of JMS protocol not JCA protocol.

                                   

                                  The TCK test is using an XAConnection that is not enlisted in a transaction

                                  and then doing JMS calls that would not be allowed if it where.

                                   

                                  JBossMQ handles this case no problem.

                                  i.e. The XASession behaves as a normal Session unless/until the XAResource is enlisted.

                                   

                                  This behaviour is currently not specified in the JMS spec

                                  (little of the XA interface is specified and it is even optional)

                                  so any error is likely in the assumptions the TCK is making.

                                  e.g. using xa connection factory for client acknowledge processing.

                                   

                                  If HornetQ doesn't want to support this unmandated but not disallowed behaviour

                                  (clearly all other JMS providers support it otherwise they wouldn't pass the TCK)

                                  then the correct approach would be to challenge the test.

                                  • 14. Re: HornetQ RA integration
                                    timfox

                                    Adrian,

                                     

                                    So you're saying it's correct for a JCA impl to call

                                     

                                    getManagedConnection()

                                     

                                    then

                                     

                                    managedConnection.getXAResource()

                                     

                                    and then never enlist the resource in a tx, and expect the managed connection to behave as non transacted?

                                     

                                    I can't see this requirement in the JCA spec anyway, but I will defer to your better knowledge of JCA.

                                     

                                    Our assumption has been, if the AS calls getXAResource() it's reasonable to expect it has done so because it's going to enlist that resource in a tx.

                                     

                                    If that's not correct, I find it odd. However our impl should work in either case now, since Jeff has created a proxy around the real XAResource which switches between a non transacted and an XA session behind the scenes depending on whether the resource has been enlisted or not.

                                    1 2 Previous Next