View Javadoc

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