EventFileReaderImpl implements EventFileReader { @Override public EventFile read(File file) { EventFile eventFile = new EventFile(); String fileName = file.getName(); try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)))) { MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM); int fileVersion = dis.readInt(); md.update(Ints.toByteArray(fileVersion)); if (fileVersion < EVENT_STREAM_FILE_VERSION_2 || fileVersion > EVENT_STREAM_FILE_VERSION_3) { throw new InvalidEventFileException("Invalid event stream file version " + fileVersion); } byte typePrevHash = dis.readByte(); md.update(typePrevHash); if (typePrevHash != EVENT_TYPE_PREV_HASH) { throw new InvalidEventFileException("Expect EVENT_TYPE_PREV_HASH marker, got " + typePrevHash); } byte[] prevFileHash = new byte[EVENT_PREV_HASH_LENGTH]; dis.readFully(prevFileHash); md.update(prevFileHash); byte[] remaining = dis.readAllBytes(); if (remaining.length != 0) { if (fileVersion == EVENT_STREAM_FILE_VERSION_2) { md.update(remaining); } else { MessageDigest mdForEventData = MessageDigest.getInstance(HASH_ALGORITHM); md.update(mdForEventData.digest(remaining)); } } eventFile.setName(fileName); eventFile.setFileVersion(fileVersion); eventFile.setPreviousHash(Hex.encodeHexString(prevFileHash)); eventFile.setFileHash(Hex.encodeHexString(md.digest())); eventFile.setCount(0L); } catch (InvalidEventFileException e) { throw e; } catch (Exception e) { throw new InvalidEventFileException("Error reading bad event file " + fileName, e); } return eventFile; }  @Override EventFile read(File file); static final String HASH_ALGORITHM; static final byte EVENT_TYPE_PREV_HASH; static final int EVENT_PREV_HASH_LENGTH; static final byte EVENT_STREAM_FILE_VERSION_2; static final byte EVENT_STREAM_FILE_VERSION_3; }
@Test void readValidFileVersion2() { File validFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_2, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, prevHash, content); EventFile eventFile = eventFileReader.read(validFile); verifyForSuccess(eventFile, validFile, EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_2, prevHash); }
@Test void readValidFileVersion3() { File validFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, prevHash, content); EventFile eventFile = eventFileReader.read(validFile); verifyForSuccess(eventFile, validFile, EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, prevHash); }
@Test void readValidFileWithNoContent() { File validFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, prevHash, null); EventFile eventFile = eventFileReader.read(validFile); verifyForSuccess(eventFile, validFile, EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, prevHash); }
@Test void readInvalidFileWithInvalidVersion1() { File invalidFile = createTmpEventFile(1, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, prevHash, content); assertThrows(InvalidEventFileException.class, () -> { eventFileReader.read(invalidFile); }); }
@Test void readInvalidFileWithInvalidVersion4() { File invalidFile = createTmpEventFile(4, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, prevHash, content); assertThrows(InvalidEventFileException.class, () -> { eventFileReader.read(invalidFile); }); }
@Test void readInvalidFileWithInvalidPrevHashMarker() { File invalidFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, (byte) 0x0, prevHash, content); assertThrows(InvalidEventFileException.class, () -> { eventFileReader.read(invalidFile); }); }
@Test void readInvalidFileWithNoPrevHash() { File invalidFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, null, null); assertThrows(InvalidEventFileException.class, () -> { eventFileReader.read(invalidFile); }); }
@Test void readInvalidFileWithIncompletePrevHash() { byte[] incompletePrevHash = new byte[EventFileReaderImpl.EVENT_PREV_HASH_LENGTH - 2]; File invalidFile = createTmpEventFile(EventFileReaderImpl.EVENT_STREAM_FILE_VERSION_3, EventFileReaderImpl.EVENT_TYPE_PREV_HASH, incompletePrevHash, null); assertThrows(InvalidEventFileException.class, () -> { eventFileReader.read(invalidFile); }); }