/*
* Jalisto - JAva LIght STOrage
* Copyright (C) 2000-2005 Xcalia http://www.xcalia.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Xcalia
* 71, rue Desnouettes
* 75014 Paris - France
* http://www.xcalia.com
*/
package org.objectweb.jalisto.se.storage.raf.log.synraf.recover;
import org.objectweb.jalisto.se.api.JalistoProperties;
import org.objectweb.jalisto.se.api.internal.Constants;
import org.objectweb.jalisto.se.api.physical.PluggablePhysicalFileAccess;
import org.objectweb.jalisto.se.JalistoFactory;
import org.objectweb.jalisto.se.storage.raf.log.backup.LogBoundary;
import org.objectweb.jalisto.se.storage.raf.log.backup.LogObject;
import org.objectweb.jalisto.se.storage.raf.log.synraf.PhysicalFileAccessLogSynrafImpl;
import org.objectweb.jalisto.se.storage.raf.log.synraf.action.LogAction;
import java.io.EOFException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
public class RecoverBase {
public void recoverBase(JalistoProperties properties) throws Exception {
String[] pathes = properties.getPathes();
String logActionFileName = properties.getLogFileName();
RandomAccessFile logActionFile = new RandomAccessFile(logActionFileName, "r");
ArrayList actionObjects = new ArrayList();
boolean readLogActionFailed = false;
boolean logActionStructureError = false;
try {
while (logActionFile.getFilePointer() < logActionFile.length()) {
LogAction logAction = new LogAction();
logAction.readFrom(logActionFile);
actionObjects.add(logAction);
}
try {
// last logged action must be a commit
LogAction logAction = (LogAction) actionObjects.get(actionObjects.size() - 1);
if (logAction.getActionType() == LogAction.COMMIT_ACTION) {
System.out.println("Log file " + logActionFileName + " is OK");
return;
}
} catch (ClassCastException cce) {
}
logActionStructureError = true;
} catch (EOFException e) {
readLogActionFailed = true;
}
boolean allLogAreOk = true;
boolean allLogAreClosed = true;
if (!readLogActionFailed && logActionStructureError) {
// readLogActionFailed = true => crash during logAction : no backup from buffer
for (short i = 0; i < pathes.length; i++) {
String baseFileName = pathes[i];
String bufferLogFileName = baseFileName + Constants.LOG_POSTFIX;
RandomAccessFile base = new RandomAccessFile(baseFileName, "rw");
RandomAccessFile bufferLog = new RandomAccessFile(bufferLogFileName, "r");
bufferLog.seek(0);
ArrayList logObjects = new ArrayList();
boolean readError = false;
boolean structureError = false;
boolean hasError;
while ((!readError) && (bufferLog.getFilePointer() < bufferLog.length())) {
try {
Object lo = LogObject.readFrom(bufferLog);
logObjects.add(lo);
} catch (EOFException e) {
readError = true;
}
}
if (!logObjects.isEmpty()) {
try {
LogBoundary boundary = (LogBoundary) logObjects.get(logObjects.size() - 1);
structureError = boundary.isBegin(); // must not be begin
} catch (ClassCastException cce) { // last logElement is not a boundary
structureError = true;
}
}
hasError = readError || structureError;
allLogAreClosed = allLogAreClosed && (!structureError);
allLogAreOk = allLogAreOk && (!hasError);
if (hasError) {
System.out.println("RECOVER " + baseFileName + " from log file " + bufferLogFileName);
for (int j = (logObjects.size() - 1); j > -1; j--) {
LogObject logObject = (LogObject) logObjects.get(j);
logObject.undoOn(base);
}
} else {
System.out.println("No need to recover " + pathes[i]);
}
base.close();
bufferLog.close();
}
}
System.out.println("Undo actions from the last transaction");
PluggablePhysicalFileAccess physicalAccessInternal =
JalistoFactory.getInternalFactory().getPhysicalAccess(properties);
int startingIndex;
if (allLogAreClosed) {
startingIndex = actionObjects.size() - 1;
} else {
startingIndex = actionObjects.size() - 2; // la dernire action est annule par le buffer backup
}
for (int j = startingIndex; j > -1; j--) {
LogAction logAction = (LogAction) actionObjects.get(j);
logAction.undoOn(physicalAccessInternal);
}
}
public static void main(String[] args) {
try {
JalistoProperties prop;
if (args.length < 1) {
prop = JalistoFactory.getInternalFactory().getProperties("jalisto.properties");
} else {
prop = JalistoFactory.getInternalFactory().getProperties(args[0]);
}
prop.setProperty(JalistoProperties.PHYSICAL_ACCESS_CLASS_KEY, PhysicalFileAccessLogSynrafImpl.class.getName());
(new RecoverBase()).recoverBase(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
}
|