use of io.pravega.segmentstore.contracts.StreamSegmentException in project pravega by pravega.
the class RecoveryProcessor method recoverOperation.
protected void recoverOperation(DataFrameRecord<Operation> dataFrameRecord, OperationMetadataUpdater metadataUpdater) throws DataCorruptionException {
// Update Metadata Sequence Number.
Operation operation = dataFrameRecord.getItem();
metadataUpdater.setOperationSequenceNumber(operation.getSequenceNumber());
// Update the metadata with the information from the Operation.
try {
log.debug("{} Recovering {}.", this.traceObjectId, operation);
metadataUpdater.preProcessOperation(operation);
metadataUpdater.acceptOperation(operation);
} catch (StreamSegmentException | ContainerException ex) {
// Metadata update failures should not happen during recovery.
throw new DataCorruptionException(String.format("Unable to update metadata for Log Operation '%s'.", operation), ex);
}
// Update in-memory structures.
this.stateUpdater.process(operation);
}
use of io.pravega.segmentstore.contracts.StreamSegmentException in project pravega by pravega.
the class RollingStorage method create.
@Override
public SegmentProperties create(String segmentName, SegmentRollingPolicy rollingPolicy) throws StreamSegmentException {
Preconditions.checkNotNull(rollingPolicy, "rollingPolicy");
String headerName = StreamSegmentNameUtils.getHeaderSegmentName(segmentName);
long traceId = LoggerHelpers.traceEnter(log, "create", segmentName, rollingPolicy);
// RollingStorage to this baseStorage).
if (this.baseStorage.exists(segmentName)) {
throw new StreamSegmentExistsException(segmentName);
}
// Create the header file, and then serialize the contents to it.
// If the header file already exists, then it's OK if it's empty (probably a remnant from a previously failed
// attempt); in that case we ignore it and let the creation proceed.
SegmentHandle headerHandle = null;
try {
try {
this.baseStorage.create(headerName);
} catch (StreamSegmentExistsException ex) {
checkIfEmptyAndNotSealed(ex, headerName);
log.debug("Empty Segment Header found for '{}'; treating as inexistent.", segmentName);
}
headerHandle = this.baseStorage.openWrite(headerName);
serializeHandle(new RollingSegmentHandle(headerHandle, rollingPolicy, Collections.emptyList()));
} catch (StreamSegmentExistsException ex) {
throw ex;
} catch (Exception ex) {
if (!Exceptions.mustRethrow(ex) && headerHandle != null) {
// otherwise we'll leave behind an empty file.
try {
log.warn("Could not create Header Segment for '{}', rolling back.", segmentName, ex);
this.baseStorage.delete(headerHandle);
} catch (Exception ex2) {
ex.addSuppressed(ex2);
}
}
throw ex;
}
LoggerHelpers.traceLeave(log, "create", traceId, segmentName);
return StreamSegmentInformation.builder().name(segmentName).build();
}
use of io.pravega.segmentstore.contracts.StreamSegmentException in project pravega by pravega.
the class OperationProcessorTests method testWithInvalidOperations.
/**
* Tests the ability of the OperationProcessor to process Operations when encountering invalid operations (such as
* appends to StreamSegments that do not exist or to those that are sealed). This covers the following exceptions:
* * StreamSegmentNotExistsException
* * StreamSegmentSealedException
* * General MetadataUpdateException.
*/
@Test
public void testWithInvalidOperations() throws Exception {
int streamSegmentCount = 10;
int appendsPerStreamSegment = 40;
// We are going to prematurely seal this StreamSegment.
long sealedStreamSegmentId = 6;
// We are going to prematurely mark this StreamSegment as deleted.
long deletedStreamSegmentId = 8;
// This is a bogus StreamSegment, that does not exist.
long nonExistentStreamSegmentId;
@Cleanup TestContext context = new TestContext();
// Generate some test data (no need to complicate ourselves with Transactions here; that is tested in the no-failure test).
HashSet<Long> streamSegmentIds = createStreamSegmentsInMetadata(streamSegmentCount, context.metadata);
nonExistentStreamSegmentId = streamSegmentIds.size();
streamSegmentIds.add(nonExistentStreamSegmentId);
context.metadata.getStreamSegmentMetadata(sealedStreamSegmentId).markSealed();
context.metadata.getStreamSegmentMetadata(deletedStreamSegmentId).markDeleted();
List<Operation> operations = generateOperations(streamSegmentIds, new HashMap<>(), appendsPerStreamSegment, METADATA_CHECKPOINT_EVERY, false, false);
// Setup an OperationProcessor and start it.
@Cleanup TestDurableDataLog dataLog = TestDurableDataLog.create(CONTAINER_ID, MAX_DATA_LOG_APPEND_SIZE, executorService());
dataLog.initialize(TIMEOUT);
@Cleanup OperationProcessor operationProcessor = new OperationProcessor(context.metadata, context.stateUpdater, dataLog, getNoOpCheckpointPolicy(), executorService());
operationProcessor.startAsync().awaitRunning();
// Process all generated operations.
List<OperationWithCompletion> completionFutures = processOperations(operations, operationProcessor);
// Wait for all such operations to complete. We are expecting exceptions, so verify that we do.
AssertExtensions.assertThrows("No operations failed.", OperationWithCompletion.allOf(completionFutures)::join, ex -> ex instanceof MetadataUpdateException || ex instanceof StreamSegmentException);
HashSet<Long> streamSegmentsWithNoContents = new HashSet<>();
streamSegmentsWithNoContents.add(sealedStreamSegmentId);
streamSegmentsWithNoContents.add(deletedStreamSegmentId);
streamSegmentsWithNoContents.add(nonExistentStreamSegmentId);
// Verify that the "right" operations failed, while the others succeeded.
for (OperationWithCompletion oc : completionFutures) {
if (oc.operation instanceof StorageOperation) {
long streamSegmentId = ((StorageOperation) oc.operation).getStreamSegmentId();
if (streamSegmentsWithNoContents.contains(streamSegmentId)) {
Assert.assertTrue("Completion future for invalid StreamSegment " + streamSegmentId + " did not complete exceptionally.", oc.completion.isCompletedExceptionally());
Predicate<Throwable> errorValidator;
if (streamSegmentId == sealedStreamSegmentId) {
errorValidator = ex -> ex instanceof StreamSegmentSealedException;
} else if (streamSegmentId == deletedStreamSegmentId) {
errorValidator = ex -> ex instanceof StreamSegmentNotExistsException;
} else {
errorValidator = ex -> ex instanceof MetadataUpdateException;
}
AssertExtensions.assertThrows("Unexpected exception for failed Operation.", oc.completion::join, errorValidator);
continue;
}
}
// If we get here, we must verify no exception was thrown.
oc.completion.join();
}
performLogOperationChecks(completionFutures, context.memoryLog, dataLog, context.metadata);
performMetadataChecks(streamSegmentIds, streamSegmentsWithNoContents, new HashMap<>(), completionFutures, context.metadata, false, false);
performReadIndexChecks(completionFutures, context.readIndex);
operationProcessor.stopAsync().awaitTerminated();
}
Aggregations