Search in sources :

Example 1 with ConnectionFailedException

use of io.pravega.shared.protocol.netty.ConnectionFailedException in project pravega by pravega.

the class ClientConnectionInboundHandler method sendAsync.

@Override
public void sendAsync(List<Append> appends, CompletedCallback callback) {
    recentMessage.set(true);
    Channel ch;
    try {
        ch = getChannel();
    } catch (ConnectionFailedException e) {
        callback.complete(new ConnectionFailedException("Connection to " + connectionName + " is not established."));
        return;
    }
    PromiseCombiner combiner = new PromiseCombiner();
    for (Append append : appends) {
        batchSizeTracker.recordAppend(append.getEventNumber(), append.getData().readableBytes());
        combiner.add(ch.write(append));
    }
    ch.flush();
    ChannelPromise promise = ch.newPromise();
    promise.addListener(new GenericFutureListener<Future<? super Void>>() {

        @Override
        public void operationComplete(Future<? super Void> future) throws Exception {
            Throwable cause = future.cause();
            callback.complete(cause == null ? null : new ConnectionFailedException(cause));
        }
    });
    combiner.finish(promise);
}
Also used : PromiseCombiner(io.netty.util.concurrent.PromiseCombiner) Append(io.pravega.shared.protocol.netty.Append) Channel(io.netty.channel.Channel) ScheduledFuture(io.netty.util.concurrent.ScheduledFuture) CompletableFuture(java.util.concurrent.CompletableFuture) Future(io.netty.util.concurrent.Future) ChannelPromise(io.netty.channel.ChannelPromise) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException)

Example 2 with ConnectionFailedException

use of io.pravega.shared.protocol.netty.ConnectionFailedException in project pravega by pravega.

the class ConnectionFactoryImpl method establishConnection.

@Override
public CompletableFuture<ClientConnection> establishConnection(PravegaNodeUri location, ReplyProcessor rp) {
    Preconditions.checkNotNull(location);
    Exceptions.checkNotClosed(closed.get(), this);
    final SslContext sslCtx;
    if (clientConfig.isEnableTls()) {
        try {
            SslContextBuilder sslCtxFactory = SslContextBuilder.forClient();
            if (Strings.isNullOrEmpty(clientConfig.getTrustStore())) {
                sslCtxFactory = sslCtxFactory.trustManager(FingerprintTrustManagerFactory.getInstance(FingerprintTrustManagerFactory.getDefaultAlgorithm()));
            } else {
                sslCtxFactory = SslContextBuilder.forClient().trustManager(new File(clientConfig.getTrustStore()));
            }
            sslCtx = sslCtxFactory.build();
        } catch (SSLException | NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    } else {
        sslCtx = null;
    }
    AppendBatchSizeTracker batchSizeTracker = new AppendBatchSizeTrackerImpl();
    ClientConnectionInboundHandler handler = new ClientConnectionInboundHandler(location.getEndpoint(), rp, batchSizeTracker);
    Bootstrap b = new Bootstrap();
    b.group(group).channel(nio ? NioSocketChannel.class : EpollSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {

        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline p = ch.pipeline();
            if (sslCtx != null) {
                SslHandler sslHandler = sslCtx.newHandler(ch.alloc(), location.getEndpoint(), location.getPort());
                if (clientConfig.isValidateHostName()) {
                    SSLEngine sslEngine = sslHandler.engine();
                    SSLParameters sslParameters = sslEngine.getSSLParameters();
                    sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
                    sslEngine.setSSLParameters(sslParameters);
                }
                p.addLast(sslHandler);
            }
            // p.addLast(new LoggingHandler(LogLevel.INFO));
            p.addLast(new ExceptionLoggingHandler(location.getEndpoint()), new CommandEncoder(batchSizeTracker), new LengthFieldBasedFrameDecoder(WireCommands.MAX_WIRECOMMAND_SIZE, 4, 4), new CommandDecoder(), handler);
        }
    });
    // Start the client.
    CompletableFuture<ClientConnection> connectionComplete = new CompletableFuture<>();
    try {
        b.connect(location.getEndpoint(), location.getPort()).addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {
                    // since ChannelFuture is complete future.channel() is not a blocking call.
                    Channel ch = future.channel();
                    log.debug("Connect operation completed for channel:{}, local address:{}, remote address:{}", ch.id(), ch.localAddress(), ch.remoteAddress());
                    // Once a channel is closed the channel group implementation removes it.
                    allChannels.add(ch);
                    connectionComplete.complete(handler);
                } else {
                    connectionComplete.completeExceptionally(new ConnectionFailedException(future.cause()));
                }
            }
        });
    } catch (Exception e) {
        connectionComplete.completeExceptionally(new ConnectionFailedException(e));
    }
    // check if channel is registered.
    CompletableFuture<Void> channelRegisteredFuture = new CompletableFuture<>();
    handler.completeWhenRegistered(channelRegisteredFuture);
    return connectionComplete.thenCombine(channelRegisteredFuture, (clientConnection, v) -> clientConnection);
}
Also used : NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) EpollSocketChannel(io.netty.channel.epoll.EpollSocketChannel) SocketChannel(io.netty.channel.socket.SocketChannel) SSLEngine(javax.net.ssl.SSLEngine) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) CommandEncoder(io.pravega.shared.protocol.netty.CommandEncoder) SSLException(javax.net.ssl.SSLException) CompletableFuture(java.util.concurrent.CompletableFuture) SSLParameters(javax.net.ssl.SSLParameters) ExceptionLoggingHandler(io.pravega.shared.protocol.netty.ExceptionLoggingHandler) Bootstrap(io.netty.bootstrap.Bootstrap) EpollSocketChannel(io.netty.channel.epoll.EpollSocketChannel) LengthFieldBasedFrameDecoder(io.netty.handler.codec.LengthFieldBasedFrameDecoder) SslContext(io.netty.handler.ssl.SslContext) ChannelFuture(io.netty.channel.ChannelFuture) AppendBatchSizeTracker(io.pravega.shared.protocol.netty.AppendBatchSizeTracker) CommandDecoder(io.pravega.shared.protocol.netty.CommandDecoder) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) EpollSocketChannel(io.netty.channel.epoll.EpollSocketChannel) SocketChannel(io.netty.channel.socket.SocketChannel) Channel(io.netty.channel.Channel) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) SSLException(javax.net.ssl.SSLException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ChannelPipeline(io.netty.channel.ChannelPipeline) SslHandler(io.netty.handler.ssl.SslHandler) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) SslContextBuilder(io.netty.handler.ssl.SslContextBuilder) File(java.io.File) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException)

Example 3 with ConnectionFailedException

use of io.pravega.shared.protocol.netty.ConnectionFailedException in project pravega by pravega.

the class SegmentOutputStreamImpl method reconnect.

@VisibleForTesting
void reconnect() {
    if (state.isClosed()) {
        return;
    }
    log.debug("(Re)connect invoked, Segment: {}, writerID: {}", segmentName, writerId);
    state.setupConnection.registerAndRunReleaser(() -> {
        Retry.indefinitelyWithExpBackoff(retrySchedule.getInitialMillis(), retrySchedule.getMultiplier(), retrySchedule.getMaxDelay(), t -> log.warn(writerId + " Failed to connect: ", t)).runAsync(() -> {
            log.debug("Running reconnect for segment:{} writerID: {}", segmentName, writerId);
            if (state.isClosed() || state.isAlreadySealed()) {
                return CompletableFuture.completedFuture(null);
            }
            Preconditions.checkState(state.getConnection() == null);
            log.info("Fetching endpoint for segment {}, writerID: {}", segmentName, writerId);
            return controller.getEndpointForSegment(segmentName).thenComposeAsync((PravegaNodeUri uri) -> {
                log.info("Establishing connection to {} for {}, writerID: {}", uri, segmentName, writerId);
                return connectionFactory.establishConnection(uri, responseProcessor);
            }, connectionFactory.getInternalExecutor()).thenComposeAsync(connection -> {
                CompletableFuture<Void> connectionSetupFuture = state.newConnection(connection);
                SetupAppend cmd = new SetupAppend(requestIdGenerator.get(), writerId, segmentName, delegationToken);
                try {
                    connection.send(cmd);
                } catch (ConnectionFailedException e1) {
                    // This needs to be invoked here because call to failConnection from netty may occur before state.newConnection above.
                    state.failConnection(e1);
                    throw Lombok.sneakyThrow(e1);
                }
                return connectionSetupFuture.exceptionally(t -> {
                    if (Exceptions.unwrap(t) instanceof SegmentSealedException) {
                        log.info("Ending reconnect attempts to {} because segment is sealed", segmentName);
                        return null;
                    }
                    throw Lombok.sneakyThrow(t);
                });
            }, connectionFactory.getInternalExecutor());
        }, connectionFactory.getInternalExecutor());
    }, new CompletableFuture<ClientConnection>());
}
Also used : ClientConnection(io.pravega.client.netty.impl.ClientConnection) AuthenticationException(io.pravega.common.auth.AuthenticationException) Getter(lombok.Getter) Retry(io.pravega.common.util.Retry) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) NoSuchSegment(io.pravega.shared.protocol.netty.WireCommands.NoSuchSegment) Exceptions(io.pravega.common.Exceptions) ConditionalCheckFailed(io.pravega.shared.protocol.netty.WireCommands.ConditionalCheckFailed) RequiredArgsConstructor(lombok.RequiredArgsConstructor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) PendingEvent(io.pravega.client.stream.impl.PendingEvent) Append(io.pravega.shared.protocol.netty.Append) Supplier(java.util.function.Supplier) Unpooled(io.netty.buffer.Unpooled) ArrayList(java.util.ArrayList) SetupAppend(io.pravega.shared.protocol.netty.WireCommands.SetupAppend) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) FailingReplyProcessor(io.pravega.shared.protocol.netty.FailingReplyProcessor) Map(java.util.Map) ToString(lombok.ToString) PravegaNodeUri(io.pravega.shared.protocol.netty.PravegaNodeUri) ConnectionFactory(io.pravega.client.netty.impl.ConnectionFactory) KeepAlive(io.pravega.shared.protocol.netty.WireCommands.KeepAlive) ReusableLatch(io.pravega.common.util.ReusableLatch) RetryWithBackoff(io.pravega.common.util.Retry.RetryWithBackoff) AppendSetup(io.pravega.shared.protocol.netty.WireCommands.AppendSetup) ConcurrentNavigableMap(java.util.concurrent.ConcurrentNavigableMap) ReusableFutureLatch(io.pravega.common.util.ReusableFutureLatch) UUID(java.util.UUID) WireCommands(io.pravega.shared.protocol.netty.WireCommands) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) WrongHost(io.pravega.shared.protocol.netty.WireCommands.WrongHost) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Slf4j(lombok.extern.slf4j.Slf4j) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) DataAppended(io.pravega.shared.protocol.netty.WireCommands.DataAppended) SegmentIsSealed(io.pravega.shared.protocol.netty.WireCommands.SegmentIsSealed) Controller(io.pravega.client.stream.impl.Controller) Lombok(lombok.Lombok) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) PravegaNodeUri(io.pravega.shared.protocol.netty.PravegaNodeUri) SetupAppend(io.pravega.shared.protocol.netty.WireCommands.SetupAppend) ClientConnection(io.pravega.client.netty.impl.ClientConnection) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 4 with ConnectionFailedException

