1
2
3
4
5
6
7
8
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
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 }