use of io.pravega.controller.stream.api.grpc.v1.Controller.TxnStatus in project pravega by pravega.
the class SegmentHelper method abortTransaction.
public CompletableFuture<TxnStatus> abortTransaction(final String scope, final String stream, final int segmentNumber, final UUID txId, final HostControllerStore hostControllerStore, final ConnectionFactory clientCF, String delegationToken) {
final Controller.NodeUri uri = getSegmentUri(scope, stream, segmentNumber, hostControllerStore);
final CompletableFuture<TxnStatus> result = new CompletableFuture<>();
final WireCommandType type = WireCommandType.ABORT_TRANSACTION;
final FailingReplyProcessor replyProcessor = new FailingReplyProcessor() {
@Override
public void connectionDropped() {
log.warn("abortTransaction {}/{}/{} connectionDropped", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.ConnectionDropped));
}
@Override
public void wrongHost(WireCommands.WrongHost wrongHost) {
log.warn("abortTransaction {}/{}/{} wrongHost", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.UnknownHost));
}
@Override
public void transactionCommitted(WireCommands.TransactionCommitted transactionCommitted) {
log.warn("abortTransaction {}/{}/{} TransactionCommitted", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.PreconditionFailed));
}
@Override
public void transactionAborted(WireCommands.TransactionAborted transactionDropped) {
log.debug("abortTransaction {}/{}/{} transactionAborted", scope, stream, segmentNumber);
result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.SUCCESS).build());
}
@Override
public void noSuchSegment(WireCommands.NoSuchSegment noSuchSegment) {
log.info("abortTransaction {}/{}/{} NoSuchSegment", scope, stream, segmentNumber);
result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.SUCCESS).build());
}
@Override
public void processingFailure(Exception error) {
log.info("abortTransaction {}/{}/{} failed", scope, stream, segmentNumber, error);
result.completeExceptionally(error);
}
@Override
public void authTokenCheckFailed(WireCommands.AuthTokenCheckFailed authTokenCheckFailed) {
result.completeExceptionally(new WireCommandFailedException(new AuthenticationException(authTokenCheckFailed.toString()), type, WireCommandFailedException.Reason.AuthFailed));
}
};
WireCommands.AbortTransaction request = new WireCommands.AbortTransaction(idGenerator.get(), Segment.getScopedName(scope, stream, segmentNumber), txId, delegationToken);
sendRequestAsync(request, replyProcessor, result, clientCF, ModelHelper.encode(uri));
return result;
}
use of io.pravega.controller.stream.api.grpc.v1.Controller.TxnStatus in project pravega by pravega.
the class SegmentHelper method commitTransaction.
public CompletableFuture<TxnStatus> commitTransaction(final String scope, final String stream, final int segmentNumber, final UUID txId, final HostControllerStore hostControllerStore, final ConnectionFactory clientCF, String delegationToken) {
final Controller.NodeUri uri = getSegmentUri(scope, stream, segmentNumber, hostControllerStore);
final CompletableFuture<TxnStatus> result = new CompletableFuture<>();
final WireCommandType type = WireCommandType.COMMIT_TRANSACTION;
final FailingReplyProcessor replyProcessor = new FailingReplyProcessor() {
@Override
public void connectionDropped() {
log.warn("commitTransaction {}/{}/{} connection dropped", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.ConnectionDropped));
}
@Override
public void wrongHost(WireCommands.WrongHost wrongHost) {
log.warn("commitTransaction {}/{}/{} wrongHost", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.UnknownHost));
}
@Override
public void transactionCommitted(WireCommands.TransactionCommitted transactionCommitted) {
log.debug("commitTransaction {}/{}/{} TransactionCommitted", scope, stream, segmentNumber);
result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.SUCCESS).build());
}
@Override
public void transactionAborted(WireCommands.TransactionAborted transactionAborted) {
log.warn("commitTransaction {}/{}/{} Transaction aborted", scope, stream, segmentNumber);
result.completeExceptionally(new WireCommandFailedException(type, WireCommandFailedException.Reason.PreconditionFailed));
}
@Override
public void noSuchSegment(WireCommands.NoSuchSegment noSuchSegment) {
log.info("commitTransaction {}/{}/{} NoSuchSegment", scope, stream, segmentNumber);
result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.SUCCESS).build());
}
@Override
public void processingFailure(Exception error) {
log.error("commitTransaction {}/{}/{} failed", scope, stream, segmentNumber, error);
result.completeExceptionally(error);
}
@Override
public void authTokenCheckFailed(WireCommands.AuthTokenCheckFailed authTokenCheckFailed) {
result.completeExceptionally(new WireCommandFailedException(new AuthenticationException(authTokenCheckFailed.toString()), type, WireCommandFailedException.Reason.AuthFailed));
}
};
WireCommands.CommitTransaction request = new WireCommands.CommitTransaction(idGenerator.get(), Segment.getScopedName(scope, stream, segmentNumber), txId, delegationToken);
sendRequestAsync(request, replyProcessor, result, clientCF, ModelHelper.encode(uri));
return result;
}
use of io.pravega.controller.stream.api.grpc.v1.Controller.TxnStatus in project pravega by pravega.
the class StreamTransactionMetadataTasksTest method failOverTests.
@Test
public void failOverTests() throws CheckpointStoreException, InterruptedException {
// Create mock writer objects.
EventStreamWriterMock<CommitEvent> commitWriter = new EventStreamWriterMock<>();
EventStreamWriterMock<AbortEvent> abortWriter = new EventStreamWriterMock<>();
EventStreamReader<CommitEvent> commitReader = commitWriter.getReader();
EventStreamReader<AbortEvent> abortReader = abortWriter.getReader();
consumer = new ControllerService(streamStore, hostStore, streamMetadataTasks, txnTasks, segmentHelperMock, executor, null);
// Create test scope and stream.
final ScalingPolicy policy1 = ScalingPolicy.fixed(2);
final StreamConfiguration configuration1 = StreamConfiguration.builder().scope(SCOPE).streamName(STREAM).scalingPolicy(policy1).build();
Assert.assertEquals(Controller.CreateScopeStatus.Status.SUCCESS, consumer.createScope(SCOPE).join().getStatus());
Assert.assertEquals(Controller.CreateStreamStatus.Status.SUCCESS, streamMetadataTasks.createStream(SCOPE, STREAM, configuration1, System.currentTimeMillis()).join());
// Set up txn task for creating transactions from a failedHost.
StreamTransactionMetadataTasks failedTxnTasks = new StreamTransactionMetadataTasks(streamStore, hostStore, segmentHelperMock, executor, "failedHost", connectionFactory, false, "");
failedTxnTasks.initializeStreamWriters("commitStream", new EventStreamWriterMock<>(), "abortStream", new EventStreamWriterMock<>());
// Create 3 transactions from failedHost.
VersionedTransactionData tx1 = failedTxnTasks.createTxn(SCOPE, STREAM, 10000, 10000, null).join().getKey();
VersionedTransactionData tx2 = failedTxnTasks.createTxn(SCOPE, STREAM, 10000, 10000, null).join().getKey();
VersionedTransactionData tx3 = failedTxnTasks.createTxn(SCOPE, STREAM, 10000, 10000, null).join().getKey();
// Ping another txn from failedHost.
UUID txnId = UUID.randomUUID();
streamStore.createTransaction(SCOPE, STREAM, txnId, 10000, 30000, 30000, null, executor).join();
PingTxnStatus pingStatus = failedTxnTasks.pingTxn(SCOPE, STREAM, txnId, 10000, null).join();
VersionedTransactionData tx4 = streamStore.getTransactionData(SCOPE, STREAM, txnId, null, executor).join();
// Validate versions of all txn
Assert.assertEquals(0, tx1.getVersion());
Assert.assertEquals(0, tx2.getVersion());
Assert.assertEquals(0, tx3.getVersion());
Assert.assertEquals(1, tx4.getVersion());
Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus());
// Validate the txn index.
Assert.assertEquals(1, streamStore.listHostsOwningTxn().join().size());
// Change state of one txn to COMMITTING.
TxnStatus txnStatus2 = streamStore.sealTransaction(SCOPE, STREAM, tx2.getId(), true, Optional.empty(), null, executor).thenApply(AbstractMap.SimpleEntry::getKey).join();
Assert.assertEquals(TxnStatus.COMMITTING, txnStatus2);
// Change state of another txn to ABORTING.
TxnStatus txnStatus3 = streamStore.sealTransaction(SCOPE, STREAM, tx3.getId(), false, Optional.empty(), null, executor).thenApply(AbstractMap.SimpleEntry::getKey).join();
Assert.assertEquals(TxnStatus.ABORTING, txnStatus3);
// Create transaction tasks for sweeping txns from failedHost.
txnTasks = new StreamTransactionMetadataTasks(streamStore, hostStore, segmentHelperMock, executor, "host", connectionFactory, false, "");
TxnSweeper txnSweeper = new TxnSweeper(streamStore, txnTasks, 100, executor);
// Before initializing, txnSweeper.sweepFailedHosts would throw an error
AssertExtensions.assertThrows("IllegalStateException before initialization", txnSweeper.sweepFailedProcesses(() -> Collections.singleton("host")), ex -> ex instanceof IllegalStateException);
// Initialize stream writers.
txnTasks.initializeStreamWriters("commitStream", commitWriter, "abortStream", abortWriter);
// Validate that txnTasks is ready.
assertTrue(txnTasks.isReady());
// Sweep txns that were being managed by failedHost.
txnSweeper.sweepFailedProcesses(() -> Collections.singleton("host")).join();
// Validate that sweeping completes correctly.
Assert.assertEquals(0, streamStore.listHostsOwningTxn().join().size());
Assert.assertEquals(TxnStatus.ABORTING, streamStore.transactionStatus(SCOPE, STREAM, tx1.getId(), null, executor).join());
Assert.assertEquals(TxnStatus.COMMITTING, streamStore.transactionStatus(SCOPE, STREAM, tx2.getId(), null, executor).join());
Assert.assertEquals(TxnStatus.ABORTING, streamStore.transactionStatus(SCOPE, STREAM, tx3.getId(), null, executor).join());
Assert.assertEquals(TxnStatus.ABORTING, streamStore.transactionStatus(SCOPE, STREAM, tx4.getId(), null, executor).join());
// Create commit and abort event processors.
ConnectionFactory connectionFactory = Mockito.mock(ConnectionFactory.class);
BlockingQueue<CommitEvent> processedCommitEvents = new LinkedBlockingQueue<>();
BlockingQueue<AbortEvent> processedAbortEvents = new LinkedBlockingQueue<>();
createEventProcessor("commitRG", "commitStream", commitReader, commitWriter, () -> new CommitEventProcessor(streamStore, streamMetadataTasks, hostStore, executor, segmentHelperMock, connectionFactory, processedCommitEvents));
createEventProcessor("abortRG", "abortStream", abortReader, abortWriter, () -> new ConcurrentEventProcessor<>(new AbortRequestHandler(streamStore, streamMetadataTasks, hostStore, executor, segmentHelperMock, connectionFactory, processedAbortEvents), executor));
// Wait until the commit event is processed and ensure that the txn state is COMMITTED.
CommitEvent commitEvent = processedCommitEvents.take();
assertEquals(tx2.getId(), commitEvent.getTxid());
assertEquals(TxnStatus.COMMITTED, streamStore.transactionStatus(SCOPE, STREAM, tx2.getId(), null, executor).join());
// Wait until 3 abort events are processed and ensure that the txn state is ABORTED.
Predicate<AbortEvent> predicate = event -> event.getTxid().equals(tx1.getId()) || event.getTxid().equals(tx3.getId()) || event.getTxid().equals(tx4.getId());
AbortEvent abortEvent1 = processedAbortEvents.take();
assertTrue(predicate.test(abortEvent1));
AbortEvent abortEvent2 = processedAbortEvents.take();
assertTrue(predicate.test(abortEvent2));
AbortEvent abortEvent3 = processedAbortEvents.take();
assertTrue(predicate.test(abortEvent3));
assertEquals(TxnStatus.ABORTED, streamStore.transactionStatus(SCOPE, STREAM, tx1.getId(), null, executor).join());
assertEquals(TxnStatus.ABORTED, streamStore.transactionStatus(SCOPE, STREAM, tx3.getId(), null, executor).join());
assertEquals(TxnStatus.ABORTED, streamStore.transactionStatus(SCOPE, STREAM, tx4.getId(), null, executor).join());
}
use of io.pravega.controller.stream.api.grpc.v1.Controller.TxnStatus in project pravega by pravega.
the class TimeoutServiceTest method testTimeoutTaskFailureInvalidVersion.
@Test(timeout = 10000)
public void testTimeoutTaskFailureInvalidVersion() throws InterruptedException {
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, UUID.randomUUID(), LEASE, 10 * LEASE, SCALE_GRACE_PERIOD, null, executor).join();
// Submit transaction to TimeoutService with incorrect tx version identifier.
timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion() + 1, LEASE, txData.getMaxExecutionExpiryTime(), txData.getScaleGracePeriod());
Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (1.25 * LEASE + RETRY_DELAY), TimeUnit.MILLISECONDS);
Assert.assertNotNull(result);
Assert.assertTrue(result.isPresent());
Assert.assertEquals(StoreException.WriteConflictException.class, result.get().getClass());
TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
}
use of io.pravega.controller.stream.api.grpc.v1.Controller.TxnStatus in project pravega by pravega.
the class StreamTransactionMetadataTasksTest method commitAbortTests.
@Test(timeout = 5000)
@SuppressWarnings("unchecked")
public void commitAbortTests() {
// Create mock writer objects.
final List<CompletableFuture<Void>> commitWriterResponses = getWriteResultSequence(5);
final List<CompletableFuture<Void>> abortWriterResponses = getWriteResultSequence(5);
EventStreamWriter<CommitEvent> commitWriter = Mockito.mock(EventStreamWriter.class);
Mockito.when(commitWriter.writeEvent(anyString(), any())).thenAnswer(new SequenceAnswer<>(commitWriterResponses));
EventStreamWriter<AbortEvent> abortWriter = Mockito.mock(EventStreamWriter.class);
Mockito.when(abortWriter.writeEvent(anyString(), any())).thenAnswer(new SequenceAnswer<>(abortWriterResponses));
// Create transaction tasks.
txnTasks = new StreamTransactionMetadataTasks(streamStore, hostStore, segmentHelperMock, executor, "host", connectionFactory, false, "");
txnTasks.initializeStreamWriters("commitStream", commitWriter, "abortStream", abortWriter);
// Create ControllerService.
consumer = new ControllerService(streamStore, hostStore, streamMetadataTasks, txnTasks, segmentHelperMock, executor, null);
final ScalingPolicy policy1 = ScalingPolicy.fixed(2);
final StreamConfiguration configuration1 = StreamConfiguration.builder().scope(SCOPE).streamName(STREAM).scalingPolicy(policy1).build();
// Create stream and scope
Assert.assertEquals(Controller.CreateScopeStatus.Status.SUCCESS, consumer.createScope(SCOPE).join().getStatus());
Assert.assertEquals(Controller.CreateStreamStatus.Status.SUCCESS, streamMetadataTasks.createStream(SCOPE, STREAM, configuration1, 0).join());
// Create 2 transactions
final long lease = 5000;
final long scaleGracePeriod = 10000;
VersionedTransactionData txData1 = txnTasks.createTxn(SCOPE, STREAM, lease, scaleGracePeriod, null).join().getKey();
VersionedTransactionData txData2 = txnTasks.createTxn(SCOPE, STREAM, lease, scaleGracePeriod, null).join().getKey();
// Commit the first one
TxnStatus status = txnTasks.commitTxn(SCOPE, STREAM, txData1.getId(), null).join();
Assert.assertEquals(TxnStatus.COMMITTING, status);
// Abort the second one
status = txnTasks.abortTxn(SCOPE, STREAM, txData2.getId(), txData2.getVersion(), null).join();
Assert.assertEquals(TxnStatus.ABORTING, status);
}
Aggregations