@Test public void shouldPersistSnapshot() throws Exception { final var index = 1L; final var term = 0L; final var receivedSnapshot = takeAndReceiveSnapshot(index, term); final var snapshot = receivedSnapshot.persist(); assertThat(snapshot).isNotNull(); assertThat(receiverPendingSnapshotsDir.toFile().listFiles()).isEmpty(); assertThat(receiverSnapshotsDir).exists(); final var files = receiverSnapshotsDir.toFile().listFiles(); assertThat(files).isNotNull().hasSize(1); final var dir = files[0]; assertThat(dir).hasName(snapshot.getId()); final var snapshotFileList = dir.listFiles(); assertThat(snapshotFileList).isNotNull().extracting(File::getName).containsExactly("file1.txt"); }
@Override public PersistedSnapshot persist() { if (snapshotStore.hasSnapshotId(metadata.getSnapshotIdAsString())) { abort(); return snapshotStore.getLatestSnapshot().orElseThrow(); } final var files = directory.toFile().listFiles(); Objects.requireNonNull(files, "No chunks have been applied yet"); if (files.length != expectedTotalCount) { throw new IllegalStateException( String.format( "Expected '%d' chunk files for this snapshot, but found '%d'. Files are: %s.", expectedSnapshotChecksum, files.length, Arrays.toString(files))); } final var filePaths = Arrays.stream(files).sorted().map(File::toPath).collect(Collectors.toList()); final long actualSnapshotChecksum; try { actualSnapshotChecksum = ChecksumUtil.createCombinedChecksum(filePaths); } catch (final IOException e) { throw new UncheckedIOException("Unexpected exception on calculating snapshot checksum.", e); } if (actualSnapshotChecksum != expectedSnapshotChecksum) { throw new IllegalStateException( String.format( "Expected snapshot checksum %d, but calculated %d.", expectedSnapshotChecksum, actualSnapshotChecksum)); } return snapshotStore.newSnapshot(metadata, directory); }
FileBasedReceivedSnapshot implements ReceivedSnapshot { @Override public PersistedSnapshot persist() { if (snapshotStore.hasSnapshotId(metadata.getSnapshotIdAsString())) { abort(); return snapshotStore.getLatestSnapshot().orElseThrow(); } final var files = directory.toFile().listFiles(); Objects.requireNonNull(files, "No chunks have been applied yet"); if (files.length != expectedTotalCount) { throw new IllegalStateException( String.format( "Expected '%d' chunk files for this snapshot, but found '%d'. Files are: %s.", expectedSnapshotChecksum, files.length, Arrays.toString(files))); } final var filePaths = Arrays.stream(files).sorted().map(File::toPath).collect(Collectors.toList()); final long actualSnapshotChecksum; try { actualSnapshotChecksum = ChecksumUtil.createCombinedChecksum(filePaths); } catch (final IOException e) { throw new UncheckedIOException("Unexpected exception on calculating snapshot checksum.", e); } if (actualSnapshotChecksum != expectedSnapshotChecksum) { throw new IllegalStateException( String.format( "Expected snapshot checksum %d, but calculated %d.", expectedSnapshotChecksum, actualSnapshotChecksum)); } return snapshotStore.newSnapshot(metadata, directory); } }
FileBasedReceivedSnapshot implements ReceivedSnapshot { @Override public PersistedSnapshot persist() { if (snapshotStore.hasSnapshotId(metadata.getSnapshotIdAsString())) { abort(); return snapshotStore.getLatestSnapshot().orElseThrow(); } final var files = directory.toFile().listFiles(); Objects.requireNonNull(files, "No chunks have been applied yet"); if (files.length != expectedTotalCount) { throw new IllegalStateException( String.format( "Expected '%d' chunk files for this snapshot, but found '%d'. Files are: %s.", expectedSnapshotChecksum, files.length, Arrays.toString(files))); } final var filePaths = Arrays.stream(files).sorted().map(File::toPath).collect(Collectors.toList()); final long actualSnapshotChecksum; try { actualSnapshotChecksum = ChecksumUtil.createCombinedChecksum(filePaths); } catch (final IOException e) { throw new UncheckedIOException("Unexpected exception on calculating snapshot checksum.", e); } if (actualSnapshotChecksum != expectedSnapshotChecksum) { throw new IllegalStateException( String.format( "Expected snapshot checksum %d, but calculated %d.", expectedSnapshotChecksum, actualSnapshotChecksum)); } return snapshotStore.newSnapshot(metadata, directory); } FileBasedReceivedSnapshot(
      final FileBasedSnapshotMetadata metadata,
      final Path directory,
      final FileBasedSnapshotStore snapshotStore); }
