1 2 Previous Next 15 Replies Latest reply on Feb 3, 2014 4:59 PM by evidence01

    Switchyard - Control JMS redelivery. Best practices

    evidence01

      I am in need to control the redelivery properties of the JMS client bindings. So far I have found no way to do so against the JMS or JCA bindings. The default redelivery policy of 1 is inadequate for production environments.

       

      What is the recommend way to accomplish this?An example would be great...

       

      Thanks

      Jacek

        • 1. Re: Switchyard - Control JMS redelivery. Best practices
          igarashitm

          Hi Jacek, JMS redelivery is handled by JMS provider - for example, this content may be helpful if you are using HornetQ: http://docs.jboss.org/hornetq/2.4.0.Final/docs/user-manual/html_single/index.html#undelivered-messages hth, Tomo

          • 2. Re: Switchyard - Control JMS redelivery. Best practices
            evidence01

            HornetQ on jboss defaults to redelivery attempts of 10. SW bags out after 1 at the JMS endpoint level. Thoughts?

            • 3. Re: Switchyard - Control JMS redelivery. Best practices
              igarashitm

              HornetQ redelivery works for me. policy-transaction demo in our quickstarts is using JCA, actually triggers 3 times redelivery by the rollback. I did try with camel-jms before and it also succeeded.

              • 4. Re: Switchyard - Control JMS redelivery. Best practices
                evidence01

                OK some more data.

                 

                I finally figured out that my service flow had all IN_ONLY services. After reading Camel RouteBuilder onException statement II, it seemed that IN only with JMS is BAD....so i swtiched to IN_OUT.

                 

                I finally added a return type and they got parsed as IN_OUT and now Fault propagation is working back to the invoker, however i still does not seem to be "rolling back" the transaction across the service flow even though All JMS endpoints are transaction and all routes in between have a global transaction property set. Below is the final Service reference which is a JMS endpoint tied to a JMS Topic that is on a remote server. The exchange now properly handles the fault, however why is rollbackOnFault false? Would this not drive the roll-back of the global transaction?

                 

                What is more puzzling is that a service flow with JMS IN from Q -> Camel route -> JMS OUT to Q works perfect for IN_ONLY.

                 

                However JMS IN from Q -> Camel route -> JMS Topic OUT does not work with an IN_ONLY setup NOR a IN_OUT setup. I cannot understand why the service flow is not unwinding back and keeping the message in the JMS IN from Q in that scenario....Why does a Topic OUT versus Queue OUT matter????????????????

                 

                I am stumped on this one.

                 

                ------- Begin Message Trace -------

                Consumer -> {urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}FlowFromEsbBridge/PutFlowInEsbMaster

                Provider -> {urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsbMaster

                Operation -> enqueueFlowData

                MEP -> IN_OUT

                Phase -> OUT

                State -> FAULT

                Exchange Context ->

                    CamelCreatedTimestamp ............................: Thu Jan 23 00:39:11 CST 2014

                    CamelFailureEndpoint .............................: direct://%7Burn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0%7DFlowFromEsbBridge/PutFlowInEsbMaster

                    CamelFilterMatched ...............................: true

                    CamelToEndpoint ..................................: direct://%7Burn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0%7DFlowFromEsbBridge/PutFlowInEsbMaster

                    org.switchyard.bus.camel.consumer ................: ServiceReference [name={urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}FlowFromEsbBridge/PutFlowInEsbMaster, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: enqueueFlowData : IN_OUT  : [java:com.securelogix.data.model.Flow, java:boolean, java:java.lang.Exception]]], domain=ServiceDomain [name=null]]

                    org.switchyard.bus.camel.contract ................: org.switchyard.metadata.BaseExchangeContract@ea978af

                    org.switchyard.bus.camel.dispatcher ..............: org.switchyard.bus.camel.ExchangeDispatcher@183230ae

                    org.switchyard.bus.camel.fault ...................: true

                    org.switchyard.bus.camel.labels ..................: {org.switchyard.exchangeGatewayName=[org.switchyard.label.behavior.transient], org.switchyard.exchangeInitiatedNS=[org.switchyard.label.behavior.transient], org.switchyard.exchange.transaction.beforeInvoked=[org.switchyard.label.behavior.transient], org.switchyard.security.context.SecurityContext=[org.switchyard.label.behavior.transient]}

                    org.switchyard.bus.camel.phase ...................: OUT

                    org.switchyard.bus.camel.provider ................: Service [name={urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsbMaster, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: enqueueFlowData : IN_OUT  : [java:com.s.data.model.Flow, java:boolean, java:java.lang.Exception]]], domain=ServiceDomain [name=null], metadata=org.switchyard.metadata.ServiceMetadataBuilder$ServiceMetadataImpl@34a31be0]

                    org.switchyard.bus.camel.replyHandler ............: org.switchyard.component.camel.CamelResponseHandler@719fbeb

                    org.switchyard.exchange.transaction.beforeInvoked : true

                    org.switchyard.exchangeGatewayName ...............: _PutFlowInEsbMaster_jms_1

                    org.switchyard.exchangeInitiatedNS ...............: 452793249828219

                    org.switchyard.faultType .........................: java:java.lang.Exception

                    org.switchyard.operationName .....................: enqueueFlowData

                    org.switchyard.rollbackOnFault ...................: false

                    org.switchyard.security.context.SecurityContext ..: DefaultSecurityContext@1295043428[systemUUID=b5ba7631-3b95-4968-a621-74a0f88564dc, expirationMillis=0, credentials=[], securityDomainsToSubjects={}]

                    org.switchyard.serviceName .......................: {urn:com.s.enum_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsb

                Message Context ->

                    org.switchyard.bus.camel.labels ...........: {org.switchyard.contentType=[org.switchyard.label.behavior.transient], org.switchyard.bus.camel.messageSent=[org.switchyard.label.behavior.transient], org.switchyard.exchangeDurationMS=[org.switchyard.label.behavior.transient], org.switchyard.transform.TransformSequence=[org.switchyard.label.behavior.transient]}

                    org.switchyard.bus.camel.messageSent ......: true

                    org.switchyard.contentType ................: java:java.lang.Exception

                    org.switchyard.exchangeDurationMS .........: 32

                    org.switchyard.messageId ..................: ID-jayslinuxmobile-34686-1390459110993-0-196

                    org.switchyard.relatesTo ..................: ID-jayslinuxmobile-34686-1390459110993-0-192

                    org.switchyard.transform.TransformSequence : org.switchyard.transform.TransformSequence@30efb36b

                ------ End Message Trace -------

                00:39:11,119 WARN  [org.apache.camel.processor.DefaultErrorHandler] (Camel (camel-1) thread #2 - JmsConsumer[enumFlowQueue]) Failed delivery for (MessageId: ID-jayslinuxmobile-34686-1390459110993-0-189 on ExchangeId: ID-jayslinuxmobile-34686-1390459110993-0-190). On delivery attempt: 0 caught: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Could not create a session: IJ000453: Unable to get managed connection for java:/MediationConnectionFactory

                • 5. Re: Switchyard - Control JMS redelivery. Best practices
                  igarashitm

                  The exchange now properly handles the fault, however why is rollbackOnFault false? Would this not drive the roll-back of the global transaction?

                  That's by design. For IN_OUT, transaction is committed if checked exception is thrown. You may want to throw an runtime exception to trigger rollback, or simply set rollbackOnFault context property to true.

                   

                  What is more puzzling is that a service flow with JMS IN from Q -> Camel route -> JMS OUT to Q works perfect for IN_ONLY.

                   

                  However JMS IN from Q -> Camel route -> JMS Topic OUT does not work with an IN_ONLY setup NOR a IN_OUT setup. I cannot understand why the service flow is not unwinding back and keeping the message in the JMS IN from Q in that scenario....Why does a Topic OUT versus Queue OUT matter????????????????

                   

                  I am stumped on this one.

                   

                  ------- Begin Message Trace -------

                  Consumer -> {urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}FlowFromEsbBridge/PutFlowInEsbMaster

                  Provider -> {urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsbMaster

                  Operation -> enqueueFlowData

                  MEP -> IN_OUT

                  Phase -> OUT

                  State -> FAULT

                  Exchange Context ->

                      CamelCreatedTimestamp ............................: Thu Jan 23 00:39:11 CST 2014

                      CamelFailureEndpoint .............................: direct://%7Burn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0%7DFlowFromEsbBridge/PutFlowInEsbMaster

                      CamelFilterMatched ...............................: true

                      CamelToEndpoint ..................................: direct://%7Burn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0%7DFlowFromEsbBridge/PutFlowInEsbMaster

                      org.switchyard.bus.camel.consumer ................: ServiceReference [name={urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}FlowFromEsbBridge/PutFlowInEsbMaster, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: enqueueFlowData : IN_OUT  : [java:com.securelogix.data.model.Flow, java:boolean, java:java.lang.Exception]]], domain=ServiceDomain [name=null]]

                      org.switchyard.bus.camel.contract ................: org.switchyard.metadata.BaseExchangeContract@ea978af

                      org.switchyard.bus.camel.dispatcher ..............: org.switchyard.bus.camel.ExchangeDispatcher@183230ae

                      org.switchyard.bus.camel.fault ...................: true

                      org.switchyard.bus.camel.labels ..................: {org.switchyard.exchangeGatewayName=[org.switchyard.label.behavior.transient], org.switchyard.exchangeInitiatedNS=[org.switchyard.label.behavior.transient], org.switchyard.exchange.transaction.beforeInvoked=[org.switchyard.label.behavior.transient], org.switchyard.security.context.SecurityContext=[org.switchyard.label.behavior.transient]}

                      org.switchyard.bus.camel.phase ...................: OUT

                      org.switchyard.bus.camel.provider ................: Service [name={urn:com.s.e_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsbMaster, interface=SWITCHYARD010007: BaseServiceInterface [type=java, operations=[SWITCHYARD010008: enqueueFlowData : IN_OUT  : [java:com.s.data.model.Flow, java:boolean, java:java.lang.Exception]]], domain=ServiceDomain [name=null], metadata=org.switchyard.metadata.ServiceMetadataBuilder$ServiceMetadataImpl@34a31be0]

                      org.switchyard.bus.camel.replyHandler ............: org.switchyard.component.camel.CamelResponseHandler@719fbeb

                      org.switchyard.exchange.transaction.beforeInvoked : true

                      org.switchyard.exchangeGatewayName ...............: _PutFlowInEsbMaster_jms_1

                      org.switchyard.exchangeInitiatedNS ...............: 452793249828219

                      org.switchyard.faultType .........................: java:java.lang.Exception

                      org.switchyard.operationName .....................: enqueueFlowData

                      org.switchyard.rollbackOnFault ...................: false

                      org.switchyard.security.context.SecurityContext ..: DefaultSecurityContext@1295043428[systemUUID=b5ba7631-3b95-4968-a621-74a0f88564dc, expirationMillis=0, credentials=[], securityDomainsToSubjects={}]

                      org.switchyard.serviceName .......................: {urn:com.s.enum_uc.switchyard:enum-uc-service-switchyard:1.0}PutFlowInEsb

                  Message Context ->

                      org.switchyard.bus.camel.labels ...........: {org.switchyard.contentType=[org.switchyard.label.behavior.transient], org.switchyard.bus.camel.messageSent=[org.switchyard.label.behavior.transient], org.switchyard.exchangeDurationMS=[org.switchyard.label.behavior.transient], org.switchyard.transform.TransformSequence=[org.switchyard.label.behavior.transient]}

                      org.switchyard.bus.camel.messageSent ......: true

                      org.switchyard.contentType ................: java:java.lang.Exception

                      org.switchyard.exchangeDurationMS .........: 32

                      org.switchyard.messageId ..................: ID-jayslinuxmobile-34686-1390459110993-0-196

                      org.switchyard.relatesTo ..................: ID-jayslinuxmobile-34686-1390459110993-0-192

                      org.switchyard.transform.TransformSequence : org.switchyard.transform.TransformSequence@30efb36b

                  ------ End Message Trace -------

                  00:39:11,119 WARN  [org.apache.camel.processor.DefaultErrorHandler] (Camel (camel-1) thread #2 - JmsConsumer[enumFlowQueue]) Failed delivery for (MessageId: ID-jayslinuxmobile-34686-1390459110993-0-189 on ExchangeId: ID-jayslinuxmobile-34686-1390459110993-0-190). On delivery attempt: 0 caught: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Could not create a session: IJ000453: Unable to get managed connection for java:/MediationConnectionFactory

                  According to the last message, Topic vs Queue doesn't matter - Apparently it just failed to get connection from java:/MediationConnectionFactory.

                  • 6. Re: Switchyard - Control JMS redelivery. Best practices
                    evidence01

                    The lookup of the connectionfactory should rollback the tx since the endpoint cant get a connection to the remote topic. but it doesn't. the fault consumes and the message is lost.

                    • 7. Re: Switchyard - Control JMS redelivery. Best practices
                      evidence01

                      Question,

                       

                      Why does te following occur for the exact same container/connection factory setup?

                       

                      JMS IN_ONLY from Q with LocalJmsXA -> Camel route -> JMS IN_ONLY to Q with RemoteJmsXA

                       

                      The above correctly STORES and keeps data in the left side Q when JMS cannot obtain a connection or a connectionfactory reference to RemoteJmsXA. I consider this correct behaviour.

                       

                      Now when you change one thing

                       

                      JMS IN_ONLY from Q with LocalJmsXA -> Camel route -> JMS IN_ONLY to Topic with RemoteJmsXA

                       

                      It breaks. The message are consumed and lost under the exact same error scenario? Why would that be?

                      • 8. Re: Switchyard - Control JMS redelivery. Best practices
                        igarashitm

                        I don't think SwitchYard causes that behavior. Can you attach your application and a testcase to repruduce?

                        • 9. Re: Switchyard - Control JMS redelivery. Best practices
                          evidence01

                          Here we go. Attached is the src and META-INF for the use-case. Run HQQueueTest. Also see standalone-full.xml which shows my specific jboss settings ontop of the regular standalone-full for jboss as 7.2

                           

                          I greatly appreciate your eyes on this.

                          -J

                          • 10. Re: Switchyard - Control JMS redelivery. Best practices
                            igarashitm

                            Hi Jacek,

                             

                            1. Can you include pom.xml as well?
                            2. It seems to have compilation errors
                            3. HQTopicTest is included but not HQQueueTest
                            4. I couldn't understand what are you trying to test with HQTopicTest. It just sends messages to testTopic and consume from it. No relation with included SwitchYard application
                            • 11. Re: Switchyard - Control JMS redelivery. Best practices
                              evidence01

                              Attached is a gradle project. we do not use maven. Just get gradle and run gradle build. Deploy the jar to jboss.

                               

                              Then run gradle test to inject a message into the inbound Q, the message will propagate through the service flow and fail on because the outbound Topic does NOT exist. The message is then lost and does not rollback tp the enumFlowQueue.

                               

                              -J

                              • 12. Re: Switchyard - Control JMS redelivery. Best practices
                                igarashitm

                                Thanks for providing good stuffs - I'm not sure if it's exactly same problem you've been describing though, I found a bug in camel reference binding:

                                https://issues.jboss.org/browse/SWITCHYARD-1950


                                It doesn't matter if the destination is topic or queue. An Exception is not propagated to the service consumer if there's a camel reference binding with IN_ONLY.

                                1 of 1 people found this helpful
                                • 13. Re: Switchyard - Control JMS redelivery. Best practices
                                  evidence01

                                  That sounds exactly like my issue. Basically the outbound JMS endpoint fails for whatever reason and never propagates back an error. That breaks transactional assumptions about the service flow.

                                   

                                  So, Tomo. let me ask you this:

                                   

                                  Im my flow I have

                                   

                                  JMS IN_ONLY inbound -> BEAN -> Camel XML -> IN_ONLY JMS outbound.

                                   

                                  I want ANY failure in the BEAN, Camel XML or JMS outbound to proagate BACK to the inbound JMS endpoint so it can rollback the message to the Queue and then "redelivery" strategies take over via the Jboss container.

                                   

                                  You mention IN_OUT workaround (which is what i did try some), however based on my example what do i need to make IN_OUT, which stages specifically? all of them, just the outbound JMS, the middle ones? can i just return a boolean so the parser thinks they are IN_OUT?

                                   

                                  and do i need to use the :Global transaction" modifier on ALL of them or can i leave them as non-managed?

                                   

                                  Seems like SW should support Robust IN_ONLY MEP...

                                   

                                  J

                                  • 14. Re: Switchyard - Control JMS redelivery. Best practices
                                    kcbabo

                                    If you want to see exceptions for invocations on an in-only reference from a bean service, consider using the ReferenceInvoker contract:

                                    Bean - SwitchYard - Project Documentation Editor

                                     

                                    If an exception occurs on the invocation you will be able to inspect it post-invocation and rethrow or do whatever you want with it at that point.

                                    1 of 1 people found this helpful
                                    1 2 Previous Next