1 17 18 package org.apache.geronimo.transaction.manager; 19 20 import java.util.ArrayList ; 21 import java.util.Arrays ; 22 import java.util.List ; 23 24 import javax.transaction.xa.XAException ; 25 import javax.transaction.xa.XAResource ; 26 import javax.transaction.xa.Xid ; 27 28 import junit.framework.TestCase; 29 30 36 public class RecoveryTest extends TestCase { 37 38 XidFactory xidFactory = new XidFactoryImpl(); 39 private final String RM1 = "rm1"; 40 private final String RM2 = "rm2"; 41 private final String RM3 = "rm3"; 42 43 public void testCommittedRMToBeRecovered() throws Exception { 44 MockLog mockLog = new MockLog(); 45 Xid [] xids = getXidArray(1); 46 MockXAResource xares1 = new MockXAResource(RM1, new Xid [0]); 51 MockTransactionInfo[] txInfos = makeTxInfos(xids); 52 addBranch(txInfos, xares1); 53 prepareLog(mockLog, txInfos); 54 Recovery recovery = new RecoveryImpl(mockLog, xidFactory); 55 recovery.recoverLog(); 56 assertTrue(!recovery.hasRecoveryErrors()); 57 assertTrue(recovery.getExternalXids().isEmpty()); 58 assertTrue(!recovery.localRecoveryComplete()); 59 recovery.recoverResourceManager(xares1); 60 assertEquals(0, xares1.committed.size()); 61 assertTrue(recovery.localRecoveryComplete()); 62 63 } 64 65 public void test2ResOnlineAfterRecoveryStart() throws Exception { 66 MockLog mockLog = new MockLog(); 67 Xid [] xids = getXidArray(3); 68 MockXAResource xares1 = new MockXAResource(RM1, xids); 69 MockXAResource xares2 = new MockXAResource(RM2, xids); 70 MockTransactionInfo[] txInfos = makeTxInfos(xids); 71 addBranch(txInfos, xares1); 72 addBranch(txInfos, xares2); 73 prepareLog(mockLog, txInfos); 74 Recovery recovery = new RecoveryImpl(mockLog, xidFactory); 75 recovery.recoverLog(); 76 assertTrue(!recovery.hasRecoveryErrors()); 77 assertTrue(recovery.getExternalXids().isEmpty()); 78 assertTrue(!recovery.localRecoveryComplete()); 79 recovery.recoverResourceManager(xares1); 80 assertTrue(!recovery.localRecoveryComplete()); 81 assertEquals(3, xares1.committed.size()); 82 recovery.recoverResourceManager(xares2); 83 assertEquals(3, xares2.committed.size()); 84 assertTrue(recovery.localRecoveryComplete()); 85 86 } 87 88 private void addBranch(MockTransactionInfo[] txInfos, MockXAResource xaRes) { 89 for (int i = 0; i < txInfos.length; i++) { 90 MockTransactionInfo txInfo = txInfos[i]; 91 txInfo.branches.add(new MockTransactionBranchInfo(xaRes.getName())); 92 } 93 } 94 95 private MockTransactionInfo[] makeTxInfos(Xid [] xids) { 96 MockTransactionInfo[] txInfos = new MockTransactionInfo[xids.length]; 97 for (int i = 0; i < xids.length; i++) { 98 Xid xid = xids[i]; 99 txInfos[i] = new MockTransactionInfo(xid, new ArrayList ()); 100 } 101 return txInfos; 102 } 103 104 public void test3ResOnlineAfterRecoveryStart() throws Exception { 105 MockLog mockLog = new MockLog(); 106 Xid [] xids12 = getXidArray(3); 107 List xids12List = Arrays.asList(xids12); 108 Xid [] xids13 = getXidArray(3); 109 List xids13List = Arrays.asList(xids13); 110 Xid [] xids23 = getXidArray(3); 111 List xids23List = Arrays.asList(xids23); 112 ArrayList tmp = new ArrayList (); 113 tmp.addAll(xids12List); 114 tmp.addAll(xids13List); 115 Xid [] xids1 = (Xid []) tmp.toArray(new Xid [6]); 116 tmp.clear(); 117 tmp.addAll(xids12List); 118 tmp.addAll(xids23List); 119 Xid [] xids2 = (Xid []) tmp.toArray(new Xid [6]); 120 tmp.clear(); 121 tmp.addAll(xids13List); 122 tmp.addAll(xids23List); 123 Xid [] xids3 = (Xid []) tmp.toArray(new Xid [6]); 124 125 MockXAResource xares1 = new MockXAResource(RM1, xids1); 126 MockXAResource xares2 = new MockXAResource(RM2, xids2); 127 MockXAResource xares3 = new MockXAResource(RM3, xids3); 128 MockTransactionInfo[] txInfos12 = makeTxInfos(xids12); 129 addBranch(txInfos12, xares1); 130 addBranch(txInfos12, xares2); 131 prepareLog(mockLog, txInfos12); 132 MockTransactionInfo[] txInfos13 = makeTxInfos(xids13); 133 addBranch(txInfos13, xares1); 134 addBranch(txInfos13, xares3); 135 prepareLog(mockLog, txInfos13); 136 MockTransactionInfo[] txInfos23 = makeTxInfos(xids23); 137 addBranch(txInfos23, xares2); 138 addBranch(txInfos23, xares3); 139 prepareLog(mockLog, txInfos23); 140 Recovery recovery = new RecoveryImpl(mockLog, xidFactory); 141 recovery.recoverLog(); 142 assertTrue(!recovery.hasRecoveryErrors()); 143 assertTrue(recovery.getExternalXids().isEmpty()); 144 assertEquals(9, recovery.localUnrecoveredCount()); 145 recovery.recoverResourceManager(xares1); 146 assertEquals(9, recovery.localUnrecoveredCount()); 147 assertEquals(6, xares1.committed.size()); 148 recovery.recoverResourceManager(xares2); 149 assertEquals(6, recovery.localUnrecoveredCount()); 150 assertEquals(6, xares2.committed.size()); 151 recovery.recoverResourceManager(xares3); 152 assertEquals(0, recovery.localUnrecoveredCount()); 153 assertEquals(6, xares3.committed.size()); 154 155 } 156 157 private void prepareLog(TransactionLog txLog, MockTransactionInfo[] txInfos) throws LogException { 158 for (int i = 0; i < txInfos.length; i++) { 159 MockTransactionInfo txInfo = txInfos[i]; 160 txLog.prepare(txInfo.globalXid, txInfo.branches); 161 } 162 } 163 164 165 private Xid [] getXidArray(int i) { 166 Xid [] xids = new Xid [i]; 167 for (int j = 0; j < xids.length; j++) { 168 xids[j] = xidFactory.createXid(); 169 } 170 return xids; 171 } 172 173 private static class MockXAResource implements NamedXAResource { 174 175 private final String name; 176 private final Xid [] xids; 177 private final List committed = new ArrayList (); 178 private final List rolledBack = new ArrayList (); 179 180 public MockXAResource(String name, Xid [] xids) { 181 this.name = name; 182 this.xids = xids; 183 } 184 185 public String getName() { 186 return name; 187 } 188 189 public void commit(Xid xid, boolean onePhase) throws XAException { 190 committed.add(xid); 191 } 192 193 public void end(Xid xid, int flags) throws XAException { 194 } 195 196 public void forget(Xid xid) throws XAException { 197 } 198 199 public int getTransactionTimeout() throws XAException { 200 return 0; 201 } 202 203 public boolean isSameRM(XAResource xaResource) throws XAException { 204 return false; 205 } 206 207 public int prepare(Xid xid) throws XAException { 208 return 0; 209 } 210 211 public Xid [] recover(int flag) throws XAException { 212 return xids; 213 } 214 215 public void rollback(Xid xid) throws XAException { 216 rolledBack.add(xid); 217 } 218 219 public boolean setTransactionTimeout(int seconds) throws XAException { 220 return false; 221 } 222 223 public void start(Xid xid, int flags) throws XAException { 224 } 225 226 public List getCommitted() { 227 return committed; 228 } 229 230 public List getRolledBack() { 231 return rolledBack; 232 } 233 234 235 } 236 237 private static class MockTransactionInfo { 238 private Xid globalXid; 239 private List branches; 240 241 public MockTransactionInfo(Xid globalXid, List branches) { 242 this.globalXid = globalXid; 243 this.branches = branches; 244 } 245 } 246 247 private static class MockTransactionBranchInfo implements TransactionBranchInfo { 248 private String name; 249 250 public MockTransactionBranchInfo(String name) { 251 this.name = name; 252 } 253 254 public String getResourceName() { 255 return name; 256 } 257 258 public Xid getBranchXid() { 259 return null; 260 } 261 } 262 } 263 | Popular Tags |