Commit 2ff67f65 authored by Jonathan Haas's avatar Jonathan Haas

Leere Containerdateien werden jetzt beim Archivieren ignoriert/repariert.

parent 3ddb8db0
......@@ -54,21 +54,24 @@ public class TestDamagedContainer extends ExtendedOnlineArchiveTest {
@Test(timeout = 200000)
public void testDamagedContainers() throws Exception {
startArS_Setup(3);
startArS_Setup(4);
sendDataWait(0, 13, TIMEOUT_60);
sendDataWait(1, 13, TIMEOUT_60);
sendDataWait(2, 13, TIMEOUT_60);
sendDataWait(3, 13, TIMEOUT_60);
String contDir0 = getContDir(am, 0, ArchiveDataKind.ONLINE);
String contDir1 = getContDir(am, 1, ArchiveDataKind.ONLINE);
String contDir2 = getContDir(am, 2, ArchiveDataKind.ONLINE);
String contDir3 = getContDir(am, 3, ArchiveDataKind.ONLINE);
// Die offenen Container haben die IDs 2, 4, 6
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir0));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir1));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir2));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir3));
Thread.sleep(1000);
quitArS(1000);
......@@ -79,6 +82,7 @@ public class TestDamagedContainer extends ExtendedOnlineArchiveTest {
destroyContainer1(contDir0, 2);
destroyContainer2(contDir1, 4);
destroyContainer3(contDir2, 6);
destroyContainer4(contDir3, 8);
includeNoDataNoSourcePotGap(); // Sicherstellen, dass Lücke nicht unterdrückt wird
......@@ -87,10 +91,12 @@ public class TestDamagedContainer extends ExtendedOnlineArchiveTest {
sendDataWait(0, 3, TIMEOUT_60);
sendDataWait(1, 3, TIMEOUT_60);
sendDataWait(2, 3, TIMEOUT_60);
sendDataWait(3, 3, TIMEOUT_60);
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir0));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir1));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir2));
ArchiveFileViewer.analyzeFileOrDirectory(new File(contDir3));
Thread.sleep(1000);
}
......@@ -132,6 +138,17 @@ public class TestDamagedContainer extends ExtendedOnlineArchiveTest {
}
}
}
/**
* Verkürzt die Containerdatei auf 0 Bytes
* @param contDir
* @param contId
*/
private void destroyContainer4(final String contDir, final int contId) throws IOException {
try(RandomAccessFile raf = new RandomAccessFile(new File(contDir, PersistenceManager.getContFileName(contId)), "rw")) {
raf.setLength(0);
}
}
private void startArS_Setup(int anzObj) throws Exception {
String[] subscrObjs = new String[anzObj];
......
......@@ -621,6 +621,9 @@ public class ContainerFile {
closeRandomAccessFile(raf);
}
}
catch(PersistenceException e) {
throw e;
}
catch(Exception e) {
throw new PersistenceException("Container-Header konnte nicht gelesen werden: " + e.getMessage() + "\n" + this, e);
}
......
......@@ -712,10 +712,19 @@ public final class PersistenceManager {
File persDir = ContainerFileHandle.getCreatePersDir(din.getDataIdentification(), archiveDataKind, this);
File contFile = new File(persDir, getContFileName(containerId));
try(BufferedRandomAccessFile file = new BufferedRandomAccessFile(contFile)) {
file.seek(file.length() - 3);
byte[] tmp = new byte[3];
file.readFully(tmp);
if(!Arrays.equals(tmp, ByteIO.SEPARATOR)) {
boolean isBroken;
if(file.length() < 384) {
// Container zu kurz
isBroken = true;
}
else {
file.seek(file.length() - 3);
byte[] tmp = new byte[3];
file.readFully(tmp);
isBroken = !Arrays.equals(tmp, ByteIO.SEPARATOR);
}
if(isBroken) {
// Defekte Containerdatei!
logger.warning("Container " + contFile + " ist beschädigt und wird repariert.");
fixContainerFile(din, archiveDataKind, contFile, file);
......@@ -737,6 +746,10 @@ public final class PersistenceManager {
private void fixContainerFile(final DataIdentNode dataIdentNode, final ArchiveDataKind archiveDataKind, final File containerFile, final BufferedRandomAccessFile container) throws PersistenceException {
int numDs = 0;
try {
if(container.length() < 384) {
// Wir wollen direkt in den catch-Block unten springen statt die Containerdatei zu verlängern
throw new IOException("Container hat keinen Header, Länge ist nur " + container.length() + " Bytes.");
}
container.seek(384);
long lastValidPosition = 384;
......@@ -772,7 +785,20 @@ public final class PersistenceManager {
}
}
catch(Exception e) {
throw new PersistenceException(containerFile.toString() + ": Unerwarteter Fehler bei der Reparatur", e);
try {
container.close();
}
catch(IOException ignored) {
}
final Path contFile = containerFile.toPath();
Path target = contFile.resolveSibling(contFile.getFileName() + ".defect");
try {
Files.move(contFile, target);
}
catch(IOException e1) {
throw new PersistenceException("Umbenennen der defekten Containerdatei fehlgeschlagen: " + contFile, e1);
}
logger.warning("Container " + contFile + " konnte nicht gelesen werden und wurde in " + target.getFileName() + " umbenannt.");
}
try {
......@@ -786,7 +812,7 @@ public final class PersistenceManager {
);
}
catch(Exception e) {
throw new PersistenceException(containerFile.toString() + ": Unerwarteter Fehler bei der Reparatur: " + e);
throw new PersistenceException(containerFile.toString() + ": Unerwarteter Fehler bei der Reparatur: ", e);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment