View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.vm.functional.transactions;
8   
9   import org.mule.api.transaction.TransactionCallback;
10  import org.mule.api.transaction.TransactionConfig;
11  import org.mule.module.client.MuleClient;
12  import org.mule.transaction.TransactionTemplate;
13  
14  import javax.transaction.Transaction;
15  
16  import org.apache.commons.logging.Log;
17  import org.apache.commons.logging.LogFactory;
18  import org.junit.Test;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertNotNull;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertSame;
24  
25  /** Test transaction behavior when "joinExternal" is set to disallow joining external transactions
26   * There is one test per legal transactional behavior (e.g. ALWAYS_BEGIN).
27   */
28  public class NoExternalTransactionTestCase extends AbstractExternalTransactionTestCase
29  {
30  
31      public static final long WAIT = 3000L;
32  
33      protected static final Log logger = LogFactory.getLog(NoExternalTransactionTestCase.class);
34  
35      @Override
36      protected String getConfigResources()
37      {
38          return "org/mule/test/config/no-external-transaction-config.xml";
39      }
40  
41      @Test
42      public void testBeginOrJoinTransaction() throws Exception
43      {
44          init();
45          TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_BEGIN_OR_JOIN, false);
46  
47          logger.debug("TM is a " + tm.getClass().toString());
48          tm.begin();
49          final Transaction tx = tm.getTransaction();
50          final TestResource resource1 = new TestResource(tm);
51          tx.enlistResource(resource1);
52          assertNotNull(tx);
53  
54          String result;
55          Exception ex = null;
56  
57          // This will throw, becasue nested transactions are not supported
58          try
59          {
60              result = tt.execute(new TransactionCallback<String>()
61              {
62                  public String doInTransaction() throws Exception
63                  {
64                      return "OK";
65                  }
66              });
67          }
68          catch (Exception e)
69          {
70              ex = e;
71              logger.debug("saw exception " + e.getMessage());
72          }
73          assertNotNull(ex);
74          tm.rollback();
75  
76          // now try with no active transaction
77          result = tt.execute(new TransactionCallback<String>()
78          {
79              public String doInTransaction() throws Exception
80              {
81                  Transaction muleTx = tm.getTransaction();
82                  muleTx.enlistResource(resource1);
83                  resource1.setValue(15);
84                  return "OK";
85              }
86          });
87  
88          // Mule began and committed the transaction
89          assertEquals(15, resource1.getPersistentValue());
90      }
91  
92      @Test
93      public void testBeginTransaction() throws Exception
94      {
95          init();
96          TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_ALWAYS_BEGIN, false);
97  
98          tm.begin();
99          final Transaction tx = tm.getTransaction();
100         final TestResource resource1 = new TestResource(tm);
101         tx.enlistResource(resource1);
102         assertNotNull(tx);
103 
104         String result;
105         Exception ex = null;
106 
107         // This will throw, because nested transactions are not supported
108         try
109         {
110             result = tt.execute(new TransactionCallback<String>()
111             {
112                 public String doInTransaction() throws Exception
113                 {
114                     return "OK";
115                 }
116             });
117         }
118         catch (Exception e)
119         {
120             ex = e;
121             logger.debug("saw exception " + e.getMessage());
122         }
123         assertNotNull(ex);
124         tm.rollback();
125 
126         // now try with no active transaction
127         result = tt.execute(new TransactionCallback<String>()
128         {
129             public String doInTransaction() throws Exception
130             {
131                 Transaction muleTx = tm.getTransaction();
132                 muleTx.enlistResource(resource1);
133                 resource1.setValue(15);
134                 return "OK";
135             }
136         });
137 
138         // Mule began and committed the transaction
139         assertEquals(15, resource1.getPersistentValue());
140     }
141 
142     @Test
143     public void testNoTransactionProcessing() throws Exception
144     {
145         init();
146         TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_NONE, false);
147 
148         tm.begin();
149         final Transaction tx = tm.getTransaction();
150         final TestResource resource1 = new TestResource(tm);
151 
152         assertNotNull(tx);
153         tx.enlistResource(resource1);
154         resource1.setValue(14);
155         String result = tt.execute(new TransactionCallback<String>()
156         {
157             public String doInTransaction() throws Exception
158             {
159                 Transaction muleTx = tm.getTransaction();
160                 assertNotNull(muleTx);
161                 return "OK";
162             }
163         });
164 
165         // transaction ignored, no commit
166         assertEquals("OK", result);
167         assertEquals(14, resource1.getValue());
168         assertEquals(0, resource1.getPersistentValue());
169         tm.commit();
170 
171         // Now it's committed
172         assertEquals(14, resource1.getPersistentValue());
173 
174         result = tt.execute(new TransactionCallback<String>()
175         {
176             public String doInTransaction() throws Exception
177             {
178                 Transaction muleTx = tm.getTransaction();
179                 assertNull(muleTx);
180                 return "OK";
181             }
182         });
183     }
184 
185     @Test
186     public void testAlwaysJoinTransaction() throws Exception
187     {
188         init();
189         TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_ALWAYS_JOIN, false);
190 
191         tm.begin();
192         final Transaction tx = tm.getTransaction();
193         final TestResource resource1 = new TestResource(tm);
194         tx.enlistResource(resource1);
195         assertNotNull(tx);
196 
197         Exception ex = null;
198         String result;
199         try
200         {
201             // Thjis will throw, because Mule sees no transaction to join
202             result = tt.execute(new TransactionCallback<String>()
203             {
204                 public String doInTransaction() throws Exception
205                 {
206                     Transaction muleTx = tm.getTransaction();
207                     assertSame(tx, muleTx);
208                     resource1.setValue(14);
209                     return "OK";
210                 }
211             });
212         }
213         catch (Exception e)
214         {
215             ex = e;
216             logger.debug("saw exception " + e.getMessage());
217         }
218 
219         // Not committed yet, since Mule joined the external transaction
220         assertNotNull(ex);
221         tm.rollback();
222 
223         // try with no active transaction.. Should still throw
224         try
225         {
226             result = tt.execute(new TransactionCallback<String>()
227             {
228                 public String doInTransaction() throws Exception
229                 {
230                     return "OK";
231                 }
232             });
233         }
234         catch (Exception e)
235         {
236             ex = e;
237             logger.debug("saw exception " + e.getMessage());
238         }
239         assertNotNull(ex);
240     }
241 
242     @Test
243     public void testJoinTransactionIfPossible() throws Exception
244     {
245         init();
246         TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_JOIN_IF_POSSIBLE, false);
247 
248         tm.begin();
249         final Transaction tx = tm.getTransaction();
250         final TestResource resource1 = new TestResource(tm);
251         tx.enlistResource(resource1);
252         assertNotNull(tx);
253         String result = tt.execute(new TransactionCallback<String>()
254         {
255             public String doInTransaction() throws Exception
256             {
257                 Transaction muleTx = tm.getTransaction();
258                 assertSame(tx, muleTx);
259                 resource1.setValue(14);
260                 return "OK";
261             }
262         });
263 
264         // Not committed yet, since Mule saw no transaction to join
265         assertEquals("OK", result);
266         assertEquals(14, resource1.getValue());
267         assertEquals(0, resource1.getPersistentValue());
268         tm.commit();
269 
270         // Now it's committed
271         assertEquals(14, resource1.getPersistentValue());
272 
273         // try with no active transaction.. Should run with none
274         result = tt.execute(new TransactionCallback<String>()
275         {
276             public String doInTransaction() throws Exception
277             {
278                 Transaction muleTx = tm.getTransaction();
279                 assertNull(muleTx);
280                 return "OK";
281             }
282         });
283         assertEquals("OK", result);
284     }
285 
286     @Test
287     public void testNoTransactionAllowed() throws Exception
288     {
289         init();
290         TransactionTemplate<String> tt = createTransactionTemplate(TransactionConfig.ACTION_NEVER, false);
291 
292         tm.begin();
293         final Transaction tx = tm.getTransaction();
294         final TestResource resource1 = new TestResource(tm);
295         tx.enlistResource(resource1);
296         assertNotNull(tx);
297 
298         // This will not throw since Mule sees no transaction
299         String result = tt.execute(new TransactionCallback<String>()
300         {
301             public String doInTransaction() throws Exception
302             {
303                 resource1.setValue(14);
304                 return "OK";
305             }
306         });
307 
308         // Not committed yet, since Mule saw no transaction to join
309         assertEquals("OK", result);
310         assertEquals(14, resource1.getValue());
311         assertEquals(0, resource1.getPersistentValue());
312         tm.commit();
313 
314         // Now it's committed
315         assertEquals(14, resource1.getPersistentValue());
316     }
317 
318         /** Check that the configuration specifies considers external transactions */
319     @Test
320     public void testConfiguration() throws Exception
321     {
322         MuleClient client = new MuleClient(muleContext);
323         tm = client.getMuleContext().getTransactionManager();
324         tm.begin();
325 
326         // This will fail, since there will be no Mule transaction to join
327         client.send("vm://entry?connector=vm-normal", "OK", null);
328         Object response = client.request("queue", WAIT);
329         assertNull(response);
330 
331         tm.commit();
332     }
333 
334 }