mirror of https://github.com/grpc/grpc-java.git
xds: fix the new server API for ServerXdsClient (#7666)
This commit is contained in:
parent
192614bf51
commit
3811ef3d22
|
|
@ -58,7 +58,7 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
private int listenerPort = -1;
|
||||
private final boolean newServerApi;
|
||||
@Nullable private final String instanceIp;
|
||||
private final String grpcServerResourceId;
|
||||
private String grpcServerResourceId;
|
||||
@Nullable
|
||||
private ScheduledHandle ldsRespTimer;
|
||||
|
||||
|
|
@ -78,6 +78,13 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
listenerWatcher = checkNotNull(watcher, "watcher");
|
||||
checkArgument(port > 0, "port needs to be > 0");
|
||||
listenerPort = port;
|
||||
if (newServerApi) {
|
||||
String listeningAddress = instanceIp + ":" + listenerPort;
|
||||
grpcServerResourceId =
|
||||
grpcServerResourceId + "?udpa.resource.listening_address=" + listeningAddress;
|
||||
} else {
|
||||
grpcServerResourceId = ":" + listenerPort;
|
||||
}
|
||||
getSyncContext().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -90,7 +97,7 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
ldsRespTimer =
|
||||
getSyncContext()
|
||||
.schedule(
|
||||
new ListenerResourceFetchTimeoutTask(":" + port),
|
||||
new ListenerResourceFetchTimeoutTask(grpcServerResourceId),
|
||||
INITIAL_RESOURCE_FETCH_TIMEOUT_SEC, TimeUnit.SECONDS, getTimeService());
|
||||
}
|
||||
}
|
||||
|
|
@ -101,10 +108,7 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
@Override
|
||||
Collection<String> getSubscribedResources(ResourceType type) {
|
||||
if (newServerApi) {
|
||||
String listeningAddress = instanceIp + ":" + listenerPort;
|
||||
String resourceName =
|
||||
grpcServerResourceId + "?udpa.resource.listening_address=" + listeningAddress;
|
||||
return ImmutableList.<String>of(resourceName);
|
||||
return ImmutableList.<String>of(grpcServerResourceId);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -161,7 +165,7 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
}
|
||||
} else {
|
||||
if (ldsRespTimer == null) {
|
||||
listenerWatcher.onResourceDoesNotExist(":" + listenerPort);
|
||||
listenerWatcher.onResourceDoesNotExist(grpcServerResourceId);
|
||||
}
|
||||
}
|
||||
ackResponse(ResourceType.LDS, versionInfo, nonce);
|
||||
|
|
@ -172,17 +176,16 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
|
||||
private boolean isRequestedListener(Listener listener) {
|
||||
if (newServerApi) {
|
||||
return "TRAFFICDIRECTOR_INBOUND_LISTENER".equals(listener.getName())
|
||||
return grpcServerResourceId.equals(listener.getName())
|
||||
&& listener.getTrafficDirection().equals(TrafficDirection.INBOUND)
|
||||
&& hasMatchingFilter(listener.getFilterChainsList());
|
||||
&& isAddressMatching(listener.getAddress(), listenerPort);
|
||||
}
|
||||
return isAddressMatching(listener.getAddress())
|
||||
return isAddressMatching(listener.getAddress(), 15001)
|
||||
&& hasMatchingFilter(listener.getFilterChainsList());
|
||||
}
|
||||
|
||||
private boolean isAddressMatching(Address address) {
|
||||
return newServerApi || (address.hasSocketAddress()
|
||||
&& (address.getSocketAddress().getPortValue() == 15001));
|
||||
private boolean isAddressMatching(Address address, int portToMatch) {
|
||||
return address.hasSocketAddress() && (address.getSocketAddress().getPortValue() == portToMatch);
|
||||
}
|
||||
|
||||
private boolean hasMatchingFilter(List<FilterChain> filterChainsList) {
|
||||
|
|
@ -211,7 +214,7 @@ final class ServerXdsClient extends AbstractXdsClient {
|
|||
ldsRespTimer =
|
||||
getSyncContext()
|
||||
.schedule(
|
||||
new ListenerResourceFetchTimeoutTask(":" + listenerPort),
|
||||
new ListenerResourceFetchTimeoutTask(grpcServerResourceId),
|
||||
INITIAL_RESOURCE_FETCH_TIMEOUT_SEC, TimeUnit.SECONDS, getTimeService());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public final class XdsClientWrapperForServerSds {
|
|||
private final int port;
|
||||
private ScheduledExecutorService timeService;
|
||||
private XdsClient.ListenerWatcher listenerWatcher;
|
||||
private boolean newServerApi;
|
||||
@VisibleForTesting final Set<ServerWatcher> serverWatchers = new HashSet<>();
|
||||
|
||||
/**
|
||||
|
|
@ -109,6 +110,7 @@ public final class XdsClientWrapperForServerSds {
|
|||
}
|
||||
Node node = bootstrapInfo.getNode();
|
||||
timeService = SharedResourceHolder.get(timeServiceResource);
|
||||
newServerApi = channel.isUseProtocolV3() && experimentalNewServerApiEnvVar;
|
||||
XdsClient xdsClientImpl =
|
||||
new ServerXdsClient(
|
||||
channel,
|
||||
|
|
@ -180,7 +182,8 @@ public final class XdsClientWrapperForServerSds {
|
|||
FilterChainComparator comparator = new FilterChainComparator(localInetAddr);
|
||||
FilterChain bestMatch =
|
||||
filterChains.isEmpty() ? null : Collections.max(filterChains, comparator);
|
||||
if (bestMatch != null && comparator.isMatching(bestMatch.getFilterChainMatch())) {
|
||||
if (bestMatch != null
|
||||
&& (newServerApi || comparator.isMatching(bestMatch.getFilterChainMatch()))) {
|
||||
return bestMatch.getDownstreamTlsContext();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ public class ServerXdsClientNewServerApiTest {
|
|||
StreamObserver<DiscoveryResponse> responseObserver = responseObservers.poll();
|
||||
StreamObserver<DiscoveryRequest> requestObserver = requestObservers.poll();
|
||||
|
||||
// Client sends an LDS request with null in lds resource name
|
||||
verify(requestObserver)
|
||||
.onNext(eq(XdsClientTestHelper.buildDiscoveryRequest(NODE, "",
|
||||
ImmutableList.of("test/value?udpa.resource.listening_address=192.168.3.7:7000"),
|
||||
|
|
@ -262,7 +261,8 @@ public class ServerXdsClientNewServerApiTest {
|
|||
verify(listenerWatcher, never()).onResourceDoesNotExist(":" + PORT);
|
||||
verify(listenerWatcher, never()).onError(any(Status.class));
|
||||
fakeClock.forwardTime(ServerXdsClient.INITIAL_RESOURCE_FETCH_TIMEOUT_SEC, TimeUnit.SECONDS);
|
||||
verify(listenerWatcher).onResourceDoesNotExist(":" + PORT);
|
||||
verify(listenerWatcher)
|
||||
.onResourceDoesNotExist("test/value?udpa.resource.listening_address=192.168.3.7:" + PORT);
|
||||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).isEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -273,7 +273,6 @@ public class ServerXdsClientNewServerApiTest {
|
|||
StreamObserver<DiscoveryResponse> responseObserver = responseObservers.poll();
|
||||
StreamObserver<DiscoveryRequest> requestObserver = requestObservers.poll();
|
||||
|
||||
// Client sends an LDS request with null in lds resource name
|
||||
verify(requestObserver)
|
||||
.onNext(
|
||||
eq(
|
||||
|
|
@ -286,27 +285,31 @@ public class ServerXdsClientNewServerApiTest {
|
|||
"")));
|
||||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).hasSize(1);
|
||||
|
||||
final FilterChain filterChainOutbound = buildFilterChain(buildFilterChainMatch(8000), null);
|
||||
final FilterChain filterChainInbound = buildFilterChain(buildFilterChainMatch(PORT,
|
||||
CidrRange.newBuilder().setAddressPrefix(LOCAL_IP)
|
||||
.setPrefixLen(UInt32Value.of(32)).build()),
|
||||
final FilterChain filterChainInbound = buildFilterChain(buildFilterChainMatch("managed-mtls"),
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext("google-sds-config-default",
|
||||
"ROOTCA"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
List<Any> listeners = ImmutableList.of(
|
||||
Any.pack(buildListener("bar.googleapis.com",
|
||||
Any.pack(HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration("route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(buildListenerWithFilterChain(LISTENER_NAME, 15001, "0.0.0.0",
|
||||
filterChainOutbound,
|
||||
filterChainInbound
|
||||
)));
|
||||
List<Any> listeners =
|
||||
ImmutableList.of(
|
||||
Any.pack(
|
||||
buildListener(
|
||||
"bar.googleapis.com",
|
||||
Any.pack(
|
||||
HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration(
|
||||
"route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(
|
||||
buildListenerWithFilterChain(
|
||||
"test/value?udpa.resource.listening_address=192.168.3.7:7000",
|
||||
7000,
|
||||
"0.0.0.0",
|
||||
filterChainInbound)));
|
||||
DiscoveryResponse response =
|
||||
buildDiscoveryResponse("0", listeners, ResourceType.LDS.typeUrl(), "0000");
|
||||
responseObserver.onNext(response);
|
||||
|
|
@ -327,20 +330,12 @@ public class ServerXdsClientNewServerApiTest {
|
|||
verify(listenerWatcher, times(1)).onListenerChanged(listenerUpdateCaptor.capture());
|
||||
ListenerUpdate configUpdate = listenerUpdateCaptor.getValue();
|
||||
EnvoyServerProtoData.Listener listener = configUpdate.getListener();
|
||||
assertThat(listener.getName()).isEqualTo(LISTENER_NAME);
|
||||
assertThat(listener.getAddress()).isEqualTo("0.0.0.0:15001");
|
||||
assertThat(listener.getFilterChains()).hasSize(2);
|
||||
EnvoyServerProtoData.FilterChain filterChainOutboundInListenerUpdate
|
||||
= listener.getFilterChains().get(0);
|
||||
assertThat(filterChainOutboundInListenerUpdate.getFilterChainMatch().getDestinationPort())
|
||||
.isEqualTo(8000);
|
||||
assertThat(listener.getName())
|
||||
.isEqualTo("test/value?udpa.resource.listening_address=192.168.3.7:7000");
|
||||
assertThat(listener.getAddress()).isEqualTo("0.0.0.0:7000");
|
||||
assertThat(listener.getFilterChains()).hasSize(1);
|
||||
EnvoyServerProtoData.FilterChain filterChainInboundInListenerUpdate
|
||||
= listener.getFilterChains().get(1);
|
||||
EnvoyServerProtoData.FilterChainMatch inBoundfilterChainMatch =
|
||||
filterChainInboundInListenerUpdate.getFilterChainMatch();
|
||||
assertThat(inBoundfilterChainMatch.getDestinationPort()).isEqualTo(PORT);
|
||||
assertThat(inBoundfilterChainMatch.getPrefixRanges()).containsExactly(
|
||||
new EnvoyServerProtoData.CidrRange(LOCAL_IP, 32));
|
||||
= listener.getFilterChains().get(0);
|
||||
CommonTlsContext downstreamCommonTlsContext =
|
||||
filterChainInboundInListenerUpdate.getDownstreamTlsContext().getCommonTlsContext();
|
||||
assertThat(downstreamCommonTlsContext.getTlsCertificateSdsSecretConfigs(0).getName())
|
||||
|
|
@ -357,32 +352,23 @@ public class ServerXdsClientNewServerApiTest {
|
|||
/** Client receives LDS responses for updating Listener previously received. */
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void notifyUpdatedListener() throws InvalidProtocolBufferException {
|
||||
public void notifyUpdatedListener() {
|
||||
xdsClient.watchListenerData(PORT, listenerWatcher);
|
||||
StreamObserver<DiscoveryResponse> responseObserver = responseObservers.poll();
|
||||
StreamObserver<DiscoveryRequest> requestObserver = requestObservers.poll();
|
||||
|
||||
final FilterChain filterChainOutbound = buildFilterChain(buildFilterChainMatch(8000), null);
|
||||
final FilterChain filterChainInbound = buildFilterChain(buildFilterChainMatch(PORT,
|
||||
CidrRange.newBuilder().setAddressPrefix(LOCAL_IP)
|
||||
.setPrefixLen(UInt32Value.of(32)).build()),
|
||||
final FilterChain filterChainInbound = buildFilterChain(buildFilterChainMatch("managed-mtls"),
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext("google-sds-config-default",
|
||||
"ROOTCA"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
List<Any> listeners = ImmutableList.of(
|
||||
Any.pack(buildListener("bar.googleapis.com",
|
||||
Any.pack(HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration("route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(buildListenerWithFilterChain(LISTENER_NAME, 15001, "0.0.0.0",
|
||||
filterChainOutbound,
|
||||
filterChainInbound
|
||||
)));
|
||||
List<Any> listeners =
|
||||
ImmutableList.of(
|
||||
Any.pack(
|
||||
buildListenerWithFilterChain(
|
||||
"test/value?udpa.resource.listening_address=192.168.3.7:7000",
|
||||
7000,
|
||||
"0.0.0.0",
|
||||
filterChainInbound)));
|
||||
DiscoveryResponse response =
|
||||
buildDiscoveryResponse("0", listeners, ResourceType.LDS.typeUrl(), "0000");
|
||||
responseObserver.onNext(response);
|
||||
|
|
@ -392,17 +378,20 @@ public class ServerXdsClientNewServerApiTest {
|
|||
|
||||
reset(requestObserver);
|
||||
// Management server sends another LDS response with updates for Listener.
|
||||
final FilterChain filterChainNewInbound = buildFilterChain(buildFilterChainMatch(PORT,
|
||||
CidrRange.newBuilder().setAddressPrefix(LOCAL_IP)
|
||||
.setPrefixLen(UInt32Value.of(32)).build()),
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext("google-sds-config-default1",
|
||||
"ROOTCA2"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
final FilterChain filterChainNewInbound =
|
||||
buildFilterChain(
|
||||
buildFilterChainMatch("managed-mtls"),
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default1", "ROOTCA2"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
List<Any> listeners1 =
|
||||
ImmutableList.of(
|
||||
Any.pack(
|
||||
buildListenerWithFilterChain(
|
||||
LISTENER_NAME, 15001, "0.0.0.0", filterChainNewInbound)));
|
||||
"test/value?udpa.resource.listening_address=192.168.3.7:7000",
|
||||
7000,
|
||||
"0.0.0.0",
|
||||
filterChainNewInbound)));
|
||||
DiscoveryResponse response1 =
|
||||
buildDiscoveryResponse("1", listeners1, ResourceType.LDS.typeUrl(), "0001");
|
||||
responseObserver.onNext(response1);
|
||||
|
|
@ -424,14 +413,11 @@ public class ServerXdsClientNewServerApiTest {
|
|||
verify(listenerWatcher, times(2)).onListenerChanged(listenerUpdateCaptor.capture());
|
||||
ListenerUpdate configUpdate = listenerUpdateCaptor.getValue();
|
||||
EnvoyServerProtoData.Listener listener = configUpdate.getListener();
|
||||
assertThat(listener.getName()).isEqualTo(LISTENER_NAME);
|
||||
assertThat(listener.getName())
|
||||
.isEqualTo("test/value?udpa.resource.listening_address=192.168.3.7:7000");
|
||||
assertThat(listener.getFilterChains()).hasSize(1);
|
||||
EnvoyServerProtoData.FilterChain filterChain =
|
||||
Iterables.getOnlyElement(listener.getFilterChains());
|
||||
EnvoyServerProtoData.FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch();
|
||||
assertThat(filterChainMatch.getDestinationPort()).isEqualTo(PORT);
|
||||
assertThat(filterChainMatch.getPrefixRanges()).containsExactly(
|
||||
new EnvoyServerProtoData.CidrRange(LOCAL_IP, 32));
|
||||
CommonTlsContext downstreamCommonTlsContext =
|
||||
filterChain.getDownstreamTlsContext().getCommonTlsContext();
|
||||
assertThat(downstreamCommonTlsContext.getTlsCertificateSdsSecretConfigs(0).getName())
|
||||
|
|
@ -444,45 +430,48 @@ public class ServerXdsClientNewServerApiTest {
|
|||
.isEqualTo("ROOTCA2");
|
||||
}
|
||||
|
||||
/** Client receives LDS response containing non-matching port in the filterMatch. */
|
||||
/** Client receives LDS response containing non-matching port. */
|
||||
@Test
|
||||
public void ldsResponse_nonMatchingPort() {
|
||||
xdsClient.watchListenerData(PORT, listenerWatcher);
|
||||
StreamObserver<DiscoveryResponse> responseObserver = responseObservers.poll();
|
||||
requestObservers.poll();
|
||||
|
||||
final FilterChain filterChainInbound = buildFilterChain(buildFilterChainMatch(8000), null);
|
||||
final FilterChain filterChainOutbound = buildFilterChain(buildFilterChainMatch(
|
||||
PORT + 1, // add 1 to mismatch
|
||||
CidrRange.newBuilder().setAddressPrefix(LOCAL_IP)
|
||||
.setPrefixLen(UInt32Value.of(32)).build()),
|
||||
final FilterChain filterChainInbound =
|
||||
buildFilterChain(buildFilterChainMatch("managed-mtls"), null);
|
||||
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext("google-sds-config-default",
|
||||
"ROOTCA"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
List<Any> listeners = ImmutableList.of(
|
||||
Any.pack(buildListener("bar.googleapis.com",
|
||||
Any.pack(HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration("route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(buildListenerWithFilterChain(LISTENER_NAME, PORT, "0.0.0.0",
|
||||
filterChainInbound,
|
||||
filterChainOutbound
|
||||
)));
|
||||
List<Any> listeners =
|
||||
ImmutableList.of(
|
||||
Any.pack(
|
||||
buildListener(
|
||||
"bar.googleapis.com",
|
||||
Any.pack(
|
||||
HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration(
|
||||
"route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(
|
||||
buildListenerWithFilterChain(
|
||||
"test/value?udpa.resource.listening_address=192.168.3.7:7000",
|
||||
PORT + 1,
|
||||
"0.0.0.0",
|
||||
filterChainInbound)));
|
||||
DiscoveryResponse response =
|
||||
buildDiscoveryResponse("0", listeners, ResourceType.LDS.typeUrl(), "0000");
|
||||
responseObserver.onNext(response);
|
||||
|
||||
verify(listenerWatcher, never()).onListenerChanged(any(ListenerUpdate.class));
|
||||
verify(listenerWatcher, never()).onResourceDoesNotExist(":" + PORT);
|
||||
verify(listenerWatcher, never())
|
||||
.onResourceDoesNotExist("test/value?udpa.resource.listening_address=192.168.3.7:" + PORT);
|
||||
verify(listenerWatcher, never()).onError(any(Status.class));
|
||||
fakeClock.forwardTime(ServerXdsClient.INITIAL_RESOURCE_FETCH_TIMEOUT_SEC, TimeUnit.SECONDS);
|
||||
verify(listenerWatcher).onResourceDoesNotExist(":" + PORT);
|
||||
verify(listenerWatcher)
|
||||
.onResourceDoesNotExist("test/value?udpa.resource.listening_address=192.168.3.7:" + PORT);
|
||||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).isEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -670,6 +659,10 @@ public class ServerXdsClientNewServerApiTest {
|
|||
.build();
|
||||
}
|
||||
|
||||
static FilterChainMatch buildFilterChainMatch(String...values) {
|
||||
return FilterChainMatch.newBuilder().addAllApplicationProtocols(Arrays.asList(values)).build();
|
||||
}
|
||||
|
||||
static Filter buildTestFilter(String name) {
|
||||
return
|
||||
Filter.newBuilder()
|
||||
|
|
|
|||
Loading…
Reference in New Issue