View Javadoc
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 }