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