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