use of io.pravega.shared.protocol.netty.ConnectionFailedException in project pravega by pravega.

the class SegmentInputStreamTest method testExceptionRecovery.

@Test
public void testExceptionRecovery() throws EndOfSegmentException, SegmentTruncatedException {
    byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    ByteBuffer wireData = createEventFromData(data);
    TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 7);
    @Cleanup SegmentInputStreamImpl stream = new SegmentInputStreamImpl(fakeNetwork, 0);
    fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2)));
    fakeNetwork.completeExceptionally(1, new ConnectionFailedException());
    fakeNetwork.complete(2, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2)));
    fakeNetwork.complete(3, new WireCommands.SegmentRead(segment.getScopedName(), 2, false, false, ByteBufferUtils.slice(wireData, 2, 7)));
    fakeNetwork.complete(4, new WireCommands.SegmentRead(segment.getScopedName(), 9, false, false, ByteBufferUtils.slice(wireData, 9, 2)));
    fakeNetwork.complete(5, new WireCommands.SegmentRead(segment.getScopedName(), 11, false, false, ByteBufferUtils.slice(wireData, 11, wireData.capacity() - 11)));
    AssertExtensions.assertThrows(ConnectionFailedException.class, () -> stream.read());
    ByteBuffer read = stream.read();
    assertEquals(ByteBuffer.wrap(data), read);
}
Also used : WireCommands(io.pravega.shared.protocol.netty.WireCommands) ByteBuffer(java.nio.ByteBuffer) Cleanup(lombok.Cleanup) SegmentRead(io.pravega.shared.protocol.netty.WireCommands.SegmentRead) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) Test(org.junit.Test)

Example 5 with ConnectionFailedException

use of io.pravega.shared.protocol.netty.ConnectionFailedException in project pravega by pravega.

the class SegmentOutputStreamTest method testFailOnClose.

/**
 * Verifies that if a exception is encountered while flushing data inside of close, the
 * connection is reestablished and the data is retransmitted before close returns.
 */
