use of io.grpc.Attributes in project grpc-java by grpc.
the class GrpclbLoadBalancerTest method delegatingRoundRobinThenNameResolutionFails.
@Test
public void delegatingRoundRobinThenNameResolutionFails() {
List<ResolvedServerInfoGroup> resolvedServers = createResolvedServerInfoGroupList(false, false);
Attributes resolutionAttrs = Attributes.newBuilder().set(RESOLUTION_ATTR, "yeah").set(GrpclbConstants.ATTR_LB_POLICY, LbPolicy.ROUND_ROBIN).build();
deliverResolvedAddresses(resolvedServers, resolutionAttrs);
verify(roundRobinBalancerFactory).newLoadBalancer(helper);
verify(roundRobinBalancer).handleResolvedAddresses(resolvedServers, resolutionAttrs);
// Then let name resolution fail. The error will be passed directly to the delegate.
Status error = Status.NOT_FOUND.withDescription("www.google.com not found");
deliverNameResolutionError(error);
verify(roundRobinBalancer).handleNameResolutionError(error);
verify(helper, never()).updatePicker(any(SubchannelPicker.class));
verifyNoMoreInteractions(pickFirstBalancerFactory);
verifyNoMoreInteractions(pickFirstBalancer);
}
use of io.grpc.Attributes in project grpc-java by grpc.
the class GrpclbLoadBalancerTest method grpclbWorking.
@Test
public void grpclbWorking() {
InOrder inOrder = inOrder(helper);
List<ResolvedServerInfoGroup> grpclbResolutionList = createResolvedServerInfoGroupList(true, true);
Attributes grpclbResolutionAttrs = Attributes.newBuilder().set(GrpclbConstants.ATTR_LB_POLICY, LbPolicy.GRPCLB).build();
deliverResolvedAddresses(grpclbResolutionList, grpclbResolutionAttrs);
assertSame(LbPolicy.GRPCLB, balancer.getLbPolicy());
assertNull(balancer.getDelegate());
verify(helper).createOobChannel(eq(grpclbResolutionList.get(0).toEquivalentAddressGroup()), eq(lbAuthority(0)));
assertEquals(1, fakeOobChannels.size());
ManagedChannel oobChannel = fakeOobChannels.poll();
verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
// Simulate receiving LB response
List<ServerEntry> backends1 = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
inOrder.verify(helper, never()).updatePicker(any(SubchannelPicker.class));
lbResponseObserver.onNext(buildInitialResponse());
lbResponseObserver.onNext(buildLbResponse(backends1));
inOrder.verify(helper).createSubchannel(eq(new EquivalentAddressGroup(backends1.get(0).addr)), any(Attributes.class));
inOrder.verify(helper).createSubchannel(eq(new EquivalentAddressGroup(backends1.get(1).addr)), any(Attributes.class));
assertEquals(2, mockSubchannels.size());
Subchannel subchannel1 = mockSubchannels.poll();
Subchannel subchannel2 = mockSubchannels.poll();
verify(subchannel1).requestConnection();
verify(subchannel2).requestConnection();
assertEquals(new EquivalentAddressGroup(backends1.get(0).addr), subchannel1.getAddresses());
assertEquals(new EquivalentAddressGroup(backends1.get(1).addr), subchannel2.getAddresses());
// Before any subchannel is READY, a buffer picker will be provided
inOrder.verify(helper).updatePicker(same(GrpclbLoadBalancer.BUFFER_PICKER));
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(CONNECTING));
deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(CONNECTING));
inOrder.verify(helper, times(2)).updatePicker(same(GrpclbLoadBalancer.BUFFER_PICKER));
// Let subchannels be connected
deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker1 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker1.list).containsExactly(new RoundRobinEntry(subchannel2, "token0002"));
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker2 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker2.list).containsExactly(new RoundRobinEntry(subchannel1, "token0001"), new RoundRobinEntry(subchannel2, "token0002")).inOrder();
// Disconnected subchannels
verify(subchannel1).requestConnection();
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(IDLE));
verify(subchannel1, times(2)).requestConnection();
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker3 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker3.list).containsExactly(new RoundRobinEntry(subchannel2, "token0002"));
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(CONNECTING));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker4 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker4.list).containsExactly(new RoundRobinEntry(subchannel2, "token0002"));
// As long as there is at least one READY subchannel, round robin will work.
Status error1 = Status.UNAVAILABLE.withDescription("error1");
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forTransientFailure(error1));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker5 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker5.list).containsExactly(new RoundRobinEntry(subchannel2, "token0002"));
// If no subchannel is READY, will propagate an error from an arbitrary subchannel (but here
// only subchannel1 has error).
verify(subchannel2).requestConnection();
deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(IDLE));
verify(subchannel2, times(2)).requestConnection();
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
ErrorPicker picker6 = (ErrorPicker) pickerCaptor.getValue();
assertNull(picker6.result.getSubchannel());
assertSame(error1, picker6.result.getStatus());
// Update backends, with a drop entry
List<ServerEntry> backends2 = Arrays.asList(// New address
new ServerEntry("127.0.0.1", 2030, "token0003"), // drop
null, // Existing address with token changed
new ServerEntry("127.0.0.1", 2010, "token0004"), // New address appearing second time
new ServerEntry("127.0.0.1", 2030, "token0005"));
verify(subchannel1, never()).shutdown();
lbResponseObserver.onNext(buildLbResponse(backends2));
// not in backends2, closed
verify(subchannel1).shutdown();
// backends2[2], will be kept
verify(subchannel2, never()).shutdown();
inOrder.verify(helper, never()).createSubchannel(eq(new EquivalentAddressGroup(backends2.get(2).addr)), any(Attributes.class));
inOrder.verify(helper).createSubchannel(eq(new EquivalentAddressGroup(backends2.get(0).addr)), any(Attributes.class));
assertEquals(1, mockSubchannels.size());
Subchannel subchannel3 = mockSubchannels.poll();
verify(subchannel3).requestConnection();
assertEquals(new EquivalentAddressGroup(backends2.get(0).addr), subchannel3.getAddresses());
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker7 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker7.list).containsExactly(GrpclbLoadBalancer.DROP_ENTRY);
// State updates on obsolete subchannel1 will have no effect
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(READY));
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE));
deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(SHUTDOWN));
inOrder.verifyNoMoreInteractions();
deliverSubchannelState(subchannel3, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker8 = (RoundRobinPicker) pickerCaptor.getValue();
// subchannel2 is still IDLE, thus not in the active list
assertThat(picker8.list).containsExactly(new RoundRobinEntry(subchannel3, "token0003"), GrpclbLoadBalancer.DROP_ENTRY, new RoundRobinEntry(subchannel3, "token0005")).inOrder();
// subchannel2 becomes READY and makes it into the list
deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updatePicker(pickerCaptor.capture());
RoundRobinPicker picker9 = (RoundRobinPicker) pickerCaptor.getValue();
assertThat(picker9.list).containsExactly(new RoundRobinEntry(subchannel3, "token0003"), GrpclbLoadBalancer.DROP_ENTRY, new RoundRobinEntry(subchannel2, "token0004"), new RoundRobinEntry(subchannel3, "token0005")).inOrder();
verify(subchannel3, never()).shutdown();
assertFalse(oobChannel.isShutdown());
assertEquals(1, lbRequestObservers.size());
verify(lbRequestObservers.peek(), never()).onCompleted();
verify(lbRequestObservers.peek(), never()).onError(any(Throwable.class));
}
use of io.grpc.Attributes in project grpc-java by grpc.
the class ServerImplTest method transportFilters.
@Test
public void transportFilters() throws Exception {
final SocketAddress remoteAddr = mock(SocketAddress.class);
final Attributes.Key<String> key1 = Attributes.Key.of("test-key1");
final Attributes.Key<String> key2 = Attributes.Key.of("test-key2");
final Attributes.Key<String> key3 = Attributes.Key.of("test-key3");
final AtomicReference<Attributes> filter1TerminationCallbackArgument = new AtomicReference<Attributes>();
final AtomicReference<Attributes> filter2TerminationCallbackArgument = new AtomicReference<Attributes>();
final AtomicInteger readyCallbackCalled = new AtomicInteger(0);
final AtomicInteger terminationCallbackCalled = new AtomicInteger(0);
ServerTransportFilter filter1 = new ServerTransportFilter() {
@Override
public Attributes transportReady(Attributes attrs) {
assertEquals(Attributes.newBuilder().set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, remoteAddr).build(), attrs);
readyCallbackCalled.incrementAndGet();
return Attributes.newBuilder(attrs).set(key1, "yalayala").set(key2, "blabla").build();
}
@Override
public void transportTerminated(Attributes attrs) {
terminationCallbackCalled.incrementAndGet();
filter1TerminationCallbackArgument.set(attrs);
}
};
ServerTransportFilter filter2 = new ServerTransportFilter() {
@Override
public Attributes transportReady(Attributes attrs) {
assertEquals(Attributes.newBuilder().set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, remoteAddr).set(key1, "yalayala").set(key2, "blabla").build(), attrs);
readyCallbackCalled.incrementAndGet();
return Attributes.newBuilder(attrs).set(key1, "ouch").set(key3, "puff").build();
}
@Override
public void transportTerminated(Attributes attrs) {
terminationCallbackCalled.incrementAndGet();
filter2TerminationCallbackArgument.set(attrs);
}
};
Attributes expectedTransportAttrs = Attributes.newBuilder().set(key1, "ouch").set(key2, "blabla").set(key3, "puff").set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, remoteAddr).build();
createAndStartServer(ImmutableList.of(filter1, filter2));
ServerTransportListener transportListener = transportServer.registerNewServerTransport(new SimpleServerTransport());
Attributes transportAttrs = transportListener.transportReady(Attributes.newBuilder().set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, remoteAddr).build());
assertEquals(expectedTransportAttrs, transportAttrs);
server.shutdown();
server.awaitTermination();
assertEquals(expectedTransportAttrs, filter1TerminationCallbackArgument.get());
assertEquals(expectedTransportAttrs, filter2TerminationCallbackArgument.get());
assertEquals(2, readyCallbackCalled.get());
assertEquals(2, terminationCallbackCalled.get());
}
use of io.grpc.Attributes in project grpc-java by grpc.
the class ManagedChannelImplTest method subchannels.
@Test
public void subchannels() {
createChannel(new FakeNameResolverFactory(true), NO_INTERCEPTOR);
// createSubchannel() always return a new Subchannel
Attributes attrs1 = Attributes.newBuilder().set(SUBCHANNEL_ATTR_KEY, "attr1").build();
Attributes attrs2 = Attributes.newBuilder().set(SUBCHANNEL_ATTR_KEY, "attr2").build();
Subchannel sub1 = helper.createSubchannel(addressGroup, attrs1);
Subchannel sub2 = helper.createSubchannel(addressGroup, attrs2);
assertNotSame(sub1, sub2);
assertNotSame(attrs1, attrs2);
assertSame(attrs1, sub1.getAttributes());
assertSame(attrs2, sub2.getAttributes());
assertSame(addressGroup, sub1.getAddresses());
assertSame(addressGroup, sub2.getAddresses());
// requestConnection()
verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), any(String.class), any(String.class));
sub1.requestConnection();
verify(mockTransportFactory).newClientTransport(socketAddress, authority, userAgent);
MockClientTransportInfo transportInfo1 = transports.poll();
assertNotNull(transportInfo1);
sub2.requestConnection();
verify(mockTransportFactory, times(2)).newClientTransport(socketAddress, authority, userAgent);
MockClientTransportInfo transportInfo2 = transports.poll();
assertNotNull(transportInfo2);
sub1.requestConnection();
sub2.requestConnection();
verify(mockTransportFactory, times(2)).newClientTransport(socketAddress, authority, userAgent);
// shutdown() has a delay
sub1.shutdown();
timer.forwardTime(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS - 1, TimeUnit.SECONDS);
sub1.shutdown();
verify(transportInfo1.transport, never()).shutdown();
timer.forwardTime(1, TimeUnit.SECONDS);
verify(transportInfo1.transport).shutdown();
// ... but not after Channel is terminating
verify(mockLoadBalancer, never()).shutdown();
channel.shutdown();
verify(mockLoadBalancer).shutdown();
verify(transportInfo2.transport, never()).shutdown();
sub2.shutdown();
verify(transportInfo2.transport).shutdown();
}
use of io.grpc.Attributes in project grpc-java by grpc.
the class ClientCallImplTest method getAttributes.
@Test
public void getAttributes() {
ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>(method, MoreExecutors.directExecutor(), CallOptions.DEFAULT, statsTraceCtx, provider, deadlineCancellationExecutor);
Attributes attrs = Attributes.newBuilder().set(Key.<String>of("fake key"), "fake value").build();
when(stream.getAttributes()).thenReturn(attrs);
assertNotEquals(attrs, call.getAttributes());
call.start(callListener, new Metadata());
assertEquals(attrs, call.getAttributes());
}
Aggregations