View Javadoc

1   /*
2    * $Id: VmXATransactionTestCase.java 22449 2011-07-19 07:40:43Z justin.calleja $
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  package org.mule.transport.vm.functional;
11  
12  import static org.junit.Assert.assertNotNull;
13  import static org.junit.Assert.assertTrue;
14  
15  import java.lang.reflect.Field;
16  import java.lang.reflect.Method;
17  import java.util.Arrays;
18  import java.util.Collection;
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import javax.transaction.Transaction;
23  import javax.transaction.xa.XAException;
24  import javax.transaction.xa.XAResource;
25  import javax.transaction.xa.Xid;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.junit.Test;
30  import org.junit.runners.Parameterized.Parameters;
31  import org.mule.api.MuleMessage;
32  import org.mule.module.client.MuleClient;
33  import org.mule.tck.AbstractServiceAndFlowTestCase;
34  import org.mule.transaction.TransactionCoordination;
35  import org.mule.transaction.XaTransaction;
36  
37  public class VmXATransactionTestCase extends AbstractServiceAndFlowTestCase
38  {
39      
40      protected static final Log logger = LogFactory.getLog(VmTransactionTestCase.class);
41      protected static volatile boolean success = true;
42      protected static volatile boolean wouldBeDisabled = false;
43  
44      public VmXATransactionTestCase(ConfigVariant variant, String configResources)
45      {
46          super(variant, configResources);
47      }
48      
49      @Parameters
50      public static Collection<Object[]> parameters()
51      {
52          return Arrays.asList(new Object[][]{
53              {ConfigVariant.SERVICE, "vm-xa-transaction-service.xml"},
54              {ConfigVariant.FLOW, "vm-xa-transaction-flow.xml"}
55          });
56      }
57      
58      @Test
59      public void testTransactionQueueEventsTrue() throws Exception
60      {
61  
62          MuleClient client = new MuleClient(muleContext);
63          client.dispatch("vm://in", "TEST", null);
64          MuleMessage message = client.request("vm://out", 10000);
65          assertNotNull(message);
66          if (wouldBeDisabled)
67          {
68              throw new IllegalStateException("Test is wrong, and must be disabled");
69          }
70          assertTrue(success);
71      }
72  
73      public static class TestComponent
74      {
75  
76          public Object process(Object a) throws Exception
77          {
78              success = checkTransaction(TransactionCoordination.getInstance().getTransaction());
79              return a;
80          }
81  
82          private boolean checkTransaction(org.mule.api.transaction.Transaction transaction) throws Exception
83          {
84              if (!(transaction instanceof XaTransaction))
85              {
86                  return false;
87              }
88              Transaction tx = ((XaTransaction) transaction).getTransaction();
89              //add test resource
90              TestResource testResource = new TestResource();
91              transaction.bindResource("TestReource", testResource);
92              tx.enlistResource(testResource);
93  
94              Field field = transaction.getClass().getDeclaredField("resources");
95              field.setAccessible(true);
96              Map resources = (Map) field.get(transaction);
97              if (resources == null)
98              {
99                  return false;
100             }
101             logger.debug("Mule XATransaction :: registered " + resources.size());
102 
103             Iterator i = resources.entrySet().iterator();
104             boolean result = true;
105             while (i.hasNext())
106             {
107                 Map.Entry entry = (Map.Entry) i.next();
108                 XAResource xaResource = getXAResource(entry.getValue());
109                 logger.debug("XAResource " + xaResource);
110                 boolean enlisted = isXAResourceEnlisted(tx, xaResource);
111                 result = result && enlisted;
112                 if (xaResource instanceof TestResource)
113                 {
114                     logger.debug("Check status for TestResource " + enlisted);
115                     if (!enlisted)
116                     {
117                         wouldBeDisabled = true;
118                         throw new IllegalStateException("Test is wrong, and must be disabled");
119                     }
120                 }
121             }
122 
123             return result;
124         }
125 
126         private boolean isXAResourceEnlisted(Transaction transaction, XAResource xaResource)
127         {
128             if (transaction instanceof
129                     com.arjuna.ats.jta.transaction.Transaction)
130             {
131                 com.arjuna.ats.jta.transaction.Transaction tx = (com.arjuna.ats.jta.transaction.Transaction) transaction;
132 
133                 int state = tx.getXAResourceState(xaResource);
134                 return (state == 0);
135             }
136             return false;
137         }
138 
139         private XAResource getXAResource(Object resource) throws Exception
140         {
141             if (resource instanceof XAResource)
142             {
143                 return (XAResource) resource;
144             }
145             Method method = resource.getClass().getMethod("getXAResource");
146             return (XAResource) method.invoke(resource);
147         }
148 
149 
150     }
151 
152     public static class TestResource implements XAResource
153     {
154 
155         public void commit(Xid id, boolean onePhase) throws XAException
156         {
157             logger.debug("XA_COMMIT[" + id + "]");
158         }
159 
160         public void end(Xid xid, int flags) throws XAException
161         {
162             logger.debug("XA_END[" + xid + "] Flags=" + flags);
163         }
164 
165         public void forget(Xid xid) throws XAException
166         {
167             logger.debug("XA_FORGET[" + xid + "]");
168         }
169 
170         public int getTransactionTimeout() throws XAException
171         {
172             return (_timeout);
173         }
174 
175         public boolean isSameRM(XAResource xares) throws XAException
176         {
177             return (xares.equals(this));
178         }
179 
180         public int prepare(Xid xid) throws XAException
181         {
182             logger.debug("XA_PREPARE[" + xid + "]");
183 
184             return (XA_OK);
185         }
186 
187         public Xid[] recover(int flag) throws XAException
188         {
189             logger.debug("RECOVER[" + flag + "]");
190             return (null);
191         }
192 
193         public void rollback(Xid xid) throws XAException
194         {
195             logger.debug("XA_ROLLBACK[" + xid + "]");
196         }
197 
198         public boolean setTransactionTimeout(int seconds) throws XAException
199         {
200             _timeout = seconds;
201             return (true);
202         }
203 
204         public void start(Xid xid, int flags) throws XAException
205         {
206             logger.debug("XA_START[" + xid + "] Flags=" + flags);
207         }
208 
209         protected int _timeout = 0;
210     }
211 
212 
213 }