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