use of com.couchbase.client.core.deps.io.netty.channel.local.LocalAddress in project couchbase-jvm-clients by couchbase.
the class BaseEndpointIntegrationTest method mustReconnectWhenChannelCloses.
/**
* When the underlying channel closes, the endpoint must continue to reconnect until being instructed
* to stop with an explicit disconnect command.
*/
@Test
void mustReconnectWhenChannelCloses() {
LocalServerController localServerController = startLocalServer(eventLoopGroup);
ServiceContext serviceContext = new ServiceContext(new CoreContext(null, 1, env, authenticator()), "127.0.0.1", 1234, ServiceType.KV, Optional.empty());
BaseEndpoint endpoint = new BaseEndpoint("127.0.0.1", 1234, eventLoopGroup, serviceContext, CircuitBreakerConfig.enabled(false).build(), ServiceType.QUERY, false) {
@Override
protected PipelineInitializer pipelineInitializer() {
return (endpoint, pipeline) -> {
};
}
@Override
protected SocketAddress remoteAddress() {
return new LocalAddress("server");
}
};
List<EndpointState> transitions = Collections.synchronizedList(new ArrayList<>());
endpoint.states().subscribe(transitions::add);
assertEquals(0, localServerController.connectAttempts.get());
assertNull(localServerController.channel.get());
endpoint.connect();
waitUntilCondition(() -> endpoint.state() == EndpointState.CONNECTED);
waitUntilCondition(() -> localServerController.connectAttempts.get() == 1);
assertNotNull(localServerController.channel.get());
localServerController.channel.get().close().awaitUninterruptibly();
List<EndpointState> expectedTransitions = Arrays.asList(// initial state
EndpointState.DISCONNECTED, // initial connect attempt
EndpointState.CONNECTING, // properly connected the first time
EndpointState.CONNECTED, // disconnected when we kill the channel from the server side
EndpointState.DISCONNECTED, // endpoint should be reconnecting now
EndpointState.CONNECTING, // finally, we are able to reconnect completely
EndpointState.CONNECTED);
waitUntilCondition(() -> transitions.size() == expectedTransitions.size());
assertEquals(expectedTransitions, transitions);
waitUntilCondition(() -> localServerController.connectAttempts.get() >= 2);
endpoint.disconnect();
waitUntilCondition(() -> endpoint.state() == EndpointState.DISCONNECTED);
boolean hasDisconnectEvent = false;
for (Event event : eventBus.publishedEvents()) {
if (event instanceof UnexpectedEndpointDisconnectedEvent) {
hasDisconnectEvent = true;
break;
}
}
assertTrue(hasDisconnectEvent);
}
use of com.couchbase.client.core.deps.io.netty.channel.local.LocalAddress in project couchbase-jvm-clients by couchbase.
the class BaseEndpointIntegrationTest method startLocalServer.
private LocalServerController startLocalServer(final DefaultEventLoopGroup eventLoopGroup) {
final LocalServerController localServerController = new LocalServerController();
ServerBootstrap bootstrap = new ServerBootstrap().group(eventLoopGroup).localAddress(new LocalAddress("server")).childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
localServerController.channel.set(ctx.channel());
localServerController.connectAttempts.incrementAndGet();
ctx.fireChannelActive();
}
});
}
}).channel(LocalServerChannel.class);
bootstrap.bind().awaitUninterruptibly();
return localServerController;
}
use of com.couchbase.client.core.deps.io.netty.channel.local.LocalAddress in project couchbase-jvm-clients by couchbase.
the class QueryMessageHandlerBackpressureTest method requestRecordsExplicitly.
/**
* This test makes sure that even if the server returns a good bunch of data, each individual
* chunk is requested by the caller explicitly.
*/
@Test
void requestRecordsExplicitly() throws Exception {
EndpointContext endpointContext = new EndpointContext(core.context(), new HostAndPort("127.0.0.1", 1234), NoopCircuitBreaker.INSTANCE, ServiceType.QUERY, Optional.empty(), Optional.empty(), Optional.empty());
BaseEndpoint endpoint = mock(BaseEndpoint.class);
when(endpoint.pipelined()).thenReturn(false);
Bootstrap client = new Bootstrap().channel(LocalChannel.class).group(new DefaultEventLoopGroup()).remoteAddress(new LocalAddress("s1")).handler(new ChannelInitializer<LocalChannel>() {
@Override
protected void initChannel(LocalChannel ch) {
ch.pipeline().addLast(new HttpClientCodec()).addLast(new QueryMessageHandler(endpoint, endpointContext));
}
});
Channel channel = client.connect().awaitUninterruptibly().channel();
final List<byte[]> rows = Collections.synchronizedList(new ArrayList<>());
QueryRequest request = new QueryRequest(Duration.ofSeconds(1), endpointContext, BestEffortRetryStrategy.INSTANCE, endpointContext.authenticator(), "select 1=1", "myquery".getBytes(UTF_8), true, null, null, null, null, null);
channel.writeAndFlush(request);
final QueryResponse response = request.response().get();
assertEquals(0, rows.size());
StepVerifier.create(response.rows().map(v -> new String(v.data(), UTF_8)), 0).thenRequest(1).expectNext("{\"foo\":1}").thenRequest(1).expectNext("{\"bar\":1}").thenRequest(2).expectNext("{\"faz\":1}", "{\"baz\":1}").thenRequest(4).expectNext("{\"fazz\":1}", "{\"bazz\":1}", "{\"fizz\":1}", "{\"bizz\":1}").expectComplete().verify();
}
Aggregations