1 22 package org.jboss.tm.recovery; 23 24 import java.io.File ; 25 import java.nio.ByteBuffer ; 26 import java.util.ArrayList ; 27 28 import javax.transaction.xa.Xid ; 29 30 import org.jboss.tm.XidFactoryBase; 31 32 44 public class BatchRecoveryLogger 45 implements RecoveryLogger 46 { 47 48 private String [] stringDirectoryList; 49 50 51 private File [] directoryList; 52 53 54 private int logFileSize; 55 56 57 private File [] existingRecoveryLogFiles; 58 59 60 private BatchWriter[] writers; 61 62 63 private int numWriters; 64 65 66 private volatile int seqNo = 0; 67 68 69 private String heuristicStatusLogDirectoryName; 70 71 72 private File heuristicStatusLogDirectory; 73 74 75 private File [] existingHeuristicStatusLogFiles; 76 77 78 private HeuristicStatusLog heuristicStatusLogger; 79 80 81 private XidFactoryBase xidFactory; 82 83 84 private LogRestarter logCleaner; 85 86 89 96 String [] getDirectoryList() 97 { 98 return stringDirectoryList; 99 } 100 101 111 public void setDirectoryList(String [] directoryList) 112 { 113 this.stringDirectoryList = directoryList; 114 File [] list = new File [directoryList.length]; 115 for (int i = 0; i < directoryList.length; i++) 116 { 117 list[i] = new File (directoryList[i]); 118 list[i] = list[i].getAbsoluteFile(); 119 if (!list[i].exists()) 120 { 121 if (!list[i].mkdirs()) 122 { 123 throw new RuntimeException ("Unable to create recovery directory: " 124 + directoryList[i]); 125 } 126 } 127 } 128 this.directoryList = list; 129 } 130 131 136 int getLogFileSize() 137 { 138 return logFileSize; 139 } 140 141 149 public void setLogFileSize(int logFileSize) 150 { 151 this.logFileSize = logFileSize; 152 } 153 154 160 String getHeuristicStatusLogDirectory() 161 { 162 return heuristicStatusLogDirectoryName; 163 } 164 165 174 public void setHeuristicStatusLogDirectory(String heuristicStatusLogDirectoryName) 175 { 176 this.heuristicStatusLogDirectoryName = heuristicStatusLogDirectoryName; 177 heuristicStatusLogDirectory = new File (heuristicStatusLogDirectoryName); 178 heuristicStatusLogDirectory = 179 heuristicStatusLogDirectory.getAbsoluteFile(); 180 if (!heuristicStatusLogDirectory.exists()) 181 { 182 if (!heuristicStatusLogDirectory.mkdirs()) 183 { 184 throw new RuntimeException ("Unable to create heuristic status " + 185 "log directory: " 186 + heuristicStatusLogDirectoryName); 187 } 188 } 189 } 190 191 196 XidFactoryBase getXidFactory() 197 { 198 return xidFactory; 199 } 200 201 209 public void setXidFactory(XidFactoryBase xidFactory) 210 { 211 this.xidFactory = xidFactory; 212 } 213 214 220 public void start() throws Exception 221 { 222 ArrayList list = new ArrayList (); 223 for (int i = 0; i < directoryList.length; i++) 224 { 225 File dir = directoryList[i]; 226 File [] files = dir.listFiles(); 227 for (int j = 0; j < files.length; j++) 228 { 229 list.add(files[j]); 230 } 231 } 232 existingRecoveryLogFiles = (File []) list.toArray(new File [list.size()]); 233 234 logCleaner = new LogRestarter(); 235 new Thread (logCleaner, "Log file cleaner").start(); 236 237 writers = new BatchWriter[directoryList.length]; 238 String branchQualifier = xidFactory.getBranchQualifier(); 239 for (int i = 0; i < directoryList.length; i++) 240 { 241 writers[i] = new BatchWriter(branchQualifier, logFileSize / 128, 242 directoryList[i], logFileSize, logCleaner); 243 new Thread (writers[i], "Batch Recovery Log " + i).start(); 244 } 245 numWriters = writers.length; 246 247 existingHeuristicStatusLogFiles = heuristicStatusLogDirectory.listFiles(); 248 heuristicStatusLogger = 249 new HeuristicStatusLog(heuristicStatusLogDirectory); 250 } 251 252 258 public void stop() throws Exception 259 { 260 for (int i = 0; i < writers.length; i++) 261 { 262 writers[i].stop(); 263 } 264 logCleaner.stop(); 265 heuristicStatusLogger.close(); 266 } 267 268 270 274 public TxCompletionHandler saveCommitDecision(long localTransactionId, 275 String [] resources) 276 { 277 ByteBuffer buffer; 278 279 if (resources == null || resources.length == 0) 280 { 281 buffer = LogRecord.createTxCommittedRecord(localTransactionId); 282 return writers[++seqNo % numWriters].addBatch(buffer, false); 283 } 284 else 285 { 286 buffer = LogRecord.createTxCommittedRecord(localTransactionId, 287 resources); 288 return writers[++seqNo % numWriters].addBatch(buffer, true); 289 } 290 } 291 292 296 public TxCompletionHandler savePrepareDecision(long localTransactionId, 297 int inboundFormatId, 298 byte[] globalTransactionId, 299 String recoveryCoordinator, 300 String [] resources) 301 { 302 ByteBuffer buffer = LogRecord.createTxPreparedRecord(localTransactionId, 303 inboundFormatId, 304 globalTransactionId, 305 recoveryCoordinator, 306 resources); 307 return writers[++seqNo % numWriters].addBatch(buffer, true); 308 } 309 310 314 public TxCompletionHandler savePrepareDecision(long localTransactionId, 315 Xid inboundXid, 316 String [] resources) 317 { 318 ByteBuffer buffer = 319 LogRecord.createJcaTxPreparedRecord(localTransactionId, 320 inboundXid, 321 resources); 322 return writers[++seqNo % numWriters].addBatch(buffer, true); 323 } 324 325 330 public void saveHeuristicStatus(long localTransactionId, 331 boolean foreignTx, 332 int formatId, 333 byte[] globalTransactionId, 334 byte[] inboundBranchQualifier, 335 int transactionStatus, 336 int heurStatusCode, 337 boolean locallyDetectedHeuristicHazard, 338 int[] xaResourceHeuristics, 339 HeuristicStatus[] remoteResourceHeuristics) 340 { 341 ByteBuffer buffer = 342 LogRecord.createHeurStatusRecord(localTransactionId, 343 foreignTx, 344 formatId, 345 globalTransactionId, 346 inboundBranchQualifier, 347 transactionStatus, 348 heurStatusCode, 349 locallyDetectedHeuristicHazard, 350 xaResourceHeuristics, 351 remoteResourceHeuristics); 352 heuristicStatusLogger.write(buffer); 353 } 354 355 358 public void clearHeuristicStatus(long localTransactionId) 359 { 360 ByteBuffer buffer = 361 LogRecord.createHeurForgottenRecord(localTransactionId); 362 heuristicStatusLogger.write(buffer); 363 } 364 365 368 public RecoveryLogReader[] getRecoveryLogs() 369 { 370 if (existingRecoveryLogFiles == null 371 || existingRecoveryLogFiles.length == 0) 372 return null; 373 374 RecoveryLogReader[] readers = 375 new RecoveryLogReader[existingRecoveryLogFiles.length]; 376 for (int i = 0; i < readers.length; i++) 377 { 378 readers[i] = 379 new BatchRecoveryLogReader(existingRecoveryLogFiles[i], xidFactory); 380 } 381 return readers; 382 } 383 384 387 public HeuristicStatusLogReader[] getHeuristicStatusLogs() 388 { 389 if (existingHeuristicStatusLogFiles == null 390 || existingHeuristicStatusLogFiles.length == 0) 391 return null; 392 393 HeuristicStatusLogReader[] readers = 394 new HeuristicStatusLogReader[existingHeuristicStatusLogFiles.length]; 395 for (int i = 0; i < readers.length; i++) 396 { 397 readers[i] = new SimpleHeuristicStatusLogReader( 398 existingHeuristicStatusLogFiles[i]); 399 } 400 return readers; 401 } 402 403 } 404 | Popular Tags |