use of io.pravega.shared.protocol.netty.WireCommands.AuthTokenCheckFailed in project pravega by pravega.
the class LargeEventWriterTest method testRetriedErrors.
@Test(timeout = 5000)
public void testRetriedErrors() throws ConnectionFailedException, NoSuchSegmentException, AuthenticationException, SegmentSealedException {
Segment segment = Segment.fromScopedName("foo/bar/1");
MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
MockController controller = new MockController("localhost", 0, connectionFactory, false);
ClientConnection connection = Mockito.mock(ClientConnection.class);
PravegaNodeUri location = new PravegaNodeUri("localhost", 0);
connectionFactory.provideConnection(location, connection);
EmptyTokenProviderImpl tokenProvider = new EmptyTokenProviderImpl();
ArrayList<ByteBuffer> events = new ArrayList<>();
events.add(ByteBuffer.allocate(1));
AtomicBoolean failed = new AtomicBoolean(false);
AtomicBoolean succeeded = new AtomicBoolean(false);
answerRequest(connectionFactory, connection, location, SetupAppend.class, r -> new AppendSetup(r.getRequestId(), segment.getScopedName(), r.getWriterId(), WireCommands.NULL_ATTRIBUTE_VALUE));
answerRequest(connectionFactory, connection, location, ConditionalBlockEnd.class, r -> {
ByteBuf data = r.getData();
return new DataAppended(r.getRequestId(), r.getWriterId(), r.getEventNumber(), r.getEventNumber() - 1, r.getExpectedOffset() + data.readableBytes());
});
answerRequest(connectionFactory, connection, location, MergeSegments.class, r -> {
return new SegmentsMerged(r.getRequestId(), r.getSource(), r.getTarget(), -1);
});
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
failed.set(true);
connectionFactory.getProcessor(location).process(new AuthTokenCheckFailed(argument.getRequestId(), "stacktrace", ErrorCode.TOKEN_EXPIRED));
return null;
}
}).doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
succeeded.set(true);
connectionFactory.getProcessor(location).process(new SegmentCreated(argument.getRequestId(), "transient-segment"));
return null;
}
}).when(connection).send(any(CreateTransientSegment.class));
LargeEventWriter writer = new LargeEventWriter(writerId, controller, connectionFactory);
writer.writeLargeEvent(segment, events, tokenProvider, EventWriterConfig.builder().build());
assertTrue(failed.getAndSet(false));
assertTrue(succeeded.getAndSet(false));
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
failed.set(true);
connectionFactory.getProcessor(location).process(new WrongHost(argument.getRequestId(), "foo/bar/1", null, "stacktrace"));
return null;
}
}).doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
succeeded.set(true);
connectionFactory.getProcessor(location).process(new SegmentCreated(argument.getRequestId(), "transient-segment"));
return null;
}
}).when(connection).send(any(CreateTransientSegment.class));
writer = new LargeEventWriter(writerId, controller, connectionFactory);
writer.writeLargeEvent(segment, events, tokenProvider, EventWriterConfig.builder().build());
assertTrue(failed.getAndSet(false));
assertTrue(succeeded.getAndSet(false));
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
failed.set(true);
connectionFactory.getProcessor(location).processingFailure(new ConnectionFailedException());
return null;
}
}).doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
CreateTransientSegment argument = (CreateTransientSegment) invocation.getArgument(0);
succeeded.set(true);
connectionFactory.getProcessor(location).process(new SegmentCreated(argument.getRequestId(), "transient-segment"));
return null;
}
}).when(connection).send(any(CreateTransientSegment.class));
writer = new LargeEventWriter(writerId, controller, connectionFactory);
writer.writeLargeEvent(segment, events, tokenProvider, EventWriterConfig.builder().build());
assertTrue(failed.getAndSet(false));
assertTrue(succeeded.getAndSet(false));
}
use of io.pravega.shared.protocol.netty.WireCommands.AuthTokenCheckFailed in project pravega by pravega.
the class PravegaRequestProcessor method handleException.
private Void handleException(long requestId, String segment, long offset, String operation, Throwable u) {
if (u == null) {
IllegalStateException exception = new IllegalStateException("No exception to handle.");
log.error(requestId, "Error (Segment = '{}', Operation = '{}')", segment, operation, exception);
throw exception;
}
u = Exceptions.unwrap(u);
String clientReplyStackTrace = replyWithStackTraceOnError ? Throwables.getStackTraceAsString(u) : EMPTY_STACK_TRACE;
final Consumer<Throwable> failureHandler = t -> {
log.error(requestId, "Error (Segment = '{}', Operation = '{}')", segment, "handling result of " + operation, t);
connection.close();
};
if (u instanceof StreamSegmentExistsException) {
log.info(requestId, "Segment '{}' already exists and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new SegmentAlreadyExists(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof StreamSegmentNotExistsException) {
log.warn(requestId, "Segment '{}' does not exist and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new NoSuchSegment(requestId, segment, clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof StreamSegmentSealedException) {
log.info(requestId, "Segment '{}' is sealed and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new SegmentIsSealed(requestId, segment, clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof ContainerNotFoundException) {
int containerId = ((ContainerNotFoundException) u).getContainerId();
log.warn(requestId, "Wrong host. Segment = '{}' (Container {}) is not owned. Operation = '{}').", segment, containerId, operation);
invokeSafely(connection::send, new WrongHost(requestId, segment, "", clientReplyStackTrace), failureHandler);
} else if (u instanceof ReadCancellationException) {
log.info(requestId, "Sending empty response on connection {} while reading segment {} due to CancellationException.", connection, segment);
invokeSafely(connection::send, new SegmentRead(segment, offset, true, false, EMPTY_BUFFER, requestId), failureHandler);
} else if (u instanceof CancellationException) {
log.info(requestId, "Closing connection {} while performing {} due to {}.", connection, operation, u.toString());
connection.close();
} else if (u instanceof TokenExpiredException) {
log.warn(requestId, "Expired token during operation {}", operation);
invokeSafely(connection::send, new AuthTokenCheckFailed(requestId, clientReplyStackTrace, AuthTokenCheckFailed.ErrorCode.TOKEN_EXPIRED), failureHandler);
} else if (u instanceof TokenException) {
log.warn(requestId, "Token exception encountered during operation {}.", operation, u);
invokeSafely(connection::send, new AuthTokenCheckFailed(requestId, clientReplyStackTrace, AuthTokenCheckFailed.ErrorCode.TOKEN_CHECK_FAILED), failureHandler);
} else if (u instanceof UnsupportedOperationException) {
log.warn(requestId, "Unsupported Operation '{}'.", operation, u);
invokeSafely(connection::send, new OperationUnsupported(requestId, operation, clientReplyStackTrace), failureHandler);
} else if (u instanceof BadOffsetException) {
BadOffsetException badOffset = (BadOffsetException) u;
log.info(requestId, "Segment '{}' is truncated and cannot perform operation '{}' at offset '{}'", segment, operation, offset);
invokeSafely(connection::send, new SegmentIsTruncated(requestId, segment, badOffset.getExpectedOffset(), clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof TableSegmentNotEmptyException) {
log.warn(requestId, "Table segment '{}' is not empty to perform '{}'.", segment, operation);
invokeSafely(connection::send, new TableSegmentNotEmpty(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof KeyNotExistsException) {
log.warn(requestId, "Conditional update on Table segment '{}' failed as the key does not exist.", segment);
invokeSafely(connection::send, new WireCommands.TableKeyDoesNotExist(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof BadKeyVersionException) {
log.warn(requestId, "Conditional update on Table segment '{}' failed due to bad key version.", segment);
invokeSafely(connection::send, new WireCommands.TableKeyBadVersion(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (errorCodeExists(u)) {
log.warn(requestId, "Operation on segment '{}' failed due to a {}.", segment, u.getClass());
invokeSafely(connection::send, new WireCommands.ErrorMessage(requestId, segment, u.getMessage(), WireCommands.ErrorMessage.ErrorCode.valueOf(u.getClass())), failureHandler);
} else {
logError(requestId, segment, operation, u);
// Closing connection should reinitialize things, and hopefully fix the problem
connection.close();
throw new IllegalStateException("Unknown exception.", u);
}
return null;
}
use of io.pravega.shared.protocol.netty.WireCommands.AuthTokenCheckFailed in project pravega by pravega.
the class ConditionalOutputStreamImpl method handleUnexpectedReply.
@VisibleForTesting
RuntimeException handleUnexpectedReply(Reply reply, String expectation) {
log.warn("Unexpected reply {} observed instead of {} for conditional writer {}", reply, expectation, writerId);
closeConnection(reply.toString());
if (reply instanceof WireCommands.NoSuchSegment) {
throw new NoSuchSegmentException(reply.toString());
} else if (reply instanceof SegmentIsSealed) {
throw Exceptions.sneakyThrow(new SegmentSealedException(reply.toString()));
} else if (reply instanceof WrongHost) {
throw Exceptions.sneakyThrow(new ConnectionFailedException(reply.toString()));
} else if (reply instanceof InvalidEventNumber) {
InvalidEventNumber ien = (InvalidEventNumber) reply;
throw Exceptions.sneakyThrow(new ConnectionFailedException(ien.getWriterId() + " Got stale data from setupAppend on segment " + segmentId + " for ConditionalOutputStream. Event number was " + ien.getEventNumber()));
} else if (reply instanceof AuthTokenCheckFailed) {
AuthTokenCheckFailed authTokenCheckFailed = (WireCommands.AuthTokenCheckFailed) reply;
if (authTokenCheckFailed.isTokenExpired()) {
this.tokenProvider.signalTokenExpired();
throw Exceptions.sneakyThrow(new TokenExpiredException(authTokenCheckFailed.getServerStackTrace()));
} else {
throw Exceptions.sneakyThrow(new AuthenticationException(authTokenCheckFailed.toString()));
}
} else {
throw Exceptions.sneakyThrow(new ConnectionFailedException("Unexpected reply of " + reply + " when expecting an " + expectation));
}
}
Aggregations