use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.
the class StreamSegmentMapperTests method testCreateAlreadyExists.
/**
* General test for verifying behavior when a Segment/Transaction is attempted to be created but it already exists.
*
* @param segmentName The name of the segment/transaction to create.
* @param createSegment A BiFunction that is given an instance of a StreamSegmentMapper and a Collection of AttributeUpdates
* that, when invoked, will create the given segment.
*/
private void testCreateAlreadyExists(String segmentName, BiFunction<StreamSegmentMapper, Collection<AttributeUpdate>, CompletableFuture<?>> createSegment) {
final String stateSegmentName = StreamSegmentNameUtils.getStateSegmentName(segmentName);
final Map<UUID, Long> correctAttributes = Collections.singletonMap(UUID.randomUUID(), 123L);
final Collection<AttributeUpdate> correctAttributeUpdates = correctAttributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.Replace, e.getValue())).collect(Collectors.toList());
final Map<UUID, Long> badAttributes = Collections.singletonMap(UUID.randomUUID(), 456L);
final Collection<AttributeUpdate> badAttributeUpdates = badAttributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.Replace, e.getValue())).collect(Collectors.toList());
@Cleanup TestContext context = new TestContext();
@Cleanup val storage = InMemoryStorageFactory.newStorage(executorService());
storage.initialize(1);
val store = new SegmentStateStore(storage, executorService());
val mapper = new StreamSegmentMapper(context.metadata, context.operationLog, store, context.noOpMetadataCleanup, storage, executorService());
// 1. Segment Exists, and so does State File (and it's not corrupted) -> Exception must be bubbled up.
createSegment.apply(mapper, correctAttributeUpdates).join();
AssertExtensions.assertThrows("createNewStreamSegment did not fail when Segment already exists.", () -> createSegment.apply(mapper, badAttributeUpdates), ex -> ex instanceof StreamSegmentExistsException);
val state1 = store.get(segmentName, TIMEOUT).join();
AssertExtensions.assertMapEquals("Unexpected attributes after failed attempt to recreate correctly created segment", correctAttributes, state1.getAttributes());
// 2. Segment Exists, but with empty State File: State file re-created & no exception bubbled up.
storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).join();
Assert.assertNull("Expected a null SegmentState.", store.get(segmentName, TIMEOUT).join());
createSegment.apply(mapper, correctAttributeUpdates).join();
val state2 = store.get(segmentName, TIMEOUT).join();
AssertExtensions.assertMapEquals("Unexpected attributes after successful attempt to complete segment creation (missing state file)", correctAttributes, state2.getAttributes());
// 3. Segment Exists, but with corrupted State File: State file re-created & no exception bubbled up.
storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).thenCompose(v -> storage.openWrite(stateSegmentName)).thenCompose(handle -> storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
AssertExtensions.assertThrows("Expected a DataCorruptionException when reading a corrupted State File.", () -> store.get(segmentName, TIMEOUT), ex -> ex instanceof DataCorruptionException);
createSegment.apply(mapper, correctAttributeUpdates).join();
val state3 = store.get(segmentName, TIMEOUT).join();
AssertExtensions.assertMapEquals("Unexpected attributes after successful attempt to complete segment creation (corrupted state file)", correctAttributes, state3.getAttributes());
// 4. Segment Exists with non-zero length, but with empty/corrupted State File: State File re-created and exception thrown.
storage.openWrite(stateSegmentName).thenCompose(handle -> storage.delete(handle, TIMEOUT)).thenCompose(v -> storage.create(stateSegmentName, TIMEOUT)).thenCompose(v -> storage.openWrite(segmentName)).thenCompose(handle -> storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
AssertExtensions.assertThrows("createNewStreamSegment did not fail when Segment already exists (non-zero length, missing state file).", () -> createSegment.apply(mapper, correctAttributeUpdates), ex -> ex instanceof StreamSegmentExistsException);
val state4 = store.get(segmentName, TIMEOUT).join();
AssertExtensions.assertMapEquals("Unexpected attributes after failed attempt to recreate segment with non-zero length", correctAttributes, state4.getAttributes());
}
use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.
the class StorageWriter method getSegmentAggregator.
// endregion
// region Helpers
/**
* Gets, or creates, a SegmentAggregator for the given StorageOperation.
*
* @param streamSegmentId The Id of the StreamSegment to get the aggregator for.
*/
private CompletableFuture<SegmentAggregator> getSegmentAggregator(long streamSegmentId) {
SegmentAggregator existingAggregator = this.aggregators.getOrDefault(streamSegmentId, null);
if (existingAggregator != null) {
if (closeIfNecessary(existingAggregator).isClosed()) {
// Existing SegmentAggregator has become stale (most likely due to its SegmentMetadata being evicted),
// so it has been closed and we need to create a new one.
this.aggregators.remove(streamSegmentId);
} else {
return CompletableFuture.completedFuture(existingAggregator);
}
}
// Get the SegmentAggregator's Metadata.
UpdateableSegmentMetadata segmentMetadata = this.dataSource.getStreamSegmentMetadata(streamSegmentId);
if (segmentMetadata == null) {
return Futures.failedFuture(new DataCorruptionException(String.format("No StreamSegment with id '%d' is registered in the metadata.", streamSegmentId)));
}
// Then create the aggregator, and only register it after a successful initialization. Otherwise we risk
// having a registered aggregator that is not initialized.
SegmentAggregator newAggregator = new SegmentAggregator(segmentMetadata, this.dataSource, this.storage, this.config, this.timer, this.executor);
try {
CompletableFuture<Void> init = newAggregator.initialize(this.config.getFlushTimeout());
Futures.exceptionListener(init, ex -> newAggregator.close());
return init.thenApply(ignored -> {
this.aggregators.put(streamSegmentId, newAggregator);
return newAggregator;
});
} catch (Exception ex) {
newAggregator.close();
throw ex;
}
}
use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.
the class SegmentStateStoreTests method testGetCorruptedState.
/**
* Tests the get() method when there exists a state in Storage, however it is a corrupted file.
*/
@Test
public void testGetCorruptedState() throws Exception {
final String segmentName = "foo";
final String stateSegment = StreamSegmentNameUtils.getStateSegmentName(segmentName);
val store = createStateStore();
// Write some dummy contents in the file which is not how a SegmentState would be serialized.
this.storage.create(stateSegment, TIMEOUT).thenCompose(si -> this.storage.openWrite(stateSegment)).thenCompose(handle -> this.storage.write(handle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT)).join();
AssertExtensions.assertThrows("Unexpected behavior when attempting to read a corrupted state file.", () -> store.get(segmentName, TIMEOUT), ex -> ex instanceof DataCorruptionException);
}
use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.
the class BookkeeperCommandsTest method testRecoveryState.
@Test
public void testRecoveryState() {
CommandArgs args = new CommandArgs(Collections.singletonList("0"), STATE.get());
ContainerRecoverCommand.RecoveryState state = new ContainerRecoverCommand(args).new RecoveryState();
Operation op = new TestOperation();
List<DataFrameRecord.EntryInfo> entries = new ArrayList<>();
entries.add(new TestEntryInfo());
// Exercise RecoveryState logic.
state.operationComplete(op, new DataCorruptionException("Test exception"));
state.newOperation(op, entries);
state.operationComplete(op, null);
}
use of io.pravega.segmentstore.server.DataCorruptionException in project pravega by pravega.
the class BookkeeperCommandsTest method testBookKeeperRecoveryCommand.
@Test
public void testBookKeeperRecoveryCommand() throws Exception {
createLedgerInBookkeeperTestCluster(0);
String commandResult = TestUtils.executeCommand("container recover 0", STATE.get());
Assert.assertTrue(commandResult.contains("Recovery complete"));
CommandArgs args = new CommandArgs(Collections.singletonList("0"), STATE.get());
ContainerRecoverCommand command = new ContainerRecoverCommand(args);
// Test unwrap exception options.
command.unwrapDataCorruptionException(new DataCorruptionException("test"));
command.unwrapDataCorruptionException(new DataCorruptionException("test", "test"));
command.unwrapDataCorruptionException(new DataCorruptionException("test", Arrays.asList("test", "test")));
command.unwrapDataCorruptionException(new DataCorruptionException("test", (DataCorruptionException) null));
// Check that exception is thrown if ZK is not available.
this.zkUtil.stopCluster();
AssertExtensions.assertThrows(DataLogNotAvailableException.class, () -> TestUtils.executeCommand("container recover 0", STATE.get()));
}
Aggregations