use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testWithBadAttributes.
private void testWithBadAttributes(Function<Collection<AttributeUpdate>, Operation> createOperation) throws Exception {
final UUID attributeNoUpdate = UUID.randomUUID();
final UUID attributeReplaceIfGreater = UUID.randomUUID();
final UUID attributeReplaceIfEquals = UUID.randomUUID();
UpdateableContainerMetadata metadata = createMetadata();
val txn = createUpdateTransaction(metadata);
// Append #1.
Collection<AttributeUpdate> attributeUpdates = new ArrayList<>();
// Initial add, so it's ok.
attributeUpdates.add(new AttributeUpdate(attributeNoUpdate, AttributeUpdateType.None, 2));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 2));
// Initial Add.
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.Replace, 2));
val expectedValues = attributeUpdates.stream().collect(Collectors.toMap(AttributeUpdate::getAttributeId, AttributeUpdate::getValue));
Operation op = createOperation.apply(attributeUpdates);
txn.preProcessOperation(op);
txn.acceptOperation(op);
// Append #2: Try to update attribute that cannot be updated.
attributeUpdates.clear();
attributeUpdates.add(new AttributeUpdate(attributeNoUpdate, AttributeUpdateType.None, 3));
AssertExtensions.assertThrows("preProcessOperation accepted an operation that was trying to update an unmodifiable attribute.", () -> txn.preProcessOperation(createOperation.apply(attributeUpdates)), ex -> ex instanceof BadAttributeUpdateException);
// Append #3: Try to update attribute with bad value for ReplaceIfGreater attribute.
attributeUpdates.clear();
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 1));
AssertExtensions.assertThrows("preProcessOperation accepted an operation that was trying to update an attribute with the wrong value for ReplaceIfGreater.", () -> txn.preProcessOperation(createOperation.apply(attributeUpdates)), ex -> ex instanceof BadAttributeUpdateException);
// Append #4: Try to update attribute with bad value for ReplaceIfEquals attribute.
attributeUpdates.clear();
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.ReplaceIfEquals, 3, 3));
AssertExtensions.assertThrows("preProcessOperation accepted an operation that was trying to update an attribute with the wrong comparison value for ReplaceIfGreater.", () -> txn.preProcessOperation(createOperation.apply(attributeUpdates)), ex -> ex instanceof BadAttributeUpdateException);
// Reset the attribute update list to its original state so we can do the final verification.
attributeUpdates.clear();
attributeUpdates.add(new AttributeUpdate(attributeNoUpdate, AttributeUpdateType.None, 2));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 2));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.ReplaceIfGreater, 2, 2));
verifyAttributeUpdates("after rejected operations", txn, attributeUpdates, expectedValues);
txn.commit(metadata);
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes in segment metadata after commit.", expectedValues, metadata.getStreamSegmentMetadata(SEGMENT_ID));
}
use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testWithAttributes.
private void testWithAttributes(Function<Collection<AttributeUpdate>, Operation> createOperation) throws Exception {
final UUID attributeNoUpdate = UUID.randomUUID();
final UUID attributeAccumulate = UUID.randomUUID();
final UUID attributeReplace = UUID.randomUUID();
final UUID attributeReplaceIfGreater = UUID.randomUUID();
final UUID attributeReplaceIfEquals = UUID.randomUUID();
UpdateableContainerMetadata metadata = createMetadata();
val txn = createUpdateTransaction(metadata);
// Update #1.
Collection<AttributeUpdate> attributeUpdates = new ArrayList<>();
// Initial add, so it's ok.
attributeUpdates.add(new AttributeUpdate(attributeNoUpdate, AttributeUpdateType.None, 1));
attributeUpdates.add(new AttributeUpdate(attributeAccumulate, AttributeUpdateType.Accumulate, 1));
attributeUpdates.add(new AttributeUpdate(attributeReplace, AttributeUpdateType.Replace, 1));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 1));
// Need to initialize to something.
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.Replace, 1));
val expectedValues = attributeUpdates.stream().collect(Collectors.toMap(AttributeUpdate::getAttributeId, AttributeUpdate::getValue));
Operation op = createOperation.apply(attributeUpdates);
txn.preProcessOperation(op);
txn.acceptOperation(op);
// Verify that the AttributeUpdates still have the same values (there was nothing there prior) and that the updater
// has internalized the attribute updates.
verifyAttributeUpdates("after acceptOperation (1)", txn, attributeUpdates, expectedValues);
// Update #2: update all attributes that can be updated.
attributeUpdates.clear();
// 1 + 1 = 2
attributeUpdates.add(new AttributeUpdate(attributeAccumulate, AttributeUpdateType.Accumulate, 1));
attributeUpdates.add(new AttributeUpdate(attributeReplace, AttributeUpdateType.Replace, 2));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 2));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.ReplaceIfEquals, 2, 1));
expectedValues.put(attributeAccumulate, 2L);
expectedValues.put(attributeReplace, 2L);
expectedValues.put(attributeReplaceIfGreater, 2L);
expectedValues.put(attributeReplaceIfEquals, 2L);
op = createOperation.apply(attributeUpdates);
txn.preProcessOperation(op);
txn.acceptOperation(op);
// This is still in the transaction, so we need to add it for comparison sake.
attributeUpdates.add(new AttributeUpdate(attributeNoUpdate, AttributeUpdateType.None, 1));
verifyAttributeUpdates("after acceptOperation (2)", txn, attributeUpdates, expectedValues);
// Update #3: after commit, verify that attributes are committed when they need to.
val previousAcceptedValues = new HashMap<UUID, Long>(expectedValues);
txn.commit(metadata);
attributeUpdates.clear();
// 2 + 1 = 3
attributeUpdates.add(new AttributeUpdate(attributeAccumulate, AttributeUpdateType.Accumulate, 1));
attributeUpdates.add(new AttributeUpdate(attributeReplace, AttributeUpdateType.Replace, 3));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfGreater, AttributeUpdateType.ReplaceIfGreater, 3));
attributeUpdates.add(new AttributeUpdate(attributeReplaceIfEquals, AttributeUpdateType.ReplaceIfEquals, 3, 2));
expectedValues.put(attributeAccumulate, 3L);
expectedValues.put(attributeReplace, 3L);
expectedValues.put(attributeReplaceIfGreater, 3L);
expectedValues.put(attributeReplaceIfEquals, 3L);
op = createOperation.apply(attributeUpdates);
txn.preProcessOperation(op);
txn.acceptOperation(op);
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes in segment metadata after commit+acceptOperation, but prior to second commit.", previousAcceptedValues, metadata.getStreamSegmentMetadata(SEGMENT_ID));
verifyAttributeUpdates("after commit+acceptOperation", txn, attributeUpdates, expectedValues);
// Final step: commit Append #3, and verify final segment metadata.
txn.commit(metadata);
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes in segment metadata after final commit.", expectedValues, metadata.getStreamSegmentMetadata(SEGMENT_ID));
}
use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.
the class AppendProcessor method storeAppend.
private CompletableFuture<Long> storeAppend(Append append, long lastEventNumber) {
AttributeUpdateCollection attributes = AttributeUpdateCollection.from(new AttributeUpdate(AttributeId.fromUUID(append.getWriterId()), AttributeUpdateType.ReplaceIfEquals, append.getEventNumber(), lastEventNumber), new AttributeUpdate(EVENT_COUNT, AttributeUpdateType.Accumulate, append.getEventCount()));
ByteBufWrapper buf = new ByteBufWrapper(append.getData());
if (append.isConditional()) {
return store.append(append.getSegment(), append.getExpectedLength(), buf, attributes, TIMEOUT);
} else {
return store.append(append.getSegment(), buf, attributes, TIMEOUT);
}
}
use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.
the class StorageWriterTests method generateAttributeUpdates.
private AttributeUpdateCollection generateAttributeUpdates(UpdateableSegmentMetadata segmentMetadata) {
long coreAttributeValue = segmentMetadata.getAttributes().getOrDefault(CORE_ATTRIBUTE_ID, 0L) + 1;
val attributeUpdates = new AttributeUpdateCollection();
attributeUpdates.add(new AttributeUpdate(CORE_ATTRIBUTE_ID, AttributeUpdateType.Accumulate, coreAttributeValue));
for (int i = 0; i < EXTENDED_ATTRIBUTE_IDS.size(); i++) {
AttributeId id = EXTENDED_ATTRIBUTE_IDS.get(i);
long extendedAttributeValue = segmentMetadata.getAttributes().getOrDefault(id, 0L) + 13 + i;
attributeUpdates.add(new AttributeUpdate(id, AttributeUpdateType.Replace, extendedAttributeValue));
}
segmentMetadata.updateAttributes(attributeUpdates.stream().collect(Collectors.toMap(AttributeUpdate::getAttributeId, AttributeUpdate::getValue)));
return attributeUpdates;
}
use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.
the class AttributeAggregatorTests method generateUpdateAttributesAndUpdateMetadata.
private UpdateAttributesOperation generateUpdateAttributesAndUpdateMetadata(int attributeCount, TestContext context) {
Assert.assertTrue(attributeCount <= EXTENDED_ATTRIBUTE_IDS.size());
long coreAttributeValue = context.segmentMetadata.getAttributes().getOrDefault(CORE_ATTRIBUTE_ID, 0L) + 1;
val attributeUpdates = new AttributeUpdateCollection();
// Always add a Core Attribute - this should be ignored.
attributeUpdates.add(new AttributeUpdate(CORE_ATTRIBUTE_ID, AttributeUpdateType.Accumulate, coreAttributeValue));
val usedIndices = new HashSet<Integer>();
for (int i = 0; i < attributeCount; i++) {
int attributeIndex;
do {
attributeIndex = context.random.nextInt(EXTENDED_ATTRIBUTE_IDS.size());
} while (usedIndices.contains(attributeIndex));
usedIndices.add(attributeIndex);
attributeUpdates.add(new AttributeUpdate(EXTENDED_ATTRIBUTE_IDS.get(attributeIndex), AttributeUpdateType.Replace, context.random.nextLong()));
}
context.segmentMetadata.updateAttributes(attributeUpdates.stream().collect(Collectors.toMap(AttributeUpdate::getAttributeId, AttributeUpdate::getValue)));
UpdateAttributesOperation op = new UpdateAttributesOperation(context.segmentMetadata.getId(), attributeUpdates);
op.setSequenceNumber(context.containerMetadata.nextOperationSequenceNumber());
return op;
}
Aggregations