use of io.pravega.segmentstore.contracts.StreamSegmentInformation in project pravega by pravega.
the class StreamSegmentStoreTestBase method checkStorage.
private static void checkStorage(HashMap<String, ByteArrayOutputStream> segmentContents, StreamSegmentStore readOnlySegmentStore) throws Exception {
for (Map.Entry<String, ByteArrayOutputStream> e : segmentContents.entrySet()) {
String segmentName = e.getKey();
byte[] expectedData = e.getValue().toByteArray();
// 1. Deletion status
StreamSegmentInformation sp = null;
try {
sp = (StreamSegmentInformation) readOnlySegmentStore.getStreamSegmentInfo(segmentName, TIMEOUT).join();
} catch (Exception ex) {
if (!(Exceptions.unwrap(ex) instanceof StreamSegmentNotExistsException)) {
throw ex;
}
}
if (sp == null) {
AssertExtensions.assertSuppliedFutureThrows("Segment is marked as deleted in SegmentStore but was not deleted in Storage " + segmentName, () -> readOnlySegmentStore.getStreamSegmentInfo(segmentName, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
// No need to do other checks.
continue;
}
// 2. Seal Status
StreamSegmentInformation storageProps = (StreamSegmentInformation) readOnlySegmentStore.getStreamSegmentInfo(segmentName, TIMEOUT).join();
Assert.assertEquals("Segment seal status disagree between Store and Storage for segment " + segmentName, sp.isSealed(), storageProps.isSealedInStorage());
// 3. Contents.
StreamSegmentInformation metadataProps = (StreamSegmentInformation) readOnlySegmentStore.getStreamSegmentInfo(segmentName, TIMEOUT).join();
Assert.assertEquals("Unexpected Storage length for segment " + segmentName, expectedData.length, storageProps.getStorageLength());
byte[] actualData = new byte[expectedData.length];
int actualLength = 0;
int expectedLength = actualData.length;
try {
@Cleanup ReadResult readResult = readOnlySegmentStore.read(segmentName, 0, actualData.length, TIMEOUT).join();
actualLength = readResult.readRemaining(actualData, TIMEOUT);
} catch (Exception ex) {
ex = (Exception) Exceptions.unwrap(ex);
if (!(ex instanceof StreamSegmentTruncatedException) || metadataProps.getStartOffset() == 0) {
// We encountered an unexpected Exception, or a Truncated Segment which was not expected to be truncated.
throw ex;
}
// Read from the truncated point, except if the whole segment got truncated.
expectedLength = (int) (storageProps.getLength() - metadataProps.getStartOffset());
if (metadataProps.getStartOffset() < storageProps.getLength()) {
@Cleanup ReadResult readResult = readOnlySegmentStore.read(segmentName, metadataProps.getStartOffset(), expectedLength, TIMEOUT).join();
actualLength = readResult.readRemaining(actualData, TIMEOUT);
}
}
Assert.assertEquals("Unexpected number of bytes read from Storage for segment " + segmentName, expectedLength, actualLength);
AssertExtensions.assertArrayEquals("Unexpected data written to storage for segment " + segmentName, expectedData, expectedData.length - expectedLength, actualData, 0, expectedLength);
}
}
use of io.pravega.segmentstore.contracts.StreamSegmentInformation in project pravega by pravega.
the class StreamSegmentStoreTestBase method waitForSegmentInStorage.
private CompletableFuture<Void> waitForSegmentInStorage(SegmentProperties sp, StreamSegmentStore readOnlyStore) {
if (sp.getLength() == 0) {
// Empty segments may or may not exist in Storage, so don't bother complicating ourselves with this.
return CompletableFuture.completedFuture(null);
}
// We want to make sure that both the main segment and its attribute segment have been sync-ed to Storage. In case
// of the attribute segment, the only thing we can easily do is verify that it has been sealed when the main segment
// it is associated with has also been sealed.
String attributeSegmentName = NameUtils.getAttributeSegmentName(sp.getName());
TimeoutTimer timer = new TimeoutTimer(TIMEOUT);
AtomicBoolean tryAgain = new AtomicBoolean(true);
return Futures.loop(tryAgain::get, () -> {
val segInfo = getStorageSegmentInfo(sp.getName(), timer, readOnlyStore);
val attrInfo = getStorageSegmentInfo(attributeSegmentName, timer, readOnlyStore);
return CompletableFuture.allOf(segInfo, attrInfo).thenCompose(v -> {
StreamSegmentInformation storageProps = (StreamSegmentInformation) segInfo.join();
StreamSegmentInformation attrProps = (StreamSegmentInformation) attrInfo.join();
if (sp.isDeleted()) {
tryAgain.set(!storageProps.isDeletedInStorage());
} else if (sp.isSealed()) {
tryAgain.set(!storageProps.isSealedInStorage());
} else {
tryAgain.set(sp.getLength() != storageProps.getStorageLength());
}
if (tryAgain.get() && !timer.hasRemaining()) {
return Futures.<Void>failedFuture(new TimeoutException(String.format("Segment %s did not complete in Storage in the allotted time. %s ", sp.getName(), segInfo)));
} else {
return Futures.delayedFuture(Duration.ofMillis(100), executorService());
}
});
}, executorService());
}
use of io.pravega.segmentstore.contracts.StreamSegmentInformation in project pravega by pravega.
the class StreamSegmentStorageReader method read.
/**
* Reads a range of bytes from a Segment in Storage.
*
* @param handle A SegmentHandle pointing to the Segment to read from.
* @param startOffset The first offset within the Segment to read from.
* @param maxReadLength The maximum number of bytes to read.
* @param readBlockSize The maximum number of bytes to read at once (the returned StreamSegmentReadResult will be
* broken down into Entries smaller than or equal to this size).
* @param storage A ReadOnlyStorage to execute the reads against.
* @return A StreamSegmentReadResult that can be used to process the data. This will be made up of ReadResultEntries
* of the following types: Storage, Truncated or EndOfSegment.
*/
public static StreamSegmentReadResult read(SegmentHandle handle, long startOffset, int maxReadLength, int readBlockSize, ReadOnlyStorage storage) {
Exceptions.checkArgument(startOffset >= 0, "startOffset", "startOffset must be a non-negative number.");
Exceptions.checkArgument(maxReadLength >= 0, "maxReadLength", "maxReadLength must be a non-negative number.");
Preconditions.checkNotNull(handle, "handle");
Preconditions.checkNotNull(storage, "storage");
String traceId = String.format("Read[%s]", handle.getSegmentName());
// Build a SegmentInfo using the information we are given. If startOffset or length are incorrect, the underlying
// ReadOnlyStorage will throw appropriate exceptions at the caller.
StreamSegmentInformation segmentInfo = StreamSegmentInformation.builder().name(handle.getSegmentName()).startOffset(startOffset).length(startOffset + maxReadLength).build();
return new StreamSegmentReadResult(startOffset, maxReadLength, new SegmentReader(segmentInfo, handle, readBlockSize, storage), traceId);
}
Aggregations