FileBasedReceivedSnapshot implements ReceivedSnapshot { @Override public PersistedSnapshot persist() { if (snapshotStore.hasSnapshotId(metadata.getSnapshotIdAsString())) { abort(); return snapshotStore.getLatestSnapshot().orElseThrow(); } final var files = directory.toFile().listFiles(); Objects.requireNonNull(files, "No chunks have been applied yet"); if (files.length != expectedTotalCount) { throw new IllegalStateException( String.format( "Expected '%d' chunk files for this snapshot, but found '%d'. Files are: %s.", expectedSnapshotChecksum, files.length, Arrays.toString(files))); } final var filePaths = Arrays.stream(files).sorted().map(File::toPath).collect(Collectors.toList()); final long actualSnapshotChecksum; try { actualSnapshotChecksum = ChecksumUtil.createCombinedChecksum(filePaths); } catch (final IOException e) { throw new UncheckedIOException("Unexpected exception on calculating snapshot checksum.", e); } if (actualSnapshotChecksum != expectedSnapshotChecksum) { throw new IllegalStateException( String.format( "Expected snapshot checksum %d, but calculated %d.", expectedSnapshotChecksum, actualSnapshotChecksum)); } return snapshotStore.newSnapshot(metadata, directory); } FileBasedReceivedSnapshot(
      final FileBasedSnapshotMetadata metadata,
      final Path directory,
      final FileBasedSnapshotStore snapshotStore); @Override long index(); @Override boolean containsChunk(final ByteBuffer chunkId); @Override boolean isExpectedChunk(final ByteBuffer chunkId); @Override void setNextExpected(final ByteBuffer nextChunkId); @Override boolean apply(final SnapshotChunk snapshotChunk); @Override void abort(); @Override PersistedSnapshot persist(); Path getPath(); @Override String toString(); }
FileBasedReceivedSnapshot implements ReceivedSnapshot { @Override public PersistedSnapshot persist() { if (snapshotStore.hasSnapshotId(metadata.getSnapshotIdAsString())) { abort(); return snapshotStore.getLatestSnapshot().orElseThrow(); } final var files = directory.toFile().listFiles(); Objects.requireNonNull(files, "No chunks have been applied yet"); if (files.length != expectedTotalCount) { throw new IllegalStateException( String.format( "Expected '%d' chunk files for this snapshot, but found '%d'. Files are: %s.", expectedSnapshotChecksum, files.length, Arrays.toString(files))); } final var filePaths = Arrays.stream(files).sorted().map(File::toPath).collect(Collectors.toList()); final long actualSnapshotChecksum; try { actualSnapshotChecksum = ChecksumUtil.createCombinedChecksum(filePaths); } catch (final IOException e) { throw new UncheckedIOException("Unexpected exception on calculating snapshot checksum.", e); } if (actualSnapshotChecksum != expectedSnapshotChecksum) { throw new IllegalStateException( String.format( "Expected snapshot checksum %d, but calculated %d.", expectedSnapshotChecksum, actualSnapshotChecksum)); } return snapshotStore.newSnapshot(metadata, directory); } FileBasedReceivedSnapshot(
      final FileBasedSnapshotMetadata metadata,
      final Path directory,
      final FileBasedSnapshotStore snapshotStore); @Override long index(); @Override boolean containsChunk(final ByteBuffer chunkId); @Override boolean isExpectedChunk(final ByteBuffer chunkId); @Override void setNextExpected(final ByteBuffer nextChunkId); @Override boolean apply(final SnapshotChunk snapshotChunk); @Override void abort(); @Override PersistedSnapshot persist(); Path getPath(); @Override String toString();  }