use of io.grpc.ResolvedServerInfo in project grpc-java by grpc.
the class ManagedChannelImplTest method firstResolvedServerFailedToConnect.
/**
* Verify that if the first resolved address points to a server that cannot be connected, the call
* will end up with the second address which works.
*/
@Test
public void firstResolvedServerFailedToConnect() throws Exception {
final SocketAddress goodAddress = new SocketAddress() {
@Override
public String toString() {
return "goodAddress";
}
};
final SocketAddress badAddress = new SocketAddress() {
@Override
public String toString() {
return "badAddress";
}
};
final ResolvedServerInfo goodServer = new ResolvedServerInfo(goodAddress, Attributes.EMPTY);
final ResolvedServerInfo badServer = new ResolvedServerInfo(badAddress, Attributes.EMPTY);
InOrder inOrder = inOrder(mockLoadBalancer);
ResolvedServerInfoGroup serverInfoGroup = ResolvedServerInfoGroup.builder().add(badServer).add(goodServer).build();
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(serverInfoGroup.getResolvedServerInfoList());
createChannel(nameResolverFactory, NO_INTERCEPTOR);
// Start the call
ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
Metadata headers = new Metadata();
call.start(mockCallListener, headers);
executor.runDueTasks();
// Simulate name resolution results
inOrder.verify(mockLoadBalancer).handleResolvedAddresses(eq(Arrays.asList(serverInfoGroup)), eq(Attributes.EMPTY));
Subchannel subchannel = helper.createSubchannel(serverInfoGroup.toEquivalentAddressGroup(), Attributes.EMPTY);
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
subchannel.requestConnection();
inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
// The channel will starts with the first address (badAddress)
verify(mockTransportFactory).newClientTransport(same(badAddress), any(String.class), any(String.class));
verify(mockTransportFactory, times(0)).newClientTransport(same(goodAddress), any(String.class), any(String.class));
MockClientTransportInfo badTransportInfo = transports.poll();
// Which failed to connect
badTransportInfo.listener.transportShutdown(Status.UNAVAILABLE);
inOrder.verifyNoMoreInteractions();
// The channel then try the second address (goodAddress)
verify(mockTransportFactory).newClientTransport(same(goodAddress), any(String.class), any(String.class));
MockClientTransportInfo goodTransportInfo = transports.poll();
when(goodTransportInfo.transport.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class))).thenReturn(mock(ClientStream.class));
goodTransportInfo.listener.transportReady();
inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
assertEquals(READY, stateInfoCaptor.getValue().getState());
// A typical LoadBalancer will call this once the subchannel becomes READY
helper.updatePicker(mockPicker);
// Delayed transport uses the app executor to create real streams.
executor.runDueTasks();
verify(goodTransportInfo.transport).newStream(same(method), same(headers), same(CallOptions.DEFAULT), any(StatsTraceContext.class));
// The bad transport was never used.
verify(badTransportInfo.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class));
}
use of io.grpc.ResolvedServerInfo in project grpc-java by grpc.
the class ManagedChannelImplTest method allServersFailedToConnect.
/**
* Verify that if all resolved addresses failed to connect, a fail-fast call will fail, while a
* wait-for-ready call will still be buffered.
*/
@Test
public void allServersFailedToConnect() throws Exception {
final SocketAddress addr1 = new SocketAddress() {
@Override
public String toString() {
return "addr1";
}
};
final SocketAddress addr2 = new SocketAddress() {
@Override
public String toString() {
return "addr2";
}
};
final ResolvedServerInfo server1 = new ResolvedServerInfo(addr1, Attributes.EMPTY);
final ResolvedServerInfo server2 = new ResolvedServerInfo(addr2, Attributes.EMPTY);
InOrder inOrder = inOrder(mockLoadBalancer);
ResolvedServerInfoGroup serverInfoGroup = ResolvedServerInfoGroup.builder().add(server1).add(server2).build();
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(serverInfoGroup.getResolvedServerInfoList());
createChannel(nameResolverFactory, NO_INTERCEPTOR);
// Start a wait-for-ready call
ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT.withWaitForReady());
Metadata headers = new Metadata();
call.start(mockCallListener, headers);
// ... and a fail-fast call
ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT.withoutWaitForReady());
call2.start(mockCallListener2, headers);
executor.runDueTasks();
// Simulate name resolution results
inOrder.verify(mockLoadBalancer).handleResolvedAddresses(eq(Arrays.asList(serverInfoGroup)), eq(Attributes.EMPTY));
Subchannel subchannel = helper.createSubchannel(serverInfoGroup.toEquivalentAddressGroup(), Attributes.EMPTY);
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
subchannel.requestConnection();
inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
// Connecting to server1, which will fail
verify(mockTransportFactory).newClientTransport(same(addr1), any(String.class), any(String.class));
verify(mockTransportFactory, times(0)).newClientTransport(same(addr2), any(String.class), any(String.class));
MockClientTransportInfo transportInfo1 = transports.poll();
transportInfo1.listener.transportShutdown(Status.UNAVAILABLE);
// Connecting to server2, which will fail too
verify(mockTransportFactory).newClientTransport(same(addr2), any(String.class), any(String.class));
MockClientTransportInfo transportInfo2 = transports.poll();
Status server2Error = Status.UNAVAILABLE.withDescription("Server2 failed to connect");
transportInfo2.listener.transportShutdown(server2Error);
// ... which makes the subchannel enter TRANSIENT_FAILURE. The last error Status is propagated
// to LoadBalancer.
inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
assertEquals(TRANSIENT_FAILURE, stateInfoCaptor.getValue().getState());
assertSame(server2Error, stateInfoCaptor.getValue().getStatus());
// A typical LoadBalancer would create a picker with error
SubchannelPicker picker2 = mock(SubchannelPicker.class);
when(picker2.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withError(server2Error));
helper.updatePicker(picker2);
executor.runDueTasks();
// ... which fails the fail-fast call
verify(mockCallListener2).onClose(same(server2Error), any(Metadata.class));
// ... while the wait-for-ready call stays
verifyNoMoreInteractions(mockCallListener);
// No real stream was ever created
verify(transportInfo1.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class));
verify(transportInfo2.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class));
}
use of io.grpc.ResolvedServerInfo in project grpc-java by grpc.
the class RoundRobinLoadBalancerTest method setUp.
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
for (int i = 0; i < 3; i++) {
SocketAddress addr = new FakeSocketAddress("server" + i);
EquivalentAddressGroup eag = new EquivalentAddressGroup(addr);
servers.put(ResolvedServerInfoGroup.builder().add(new ResolvedServerInfo(addr)).build(), eag);
subchannels.put(eag, mock(Subchannel.class));
}
when(mockHelper.createSubchannel(any(EquivalentAddressGroup.class), any(Attributes.class))).then(new Answer<Subchannel>() {
@Override
public Subchannel answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Subchannel subchannel = subchannels.get(args[0]);
when(subchannel.getAttributes()).thenReturn((Attributes) args[1]);
return subchannel;
}
});
loadBalancer = (RoundRobinLoadBalancer) RoundRobinLoadBalancerFactory.getInstance().newLoadBalancer(mockHelper);
}
use of io.grpc.ResolvedServerInfo in project jetcd by coreos.
the class DnsSrvNameResolver method getServers.
@Override
protected List<ResolvedServerInfo> getServers() {
try {
DirContext ctx = new InitialDirContext(ENV);
NamingEnumeration<?> resolved = ctx.getAttributes(name, ATTRIBUTE_IDS).get("srv").getAll();
List<ResolvedServerInfo> servers = new LinkedList<>();
while (resolved.hasMore()) {
servers.add(srvRecordToServerInfo((String) resolved.next()));
}
return servers;
} catch (Exception e) {
LOGGER.warn("", e);
}
return Collections.emptyList();
}
use of io.grpc.ResolvedServerInfo in project grpc-java by grpc.
the class ManagedChannelImplIdlenessTest method setUp.
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(timerServicePool.getObject()).thenReturn(timer.getScheduledExecutorService());
when(executorPool.getObject()).thenReturn(executor.getScheduledExecutorService());
when(oobExecutorPool.getObject()).thenReturn(oobExecutor.getScheduledExecutorService());
when(mockLoadBalancerFactory.newLoadBalancer(any(Helper.class))).thenReturn(mockLoadBalancer);
when(mockNameResolver.getServiceAuthority()).thenReturn(AUTHORITY);
when(mockNameResolverFactory.newNameResolver(any(URI.class), any(Attributes.class))).thenReturn(mockNameResolver);
channel = new ManagedChannelImpl("fake://target", new FakeBackoffPolicyProvider(), mockNameResolverFactory, Attributes.EMPTY, mockLoadBalancerFactory, mockTransportFactory, DecompressorRegistry.getDefaultInstance(), CompressorRegistry.getDefaultInstance(), timerServicePool, executorPool, oobExecutorPool, timer.getStopwatchSupplier(), TimeUnit.SECONDS.toMillis(IDLE_TIMEOUT_SECONDS), USER_AGENT, Collections.<ClientInterceptor>emptyList(), NoopStatsContextFactory.INSTANCE);
newTransports = TestUtils.captureTransports(mockTransportFactory);
for (int i = 0; i < 2; i++) {
ResolvedServerInfoGroup.Builder resolvedServerInfoGroup = ResolvedServerInfoGroup.builder();
for (int j = 0; j < 2; j++) {
resolvedServerInfoGroup.add(new ResolvedServerInfo(new FakeSocketAddress("servergroup" + i + "server" + j)));
}
servers.add(resolvedServerInfoGroup.build());
addressGroupList.add(resolvedServerInfoGroup.build().toEquivalentAddressGroup());
}
verify(mockNameResolverFactory).newNameResolver(any(URI.class), any(Attributes.class));
// Verify the initial idleness
verify(mockLoadBalancerFactory, never()).newLoadBalancer(any(Helper.class));
verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), anyString(), anyString());
verify(mockNameResolver, never()).start(any(NameResolver.Listener.class));
}
Aggregations