processor.mergeSegments(new WireCommands.MergeSegments(4, streamSegmentName, transactionName, "")); order.verify(connection).send(new WireCommands.NoSuchSegment(4, StreamSegmentNameUtils.getTransactionNameFromId(streamSegmentName, txnid), ""));
@Override public void noSuchSegment(NoSuchSegment noSuchSegment) { final String segment = noSuchSegment.getSegment(); if (StreamSegmentNameUtils.isTransactionSegment(segment)) { log.info("Transaction Segment: {} no longer exists since the txn is aborted. {}", noSuchSegment.getSegment(), noSuchSegment.getServerStackTrace()); //close the connection and update the exception to SegmentSealed. state.failConnection(new SegmentSealedException(segment)); } else { state.failConnection(new NoSuchSegmentException(segment)); log.info("Segment being written to {} by writer {} no longer exists due to Stream Truncation, resending to the newer segment. {}", noSuchSegment.getSegment(), writerId, noSuchSegment.getServerStackTrace()); invokeResendCallBack(noSuchSegment); } }
@Override public void noSuchSegment(WireCommands.NoSuchSegment noSuchSegment) { log.info("Received noSuchSegment {}", noSuchSegment); CompletableFuture<SegmentRead> future = grabFuture(noSuchSegment.getSegment(), noSuchSegment.getRequestId()); if (future != null) { future.completeExceptionally(new SegmentTruncatedException("Segment no longer exists.")); } }
log.warn(requestId, "Segment '{}' does not exist and cannot perform operation '{}'.", segment, operation); invokeSafely(connection::send, new NoSuchSegment(requestId, segment, clientReplyStackTrace), failureHandler); } else if (u instanceof StreamSegmentSealedException) { log.info(requestId, "Segment '{}' is sealed and cannot perform operation '{}'.",
processor.getStreamSegmentInfo(new WireCommands.GetStreamSegmentInfo(4, transactionName, "")); order.verify(connection) .send(new WireCommands.NoSuchSegment(4, StreamSegmentNameUtils.getTransactionNameFromId(streamSegmentName, txnid), "")); processor.getStreamSegmentInfo(new WireCommands.GetStreamSegmentInfo(4, transactionName, "")); order.verify(connection) .send(new WireCommands.NoSuchSegment(4, StreamSegmentNameUtils.getTransactionNameFromId(streamSegmentName, txnid), "")); processor.getStreamSegmentInfo(new WireCommands.GetStreamSegmentInfo(4, transactionName, "")); order.verify(connection) .send(new WireCommands.NoSuchSegment(4, StreamSegmentNameUtils.getTransactionNameFromId(streamSegmentName, txnid), ""));
} else if (u instanceof StreamSegmentNotExistsException) { log.warn("Segment '{}' does not exist and {} cannot perform operation '{}'.", segment, writerId, doingWhat); connection.send(new NoSuchSegment(requestId, segment, clientReplyStackTrace)); } else if (u instanceof StreamSegmentSealedException) { log.info("Segment '{}' is sealed and {} cannot perform operation '{}'.", segment, writerId, doingWhat);
@Test(timeout = 10000) public void testFlushDuringTransactionAbort() throws Exception { UUID cid = UUID.randomUUID(); PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT); MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl(); cf.setExecutor(executorService()); MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf); ClientConnection connection = mock(ClientConnection.class); cf.provideConnection(uri, connection); InOrder order = Mockito.inOrder(connection); SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(TXN_SEGMENT, controller, cf, cid, segmentSealedCallback, RETRY_SCHEDULE, ""); output.reconnect(); order.verify(connection).send(new SetupAppend(1, cid, TXN_SEGMENT, "")); cf.getProcessor(uri).appendSetup(new AppendSetup(1, TXN_SEGMENT, cid, 0)); ByteBuffer data = getBuffer("test"); // Write an Event. CompletableFuture<Void> ack = new CompletableFuture<>(); output.write(PendingEvent.withoutHeader(null, data, ack)); order.verify(connection).send(new Append(TXN_SEGMENT, cid, 1, 1, Unpooled.wrappedBuffer(data), null)); assertFalse(ack.isDone()); //writer is not complete until a response from Segment Store is received. // Validate that flush() is blocking until there is a response from Segment Store. AssertExtensions.assertBlocks(() -> { // A flush() should throw a SegmentSealedException. AssertExtensions.assertThrows(SegmentSealedException.class, () -> output.flush()); }, () -> { // Simulate a NoSuchSegment response from SegmentStore due to a Transaction abort. cf.getProcessor(uri).noSuchSegment(new WireCommands.NoSuchSegment(1, TXN_SEGMENT, "SomeException")); }); AssertExtensions.assertThrows(SegmentSealedException.class, () -> output.flush()); }
cf.getProcessor(uri).noSuchSegment(new WireCommands.NoSuchSegment(1, TXN_SEGMENT, "SomeException"));
@Test public void testDeleteTableSegment() { MockConnectionFactory factory = new MockConnectionFactory(); // On receiving NoSuchSegment true should be returned. CompletableFuture<Boolean> result = helper.deleteTableSegment("", "", true, new MockHostControllerStore(), factory, "", System.nanoTime()); factory.rp.noSuchSegment(new WireCommands.NoSuchSegment(0, getQualifiedStreamSegmentName("", "", 0L), "")); assertTrue(result.join()); // On receiving SegmentDeleted true should be returned. result = helper.deleteTableSegment("", "", true, new MockHostControllerStore(), factory, "", System.nanoTime()); factory.rp.segmentDeleted(new WireCommands.SegmentDeleted(0, getQualifiedStreamSegmentName("", "", 0L))); assertTrue(result.join()); // On receiving TableSegmentNotEmpty WireCommandFailedException is thrown. result = helper.deleteTableSegment("", "", true, new MockHostControllerStore(), factory, "", System.nanoTime()); factory.rp.tableSegmentNotEmpty(new WireCommands.TableSegmentNotEmpty(0, getQualifiedStreamSegmentName("", "", 0L), "")); AssertExtensions.assertThrows("", result::join, ex -> ex instanceof WireCommandFailedException && (((WireCommandFailedException) ex).getReason() == WireCommandFailedException.Reason.TableSegmentNotEmpty)); Supplier<CompletableFuture<?>> futureSupplier = () -> helper.deleteTableSegment("", "", true, new MockHostControllerStore(), factory, "", System.nanoTime()); validateAuthTokenCheckFailed(factory, futureSupplier); validateWrongHost(factory, futureSupplier); validateConnectionDropped(factory, futureSupplier); validateProcessingFailure(factory, futureSupplier); }
@Test(timeout = 10000) public void testNoSuchSegment() throws Exception { UUID cid = UUID.randomUUID(); PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT); MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl(); cf.setExecutor(executorService()); MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf); ClientConnection connection = mock(ClientConnection.class); cf.provideConnection(uri, connection); InOrder order = Mockito.inOrder(connection); SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(SEGMENT, controller, cf, cid, segmentSealedCallback, RETRY_SCHEDULE, ""); output.reconnect(); order.verify(connection).send(new SetupAppend(1, cid, SEGMENT, "")); cf.getProcessor(uri).appendSetup(new AppendSetup(1, SEGMENT, cid, 0)); ByteBuffer data = getBuffer("test"); //Write an Event. CompletableFuture<Void> ack = new CompletableFuture<>(); output.write(PendingEvent.withoutHeader(null, data, ack)); order.verify(connection).send(new Append(SEGMENT, cid, 1, 1, Unpooled.wrappedBuffer(data), null)); assertEquals(false, ack.isDone()); //writer is not complete until a response from Segment Store is received. //Simulate a No Such Segment while waiting on flush. AssertExtensions.assertBlocks(() -> { AssertExtensions.assertThrows(SegmentSealedException.class, () -> output.flush()); }, () -> { cf.getProcessor(uri).noSuchSegment(new WireCommands.NoSuchSegment(1, SEGMENT, "SomeException")); output.getUnackedEventsOnSeal(); }); AssertExtensions.assertThrows(SegmentSealedException.class, () -> output.flush()); }
@Override public void getSegmentAttribute(GetSegmentAttribute getSegmentAttribute) { long requestId = getSegmentAttribute.getRequestId(); String segmentName = getSegmentAttribute.getSegmentName(); UUID attributeId = getSegmentAttribute.getAttributeId(); final String operation = "getSegmentAttribute"; if (!verifyToken(segmentName, getSegmentAttribute.getRequestId(), getSegmentAttribute.getDelegationToken(), operation)) { return; } long trace = LoggerHelpers.traceEnter(log, operation, getSegmentAttribute); segmentStore.getStreamSegmentInfo(segmentName, TIMEOUT) .thenAccept(properties -> { LoggerHelpers.traceLeave(log, operation, trace, properties); if (properties == null) { connection.send(new NoSuchSegment(requestId, segmentName, EMPTY_STACK_TRACE)); } 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, operation, e)); }
@Test(timeout = 10000) public void testConnectAndFailedSetupAppendDueToTruncation() throws Exception { AtomicBoolean callbackInvoked = new AtomicBoolean(); Consumer<Segment> resendToSuccessorsCallback = segment -> { callbackInvoked.set(true); }; UUID cid = UUID.randomUUID(); PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT); MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl(); ScheduledExecutorService executor = mock(ScheduledExecutorService.class); implementAsDirectExecutor(executor); // Ensure task submitted to executor is run inline. cf.setExecutor(executor); MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf); ClientConnection connection = mock(ClientConnection.class); cf.provideConnection(uri, connection); @Cleanup SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(SEGMENT, controller, cf, cid, resendToSuccessorsCallback, RETRY_SCHEDULE, ""); output.reconnect(); verify(connection).send(new SetupAppend(1, cid, SEGMENT, "")); cf.getProcessor(uri).noSuchSegment(new WireCommands.NoSuchSegment(1, SEGMENT, "SomeException")); CompletableFuture<ClientConnection> connectionFuture = output.getConnection(); assertThrows(NoSuchSegmentException.class, () -> Futures.getThrowingException(connectionFuture)); assertTrue(callbackInvoked.get()); }
@Test public void testNoSuchSegment() throws IOException { testCommand(new WireCommands.NoSuchSegment(l, testString1, "SomeException")); }
@Test public void testCompatibilityNoSuchSegmentV5() throws IOException { // Test that we are able to decode a message with a previous version ByteArrayOutputStream bout = new ByteArrayOutputStream(); NoSuchSegmentV5 commandV5 = new NoSuchSegmentV5(l, ""); commandV5.writeFields(new DataOutputStream(bout)); testCommandFromByteArray(bout.toByteArray(), new WireCommands.NoSuchSegment(l, "", "")); }
public static WireCommand readFrom(ByteBufInputStream in, int length) throws IOException { long requestId = in.readLong(); String segment = in.readUTF(); String serverStackTrace = (in.available() > 0) ? in.readUTF() : EMPTY_STACK_TRACE; return new NoSuchSegment(requestId, segment, serverStackTrace); }
@Override public void noSuchSegment(WireCommands.NoSuchSegment noSuchSegment) { if (noSuchSegment.getSegment().equals(transactionName)) { log.info("commitTransaction {} NoSuchSegment", transactionName); result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.SUCCESS).build()); } else { log.warn("commitTransaction {} Source Segment not found", noSuchSegment.getSegment()); result.complete(TxnStatus.newBuilder().setStatus(TxnStatus.Status.FAILURE).build()); } }
@Test public void testSetupOnNonExistentSegment() throws Exception { String segment = "123"; StreamSegmentStore store = this.serviceBuilder.createStreamSegmentService(); @Cleanup EmbeddedChannel channel = createChannel(store); UUID uuid = UUID.randomUUID(); NoSuchSegment setup = (NoSuchSegment) sendRequest(channel, new SetupAppend(1, uuid, segment, "")); assertEquals(segment, setup.getSegment()); }
private void validateNoSuchSegment(MockConnectionFactory factory, Supplier<CompletableFuture<?>> futureSupplier) { CompletableFuture<?> future = futureSupplier.get(); factory.rp.noSuchSegment(new WireCommands.NoSuchSegment(0, "segment", "SomeException")); AssertExtensions.assertThrows("", future::join, ex -> ex instanceof WireCommandFailedException && (((WireCommandFailedException) ex).getReason() == WireCommandFailedException.Reason.SegmentDoesNotExist)); }