On Tue, Apr 29, 2014 at 5:37 PM, kraythe . <kray...@gmail.com> wrote:
> Thats what I thought. That makes my problem perplexing. Well I will update
> the thread when I figure it out. If anyone has any ideas it would be
> appreciated.
>

If you want the message to stay, then define a 2nd jms component and
send the message using that.

> *Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
> *Author of: Hardcore Java (2003) and Maintainable Java (2012)*
> *LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
> <http://www.linkedin.com/pub/robert-simmons/40/852/a39>*
>
>
> On Tue, Apr 29, 2014 at 4:11 AM, Claus Ibsen <claus.ib...@gmail.com> wrote:
>
>> On Tue, Apr 29, 2014 at 10:59 AM, kraythe . <kray...@gmail.com> wrote:
>> > Yeah no problem. I was just hoping someone would have the answer. I keep
>> > plugging away at it. Probably some transaction issue, I dont know. You
>> can
>> > answer this perhaps :) , when I send a message to an activemq endpoint
>> with
>> > InOnly exchange pattern, will that message be subject to the transation?
>> > I.e. if the transaction fails will it get popped off AMQ?
>> >
>>
>> Yes if you do that from a camel route using the same jms component /
>> endpoint that started the transaction (eg same jms session).
>>
>> Then only when the TX commit, the message on the queue will be commit
>> and "visible" for consumers.
>> Its like figure 9.6 in Camel in Action book.
>>
>>
>> > *Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
>> > *Author of: Hardcore Java (2003) and Maintainable Java (2012)*
>> > *LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
>> > <http://www.linkedin.com/pub/robert-simmons/40/852/a39>*
>> >
>> >
>> > On Tue, Apr 29, 2014 at 2:55 AM, Claus Ibsen <claus.ib...@gmail.com>
>> wrote:
>> >
>> >> On Mon, Apr 28, 2014 at 8:48 PM, kraythe . <kray...@gmail.com> wrote:
>> >> > No one has any idea on this? It would be really great if I could find
>> the
>> >> > formula to get this to work.
>> >> >
>> >>
>> >> I dont think people always have the time to help, and especially when
>> >> its more complicated with transactions and a lot of Camel route code.
>> >>
>> >> If you want to get priority help then there is some companies that offer
>> >> that
>> >> http://camel.apache.org/commercial-camel-offerings.html
>> >>
>> >> > *Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
>> >> > *Author of: Hardcore Java (2003) and Maintainable Java (2012)*
>> >> > *LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
>> >> > <http://www.linkedin.com/pub/robert-simmons/40/852/a39>*
>> >> >
>> >> >
>> >> > On Tue, Apr 15, 2014 at 5:15 PM, kraythe . <kray...@gmail.com> wrote:
>> >> >
>> >> >> So I think there is a problem with the way rollback is implemented in
>> >> >> relation to Camel. As far as I can tell there is no way to get the
>> >> >> following working.
>> >> >>
>> >> >> package com.ea.wwce.camel.test.utilities;
>> >> >>
>> >> >> import com.ea.wwce.camel.utilities.data.RecordList;
>> >> >> import com.ea.wwce.camel.utilities.transactions.TxnHelper;
>> >> >> import org.apache.camel.ExchangePattern;
>> >> >> import org.apache.camel.builder.AdviceWithRouteBuilder;
>> >> >> import org.apache.camel.builder.RouteBuilder;
>> >> >> import org.apache.camel.component.mock.MockEndpoint;
>> >> >> import org.testng.annotations.Test;
>> >> >> import static
>> com.ea.wwce.camel.test.utilities.TransactionTestTools.*;
>> >> >> import static
>> >> >> com.ea.wwce.camel.utilities.activemq.ActiveMQHelper.endpointAMQ;
>> >> >> import static
>> >> >>
>> >>
>> com.ea.wwce.camel.utilities.jackson.RecordSerialization.toListOfJsonStrings;
>> >> >> import static org.apache.camel.ExchangePattern.InOnly;
>> >> >>
>> >> >> /** This test suite validates the transaction configuration in the
>> test
>> >> >> suite. */
>> >> >> public class JMSOnlyTransactionTest extends AMQRouteTestSupport {
>> >> >>   private static final String QUEUE_DEAD = "dead";
>> >> >>   private static final String QUEUE_INBOX = "inbox";
>> >> >>   private static final String QUEUE_OUTBOX = "outbox";
>> >> >>   private static final String ROUTE_ID_FEED = "Feed";
>> >> >>   private static final String ROUTE_ID_TEST_ROUTE = "TestRoute";
>> >> >>   private static final String ROUTE_ID_RESULTS = "ResultsRoute";
>> >> >>   private static final String ROUTE_ID_DEAD = "DeadRoute";
>> >> >>   private static final String DIRECT_FEED_INBOX =
>> "direct:feed_inbox";
>> >> >>
>> >> >>   private static final String MOCK_END = "mock:end";
>> >> >>   private static final String MOCK_BEFORE_TO_QUEUE =
>> >> >> "mock:before_to_queue";
>> >> >>   private static final String MOCK_AFTER_TO_QUEUE =
>> >> "mock:after_to_queue";
>> >> >>
>> >> >>   /** Mock endpoints. */
>> >> >>   private MockEndpoint mockEnd, mockDead, mockOutbox,
>> mockBeforeToQueue,
>> >> >> mockAfterToQueue;
>> >> >>
>> >> >>   /** Helper to initialize mocks in the test. */
>> >> >>   private void initMocks() {
>> >> >>     mockEnd = assertAndGetMockEndpoint(MOCK_END);
>> >> >>     mockDead = assertAndGetMockEndpoint(MOCK_DEAD);
>> >> >>     mockBeforeToQueue =
>> assertAndGetMockEndpoint(MOCK_BEFORE_TO_QUEUE);
>> >> >>     mockAfterToQueue = assertAndGetMockEndpoint(MOCK_AFTER_TO_QUEUE);
>> >> >>     mockOutbox =
>> >> assertAndGetMockEndpoint(mockEndpointAMQ(QUEUE_OUTBOX));
>> >> >>   }
>> >> >>
>> >> >>   @Override
>> >> >>   protected RouteBuilder createRouteBuilder() {
>> >> >>     System.out.println("createRouteBuilder");
>> >> >>     return new RouteBuilder(this.context) {
>> >> >>       @Override
>> >> >>       public void configure() {
>> >> >>         getContext().setTracing(true);
>> >> >>         from(DIRECT_FEED_INBOX).routeId(ROUTE_ID_FEED)
>> >> >>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>
>> >> >> .split(body()).marshal(dfCaseRecord).to(endpointAMQ(QUEUE_INBOX));
>> >> >>         from(endpointAMQ(QUEUE_OUTBOX)).routeId(ROUTE_ID_RESULTS)
>> >> >>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>             .unmarshal(dfCaseRecord).to(MOCK_END);
>> >> >>         from(endpointAMQ(QUEUE_DEAD)).routeId(ROUTE_ID_DEAD)
>> >> >>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>             .unmarshal(dfCaseRecord).to(MOCK_DEAD);
>> >> >>         from(endpointAMQ(QUEUE_INBOX)).routeId(ROUTE_ID_TEST_ROUTE)
>> >> >>
>> >> >>
>> .onException(RuntimeException.class).handled(true).useOriginalMessage()
>> >> >>               .to(InOnly, endpointAMQ(QUEUE_DEAD)).end()
>> >> >>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRES_NEW)
>> >> >>             .unmarshal(dfCaseRecord)
>> >> >>             .to(MOCK_BEFORE_TO_QUEUE)
>> >> >>             .marshal(dfCaseRecord)
>> >> >>             .to(endpointAMQ(QUEUE_OUTBOX))
>> >> >>             .unmarshal(dfCaseRecord)
>> >> >>             .to(MOCK_AFTER_TO_QUEUE);
>> >> >>       }
>> >> >>     };
>> >> >>   }
>> >> >>
>> >> >>   /** Advice the route, mocking ActiveMQ endpoints. */
>> >> >>   protected void adviceRoute() throws Exception {
>> >> >>     this.context.getRouteDefinition(ROUTE_ID_TEST_ROUTE).adviceWith(
>> >> >>         this.context, new AdviceWithRouteBuilder() {
>> >> >>           @Override
>> >> >>           public void configure() throws Exception {
>> >> >>             mockEndpoints("activemq:queue:*");
>> >> >>           }
>> >> >>         }
>> >> >>     );
>> >> >>   }
>> >> >>
>> >> >>   @Test
>> >> >>   public void testNormalRouting() throws Exception {
>> >> >>     adviceRoute();
>> >> >>     startCamelContext();
>> >> >>     initMocks();
>> >> >>     final RecordList cases = casesA();
>> >> >>
>> >> >>     mockEnd.expectedBodiesReceived(cases);
>> >> >>     mockBeforeToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>
>> >> >>
>> mockOutbox.expectedBodiesReceivedInAnyOrder(toListOfJsonStrings(mapper,
>> >> >> cases));
>> >> >>     mockAfterToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>
>> >> >>     template.sendBody(DIRECT_FEED_INBOX, cases);
>> >> >>
>> >> >>     mockBeforeToQueue.assertIsSatisfied();
>> >> >>     mockAfterToQueue.assertIsSatisfied();
>> >> >>     mockEnd.assertIsSatisfied();
>> >> >>     mockDead.assertIsSatisfied();
>> >> >>     mockOutbox.assertIsSatisfied();
>> >> >>   }
>> >> >>
>> >> >>   @Test
>> >> >>   public void testRollbackBeforeEnqueue() throws Exception {
>> >> >>     adviceRoute();
>> >> >>     startCamelContext();
>> >> >>     initMocks();
>> >> >>     final RecordList cases = casesA();
>> >> >>
>> >> >>     mockEnd.expectedBodiesReceivedInAnyOrder(cases.get(1),
>> >> cases.get(2));
>> >> >>     mockDead.expectedBodiesReceived(cases.get(0));
>> >> >>     mockBeforeToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>     mockBeforeToQueue.whenExchangeReceived(1, EXCEPTION_PROCESSOR);
>> >> >>
>> >> >>
>> mockOutbox.expectedBodiesReceivedInAnyOrder(toListOfJsonStrings(mapper,
>> >> >> cases.get(1), cases.get(2)));
>> >> >>     mockAfterToQueue.expectedBodiesReceivedInAnyOrder(cases.get(1),
>> >> >> cases.get(2));
>> >> >>
>> >> >>     template.sendBody(DIRECT_FEED_INBOX, cases);
>> >> >>
>> >> >>     mockBeforeToQueue.assertIsSatisfied();
>> >> >>     mockAfterToQueue.assertIsSatisfied();
>> >> >>     mockEnd.assertIsSatisfied();
>> >> >>     mockDead.assertIsSatisfied();
>> >> >>     mockOutbox.assertIsSatisfied();
>> >> >>   }
>> >> >>
>> >> >>   @Test
>> >> >>   public void testRollbackAfterEnqueue() throws Exception {
>> >> >>     adviceRoute();
>> >> >>     startCamelContext();
>> >> >>     initMocks();
>> >> >>     final RecordList cases = casesA();
>> >> >>
>> >> >>     mockEnd.expectedBodiesReceivedInAnyOrder(cases.get(1),
>> >> cases.get(2));
>> >> >>     mockDead.expectedBodiesReceivedInAnyOrder(cases.get(0));
>> >> >>     mockBeforeToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>
>> >> >>
>> mockOutbox.expectedBodiesReceivedInAnyOrder(toListOfJsonStrings(mapper,
>> >> >> cases));
>> >> >>     mockAfterToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>     mockAfterToQueue.whenExchangeReceived(1, EXCEPTION_PROCESSOR);
>> >> >>
>> >> >>     template.sendBody(DIRECT_FEED_INBOX, cases);
>> >> >>
>> >> >>     mockBeforeToQueue.assertIsSatisfied();
>> >> >>     mockAfterToQueue.assertIsSatisfied();
>> >> >>     mockDead.assertIsSatisfied();
>> >> >>     mockOutbox.assertIsSatisfied();
>> >> >>     mockEnd.assertIsSatisfied();
>> >> >>   }
>> >> >> }
>> >> >>
>> >> >> I have tried dozens of combinations in the onException clause and
>> >> nothing
>> >> >> works. Adding markRollbackOnly(), or rollback() only succeeds in
>> rolling
>> >> >> back the dead letter channel as well. Making the handled(false) cause
>> >> AMQ
>> >> >> to resubmit the transaction and rolls back the dead letter channel. I
>> >> have
>> >> >> tried a dozen combinations so if anyone has one that works I would be
>> >> >> grateful.
>> >> >>
>> >> >> *Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
>> >> >> *Author of: Hardcore Java (2003) and Maintainable Java (2012)*
>> >> >> *LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
>> >> >> <http://www.linkedin.com/pub/robert-simmons/40/852/a39>*
>> >> >>
>> >> >>
>> >> >> On Mon, Apr 14, 2014 at 1:10 PM, kraythe . <kray...@gmail.com>
>> wrote:
>> >> >>
>> >> >>> So, in the ongoing perfect transaction configuration we have an
>> >> >>> interesting use case: Consider the following route in a test:
>> >> >>>
>> >> >>>   @Override
>> >> >>>   protected RouteBuilder createRouteBuilder() {
>> >> >>>     System.out.println("createRouteBuilder");
>> >> >>>     return new RouteBuilder(this.context) {
>> >> >>>       @Override
>> >> >>>       public void configure() {
>> >> >>>         getContext().setTracing(true);
>> >> >>>         from(DIRECT_FEED_INBOX).routeId(ROUTE_ID_FEED)
>> >> >>>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>>
>> >> >>> .split(body()).marshal(dfCaseRecord).to(endpointAMQ(QUEUE_INBOX));
>> >> >>>         from(endpointAMQ(QUEUE_OUTBOX)).routeId(ROUTE_ID_RESULTS)
>> >> >>>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>>             .unmarshal(dfCaseRecord).to(MOCK_END);
>> >> >>>         from(endpointAMQ(QUEUE_DEAD)).routeId(ROUTE_ID_DEAD)
>> >> >>>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>>             .unmarshal(dfCaseRecord).to(MOCK_DEAD);
>> >> >>>         from(endpointAMQ(QUEUE_INBOX)).routeId(ROUTE_ID_TEST_ROUTE)
>> >> >>>
>> >> >>>
>> >>
>> .onException(RuntimeException.class).handled(true).useOriginalMessage().to(endpointAMQ(QUEUE_DEAD)).end()
>> >> >>>             .transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED)
>> >> >>>             .unmarshal(dfCaseRecord)
>> >> >>>             .to(MOCK_BEFORE_TO_QUEUE)
>> >> >>>             .marshal(dfCaseRecord)
>> >> >>>             .to(endpointAMQ(QUEUE_OUTBOX))
>> >> >>>             .unmarshal(dfCaseRecord)
>> >> >>>             .to(MOCK_AFTER_TO_QUEUE);
>> >> >>>       }
>> >> >>>     };
>> >> >>>   }
>> >> >>>
>> >> >>> Note that the transacted(TxnHelper.KEY_TXNPOLICY_REQUIRED) simply
>> looks
>> >> >>> up the transaction policy by name as it is just a string key for our
>> >> JNDI
>> >> >>> registry. Our test case looks like the following.
>> >> >>>
>> >> >>>   @Test
>> >> >>>   public void testRollbackAfterEnqueue() throws Exception {
>> >> >>>     adviceRoute();
>> >> >>>     startCamelContext();
>> >> >>>     initMocks();
>> >> >>>     final RecordList cases = casesA();
>> >> >>>
>> >> >>>     mockEnd.expectedMessageCount(2);
>> >> >>>     mockEnd.expectedBodiesReceived(cases.get(1), cases.get(2));
>> >> >>>     mockDead.expectedMessageCount(1);
>> >> >>>     mockDead.expectedBodiesReceived(cases.get(0));
>> >> >>>     mockBeforeToQueue.expectedMessageCount(3);
>> >> >>>     mockBeforeToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>>     mockOutbox.expectedMessageCount(3);
>> >> >>>
>> >> >>>
>> mockOutbox.expectedBodiesReceivedInAnyOrder(toListOfJsonStrings(mapper,
>> >> >>> cases));
>> >> >>>     mockAfterToQueue.expectedMessageCount(3);
>> >> >>>     mockAfterToQueue.expectedBodiesReceivedInAnyOrder(cases);
>> >> >>>     mockAfterToQueue.whenExchangeReceived(1, EXCEPTION_PROCESSOR);
>> >> >>>
>> >> >>>     template.sendBody(DIRECT_FEED_INBOX, cases);
>> >> >>>
>> >> >>>     mockBeforeToQueue.assertIsSatisfied();
>> >> >>>     mockAfterToQueue.assertIsSatisfied();
>> >> >>>     mockEnd.assertIsSatisfied();
>> >> >>>     mockDead.assertIsSatisfied();
>> >> >>>     mockOutbox.assertIsSatisfied();
>> >> >>>   }
>> >> >>>
>> >> >>> In this route the goal is that if any exceptions are thrown even
>> after
>> >> >>> the message is enqueued, it should be rolled back, the message that
>> >> >>> excepted should go to the DLQ and the messages in the outbox should
>> be
>> >> >>> rolled back but the message from the inbox should not be put back on
>> >> the
>> >> >>> queue. This is proving to be a bit of a juggling act.
>> >> >>>
>> >> >>> I tried putting markRollBackOnly() in the exception handler after
>> the
>> >> >>> to(dead) but that rolled back the dead letter queue and outbox and
>> then
>> >> >>> redelivered the inbox message. Removing the markRollbackOnly() means
>> >> >>> that the message arrives at dead and is off the inbox but it doesn't
>> >> get
>> >> >>> removed from the outbox.
>> >> >>>
>> >> >>> So I am looking for the right combination of calls to accomplish
>> what I
>> >> >>> want to do. Any suggestions?
>> >> >>>
>> >> >>> Thanks in advance.
>> >> >>>
>> >> >>> *Robert Simmons Jr. MSc. - Lead Java Architect @ EA*
>> >> >>> *Author of: Hardcore Java (2003) and Maintainable Java (2012)*
>> >> >>> *LinkedIn: **http://www.linkedin.com/pub/robert-simmons/40/852/a39
>> >> >>> <http://www.linkedin.com/pub/robert-simmons/40/852/a39>*
>> >> >>>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>> >> --
>> >> Claus Ibsen
>> >> -----------------
>> >> Red Hat, Inc.
>> >> Email: cib...@redhat.com
>> >> Twitter: davsclaus
>> >> Blog: http://davsclaus.com
>> >> Author of Camel in Action: http://www.manning.com/ibsen
>> >> hawtio: http://hawt.io/
>> >> fabric8: http://fabric8.io/
>> >>
>>
>>
>>
>> --
>> Claus Ibsen
>> -----------------
>> Red Hat, Inc.
>> Email: cib...@redhat.com
>> Twitter: davsclaus
>> Blog: http://davsclaus.com
>> Author of Camel in Action: http://www.manning.com/ibsen
>> hawtio: http://hawt.io/
>> fabric8: http://fabric8.io/
>>



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cib...@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/

Reply via email to