1 /* 2 * Copyright 2008 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.openehealth.ipf.platform.camel.core.camel.transaction; 17 18 import org.apache.camel.spring.SpringRouteBuilder; 19 import org.openehealth.ipf.platform.camel.core.support.processor.FailureProcessor; 20 21 /** 22 * @author Martin Krasser 23 */ 24 public class TransactionalMessagingRouteBuilder extends SpringRouteBuilder { 25 26 @Override 27 public void configure() throws Exception { 28 29 /* 30 * We use two JMS components here: 31 * 32 * - amqProcess for transactional message processing between JMS queues 33 * - amqDelivery for transactional delivery of messages to destinations 34 * 35 * Transacted delivery is useful if destination system are unavailable 36 * or a message transport error occured. In this case the JMS provider 37 * should be configured to attempt a redelivery (1 redelivery attempt 38 * in our case). We don't want to have redeliveries for normal message 39 * processing between JMS queues. Therefore the amqProcess JMS 40 * component is configured to do no redelivery at all. 41 * 42 * - Configuration of the amqProcess JMS component is done in 43 * context-transaction-process.xml 44 * - Configuration of the amqDelivery JMS component is done in 45 * context-transaction-delivery.xml 46 */ 47 48 49 // ----------------------------------------------------------------- 50 // Read from transacted input JMS queue and multicast to internal 51 // destinations 52 // ----------------------------------------------------------------- 53 54 from("amqProcess:queue:txm-input") 55 // on exception rollback transaction and send to txm-error 56 .onException(Exception.class).to("mock:txm-error").end() 57 .multicast() 58 .to("direct:intern-1") 59 .to("direct:intern-2"); 60 61 // ----------------------------------------------------------------- 62 // Read from first internal endpoint and route to output JMS queue 1 63 // without further message processing. 64 // ----------------------------------------------------------------- 65 66 from("direct:intern-1") 67 .to("amqProcess:queue:txm-output-1"); 68 69 // ----------------------------------------------------------------- 70 // Read from second internal endpoint and route to output JMS queue 2 71 // and throw an exception if body equals "blah". If an exception is 72 // thrown the transaction is rolled back which is 73 // 74 // - reading from input queue 75 // - writing to output queue 1 76 // 77 // If no exception is thrown then the transaction is committed which 78 // is 79 // 80 // - reading from input queue 81 // - writing to output queue 1 82 // - writing to output queue 2 83 // 84 // WHAT WE ACHIEVED HERE IS THAT WE READ AND WROTE MESSAGES FROM 85 // AND TO SEVERAL DESTINATIONS IN A SINGLE TRANSACTION WITHOUT 86 // USING XA! 87 // 88 // ----------------------------------------------------------------- 89 90 from("direct:intern-2") 91 // the noErrorHandler() can be omitted here if an explicit 92 // transactionErrorHandler(...) is configured for endpoint 93 // amqProcess:queue:txm-input 94 .errorHandler(noErrorHandler()) 95 // throw exception if body equals "blah" 96 .process(new FailureProcessor("blah")) 97 // otherwise send to output queue 2 98 .to("amqProcess:queue:txm-output-2"); 99 100 101 // ----------------------------------------------------------------- 102 // Read from transacted output queue and throw exception if body 103 // equals "blub". The amqDelivery JMS component is configured to 104 // attempt a single redelivery on rollback before giving up. 105 // without further message processing. 106 // ----------------------------------------------------------------- 107 108 from("amqDelivery:queue:txm-output-1") 109 // on exception rollback transaction and send to txm-error 110 .onException(Exception.class).to("mock:txm-error").end() 111 // throw exception if body equals "blub" 112 .process(new FailureProcessor("blub")) 113 .to("mock:txm-mock"); 114 115 // ----------------------------------------------------------------- 116 // Read from transacted output queue and send to txm-mock. 117 // ----------------------------------------------------------------- 118 119 from("amqDelivery:queue:txm-output-2") 120 .to("mock:txm-mock"); 121 122 } 123 124 }