use of io.pravega.segmentstore.contracts.Attributes in project pravega by pravega.
the class StreamSegmentMapperTests method testCreateTransactionAlreadyExists.
/**
* Tests the ability of the StreamSegmentMapper to create a new Transaction if the Transaction already exists (partially
* or fully).
*/
@Test
public void testCreateTransactionAlreadyExists() {
final String parentSegmentName = "NewSegment";
final UUID txnId = UUID.randomUUID();
final String txnName = StreamSegmentNameUtils.getTransactionNameFromId(parentSegmentName, txnId);
testCreateAlreadyExists(txnName, (mapper, attributes) -> mapper.createNewStreamSegment(parentSegmentName, null, TIMEOUT).exceptionally(ex -> {
if (Exceptions.unwrap(ex) instanceof StreamSegmentExistsException) {
return null;
}
throw new CompletionException(ex);
}).thenCompose(v -> mapper.createNewTransactionStreamSegment(parentSegmentName, txnId, attributes, TIMEOUT)));
}
use of io.pravega.segmentstore.contracts.Attributes 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.contracts.Attributes in project pravega by pravega.
the class PravegaRequestProcessor method getSegmentAttribute.
@Override
public void getSegmentAttribute(GetSegmentAttribute getSegmentAttribute) {
long requestId = getSegmentAttribute.getRequestId();
String segmentName = getSegmentAttribute.getSegmentName();
UUID attributeId = getSegmentAttribute.getAttributeId();
if (!verifyToken(segmentName, getSegmentAttribute.getRequestId(), getSegmentAttribute.getDelegationToken(), READ, "Get StreamSegment Attribute")) {
return;
}
long trace = LoggerHelpers.traceEnter(log, "getSegmentAttribute", getSegmentAttribute);
segmentStore.getStreamSegmentInfo(segmentName, false, TIMEOUT).thenAccept(properties -> {
LoggerHelpers.traceLeave(log, "getSegmentAttribute", trace, properties);
if (properties == null) {
connection.send(new NoSuchSegment(requestId, segmentName));
} else {
Map<UUID, Long> attributes = properties.getAttributes();
Long value = attributes.get(attributeId);
if (value == null) {
value = WireCommands.NULL_ATTRIBUTE_VALUE;
}
connection.send(new SegmentAttribute(requestId, value));
}
}).exceptionally(e -> handleException(requestId, segmentName, "Get attribute", e));
}
use of io.pravega.segmentstore.contracts.Attributes in project pravega by pravega.
the class PravegaRequestProcessor method createSegment.
@Override
public void createSegment(CreateSegment createStreamsSegment) {
Timer timer = new Timer();
Collection<AttributeUpdate> attributes = Arrays.asList(new AttributeUpdate(SCALE_POLICY_TYPE, AttributeUpdateType.Replace, ((Byte) createStreamsSegment.getScaleType()).longValue()), new AttributeUpdate(SCALE_POLICY_RATE, AttributeUpdateType.Replace, ((Integer) createStreamsSegment.getTargetRate()).longValue()));
if (!verifyToken(createStreamsSegment.getSegment(), createStreamsSegment.getRequestId(), createStreamsSegment.getDelegationToken(), READ_UPDATE, "Create Segment")) {
return;
}
segmentStore.createStreamSegment(createStreamsSegment.getSegment(), attributes, TIMEOUT).thenAccept(v -> {
createStreamSegment.reportSuccessEvent(timer.getElapsed());
connection.send(new SegmentCreated(createStreamsSegment.getRequestId(), createStreamsSegment.getSegment()));
}).whenComplete((res, e) -> {
if (e == null) {
if (statsRecorder != null) {
statsRecorder.createSegment(createStreamsSegment.getSegment(), createStreamsSegment.getScaleType(), createStreamsSegment.getTargetRate());
}
} else {
createStreamSegment.reportFailEvent(timer.getElapsed());
handleException(createStreamsSegment.getRequestId(), createStreamsSegment.getSegment(), "Create segment", e);
}
});
}
use of io.pravega.segmentstore.contracts.Attributes in project pravega by pravega.
the class PravegaRequestProcessor method createTransaction.
@Override
public void createTransaction(CreateTransaction createTransaction) {
if (!verifyToken(createStreamSegment.getName(), createTransaction.getRequestId(), createTransaction.getDelegationToken(), READ_UPDATE, "Create Transaction")) {
return;
}
Collection<AttributeUpdate> attributes = Collections.singleton(new AttributeUpdate(CREATION_TIME, AttributeUpdateType.None, System.currentTimeMillis()));
log.debug("Creating transaction {} ", createTransaction);
long requestId = createTransaction.getRequestId();
segmentStore.createTransaction(createTransaction.getSegment(), createTransaction.getTxid(), attributes, TIMEOUT).thenAccept(txName -> connection.send(new TransactionCreated(requestId, createTransaction.getSegment(), createTransaction.getTxid()))).exceptionally(e -> handleException(requestId, createTransaction.getSegment(), "Create transaction", e));
}
Aggregations