@Test
public void testFailOnClose() throws ConnectionFailedException {
    UUID cid = UUID.randomUUID();
    PravegaNodeUri uri = new PravegaNodeUri("endpoint", SERVICE_PORT);
    MockConnectionFactoryImpl cf = new MockConnectionFactoryImpl();
    @Cleanup("shutdown") InlineExecutor inlineExecutor = new InlineExecutor();
    cf.setExecutor(inlineExecutor);
    MockController controller = new MockController(uri.getEndpoint(), uri.getPort(), cf);
    ClientConnection connection = mock(ClientConnection.class);
    cf.provideConnection(uri, connection);
    SegmentOutputStreamImpl output = new SegmentOutputStreamImpl(SEGMENT, controller, cf, cid, segmentSealedCallback, RETRY_SCHEDULE, "");
    output.reconnect();
    InOrder inOrder = Mockito.inOrder(connection);
    inOrder.verify(connection).send(new SetupAppend(1, cid, SEGMENT, ""));
    cf.getProcessor(uri).appendSetup(new AppendSetup(1, SEGMENT, cid, 0));
    ByteBuffer data = getBuffer("test");
    // Prep mock: the mockito doAnswers setup below are triggered during the close inside of the testBlocking() call.
    CompletableFuture<Boolean> acked = new CompletableFuture<>();
    Append append = new Append(SEGMENT, cid, 1, Unpooled.wrappedBuffer(data), null);
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            cf.getProcessor(uri).connectionDropped();
            throw new ConnectionFailedException();
        }
    }).doNothing().when(connection).send(new WireCommands.KeepAlive());
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            CompletedCallback callback = (CompletedCallback) invocation.getArgument(1);
            callback.complete(null);
            return null;
        }
    }).when(connection).sendAsync(Mockito.eq(Collections.singletonList(append)), Mockito.any());
    // Queue up event.
    output.write(new PendingEvent(null, data, acked, null));
    inOrder.verify(connection).send(append);
    // Verify behavior
    Async.testBlocking(() -> {
        output.close();
    }, () -> {
        cf.getProcessor(uri).appendSetup(new AppendSetup(2, SEGMENT, cid, 0));
        cf.getProcessor(uri).dataAppended(new WireCommands.DataAppended(cid, 1, 0));
    });
    inOrder.verify(connection).send(new WireCommands.KeepAlive());
    inOrder.verify(connection).send(new SetupAppend(2, cid, SEGMENT, ""));
    inOrder.verify(connection).sendAsync(Mockito.eq(Collections.singletonList(append)), Mockito.any());
    inOrder.verify(connection).close();
    assertEquals(true, acked.isDone());
    inOrder.verifyNoMoreInteractions();
}
Also used : Cleanup(lombok.Cleanup) CompletableFuture(java.util.concurrent.CompletableFuture) PravegaNodeUri(io.pravega.shared.protocol.netty.PravegaNodeUri) InlineExecutor(io.pravega.test.common.InlineExecutor) MockConnectionFactoryImpl(io.pravega.client.stream.mock.MockConnectionFactoryImpl) SetupAppend(io.pravega.shared.protocol.netty.WireCommands.SetupAppend) ClientConnection(io.pravega.client.netty.impl.ClientConnection) UUID(java.util.UUID) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) WireCommands(io.pravega.shared.protocol.netty.WireCommands) CompletedCallback(io.pravega.client.netty.impl.ClientConnection.CompletedCallback) InOrder(org.mockito.InOrder) ByteBuffer(java.nio.ByteBuffer) AppendSetup(io.pravega.shared.protocol.netty.WireCommands.AppendSetup) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) Append(io.pravega.shared.protocol.netty.Append) SetupAppend(io.pravega.shared.protocol.netty.WireCommands.SetupAppend) PendingEvent(io.pravega.client.stream.impl.PendingEvent) InvocationOnMock(org.mockito.invocation.InvocationOnMock) MockController(io.pravega.client.stream.mock.MockController) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) Test(org.junit.Test)

Aggregations

ConnectionFailedException (io.pravega.shared.protocol.netty.ConnectionFailedException)14 CompletableFuture (java.util.concurrent.CompletableFuture)10 ClientConnection (io.pravega.client.netty.impl.ClientConnection)9 Append (io.pravega.shared.protocol.netty.Append)8 PravegaNodeUri (io.pravega.shared.protocol.netty.PravegaNodeUri)8 Test (org.junit.Test)8 WireCommands (io.pravega.shared.protocol.netty.WireCommands)7 SetupAppend (io.pravega.shared.protocol.netty.WireCommands.SetupAppend)7 UUID (java.util.UUID)7 PendingEvent (io.pravega.client.stream.impl.PendingEvent)6 MockController (io.pravega.client.stream.mock.MockController)6 AppendSetup (io.pravega.shared.protocol.netty.WireCommands.AppendSetup)6 ByteBuffer (java.nio.ByteBuffer)6 Cleanup (lombok.Cleanup)6 InOrder (org.mockito.InOrder)6 InvocationOnMock (org.mockito.invocation.InvocationOnMock)6 MockConnectionFactoryImpl (io.pravega.client.stream.mock.MockConnectionFactoryImpl)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 CompletedCallback (io.pravega.client.netty.impl.ClientConnection.CompletedCallback)4 Channel (io.netty.channel.Channel)3