use of io.pravega.segmentstore.contracts.BadAttributeUpdateException in project pravega by pravega.
the class AppendProcessor method handleException.
private void handleException(UUID writerId, long requestId, String segment, String doingWhat, Throwable u) {
if (u == null) {
IllegalStateException exception = new IllegalStateException("No exception to handle.");
log.error("Append processor: Error {} on segment = '{}'", doingWhat, segment, exception);
throw exception;
}
u = Exceptions.unwrap(u);
if (u instanceof StreamSegmentExistsException) {
log.warn("Segment '{}' already exists and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
connection.send(new SegmentAlreadyExists(requestId, segment));
} else if (u instanceof StreamSegmentNotExistsException) {
log.warn("Segment '{}' does not exist and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
connection.send(new NoSuchSegment(requestId, segment));
} else if (u instanceof StreamSegmentSealedException) {
log.info("Segment '{}' is sealed and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
connection.send(new SegmentIsSealed(requestId, segment));
} else if (u instanceof ContainerNotFoundException) {
int containerId = ((ContainerNotFoundException) u).getContainerId();
log.warn("Wrong host. Segment '{}' (Container {}) is not owned and {} cannot perform operation '{}'.", segment, containerId, writerId, doingWhat);
connection.send(new WrongHost(requestId, segment, ""));
} else if (u instanceof BadAttributeUpdateException) {
log.warn("Bad attribute update by {} on segment {}.", writerId, segment, u);
connection.send(new InvalidEventNumber(writerId, requestId));
connection.close();
} else if (u instanceof TooManyAttributesException) {
log.warn("Attribute limit would be exceeded by {} on segment {}.", writerId, segment, u);
connection.send(new InvalidEventNumber(writerId, requestId));
connection.close();
} else if (u instanceof AuthenticationException) {
log.warn("Token check failed while being written by {} on segment {}.", writerId, segment, u);
connection.send(new WireCommands.AuthTokenCheckFailed(requestId));
connection.close();
} else if (u instanceof UnsupportedOperationException) {
log.warn("Unsupported Operation '{}'.", doingWhat, u);
connection.send(new OperationUnsupported(requestId, doingWhat));
} else {
log.error("Error (Segment = '{}', Operation = 'append')", segment, u);
// Closing connection should reinitialize things, and hopefully fix the problem
connection.close();
}
}
use of io.pravega.segmentstore.contracts.BadAttributeUpdateException in project pravega by pravega.
the class PravegaRequestProcessor method updateSegmentAttribute.
@Override
public void updateSegmentAttribute(UpdateSegmentAttribute updateSegmentAttribute) {
long requestId = updateSegmentAttribute.getRequestId();
String segmentName = updateSegmentAttribute.getSegmentName();
UUID attributeId = updateSegmentAttribute.getAttributeId();
long newValue = updateSegmentAttribute.getNewValue();
long expectedValue = updateSegmentAttribute.getExpectedValue();
if (!verifyToken(segmentName, updateSegmentAttribute.getRequestId(), updateSegmentAttribute.getDelegationToken(), READ, "Update Segment Attribute")) {
return;
}
long trace = LoggerHelpers.traceEnter(log, "updateSegmentAttribute", updateSegmentAttribute);
val update = new AttributeUpdate(attributeId, AttributeUpdateType.ReplaceIfEquals, newValue, expectedValue);
segmentStore.updateAttributes(segmentName, Collections.singletonList(update), TIMEOUT).whenComplete((v, e) -> {
LoggerHelpers.traceLeave(log, "updateSegmentAttribute", trace, e);
if (e == null) {
connection.send(new SegmentAttributeUpdated(requestId, true));
} else {
if (Exceptions.unwrap(e) instanceof BadAttributeUpdateException) {
log.debug("Updating segment attribute {} failed due to: {}", update, e.getMessage());
connection.send(new SegmentAttributeUpdated(requestId, false));
} else {
handleException(requestId, segmentName, "Update attribute", e);
}
}
}).exceptionally(e -> handleException(requestId, segmentName, "Update attribute", e));
}
use of io.pravega.segmentstore.contracts.BadAttributeUpdateException in project pravega by pravega.
the class SegmentMetadataUpdateTransaction method preProcessAttributes.
/**
* Pre-processes a collection of attributes.
* After this method returns, all AttributeUpdates in the given collection will have the actual (and updated) value
* of that attribute in the Segment.
*
* @param attributeUpdates The Updates to process (if any).
* @throws BadAttributeUpdateException If any of the given AttributeUpdates is invalid given the current state of
* the segment.
* @throws TooManyAttributesException If, as a result of applying the given updates, the Segment would exceed the
* maximum allowed number of Attributes.
*/
private void preProcessAttributes(Collection<AttributeUpdate> attributeUpdates) throws BadAttributeUpdateException, TooManyAttributesException {
if (attributeUpdates == null) {
return;
}
int newAttributeCount = this.attributeValues.size();
for (AttributeUpdate u : attributeUpdates) {
AttributeUpdateType updateType = u.getUpdateType();
long previousValue = this.attributeValues.getOrDefault(u.getAttributeId(), SegmentMetadata.NULL_ATTRIBUTE_VALUE);
// Perform validation, and set the AttributeUpdate.value to the updated value, if necessary.
switch(updateType) {
case ReplaceIfGreater:
// Verify value against existing value, if any.
boolean hasValue = previousValue != SegmentMetadata.NULL_ATTRIBUTE_VALUE;
if (hasValue && u.getValue() <= previousValue) {
throw new BadAttributeUpdateException(this.name, u, String.format("Expected greater than '%s'.", previousValue));
}
break;
case ReplaceIfEquals:
// Verify value against existing value, if any.
if (u.getComparisonValue() != previousValue) {
throw new BadAttributeUpdateException(this.name, u, String.format("Expected existing value to be '%s', actual '%s'.", u.getComparisonValue(), previousValue));
}
break;
case None:
// Verify value is not already set.
if (previousValue != SegmentMetadata.NULL_ATTRIBUTE_VALUE) {
throw new BadAttributeUpdateException(this.name, u, String.format("Attribute value already set (%s).", previousValue));
}
break;
case Accumulate:
if (previousValue != SegmentMetadata.NULL_ATTRIBUTE_VALUE) {
u.setValue(previousValue + u.getValue());
}
break;
case Replace:
break;
default:
throw new BadAttributeUpdateException(this.name, u, "Unexpected update type: " + updateType);
}
if (previousValue == SegmentMetadata.NULL_ATTRIBUTE_VALUE && u.getValue() != SegmentMetadata.NULL_ATTRIBUTE_VALUE) {
// This attribute did not exist and is about to be added.
newAttributeCount++;
} else if (previousValue != SegmentMetadata.NULL_ATTRIBUTE_VALUE && u.getValue() == SegmentMetadata.NULL_ATTRIBUTE_VALUE) {
// This attribute existed and is about to be removed.
newAttributeCount--;
}
}
if (newAttributeCount > SegmentMetadata.MAXIMUM_ATTRIBUTE_COUNT && newAttributeCount > this.attributeValues.size()) {
// attributes of existing segments, but not increase their count.
throw new TooManyAttributesException(this.name, SegmentMetadata.MAXIMUM_ATTRIBUTE_COUNT);
}
}
use of io.pravega.segmentstore.contracts.BadAttributeUpdateException 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));
}
Aggregations