diff --git a/xds/src/main/java/io/grpc/xds/AbstractXdsClient.java b/xds/src/main/java/io/grpc/xds/AbstractXdsClient.java index 76d60a40c4..5e958d9815 100644 --- a/xds/src/main/java/io/grpc/xds/AbstractXdsClient.java +++ b/xds/src/main/java/io/grpc/xds/AbstractXdsClient.java @@ -227,11 +227,7 @@ final class AbstractXdsClient { // Must be synchronized. private void startRpcStream() { checkState(adsStream == null, "Previous adsStream has not been cleared yet"); - if (serverInfo.useProtocolV3()) { - adsStream = new AdsStreamV3(); - } else { - adsStream = new AdsStreamV2(); - } + adsStream = new AdsStreamV3(); Context prevContext = context.attach(); try { adsStream.start(); @@ -364,102 +360,6 @@ final class AbstractXdsClient { } } - private final class AdsStreamV2 extends AbstractAdsStream { - private StreamObserver requestWriter; - - @Override - public boolean isReady() { - return requestWriter != null && ((ClientCallStreamObserver) requestWriter).isReady(); - } - - @Override - void start() { - io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc - .AggregatedDiscoveryServiceStub stub = - io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc.newStub(channel); - StreamObserver responseReaderV2 = - new ClientResponseObserver() { - - @Override - public void beforeStart( - ClientCallStreamObserver reqStream) { - reqStream.setOnReadyHandler(AbstractXdsClient.this::readyHandler); - } - - @Override - public void onNext(final io.envoyproxy.envoy.api.v2.DiscoveryResponse response) { - syncContext.execute(new Runnable() { - @Override - public void run() { - XdsResourceType type = fromTypeUrl(response.getTypeUrl()); - if (logger.isLoggable(XdsLogLevel.DEBUG)) { - logger.log( - XdsLogLevel.DEBUG, "Received {0} response:\n{1}", type, - MessagePrinter.print(response)); - } - handleRpcResponse(type, response.getVersionInfo(), response.getResourcesList(), - response.getNonce()); - } - }); - } - - @Override - public void onError(final Throwable t) { - syncContext.execute(new Runnable() { - @Override - public void run() { - handleRpcError(t); - } - }); - } - - @Override - public void onCompleted() { - syncContext.execute(new Runnable() { - @Override - public void run() { - handleRpcCompleted(); - } - }); - } - }; - requestWriter = stub.withWaitForReady().streamAggregatedResources(responseReaderV2); - } - - @Override - void sendDiscoveryRequest(XdsResourceType type, String versionInfo, - Collection resources, String nonce, - @Nullable String errorDetail) { - checkState(requestWriter != null, "ADS stream has not been started"); - io.envoyproxy.envoy.api.v2.DiscoveryRequest.Builder builder = - io.envoyproxy.envoy.api.v2.DiscoveryRequest.newBuilder() - .setVersionInfo(versionInfo) - .setNode(bootstrapNode.toEnvoyProtoNodeV2()) - .addAllResourceNames(resources) - .setTypeUrl(type.typeUrlV2()) - .setResponseNonce(nonce); - if (errorDetail != null) { - com.google.rpc.Status error = - com.google.rpc.Status.newBuilder() - .setCode(Code.INVALID_ARGUMENT_VALUE) // FIXME(chengyuanzhang): use correct code - .setMessage(errorDetail) - .build(); - builder.setErrorDetail(error); - } - io.envoyproxy.envoy.api.v2.DiscoveryRequest request = builder.build(); - requestWriter.onNext(request); - if (logger.isLoggable(XdsLogLevel.DEBUG)) { - logger.log(XdsLogLevel.DEBUG, "Sent DiscoveryRequest\n{0}", MessagePrinter.print(request)); - } - } - - @Override - void sendError(Exception error) { - requestWriter.onError(error); - } - } - private final class AdsStreamV3 extends AbstractAdsStream { private StreamObserver requestWriter; diff --git a/xds/src/main/java/io/grpc/xds/Bootstrapper.java b/xds/src/main/java/io/grpc/xds/Bootstrapper.java index 9d0a65a6f4..df997c088d 100644 --- a/xds/src/main/java/io/grpc/xds/Bootstrapper.java +++ b/xds/src/main/java/io/grpc/xds/Bootstrapper.java @@ -60,22 +60,19 @@ public abstract class Bootstrapper { abstract ChannelCredentials channelCredentials(); - abstract boolean useProtocolV3(); - abstract boolean ignoreResourceDeletion(); @VisibleForTesting static ServerInfo create( - String target, ChannelCredentials channelCredentials, boolean useProtocolV3) { - return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials, useProtocolV3, - false); + String target, ChannelCredentials channelCredentials) { + return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials, false); } @VisibleForTesting static ServerInfo create( - String target, ChannelCredentials channelCredentials, boolean useProtocolV3, + String target, ChannelCredentials channelCredentials, boolean ignoreResourceDeletion) { - return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials, useProtocolV3, + return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials, ignoreResourceDeletion); } } diff --git a/xds/src/main/java/io/grpc/xds/BootstrapperImpl.java b/xds/src/main/java/io/grpc/xds/BootstrapperImpl.java index 9082df3129..6d0e78a2c4 100644 --- a/xds/src/main/java/io/grpc/xds/BootstrapperImpl.java +++ b/xds/src/main/java/io/grpc/xds/BootstrapperImpl.java @@ -68,7 +68,6 @@ class BootstrapperImpl extends Bootstrapper { static final String CLIENT_FEATURE_RESOURCE_IN_SOTW = "xds.config.resource-in-sotw"; // Server features. - private static final String SERVER_FEATURE_XDS_V3 = "xds_v3"; private static final String SERVER_FEATURE_IGNORE_RESOURCE_DELETION = "ignore_resource_deletion"; private final XdsLogger logger; @@ -281,16 +280,14 @@ class BootstrapperImpl extends Bootstrapper { "Server " + serverUri + ": no supported channel credentials found"); } - boolean useProtocolV3 = false; boolean ignoreResourceDeletion = false; List serverFeatures = JsonUtil.getListOfStrings(serverConfig, "server_features"); if (serverFeatures != null) { logger.log(XdsLogLevel.INFO, "Server features: {0}", serverFeatures); - useProtocolV3 = serverFeatures.contains(SERVER_FEATURE_XDS_V3); ignoreResourceDeletion = serverFeatures.contains(SERVER_FEATURE_IGNORE_RESOURCE_DELETION); } servers.add( - ServerInfo.create(serverUri, channelCredentials, useProtocolV3, ignoreResourceDeletion)); + ServerInfo.create(serverUri, channelCredentials, ignoreResourceDeletion)); } return servers.build(); } diff --git a/xds/src/main/java/io/grpc/xds/EnvoyProtoData.java b/xds/src/main/java/io/grpc/xds/EnvoyProtoData.java index 8274b23a5d..cb4fc4ee30 100644 --- a/xds/src/main/java/io/grpc/xds/EnvoyProtoData.java +++ b/xds/src/main/java/io/grpc/xds/EnvoyProtoData.java @@ -270,38 +270,6 @@ final class EnvoyProtoData { builder.addAllClientFeatures(clientFeatures); return builder.build(); } - - @SuppressWarnings("deprecation") // Deprecated v2 API setBuildVersion(). - public io.envoyproxy.envoy.api.v2.core.Node toEnvoyProtoNodeV2() { - io.envoyproxy.envoy.api.v2.core.Node.Builder builder = - io.envoyproxy.envoy.api.v2.core.Node.newBuilder(); - builder.setId(id); - builder.setCluster(cluster); - if (metadata != null) { - Struct.Builder structBuilder = Struct.newBuilder(); - for (Map.Entry entry : metadata.entrySet()) { - structBuilder.putFields(entry.getKey(), convertToValue(entry.getValue())); - } - builder.setMetadata(structBuilder); - } - if (locality != null) { - builder.setLocality( - io.envoyproxy.envoy.api.v2.core.Locality.newBuilder() - .setRegion(locality.region()) - .setZone(locality.zone()) - .setSubZone(locality.subZone())); - } - for (Address address : listeningAddresses) { - builder.addListeningAddresses(address.toEnvoyProtoAddressV2()); - } - builder.setBuildVersion(buildVersion); - builder.setUserAgentName(userAgentName); - if (userAgentVersion != null) { - builder.setUserAgentVersion(userAgentVersion); - } - builder.addAllClientFeatures(clientFeatures); - return builder.build(); - } } /** diff --git a/xds/src/main/java/io/grpc/xds/LoadReportClient.java b/xds/src/main/java/io/grpc/xds/LoadReportClient.java index 67ec92cb88..3318dfb831 100644 --- a/xds/src/main/java/io/grpc/xds/LoadReportClient.java +++ b/xds/src/main/java/io/grpc/xds/LoadReportClient.java @@ -57,7 +57,6 @@ final class LoadReportClient { private final XdsLogger logger; private final Channel channel; private final Context context; - private final boolean useProtocolV3; private final Node node; private final SynchronizationContext syncContext; private final ScheduledExecutorService timerService; @@ -77,7 +76,6 @@ final class LoadReportClient { LoadStatsManager2 loadStatsManager, Channel channel, Context context, - boolean useProtocolV3, Node node, SynchronizationContext syncContext, ScheduledExecutorService scheduledExecutorService, @@ -86,7 +84,6 @@ final class LoadReportClient { this.loadStatsManager = checkNotNull(loadStatsManager, "loadStatsManager"); this.channel = checkNotNull(channel, "xdsChannel"); this.context = checkNotNull(context, "context"); - this.useProtocolV3 = useProtocolV3; this.syncContext = checkNotNull(syncContext, "syncContext"); this.timerService = checkNotNull(scheduledExecutorService, "timeService"); this.backoffPolicyProvider = checkNotNull(backoffPolicyProvider, "backoffPolicyProvider"); @@ -161,11 +158,7 @@ final class LoadReportClient { return; } checkState(lrsStream == null, "previous lbStream has not been cleared yet"); - if (useProtocolV3) { - lrsStream = new LrsStreamV3(); - } else { - lrsStream = new LrsStreamV2(); - } + lrsStream = new LrsStreamV3(); retryStopwatch.reset().start(); Context prevContext = context.attach(); try { @@ -175,6 +168,8 @@ final class LoadReportClient { } } + // TODO(zivy@): The abstract class was used to support xds v2 and v3. Remove abstract here since + // v2 is dropped and v3 is the only supported version now. private abstract class LrsStream { boolean initialResponseReceived; boolean closed; @@ -298,105 +293,6 @@ final class LoadReportClient { } } - private final class LrsStreamV2 extends LrsStream { - StreamObserver lrsRequestWriterV2; - - @Override - void start() { - StreamObserver - lrsResponseReaderV2 = - new StreamObserver() { - @Override - public void onNext( - final io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse response) { - syncContext.execute(new Runnable() { - @Override - public void run() { - logger.log(XdsLogLevel.DEBUG, "Received LoadStatsResponse:\n{0}", response); - handleRpcResponse(response.getClustersList(), response.getSendAllClusters(), - Durations.toNanos(response.getLoadReportingInterval())); - } - }); - } - - @Override - public void onError(final Throwable t) { - syncContext.execute(new Runnable() { - @Override - public void run() { - handleRpcError(t); - } - }); - } - - @Override - public void onCompleted() { - syncContext.execute(new Runnable() { - @Override - public void run() { - handleRpcCompleted(); - } - }); - } - }; - io.envoyproxy.envoy.service.load_stats.v2.LoadReportingServiceGrpc.LoadReportingServiceStub - stubV2 = io.envoyproxy.envoy.service.load_stats.v2.LoadReportingServiceGrpc.newStub( - channel); - lrsRequestWriterV2 = stubV2.withWaitForReady().streamLoadStats(lrsResponseReaderV2); - logger.log(XdsLogLevel.DEBUG, "Sending initial LRS request"); - sendLoadStatsRequest(Collections.emptyList()); - } - - @Override - void sendLoadStatsRequest(List clusterStatsList) { - io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest.Builder requestBuilder = - io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest.newBuilder() - .setNode(node.toEnvoyProtoNodeV2()); - for (ClusterStats stats : clusterStatsList) { - requestBuilder.addClusterStats(buildClusterStats(stats)); - } - io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest request = requestBuilder.build(); - lrsRequestWriterV2.onNext(requestBuilder.build()); - logger.log(XdsLogLevel.DEBUG, "Sent LoadStatsRequest\n{0}", request); - } - - @Override - void sendError(Exception error) { - lrsRequestWriterV2.onError(error); - } - - private io.envoyproxy.envoy.api.v2.endpoint.ClusterStats buildClusterStats( - ClusterStats stats) { - io.envoyproxy.envoy.api.v2.endpoint.ClusterStats.Builder builder = - io.envoyproxy.envoy.api.v2.endpoint.ClusterStats.newBuilder() - .setClusterName(stats.clusterName()); - if (stats.clusterServiceName() != null) { - builder.setClusterServiceName(stats.clusterServiceName()); - } - for (UpstreamLocalityStats upstreamLocalityStats : stats.upstreamLocalityStatsList()) { - builder.addUpstreamLocalityStats( - io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats.newBuilder() - .setLocality( - io.envoyproxy.envoy.api.v2.core.Locality.newBuilder() - .setRegion(upstreamLocalityStats.locality().region()) - .setZone(upstreamLocalityStats.locality().zone()) - .setSubZone(upstreamLocalityStats.locality().subZone())) - .setTotalSuccessfulRequests(upstreamLocalityStats.totalSuccessfulRequests()) - .setTotalErrorRequests(upstreamLocalityStats.totalErrorRequests()) - .setTotalRequestsInProgress(upstreamLocalityStats.totalRequestsInProgress()) - .setTotalIssuedRequests(upstreamLocalityStats.totalIssuedRequests())); - } - for (DroppedRequests droppedRequests : stats.droppedRequestsList()) { - builder.addDroppedRequests( - io.envoyproxy.envoy.api.v2.endpoint.ClusterStats.DroppedRequests.newBuilder() - .setCategory(droppedRequests.category()) - .setDroppedCount(droppedRequests.droppedCount())); - } - return builder.setTotalDroppedRequests(stats.totalDroppedRequests()) - .setLoadReportInterval(Durations.fromNanos(stats.loadReportIntervalNano())).build(); - } - } - private final class LrsStreamV3 extends LrsStream { StreamObserver lrsRequestWriterV3; diff --git a/xds/src/main/java/io/grpc/xds/XdsClientImpl.java b/xds/src/main/java/io/grpc/xds/XdsClientImpl.java index b72364530d..a79fc6bfb9 100644 --- a/xds/src/main/java/io/grpc/xds/XdsClientImpl.java +++ b/xds/src/main/java/io/grpc/xds/XdsClientImpl.java @@ -157,8 +157,8 @@ final class XdsClientImpl extends XdsClient stopwatchSupplier, this); LoadReportClient lrsClient = new LoadReportClient( - loadStatsManager, xdsChannel.channel(), context, serverInfo.useProtocolV3(), - bootstrapInfo.node(), syncContext, timeService, backoffPolicyProvider, stopwatchSupplier); + loadStatsManager, xdsChannel.channel(), context, bootstrapInfo.node(), syncContext, + timeService, backoffPolicyProvider, stopwatchSupplier); serverChannelMap.put(serverInfo, xdsChannel); serverLrsClientMap.put(serverInfo, lrsClient); } @@ -302,7 +302,6 @@ final class XdsClientImpl extends XdsClient if (!resourceSubscribers.containsKey(type)) { resourceSubscribers.put(type, new HashMap<>()); subscribedResourceTypeUrls.put(type.typeUrl(), type); - subscribedResourceTypeUrls.put(type.typeUrlV2(), type); } ResourceSubscriber subscriber = (ResourceSubscriber) resourceSubscribers.get(type).get(resourceName);; @@ -334,7 +333,6 @@ final class XdsClientImpl extends XdsClient subscriber.cancelResourceWatch(); resourceSubscribers.get(type).remove(resourceName); subscribedResourceTypeUrls.remove(type.typeUrl()); - subscribedResourceTypeUrls.remove(type.typeUrlV2()); if (subscriber.xdsChannel != null) { subscriber.xdsChannel.adjustResourceSubscription(type); } diff --git a/xds/src/main/java/io/grpc/xds/XdsClusterResource.java b/xds/src/main/java/io/grpc/xds/XdsClusterResource.java index c0d6ebeefd..33f6176474 100644 --- a/xds/src/main/java/io/grpc/xds/XdsClusterResource.java +++ b/xds/src/main/java/io/grpc/xds/XdsClusterResource.java @@ -50,7 +50,6 @@ import java.util.Set; import javax.annotation.Nullable; class XdsClusterResource extends XdsResourceType { - static final String ADS_TYPE_URL_CDS_V2 = "type.googleapis.com/envoy.api.v2.Cluster"; static final String ADS_TYPE_URL_CDS = "type.googleapis.com/envoy.config.cluster.v3.Cluster"; private static final String TYPE_URL_UPSTREAM_TLS_CONTEXT = @@ -83,11 +82,6 @@ class XdsClusterResource extends XdsResourceType { return ADS_TYPE_URL_CDS; } - @Override - String typeUrlV2() { - return ADS_TYPE_URL_CDS_V2; - } - @Override boolean isFullStateOfTheWorld() { return true; @@ -100,7 +94,7 @@ class XdsClusterResource extends XdsResourceType { } @Override - CdsUpdate doParse(Args args, Message unpackedMessage, boolean isResourceV3) + CdsUpdate doParse(Args args, Message unpackedMessage) throws ResourceInvalidException { if (!(unpackedMessage instanceof Cluster)) { throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass()); @@ -167,7 +161,7 @@ class XdsClusterResource extends XdsResourceType { try { clusterConfig = unpackCompatibleType(customType.getTypedConfig(), io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig.class, - TYPE_URL_CLUSTER_CONFIG, TYPE_URL_CLUSTER_CONFIG_V2); + TYPE_URL_CLUSTER_CONFIG, null); } catch (InvalidProtocolBufferException e) { return StructOrError.fromError("Cluster " + clusterName + ": malformed ClusterConfig: " + e); } diff --git a/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java b/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java index a44fea0c57..39caa9a859 100644 --- a/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java +++ b/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java @@ -43,8 +43,6 @@ import java.util.Set; import javax.annotation.Nullable; class XdsEndpointResource extends XdsResourceType { - static final String ADS_TYPE_URL_EDS_V2 = - "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"; static final String ADS_TYPE_URL_EDS = "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"; @@ -73,11 +71,6 @@ class XdsEndpointResource extends XdsResourceType { return ADS_TYPE_URL_EDS; } - @Override - String typeUrlV2() { - return ADS_TYPE_URL_EDS_V2; - } - @Override boolean isFullStateOfTheWorld() { return false; @@ -89,7 +82,7 @@ class XdsEndpointResource extends XdsResourceType { } @Override - EdsUpdate doParse(Args args, Message unpackedMessage, boolean isResourceV3) + EdsUpdate doParse(Args args, Message unpackedMessage) throws ResourceInvalidException { if (!(unpackedMessage instanceof ClusterLoadAssignment)) { throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass()); diff --git a/xds/src/main/java/io/grpc/xds/XdsListenerResource.java b/xds/src/main/java/io/grpc/xds/XdsListenerResource.java index f367bd9690..789f78ba5b 100644 --- a/xds/src/main/java/io/grpc/xds/XdsListenerResource.java +++ b/xds/src/main/java/io/grpc/xds/XdsListenerResource.java @@ -52,12 +52,8 @@ import java.util.Set; import javax.annotation.Nullable; class XdsListenerResource extends XdsResourceType { - static final String ADS_TYPE_URL_LDS_V2 = "type.googleapis.com/envoy.api.v2.Listener"; static final String ADS_TYPE_URL_LDS = "type.googleapis.com/envoy.config.listener.v3.Listener"; - private static final String TYPE_URL_HTTP_CONNECTION_MANAGER_V2 = - "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2" - + ".HttpConnectionManager"; static final String TYPE_URL_HTTP_CONNECTION_MANAGER = "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3" + ".HttpConnectionManager"; @@ -92,18 +88,13 @@ class XdsListenerResource extends XdsResourceType { return ADS_TYPE_URL_LDS; } - @Override - String typeUrlV2() { - return ADS_TYPE_URL_LDS_V2; - } - @Override boolean isFullStateOfTheWorld() { return true; } @Override - LdsUpdate doParse(Args args, Message unpackedMessage, boolean isResourceV3) + LdsUpdate doParse(Args args, Message unpackedMessage) throws ResourceInvalidException { if (!(unpackedMessage instanceof Listener)) { throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass()); @@ -112,10 +103,10 @@ class XdsListenerResource extends XdsResourceType { if (listener.hasApiListener()) { return processClientSideListener( - listener, args, enableFaultInjection && isResourceV3); + listener, args, enableFaultInjection); } else { return processServerSideListener( - listener, args, enableRbac && isResourceV3); + listener, args, enableRbac); } } @@ -126,7 +117,7 @@ class XdsListenerResource extends XdsResourceType { try { hcm = unpackCompatibleType( listener.getApiListener().getApiListener(), HttpConnectionManager.class, - TYPE_URL_HTTP_CONNECTION_MANAGER, TYPE_URL_HTTP_CONNECTION_MANAGER_V2); + TYPE_URL_HTTP_CONNECTION_MANAGER, null); } catch (InvalidProtocolBufferException e) { throw new ResourceInvalidException( "Could not parse HttpConnectionManager config from ApiListener", e); diff --git a/xds/src/main/java/io/grpc/xds/XdsNameResolver.java b/xds/src/main/java/io/grpc/xds/XdsNameResolver.java index 74e35ca3e7..094bb944d8 100644 --- a/xds/src/main/java/io/grpc/xds/XdsNameResolver.java +++ b/xds/src/main/java/io/grpc/xds/XdsNameResolver.java @@ -202,8 +202,7 @@ final class XdsNameResolver extends NameResolver { } String ldsResourceName = expandPercentS(listenerNameTemplate, replacement); if (!XdsClient.isResourceNameValid(ldsResourceName, XdsListenerResource.getInstance().typeUrl()) - && !XdsClient.isResourceNameValid(ldsResourceName, - XdsListenerResource.getInstance().typeUrlV2())) { + ) { listener.onError(Status.INVALID_ARGUMENT.withDescription( "invalid listener resource URI for service authority: " + serviceAuthority)); return; diff --git a/xds/src/main/java/io/grpc/xds/XdsResourceType.java b/xds/src/main/java/io/grpc/xds/XdsResourceType.java index 987151d899..1302f5a59e 100644 --- a/xds/src/main/java/io/grpc/xds/XdsResourceType.java +++ b/xds/src/main/java/io/grpc/xds/XdsResourceType.java @@ -39,8 +39,7 @@ import java.util.Set; import javax.annotation.Nullable; abstract class XdsResourceType { - static final String TYPE_URL_RESOURCE_V2 = "type.googleapis.com/envoy.api.v2.Resource"; - static final String TYPE_URL_RESOURCE_V3 = + static final String TYPE_URL_RESOURCE = "type.googleapis.com/envoy.service.discovery.v3.Resource"; static final String TRANSPORT_SOCKET_NAME_TLS = "envoy.transport_sockets.tls"; @VisibleForTesting @@ -65,8 +64,6 @@ abstract class XdsResourceType { @VisibleForTesting static boolean enableOutlierDetection = getFlag("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", true); - static final String TYPE_URL_CLUSTER_CONFIG_V2 = - "type.googleapis.com/envoy.config.cluster.aggregate.v2alpha.ClusterConfig"; static final String TYPE_URL_CLUSTER_CONFIG = "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig"; static final String TYPE_URL_TYPED_STRUCT_UDPA = @@ -83,8 +80,6 @@ abstract class XdsResourceType { abstract String typeUrl(); - abstract String typeUrlV2(); - // Do not confuse with the SotW approach: it is the mechanism in which the client must specify all // resource names it is interested in with each request. Different resource types may behave // differently in this approach. For LDS and CDS resources, the server must return all resources @@ -132,13 +127,10 @@ abstract class XdsResourceType { for (int i = 0; i < resources.size(); i++) { Any resource = resources.get(i); - boolean isResourceV3; Message unpackedMessage; try { resource = maybeUnwrapResources(resource); - isResourceV3 = resource.getTypeUrl().equals(typeUrl()); - unpackedMessage = unpackCompatibleType(resource, unpackedClassName(), - typeUrl(), typeUrlV2()); + unpackedMessage = unpackCompatibleType(resource, unpackedClassName(), typeUrl(), null); } catch (InvalidProtocolBufferException e) { errors.add(String.format("%s response Resource index %d - can't decode %s: %s", typeName(), i, unpackedClassName().getSimpleName(), e.getMessage())); @@ -158,7 +150,7 @@ abstract class XdsResourceType { T resourceUpdate; try { - resourceUpdate = doParse(args, unpackedMessage, isResourceV3); + resourceUpdate = doParse(args, unpackedMessage); } catch (XdsClientImpl.ResourceInvalidException e) { errors.add(String.format("%s response %s '%s' validation error: %s", typeName(), unpackedClassName().getSimpleName(), cname, e.getMessage())); @@ -174,8 +166,7 @@ abstract class XdsResourceType { } - abstract T doParse(Args args, Message unpackedMessage, boolean isResourceV3) - throws ResourceInvalidException; + abstract T doParse(Args args, Message unpackedMessage) throws ResourceInvalidException; /** * Helper method to unpack serialized {@link com.google.protobuf.Any} message, while replacing @@ -200,10 +191,9 @@ abstract class XdsResourceType { private Any maybeUnwrapResources(Any resource) throws InvalidProtocolBufferException { - if (resource.getTypeUrl().equals(TYPE_URL_RESOURCE_V2) - || resource.getTypeUrl().equals(TYPE_URL_RESOURCE_V3)) { - return unpackCompatibleType(resource, Resource.class, TYPE_URL_RESOURCE_V3, - TYPE_URL_RESOURCE_V2).getResource(); + if (resource.getTypeUrl().equals(TYPE_URL_RESOURCE)) { + return unpackCompatibleType(resource, Resource.class, TYPE_URL_RESOURCE, + null).getResource(); } else { return resource; } diff --git a/xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java b/xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java index e6c73d2df2..35d96be435 100644 --- a/xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java +++ b/xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java @@ -65,8 +65,6 @@ import java.util.Set; import javax.annotation.Nullable; class XdsRouteConfigureResource extends XdsResourceType { - static final String ADS_TYPE_URL_RDS_V2 = - "type.googleapis.com/envoy.api.v2.RouteConfiguration"; static final String ADS_TYPE_URL_RDS = "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"; private static final String TYPE_URL_FILTER_CONFIG = @@ -102,11 +100,6 @@ class XdsRouteConfigureResource extends XdsResourceType { return ADS_TYPE_URL_RDS; } - @Override - String typeUrlV2() { - return ADS_TYPE_URL_RDS_V2; - } - @Override boolean isFullStateOfTheWorld() { return false; @@ -118,13 +111,13 @@ class XdsRouteConfigureResource extends XdsResourceType { } @Override - RdsUpdate doParse(XdsResourceType.Args args, Message unpackedMessage, boolean isResourceV3) + RdsUpdate doParse(XdsResourceType.Args args, Message unpackedMessage) throws ResourceInvalidException { if (!(unpackedMessage instanceof RouteConfiguration)) { throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass()); } return processRouteConfiguration((RouteConfiguration) unpackedMessage, - args.filterRegistry, enableFaultInjection && isResourceV3); + args.filterRegistry, enableFaultInjection); } private static RdsUpdate processRouteConfiguration( diff --git a/xds/src/main/java/io/grpc/xds/XdsServerWrapper.java b/xds/src/main/java/io/grpc/xds/XdsServerWrapper.java index a58a3f6bc2..b3bbe00582 100644 --- a/xds/src/main/java/io/grpc/xds/XdsServerWrapper.java +++ b/xds/src/main/java/io/grpc/xds/XdsServerWrapper.java @@ -180,9 +180,8 @@ final class XdsServerWrapper extends Server { return; } xdsClient = xdsClientPool.getObject(); - boolean useProtocolV3 = xdsClient.getBootstrapInfo().servers().get(0).useProtocolV3(); String listenerTemplate = xdsClient.getBootstrapInfo().serverListenerResourceNameTemplate(); - if (!useProtocolV3 || listenerTemplate == null) { + if (listenerTemplate == null) { StatusException statusException = Status.UNAVAILABLE.withDescription( "Can only support xDS v3 with listener resource name template").asException(); diff --git a/xds/src/test/java/io/grpc/xds/BootstrapperImplTest.java b/xds/src/test/java/io/grpc/xds/BootstrapperImplTest.java index d6ecda1c34..7b263b27f2 100644 --- a/xds/src/test/java/io/grpc/xds/BootstrapperImplTest.java +++ b/xds/src/test/java/io/grpc/xds/BootstrapperImplTest.java @@ -579,8 +579,6 @@ public class BootstrapperImplTest { assertThat(serverInfo.target()).isEqualTo(SERVER_URI); assertThat(serverInfo.channelCredentials()).isInstanceOf(InsecureChannelCredentials.class); assertThat(serverInfo.ignoreResourceDeletion()).isFalse(); - // xds v2: xds v3 disabled - assertThat(serverInfo.useProtocolV3()).isFalse(); } @Test @@ -603,8 +601,6 @@ public class BootstrapperImplTest { assertThat(serverInfo.target()).isEqualTo(SERVER_URI); assertThat(serverInfo.channelCredentials()).isInstanceOf(InsecureChannelCredentials.class); assertThat(serverInfo.ignoreResourceDeletion()).isFalse(); - // xds_v3 enabled - assertThat(serverInfo.useProtocolV3()).isTrue(); } @Test @@ -627,7 +623,6 @@ public class BootstrapperImplTest { assertThat(serverInfo.target()).isEqualTo(SERVER_URI); assertThat(serverInfo.channelCredentials()).isInstanceOf(InsecureChannelCredentials.class); // Only ignore_resource_deletion feature enabled: confirm it's on, and xds_v3 is off. - assertThat(serverInfo.useProtocolV3()).isFalse(); assertThat(serverInfo.ignoreResourceDeletion()).isTrue(); } @@ -650,8 +645,7 @@ public class BootstrapperImplTest { ServerInfo serverInfo = Iterables.getOnlyElement(info.servers()); assertThat(serverInfo.target()).isEqualTo(SERVER_URI); assertThat(serverInfo.channelCredentials()).isInstanceOf(InsecureChannelCredentials.class); - // xds_v3 and ignore_resource_deletion features enabled: confirm both are on. - assertThat(serverInfo.useProtocolV3()).isTrue(); + // ignore_resource_deletion features enabled: confirm both are on. assertThat(serverInfo.ignoreResourceDeletion()).isTrue(); } diff --git a/xds/src/test/java/io/grpc/xds/CdsLoadBalancer2Test.java b/xds/src/test/java/io/grpc/xds/CdsLoadBalancer2Test.java index 60ddb9f3da..1818f39dd8 100644 --- a/xds/src/test/java/io/grpc/xds/CdsLoadBalancer2Test.java +++ b/xds/src/test/java/io/grpc/xds/CdsLoadBalancer2Test.java @@ -84,7 +84,7 @@ public class CdsLoadBalancer2Test { private static final String EDS_SERVICE_NAME = "backend-service-1.googleapis.com"; private static final String DNS_HOST_NAME = "backend-service-dns.googleapis.com:443"; private static final ServerInfo LRS_SERVER_INFO = - ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create(), true); + ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create()); private final UpstreamTlsContext upstreamTlsContext = CommonTlsContextTestsUtil.buildUpstreamTlsContext("google_cloud_private_spiffe", true); private final OutlierDetection outlierDetection = OutlierDetection.create( diff --git a/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java b/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java index 6d19e166a0..f553b558c9 100644 --- a/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java +++ b/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java @@ -88,7 +88,7 @@ public class ClusterImplLoadBalancerTest { private static final String CLUSTER = "cluster-foo.googleapis.com"; private static final String EDS_SERVICE_NAME = "service.googleapis.com"; private static final ServerInfo LRS_SERVER_INFO = - ServerInfo.create("api.google.com", InsecureChannelCredentials.create(), true); + ServerInfo.create("api.google.com", InsecureChannelCredentials.create()); private final SynchronizationContext syncContext = new SynchronizationContext( new Thread.UncaughtExceptionHandler() { @Override diff --git a/xds/src/test/java/io/grpc/xds/ClusterResolverLoadBalancerTest.java b/xds/src/test/java/io/grpc/xds/ClusterResolverLoadBalancerTest.java index 4d58f88e0e..51396511dc 100644 --- a/xds/src/test/java/io/grpc/xds/ClusterResolverLoadBalancerTest.java +++ b/xds/src/test/java/io/grpc/xds/ClusterResolverLoadBalancerTest.java @@ -113,7 +113,7 @@ public class ClusterResolverLoadBalancerTest { private static final String EDS_SERVICE_NAME2 = "backend-service-bar.googleapis.com"; private static final String DNS_HOST_NAME = "dns-service.googleapis.com"; private static final ServerInfo LRS_SERVER_INFO = - ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create(), true); + ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create()); private final Locality locality1 = Locality.create("test-region-1", "test-zone-1", "test-subzone-1"); private final Locality locality2 = diff --git a/xds/src/test/java/io/grpc/xds/CsdsServiceTest.java b/xds/src/test/java/io/grpc/xds/CsdsServiceTest.java index 5272a6d297..6892324a9b 100644 --- a/xds/src/test/java/io/grpc/xds/CsdsServiceTest.java +++ b/xds/src/test/java/io/grpc/xds/CsdsServiceTest.java @@ -73,7 +73,7 @@ public class CsdsServiceTest { EnvoyProtoData.Node.newBuilder().setId(NODE_ID).build(); private static final BootstrapInfo BOOTSTRAP_INFO = BootstrapInfo.builder() .servers(ImmutableList.of( - ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create(), true))) + ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create()))) .node(BOOTSTRAP_NODE) .build(); private static final FakeXdsClient XDS_CLIENT_NO_RESOURCES = new FakeXdsClient(); diff --git a/xds/src/test/java/io/grpc/xds/EnvoyProtoDataTest.java b/xds/src/test/java/io/grpc/xds/EnvoyProtoDataTest.java index 1e372e5974..046f4abcec 100644 --- a/xds/src/test/java/io/grpc/xds/EnvoyProtoDataTest.java +++ b/xds/src/test/java/io/grpc/xds/EnvoyProtoDataTest.java @@ -86,41 +86,6 @@ public class EnvoyProtoDataTest { .addClientFeatures("feature-2") .build(); assertThat(node.toEnvoyProtoNode()).isEqualTo(nodeProto); - - @SuppressWarnings("deprecation") // Deprecated v2 API setBuildVersion(). - io.envoyproxy.envoy.api.v2.core.Node nodeProtoV2 = - io.envoyproxy.envoy.api.v2.core.Node.newBuilder() - .setId("node-id") - .setCluster("cluster") - .setMetadata(Struct.newBuilder() - .putFields("TRAFFICDIRECTOR_INTERCEPTION_PORT", - Value.newBuilder().setStringValue("ENVOY_PORT").build()) - .putFields("TRAFFICDIRECTOR_NETWORK_NAME", - Value.newBuilder().setStringValue("VPC_NETWORK_NAME").build())) - .setLocality( - io.envoyproxy.envoy.api.v2.core.Locality.newBuilder() - .setRegion("region") - .setZone("zone") - .setSubZone("subzone")) - .addListeningAddresses( - io.envoyproxy.envoy.api.v2.core.Address.newBuilder() - .setSocketAddress( - io.envoyproxy.envoy.api.v2.core.SocketAddress.newBuilder() - .setAddress("www.foo.com") - .setPortValue(8080))) - .addListeningAddresses( - io.envoyproxy.envoy.api.v2.core.Address.newBuilder() - .setSocketAddress( - io.envoyproxy.envoy.api.v2.core.SocketAddress.newBuilder() - .setAddress("www.bar.com") - .setPortValue(8088))) - .setBuildVersion("v1") - .setUserAgentName("agent") - .setUserAgentVersion("1.1") - .addClientFeatures("feature-1") - .addClientFeatures("feature-2") - .build(); - assertThat(node.toEnvoyProtoNodeV2()).isEqualTo(nodeProtoV2); } @Test diff --git a/xds/src/test/java/io/grpc/xds/LoadReportClientTest.java b/xds/src/test/java/io/grpc/xds/LoadReportClientTest.java index 8cd4d28932..c04cdd3c4b 100644 --- a/xds/src/test/java/io/grpc/xds/LoadReportClientTest.java +++ b/xds/src/test/java/io/grpc/xds/LoadReportClientTest.java @@ -33,12 +33,12 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.Struct; import com.google.protobuf.Value; import com.google.protobuf.util.Durations; -import io.envoyproxy.envoy.api.v2.core.Node; -import io.envoyproxy.envoy.api.v2.endpoint.ClusterStats; -import io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats; -import io.envoyproxy.envoy.service.load_stats.v2.LoadReportingServiceGrpc; -import io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest; -import io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse; +import io.envoyproxy.envoy.config.core.v3.Node; +import io.envoyproxy.envoy.config.endpoint.v3.ClusterStats; +import io.envoyproxy.envoy.config.endpoint.v3.UpstreamLocalityStats; +import io.envoyproxy.envoy.service.load_stats.v3.LoadReportingServiceGrpc; +import io.envoyproxy.envoy.service.load_stats.v3.LoadStatsRequest; +import io.envoyproxy.envoy.service.load_stats.v3.LoadStatsResponse; import io.grpc.Context; import io.grpc.Context.CancellationListener; import io.grpc.ManagedChannel; @@ -172,7 +172,7 @@ public class LoadReportClientTest { when(backoffPolicy2.nextBackoffNanos()) .thenReturn(TimeUnit.SECONDS.toNanos(2L), TimeUnit.SECONDS.toNanos(20L)); addFakeStatsData(); - lrsClient = new LoadReportClient(loadStatsManager, channel, Context.ROOT, false, NODE, + lrsClient = new LoadReportClient(loadStatsManager, channel, Context.ROOT, NODE, syncContext, fakeClock.getScheduledExecutorService(), backoffPolicyProvider, fakeClock.getStopwatchSupplier()); syncContext.execute(new Runnable() { diff --git a/xds/src/test/java/io/grpc/xds/SharedXdsClientPoolProviderTest.java b/xds/src/test/java/io/grpc/xds/SharedXdsClientPoolProviderTest.java index 14a8f1ce74..58bbcce737 100644 --- a/xds/src/test/java/io/grpc/xds/SharedXdsClientPoolProviderTest.java +++ b/xds/src/test/java/io/grpc/xds/SharedXdsClientPoolProviderTest.java @@ -67,7 +67,7 @@ public class SharedXdsClientPoolProviderTest { @Test public void sharedXdsClientObjectPool() throws XdsInitializationException { - ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create(), false); + ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create()); BootstrapInfo bootstrapInfo = BootstrapInfo.builder().servers(Collections.singletonList(server)).node(node).build(); when(bootstrapper.bootstrap()).thenReturn(bootstrapInfo); @@ -84,7 +84,7 @@ public class SharedXdsClientPoolProviderTest { @Test public void refCountedXdsClientObjectPool_delayedCreation() { - ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create(), false); + ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create()); BootstrapInfo bootstrapInfo = BootstrapInfo.builder().servers(Collections.singletonList(server)).node(node).build(); RefCountedXdsClientObjectPool xdsClientPool = new RefCountedXdsClientObjectPool(bootstrapInfo); @@ -96,7 +96,7 @@ public class SharedXdsClientPoolProviderTest { @Test public void refCountedXdsClientObjectPool_refCounted() { - ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create(), false); + ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create()); BootstrapInfo bootstrapInfo = BootstrapInfo.builder().servers(Collections.singletonList(server)).node(node).build(); RefCountedXdsClientObjectPool xdsClientPool = new RefCountedXdsClientObjectPool(bootstrapInfo); @@ -115,7 +115,7 @@ public class SharedXdsClientPoolProviderTest { @Test public void refCountedXdsClientObjectPool_getObjectCreatesNewInstanceIfAlreadyShutdown() { - ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create(), false); + ServerInfo server = ServerInfo.create(SERVER_URI, InsecureChannelCredentials.create()); BootstrapInfo bootstrapInfo = BootstrapInfo.builder().servers(Collections.singletonList(server)).node(node).build(); RefCountedXdsClientObjectPool xdsClientPool = new RefCountedXdsClientObjectPool(bootstrapInfo); diff --git a/xds/src/test/java/io/grpc/xds/XdsClientImplDataTest.java b/xds/src/test/java/io/grpc/xds/XdsClientImplDataTest.java index f47239c123..f15647a3ff 100644 --- a/xds/src/test/java/io/grpc/xds/XdsClientImplDataTest.java +++ b/xds/src/test/java/io/grpc/xds/XdsClientImplDataTest.java @@ -152,7 +152,7 @@ import org.junit.runners.JUnit4; public class XdsClientImplDataTest { private static final ServerInfo LRS_SERVER_INFO = - ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create(), true); + ServerInfo.create("lrs.googleapis.com", InsecureChannelCredentials.create()); @SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467 @Rule @@ -2719,9 +2719,6 @@ public class XdsClientImplDataTest { assertThat(XdsClient.isResourceNameValid(traditionalResource, XdsClusterResource.getInstance().typeUrl())) .isTrue(); - assertThat(XdsClient.isResourceNameValid(traditionalResource, - XdsRouteConfigureResource.getInstance().typeUrlV2())) - .isTrue(); String invalidPath = "xdstp:/abc/efg"; assertThat(XdsClient.isResourceNameValid(invalidPath, @@ -2736,8 +2733,6 @@ public class XdsClientImplDataTest { XdsListenerResource.getInstance().typeUrl())).isFalse(); assertThat(XdsClient.isResourceNameValid(typeMatch, XdsRouteConfigureResource.getInstance().typeUrl())).isTrue(); - assertThat(XdsClient.isResourceNameValid(typeMatch, - XdsRouteConfigureResource.getInstance().typeUrlV2())).isFalse(); } @Test diff --git a/xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java b/xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java index 1a29c28c0c..391845ad10 100644 --- a/xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java +++ b/xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java @@ -32,18 +32,22 @@ import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.Any; import com.google.protobuf.Duration; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.google.protobuf.UInt32Value; import com.google.protobuf.util.Durations; +import io.envoyproxy.envoy.api.v2.DiscoveryRequest; import io.envoyproxy.envoy.config.cluster.v3.OutlierDetection; import io.envoyproxy.envoy.config.route.v3.FilterConfig; import io.envoyproxy.envoy.config.route.v3.WeightedCluster; import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router; import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateProviderPluginInstance; import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext; +import io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc; +import io.envoyproxy.envoy.service.load_stats.v2.LoadReportingServiceGrpc; import io.grpc.BindableService; import io.grpc.ChannelCredentials; import io.grpc.Context; @@ -63,6 +67,7 @@ import io.grpc.internal.JsonUtil; import io.grpc.internal.ServiceConfigUtil; import io.grpc.internal.ServiceConfigUtil.LbConfig; import io.grpc.internal.TimeProvider; +import io.grpc.stub.StreamObserver; import io.grpc.testing.GrpcCleanupRule; import io.grpc.xds.Bootstrapper.AuthorityInfo; import io.grpc.xds.Bootstrapper.CertificateProviderInfo; @@ -119,6 +124,8 @@ import org.mockito.MockitoAnnotations; * Tests for {@link XdsClientImpl}. */ @RunWith(JUnit4.class) +// The base class was used to test both xds v2 and v3. V2 is dropped now so the base class is not +// necessary. Still keep it for future version usage. Remove if too much trouble to maintain. public abstract class XdsClientImplTestBase { private static final String SERVER_URI = "trafficdirector.googleapis.com"; private static final String SERVER_URI_CUSTOME_AUTHORITY = "trafficdirector2.googleapis.com"; @@ -190,7 +197,10 @@ public abstract class XdsClientImplTestBase { private final FakeClock fakeClock = new FakeClock(); protected final BlockingDeque resourceDiscoveryCalls = new LinkedBlockingDeque<>(1); + protected final BlockingDeque resourceDiscoveryCallsV2 = + new LinkedBlockingDeque<>(1); protected final Queue loadReportCalls = new ArrayDeque<>(); + protected final Queue loadReportCallsV2 = new ArrayDeque<>(); protected final AtomicBoolean adsEnded = new AtomicBoolean(true); protected final AtomicBoolean lrsEnded = new AtomicBoolean(true); private final MessageFactory mf = createMessageFactory(); @@ -298,7 +308,9 @@ public abstract class XdsClientImplTestBase { xdsServer = cleanupRule.register(InProcessServerBuilder .forName(serverName) .addService(adsService) + .addService(createAdsServiceV2()) .addService(lrsService) + .addService(createLrsServiceV2()) .directExecutor() .build() .start()); @@ -328,7 +340,7 @@ public abstract class XdsClientImplTestBase { } }; - xdsServerInfo = ServerInfo.create(SERVER_URI, CHANNEL_CREDENTIALS, useProtocolV3(), + xdsServerInfo = ServerInfo.create(SERVER_URI, CHANNEL_CREDENTIALS, ignoreResourceDeletion()); Bootstrapper.BootstrapInfo bootstrapInfo = Bootstrapper.BootstrapInfo.builder() @@ -339,12 +351,12 @@ public abstract class XdsClientImplTestBase { AuthorityInfo.create( "xdstp://authority.xds.com/envoy.config.listener.v3.Listener/%s", ImmutableList.of(Bootstrapper.ServerInfo.create( - SERVER_URI_CUSTOME_AUTHORITY, CHANNEL_CREDENTIALS, useProtocolV3()))), + SERVER_URI_CUSTOME_AUTHORITY, CHANNEL_CREDENTIALS))), "", AuthorityInfo.create( "xdstp:///envoy.config.listener.v3.Listener/%s", ImmutableList.of(Bootstrapper.ServerInfo.create( - SERVER_URI_EMPTY_AUTHORITY, CHANNEL_CREDENTIALS, useProtocolV3()))))) + SERVER_URI_EMPTY_AUTHORITY, CHANNEL_CREDENTIALS))))) .certProviders(ImmutableMap.of("cert-instance-name", CertificateProviderInfo.create("file-watcher", ImmutableMap.of()))) .build(); @@ -423,11 +435,9 @@ public abstract class XdsClientImplTestBase { int size) { if (size == 0) { assertThat(subscribedTypeUrls.containsKey(type.typeUrl())).isFalse(); - assertThat(subscribedTypeUrls.containsKey(type.typeUrlV2())).isFalse(); assertThat(subscribedResourcesMetadata.containsKey(type)).isFalse(); } else { assertThat(subscribedTypeUrls.containsKey(type.typeUrl())).isTrue(); - assertThat(subscribedTypeUrls.containsKey(type.typeUrlV2())).isTrue(); assertThat(subscribedResourcesMetadata.get(type)).hasSize(size); } } @@ -3589,18 +3599,22 @@ public abstract class XdsClientImplTestBase { protected abstract static class DiscoveryRpcCall { - protected abstract void verifyRequest( + protected void verifyRequest( XdsResourceType type, List resources, String versionInfo, String nonce, - Node node); + Node node) { + throw new UnsupportedOperationException(); + } protected void verifyRequest( XdsResourceType type, String resource, String versionInfo, String nonce, Node node) { verifyRequest(type, ImmutableList.of(resource), versionInfo, nonce, node); } - protected abstract void verifyRequestNack( + protected void verifyRequestNack( XdsResourceType type, List resources, String versionInfo, String nonce, - Node node, List errorMessages); + Node node, List errorMessages) { + throw new UnsupportedOperationException(); + } protected void verifyRequestNack( XdsResourceType type, String resource, String versionInfo, String nonce, Node node, @@ -3608,19 +3622,27 @@ public abstract class XdsClientImplTestBase { verifyRequestNack(type, ImmutableList.of(resource), versionInfo, nonce, node, errorMessages); } - protected abstract void verifyNoMoreRequest(); + protected void verifyNoMoreRequest() { + throw new UnsupportedOperationException(); + } - protected abstract void sendResponse( - XdsResourceType type, List resources, String versionInfo, String nonce); + protected void sendResponse( + XdsResourceType type, List resources, String versionInfo, String nonce) { + throw new UnsupportedOperationException(); + } protected void sendResponse(XdsResourceType type, Any resource, String versionInfo, String nonce) { sendResponse(type, ImmutableList.of(resource), versionInfo, nonce); } - protected abstract void sendError(Throwable t); + protected void sendError(Throwable t) { + throw new UnsupportedOperationException(); + } - protected abstract void sendCompleted(); + protected void sendCompleted() { + throw new UnsupportedOperationException(); + } } protected abstract static class LrsRpcCall { @@ -3628,9 +3650,13 @@ public abstract class XdsClientImplTestBase { /** * Verifies a LRS request has been sent with ClusterStats of the given list of clusters. */ - protected abstract void verifyNextReportClusters(List clusters); + protected void verifyNextReportClusters(List clusters) { + throw new UnsupportedOperationException(); + } - protected abstract void sendResponse(List clusters, long loadReportIntervalNano); + protected void sendResponse(List clusters, long loadReportIntervalNano) { + throw new UnsupportedOperationException(); + } } protected abstract static class MessageFactory { @@ -3731,4 +3757,83 @@ public abstract class XdsClientImplTestBase { protected abstract Message buildTerminalFilter(); } + + @Test + public void dropXdsV2Lds() { + startResourceWatcher(XdsListenerResource.getInstance(), LDS_RESOURCE, ldsResourceWatcher); + assertThat(resourceDiscoveryCallsV2).isEmpty(); + assertThat(loadReportCallsV2).isEmpty(); + } + + @Test + public void dropXdsV2Cds() { + startResourceWatcher(XdsClusterResource.getInstance(), CDS_RESOURCE, cdsResourceWatcher); + assertThat(resourceDiscoveryCallsV2).isEmpty(); + assertThat(loadReportCallsV2).isEmpty(); + } + + @Test + public void dropXdsV2Rds() { + startResourceWatcher(XdsRouteConfigureResource.getInstance(), RDS_RESOURCE, rdsResourceWatcher); + assertThat(resourceDiscoveryCallsV2).isEmpty(); + assertThat(loadReportCallsV2).isEmpty(); + } + + @Test + public void dropXdsV2Eds() { + startResourceWatcher(XdsEndpointResource.getInstance(), EDS_RESOURCE, edsResourceWatcher); + assertThat(resourceDiscoveryCallsV2).isEmpty(); + assertThat(loadReportCallsV2).isEmpty(); + } + + protected BindableService createAdsServiceV2() { + return new AggregatedDiscoveryServiceGrpc.AggregatedDiscoveryServiceImplBase() { + @Override + public StreamObserver streamAggregatedResources( + final StreamObserver responseObserver) { + assertThat(adsEnded.get()).isTrue(); // ensure previous call was ended + adsEnded.set(false); + @SuppressWarnings("unchecked") + StreamObserver requestObserver = + mock(StreamObserver.class); + DiscoveryRpcCall call = new DiscoveryRpcCall() {}; + resourceDiscoveryCallsV2.offer(call); + Context.current().addListener( + new Context.CancellationListener() { + @Override + public void cancelled(Context context) { + adsEnded.set(true); + } + }, MoreExecutors.directExecutor()); + return requestObserver; + } + }; + } + + protected BindableService createLrsServiceV2() { + return new LoadReportingServiceGrpc.LoadReportingServiceImplBase() { + @Override + public + StreamObserver + streamLoadStats( + StreamObserver + responseObserver) { + assertThat(lrsEnded.get()).isTrue(); + lrsEnded.set(false); + @SuppressWarnings("unchecked") + StreamObserver requestObserver = + mock(StreamObserver.class); + LrsRpcCall call = new LrsRpcCall() {}; + Context.current().addListener( + new Context.CancellationListener() { + @Override + public void cancelled(Context context) { + lrsEnded.set(true); + } + }, MoreExecutors.directExecutor()); + loadReportCallsV2.offer(call); + return requestObserver; + } + }; + } } diff --git a/xds/src/test/java/io/grpc/xds/XdsClientImplV2Test.java b/xds/src/test/java/io/grpc/xds/XdsClientImplV2Test.java deleted file mode 100644 index e9b3720727..0000000000 --- a/xds/src/test/java/io/grpc/xds/XdsClientImplV2Test.java +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Copyright 2020 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.xds; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import com.google.common.collect.ImmutableList; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.protobuf.Any; -import com.google.protobuf.Message; -import com.google.protobuf.UInt32Value; -import com.google.protobuf.UInt64Value; -import com.google.protobuf.util.Durations; -import com.google.rpc.Code; -import io.envoyproxy.envoy.api.v2.Cluster; -import io.envoyproxy.envoy.api.v2.Cluster.CustomClusterType; -import io.envoyproxy.envoy.api.v2.Cluster.DiscoveryType; -import io.envoyproxy.envoy.api.v2.Cluster.EdsClusterConfig; -import io.envoyproxy.envoy.api.v2.Cluster.LbPolicy; -import io.envoyproxy.envoy.api.v2.Cluster.LeastRequestLbConfig; -import io.envoyproxy.envoy.api.v2.Cluster.RingHashLbConfig; -import io.envoyproxy.envoy.api.v2.Cluster.RingHashLbConfig.HashFunction; -import io.envoyproxy.envoy.api.v2.ClusterLoadAssignment; -import io.envoyproxy.envoy.api.v2.ClusterLoadAssignment.Policy; -import io.envoyproxy.envoy.api.v2.ClusterLoadAssignment.Policy.DropOverload; -import io.envoyproxy.envoy.api.v2.DiscoveryRequest; -import io.envoyproxy.envoy.api.v2.DiscoveryResponse; -import io.envoyproxy.envoy.api.v2.Listener; -import io.envoyproxy.envoy.api.v2.Resource; -import io.envoyproxy.envoy.api.v2.RouteConfiguration; -import io.envoyproxy.envoy.api.v2.auth.CommonTlsContext; -import io.envoyproxy.envoy.api.v2.auth.SdsSecretConfig; -import io.envoyproxy.envoy.api.v2.auth.UpstreamTlsContext; -import io.envoyproxy.envoy.api.v2.cluster.CircuitBreakers; -import io.envoyproxy.envoy.api.v2.cluster.CircuitBreakers.Thresholds; -import io.envoyproxy.envoy.api.v2.cluster.OutlierDetection; -import io.envoyproxy.envoy.api.v2.core.Address; -import io.envoyproxy.envoy.api.v2.core.AggregatedConfigSource; -import io.envoyproxy.envoy.api.v2.core.ApiConfigSource; -import io.envoyproxy.envoy.api.v2.core.ConfigSource; -import io.envoyproxy.envoy.api.v2.core.GrpcService; -import io.envoyproxy.envoy.api.v2.core.GrpcService.GoogleGrpc; -import io.envoyproxy.envoy.api.v2.core.HealthStatus; -import io.envoyproxy.envoy.api.v2.core.Locality; -import io.envoyproxy.envoy.api.v2.core.Node; -import io.envoyproxy.envoy.api.v2.core.RoutingPriority; -import io.envoyproxy.envoy.api.v2.core.SelfConfigSource; -import io.envoyproxy.envoy.api.v2.core.SocketAddress; -import io.envoyproxy.envoy.api.v2.core.TransportSocket; -import io.envoyproxy.envoy.api.v2.endpoint.ClusterStats; -import io.envoyproxy.envoy.api.v2.endpoint.Endpoint; -import io.envoyproxy.envoy.api.v2.endpoint.LbEndpoint; -import io.envoyproxy.envoy.api.v2.endpoint.LocalityLbEndpoints; -import io.envoyproxy.envoy.api.v2.listener.FilterChain; -import io.envoyproxy.envoy.api.v2.route.Route; -import io.envoyproxy.envoy.api.v2.route.RouteAction; -import io.envoyproxy.envoy.api.v2.route.RouteMatch; -import io.envoyproxy.envoy.api.v2.route.VirtualHost; -import io.envoyproxy.envoy.config.cluster.aggregate.v2alpha.ClusterConfig; -import io.envoyproxy.envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager; -import io.envoyproxy.envoy.config.filter.network.http_connection_manager.v2.HttpFilter; -import io.envoyproxy.envoy.config.filter.network.http_connection_manager.v2.Rds; -import io.envoyproxy.envoy.config.listener.v2.ApiListener; -import io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc.AggregatedDiscoveryServiceImplBase; -import io.envoyproxy.envoy.service.load_stats.v2.LoadReportingServiceGrpc.LoadReportingServiceImplBase; -import io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest; -import io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse; -import io.envoyproxy.envoy.type.FractionalPercent; -import io.envoyproxy.envoy.type.FractionalPercent.DenominatorType; -import io.envoyproxy.envoy.type.matcher.RegexMatcher; -import io.grpc.BindableService; -import io.grpc.Context; -import io.grpc.Context.CancellationListener; -import io.grpc.Status; -import io.grpc.stub.StreamObserver; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.annotation.Nullable; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; -import org.mockito.ArgumentMatcher; -import org.mockito.InOrder; -import org.mockito.Mockito; - -/** - * Tests for {@link XdsClientImpl} with protocol version v2. - */ -@RunWith(Parameterized.class) -public class XdsClientImplV2Test extends XdsClientImplTestBase { - - /** Parameterized test cases. */ - @Parameters(name = "ignoreResourceDeletion={0}") - public static Iterable data() { - return ImmutableList.of(false, true); - } - - @Parameter - public boolean ignoreResourceDeletion; - - @Override - protected BindableService createAdsService() { - return new AggregatedDiscoveryServiceImplBase() { - @Override - public StreamObserver streamAggregatedResources( - final StreamObserver responseObserver) { - assertThat(adsEnded.get()).isTrue(); // ensure previous call was ended - adsEnded.set(false); - @SuppressWarnings("unchecked") - StreamObserver requestObserver = mock(StreamObserver.class); - DiscoveryRpcCall call = new DiscoveryRpcCallV2(requestObserver, responseObserver); - resourceDiscoveryCalls.offer(call); - Context.current().addListener( - new CancellationListener() { - @Override - public void cancelled(Context context) { - adsEnded.set(true); - } - }, MoreExecutors.directExecutor()); - return requestObserver; - } - }; - } - - @Override - protected BindableService createLrsService() { - return new LoadReportingServiceImplBase() { - @Override - public StreamObserver streamLoadStats( - StreamObserver responseObserver) { - assertThat(lrsEnded.get()).isTrue(); - lrsEnded.set(false); - @SuppressWarnings("unchecked") - StreamObserver requestObserver = mock(StreamObserver.class); - LrsRpcCall call = new LrsRpcCallV2(requestObserver, responseObserver); - Context.current().addListener( - new CancellationListener() { - @Override - public void cancelled(Context context) { - lrsEnded.set(true); - } - }, MoreExecutors.directExecutor()); - loadReportCalls.offer(call); - return requestObserver; - } - }; - } - - @Override - protected MessageFactory createMessageFactory() { - return new MessageFactoryV2(); - } - - @Override - protected boolean useProtocolV3() { - return false; - } - - @Override - protected boolean ignoreResourceDeletion() { - return ignoreResourceDeletion; - } - - private static class DiscoveryRpcCallV2 extends DiscoveryRpcCall { - StreamObserver requestObserver; - StreamObserver responseObserver; - - private DiscoveryRpcCallV2(StreamObserver requestObserver, - StreamObserver responseObserver) { - this.requestObserver = requestObserver; - this.responseObserver = responseObserver; - } - - @Override - protected void verifyRequest( - XdsResourceType type, List resources, String versionInfo, String nonce, - EnvoyProtoData.Node node) { - verify(requestObserver, Mockito.timeout(2000)).onNext(argThat(new DiscoveryRequestMatcher( - node.toEnvoyProtoNodeV2(), versionInfo, resources, type.typeUrlV2(), nonce, null, null))); - } - - @Override - protected void verifyRequestNack( - XdsResourceType type, List resources, String versionInfo, String nonce, - EnvoyProtoData.Node node, List errorMessages) { - verify(requestObserver, Mockito.timeout(2000)).onNext(argThat(new DiscoveryRequestMatcher( - node.toEnvoyProtoNodeV2(), versionInfo, resources, type.typeUrlV2(), nonce, - Code.INVALID_ARGUMENT_VALUE, errorMessages))); - } - - @Override - protected void verifyNoMoreRequest() { - verifyNoMoreInteractions(requestObserver); - } - - @Override - protected void sendResponse( - XdsResourceType type, List resources, String versionInfo, String nonce) { - DiscoveryResponse response = - DiscoveryResponse.newBuilder() - .setVersionInfo(versionInfo) - .addAllResources(resources) - .setTypeUrl(type.typeUrl()) - .setNonce(nonce) - .build(); - responseObserver.onNext(response); - } - - @Override - protected void sendError(Throwable t) { - responseObserver.onError(t); - } - - @Override - protected void sendCompleted() { - responseObserver.onCompleted(); - } - } - - private static class LrsRpcCallV2 extends LrsRpcCall { - private final StreamObserver requestObserver; - private final StreamObserver responseObserver; - private final InOrder inOrder; - - private LrsRpcCallV2(StreamObserver requestObserver, - StreamObserver responseObserver) { - this.requestObserver = requestObserver; - this.responseObserver = responseObserver; - inOrder = inOrder(requestObserver); - } - - @Override - protected void verifyNextReportClusters(List clusters) { - inOrder.verify(requestObserver).onNext(argThat(new LrsRequestMatcher(clusters))); - } - - @Override - protected void sendResponse(List clusters, long loadReportIntervalNano) { - LoadStatsResponse response = - LoadStatsResponse.newBuilder() - .addAllClusters(clusters) - .setLoadReportingInterval(Durations.fromNanos(loadReportIntervalNano)) - .build(); - responseObserver.onNext(response); - } - } - - private static class MessageFactoryV2 extends MessageFactory { - - @Override - protected Any buildWrappedResource(Any originalResource) { - return Any.pack(Resource.newBuilder() - .setResource(originalResource) - .build()); - } - - @SuppressWarnings("unchecked") - @Override - protected Message buildListenerWithApiListener( - String name, Message routeConfiguration, List httpFilters) { - return Listener.newBuilder() - .setName(name) - .setAddress(Address.getDefaultInstance()) - .addFilterChains(FilterChain.getDefaultInstance()) - .setApiListener( - ApiListener.newBuilder().setApiListener(Any.pack( - HttpConnectionManager.newBuilder() - .setRouteConfig((RouteConfiguration) routeConfiguration) - .addAllHttpFilters((List) httpFilters) - .build()))) - .build(); - } - - @Override - protected Message buildListenerWithApiListenerForRds(String name, String rdsResourceName) { - return Listener.newBuilder() - .setName(name) - .setAddress(Address.getDefaultInstance()) - .addFilterChains(FilterChain.getDefaultInstance()) - .setApiListener( - ApiListener.newBuilder().setApiListener(Any.pack( - HttpConnectionManager.newBuilder() - .setRds( - Rds.newBuilder() - .setRouteConfigName(rdsResourceName) - .setConfigSource( - ConfigSource.newBuilder() - .setAds(AggregatedConfigSource.getDefaultInstance()))) - .build()))) - .build(); - } - - @Override - protected Message buildListenerWithApiListenerInvalid(String name) { - return Listener.newBuilder() - .setName(name) - .setAddress(Address.getDefaultInstance()) - .setApiListener(ApiListener.newBuilder().setApiListener(FAILING_ANY)) - .build(); - } - - @Override - protected Message buildHttpFilter(String name, @Nullable Any typedConfig, boolean isOptional) { - throw new UnsupportedOperationException(); - } - - @Override - protected Any buildHttpFaultTypedConfig( - @Nullable Long delayNanos, @Nullable Integer delayRate, String upstreamCluster, - List downstreamNodes, @Nullable Integer maxActiveFaults, @Nullable Status status, - @Nullable Integer httpCode, @Nullable Integer abortRate) { - throw new UnsupportedOperationException(); - } - - @Override - protected Message buildRouteConfiguration(String name, List virtualHostList) { - RouteConfiguration.Builder builder = RouteConfiguration.newBuilder(); - builder.setName(name); - for (Message virtualHost : virtualHostList) { - builder.addVirtualHosts((VirtualHost) virtualHost); - } - return builder.build(); - } - - @Override - protected Message buildRouteConfigurationInvalid(String name) { - // Invalid Path matcher: Pattern.compile() will throw PatternSyntaxException - // when attempting to process SAFE_REGEX RouteMatch malformed safe regex pattern. - // I wish there was a simpler way. - return RouteConfiguration.newBuilder() - .setName(name) - .addVirtualHosts( - VirtualHost.newBuilder() - .setName("do not care") - .addDomains("do not care") - .addRoutes( - Route.newBuilder() - .setRoute(RouteAction.newBuilder().setCluster("do not care")) - .setMatch(RouteMatch.newBuilder() - .setSafeRegex(RegexMatcher.newBuilder().setRegex("[z-a]"))))) - .build(); - } - - @Override - protected List buildOpaqueVirtualHosts(int num) { - List virtualHosts = new ArrayList<>(num); - for (int i = 0; i < num; i++) { - VirtualHost virtualHost = - VirtualHost.newBuilder() - .setName(num + ": do not care") - .addDomains("do not care") - .addRoutes( - Route.newBuilder() - .setRoute(RouteAction.newBuilder().setCluster("do not care")) - .setMatch(RouteMatch.newBuilder() - .setPrefix("do not care"))) - .build(); - virtualHosts.add(virtualHost); - } - return virtualHosts; - } - - @SuppressWarnings("unchecked") - @Override - protected Message buildVirtualHost( - List routes, Map typedConfigMap) { - return VirtualHost.newBuilder() - .setName("do not care") - .addDomains("do not care") - .addAllRoutes((List) routes) - .putAllTypedPerFilterConfig(typedConfigMap) - .build(); - } - - @Override - protected List buildOpaqueRoutes(int num) { - List routes = new ArrayList<>(num); - for (int i = 0; i < num; i++) { - Route route = - Route.newBuilder() - .setRoute(RouteAction.newBuilder().setCluster("do not care")) - .setMatch(RouteMatch.newBuilder().setPrefix("do not care")) - .build(); - routes.add(route); - } - return routes; - } - - @Override - protected Message buildClusterInvalid(String name) { - // Unspecified cluster discovery type - return Cluster.newBuilder().setName(name).build(); - } - - @Override - protected Message buildEdsCluster(String clusterName, @Nullable String edsServiceName, - String lbPolicy, @Nullable Message ringHashLbConfig, @Nullable Message leastRequestLbConfig, - boolean enableLrs, - @Nullable Message upstreamTlsContext, String transportSocketName, - @Nullable Message circuitBreakers, @Nullable Message outlierDetection) { - Cluster.Builder builder = initClusterBuilder( - clusterName, lbPolicy, ringHashLbConfig, leastRequestLbConfig, - enableLrs, upstreamTlsContext, circuitBreakers, outlierDetection); - builder.setType(DiscoveryType.EDS); - EdsClusterConfig.Builder edsClusterConfigBuilder = EdsClusterConfig.newBuilder(); - edsClusterConfigBuilder.setEdsConfig( - ConfigSource.newBuilder().setAds(AggregatedConfigSource.getDefaultInstance())); // ADS - if (edsServiceName != null) { - edsClusterConfigBuilder.setServiceName(edsServiceName); - } - builder.setEdsClusterConfig(edsClusterConfigBuilder); - return builder.build(); - } - - @Override - protected Message buildLogicalDnsCluster(String clusterName, String dnsHostAddr, - int dnsHostPort, String lbPolicy, @Nullable Message ringHashLbConfig, - @Nullable Message leastRequestLbConfig, boolean enableLrs, - @Nullable Message upstreamTlsContext, @Nullable Message circuitBreakers) { - Cluster.Builder builder = initClusterBuilder( - clusterName, lbPolicy, ringHashLbConfig, leastRequestLbConfig, - enableLrs, upstreamTlsContext, circuitBreakers, null); - builder.setType(DiscoveryType.LOGICAL_DNS); - builder.setLoadAssignment( - ClusterLoadAssignment.newBuilder().addEndpoints( - LocalityLbEndpoints.newBuilder().addLbEndpoints( - LbEndpoint.newBuilder().setEndpoint( - Endpoint.newBuilder().setAddress( - Address.newBuilder().setSocketAddress( - SocketAddress.newBuilder() - .setAddress(dnsHostAddr).setPortValue(dnsHostPort)))))).build()); - return builder.build(); - } - - @Override - protected Message buildAggregateCluster(String clusterName, String lbPolicy, - @Nullable Message ringHashLbConfig, @Nullable Message leastRequestLbConfig, - List clusters) { - ClusterConfig clusterConfig = ClusterConfig.newBuilder().addAllClusters(clusters).build(); - CustomClusterType type = - CustomClusterType.newBuilder() - .setName(XdsResourceType.AGGREGATE_CLUSTER_TYPE_NAME) - .setTypedConfig(Any.pack(clusterConfig)) - .build(); - Cluster.Builder builder = Cluster.newBuilder().setName(clusterName).setClusterType(type); - if (lbPolicy.equals("round_robin")) { - builder.setLbPolicy(LbPolicy.ROUND_ROBIN); - } else if (lbPolicy.equals("ring_hash_experimental")) { - builder.setLbPolicy(LbPolicy.RING_HASH); - builder.setRingHashLbConfig((RingHashLbConfig) ringHashLbConfig); - } else if (lbPolicy.equals("least_request_experimental")) { - builder.setLbPolicy(LbPolicy.LEAST_REQUEST); - builder.setLeastRequestLbConfig((LeastRequestLbConfig) leastRequestLbConfig); - } else { - throw new AssertionError("Invalid LB policy"); - } - return builder.build(); - } - - private Cluster.Builder initClusterBuilder(String clusterName, String lbPolicy, - @Nullable Message ringHashLbConfig, @Nullable Message leastRequestLbConfig, - boolean enableLrs, @Nullable Message upstreamTlsContext, - @Nullable Message circuitBreakers, @Nullable Message outlierDetection) { - Cluster.Builder builder = Cluster.newBuilder(); - builder.setName(clusterName); - if (lbPolicy.equals("round_robin")) { - builder.setLbPolicy(LbPolicy.ROUND_ROBIN); - } else if (lbPolicy.equals("ring_hash_experimental")) { - builder.setLbPolicy(LbPolicy.RING_HASH); - builder.setRingHashLbConfig((RingHashLbConfig) ringHashLbConfig); - } else if (lbPolicy.equals("least_request_experimental")) { - builder.setLbPolicy(LbPolicy.LEAST_REQUEST); - builder.setLeastRequestLbConfig((LeastRequestLbConfig) leastRequestLbConfig); - } else { - throw new AssertionError("Invalid LB policy"); - } - if (enableLrs) { - builder.setLrsServer( - ConfigSource.newBuilder() - .setSelf(SelfConfigSource.getDefaultInstance())); - } - if (upstreamTlsContext != null) { - builder.setTransportSocket( - TransportSocket.newBuilder() - .setName("envoy.transport_sockets.tls") - .setTypedConfig(Any.pack(upstreamTlsContext))); - } - if (circuitBreakers != null) { - builder.setCircuitBreakers((CircuitBreakers) circuitBreakers); - } - if (outlierDetection != null) { - builder.setOutlierDetection((OutlierDetection) outlierDetection); - } - return builder; - } - - @Override - protected Message buildRingHashLbConfig(String hashFunction, long minRingSize, - long maxRingSize) { - RingHashLbConfig.Builder builder = RingHashLbConfig.newBuilder(); - if (hashFunction.equals("xx_hash")) { - builder.setHashFunction(HashFunction.XX_HASH); - } else if (hashFunction.equals("murmur_hash_2")) { - builder.setHashFunction(HashFunction.MURMUR_HASH_2); - } else { - throw new AssertionError("Invalid hash function"); - } - builder.setMinimumRingSize(UInt64Value.newBuilder().setValue(minRingSize).build()); - builder.setMaximumRingSize(UInt64Value.newBuilder().setValue(maxRingSize).build()); - return builder.build(); - } - - @Override - protected Message buildLeastRequestLbConfig(int choiceCount) { - LeastRequestLbConfig.Builder builder = LeastRequestLbConfig.newBuilder(); - builder.setChoiceCount(UInt32Value.newBuilder().setValue(choiceCount)); - return builder.build(); - } - - @Override - protected Message buildUpstreamTlsContext(String instanceName, String certName) { - GrpcService grpcService = - GrpcService.newBuilder() - .setGoogleGrpc(GoogleGrpc.newBuilder().setTargetUri(certName)) - .build(); - ConfigSource sdsConfig = - ConfigSource.newBuilder() - .setApiConfigSource(ApiConfigSource.newBuilder().addGrpcServices(grpcService)) - .build(); - SdsSecretConfig validationContextSdsSecretConfig = - SdsSecretConfig.newBuilder() - .setName(instanceName) - .setSdsConfig(sdsConfig) - .build(); - return UpstreamTlsContext.newBuilder() - .setCommonTlsContext( - CommonTlsContext.newBuilder() - .setValidationContextSdsSecretConfig(validationContextSdsSecretConfig)) - .build(); - } - - @Override - protected Message buildNewUpstreamTlsContext(String instanceName, String certName) { - return buildUpstreamTlsContext(instanceName, certName); - } - - - @Override - protected Message buildCircuitBreakers(int highPriorityMaxRequests, - int defaultPriorityMaxRequests) { - return CircuitBreakers.newBuilder() - .addThresholds( - Thresholds.newBuilder() - .setPriority(RoutingPriority.HIGH) - .setMaxRequests(UInt32Value.newBuilder().setValue(highPriorityMaxRequests))) - .addThresholds( - Thresholds.newBuilder() - .setPriority(RoutingPriority.DEFAULT) - .setMaxRequests(UInt32Value.newBuilder().setValue(defaultPriorityMaxRequests))) - .build(); - } - - @Override - protected Message buildClusterLoadAssignment(String cluster, - List localityLbEndpointsList, List dropOverloadList) { - ClusterLoadAssignment.Builder builder = ClusterLoadAssignment.newBuilder(); - builder.setClusterName(cluster); - for (Message localityLbEndpoints : localityLbEndpointsList) { - builder.addEndpoints((LocalityLbEndpoints) localityLbEndpoints); - } - Policy.Builder policyBuilder = Policy.newBuilder(); - for (Message dropOverload : dropOverloadList) { - policyBuilder.addDropOverloads((DropOverload) dropOverload); - } - builder.setPolicy(policyBuilder); - return builder.build(); - } - - @Override - protected Message buildClusterLoadAssignmentInvalid(String cluster) { - // Negative priority LocalityLbEndpoint. - return ClusterLoadAssignment.newBuilder() - .setClusterName(cluster) - .addEndpoints(LocalityLbEndpoints.newBuilder() - .setPriority(-1) - .setLoadBalancingWeight(UInt32Value.newBuilder().setValue(1))) - .build(); - } - - @Override - protected Message buildLocalityLbEndpoints(String region, String zone, String subZone, - List lbEndpointList, int loadBalancingWeight, int priority) { - LocalityLbEndpoints.Builder builder = LocalityLbEndpoints.newBuilder(); - builder.setLocality( - Locality.newBuilder().setRegion(region).setZone(zone).setSubZone(subZone)); - for (Message lbEndpoint : lbEndpointList) { - builder.addLbEndpoints((LbEndpoint) lbEndpoint); - } - builder.setLoadBalancingWeight(UInt32Value.of(loadBalancingWeight)); - builder.setPriority(priority); - return builder.build(); - } - - @Override - protected Message buildLbEndpoint(String address, int port, String healthStatus, - int lbWeight) { - HealthStatus status; - switch (healthStatus) { - case "unknown": - status = HealthStatus.UNKNOWN; - break; - case "healthy": - status = HealthStatus.HEALTHY; - break; - case "unhealthy": - status = HealthStatus.UNHEALTHY; - break; - case "draining": - status = HealthStatus.DRAINING; - break; - case "timeout": - status = HealthStatus.TIMEOUT; - break; - case "degraded": - status = HealthStatus.DEGRADED; - break; - default: - status = HealthStatus.UNRECOGNIZED; - } - return LbEndpoint.newBuilder() - .setEndpoint( - Endpoint.newBuilder().setAddress( - Address.newBuilder().setSocketAddress( - SocketAddress.newBuilder().setAddress(address).setPortValue(port)))) - .setHealthStatus(status) - .setLoadBalancingWeight(UInt32Value.of(lbWeight)) - .build(); - } - - @Override - protected Message buildDropOverload(String category, int dropPerMillion) { - return DropOverload.newBuilder() - .setCategory(category) - .setDropPercentage( - FractionalPercent.newBuilder() - .setNumerator(dropPerMillion) - .setDenominator(DenominatorType.MILLION)) - .build(); - } - - @Override - protected Message buildFilterChain(List alpn, Message tlsContext, - String transportSocketName, Message... filters) { - throw new UnsupportedOperationException(); - } - - @Override - protected Message buildListenerWithFilterChain( - String name, int portValue, String address, Message... filterChains) { - throw new UnsupportedOperationException(); - } - - @Override - protected Message buildHttpConnectionManagerFilter( - @Nullable String rdsName, @Nullable Message routeConfig, List httpFilters) { - throw new UnsupportedOperationException(); - } - - @Override - protected Message buildTerminalFilter() { - throw new UnsupportedOperationException(); - } - } - - /** - * Matches a {@link DiscoveryRequest} with the same node metadata, versionInfo, typeUrl, - * response nonce and collection of resource names regardless of order. - */ - private static class DiscoveryRequestMatcher implements ArgumentMatcher { - private final Node node; - private final String versionInfo; - private final String typeUrl; - private final Set resources; - private final String responseNonce; - @Nullable private final Integer errorCode; - private final List errorMessages; - - private DiscoveryRequestMatcher(Node node, String versionInfo, List resources, - String typeUrl, String responseNonce, @Nullable Integer errorCode, - @Nullable List errorMessages) { - this.node = node; - this.versionInfo = versionInfo; - this.resources = new HashSet<>(resources); - this.typeUrl = typeUrl; - this.responseNonce = responseNonce; - this.errorCode = errorCode; - this.errorMessages = errorMessages != null ? errorMessages : ImmutableList.of(); - } - - @Override - public boolean matches(DiscoveryRequest argument) { - if (!typeUrl.equals(argument.getTypeUrl())) { - return false; - } - if (!versionInfo.equals(argument.getVersionInfo())) { - return false; - } - if (!responseNonce.equals(argument.getResponseNonce())) { - return false; - } - if (!resources.equals(new HashSet<>(argument.getResourceNamesList()))) { - return false; - } - if (errorCode == null && argument.hasErrorDetail()) { - return false; - } - if (errorCode != null - && !matchErrorDetail(argument.getErrorDetail(), errorCode, errorMessages)) { - return false; - } - return node.equals(argument.getNode()); - } - } - - /** - * Matches a {@link LoadStatsRequest} containing a collection of {@link ClusterStats} with - * the same list of clusterName:clusterServiceName pair. - */ - private static class LrsRequestMatcher implements ArgumentMatcher { - private final List expected; - - private LrsRequestMatcher(List clusterNames) { - expected = new ArrayList<>(); - for (String[] pair : clusterNames) { - expected.add(pair[0] + ":" + (pair[1] == null ? "" : pair[1])); - } - Collections.sort(expected); - } - - @Override - public boolean matches(LoadStatsRequest argument) { - List actual = new ArrayList<>(); - for (ClusterStats clusterStats : argument.getClusterStatsList()) { - actual.add(clusterStats.getClusterName() + ":" + clusterStats.getClusterServiceName()); - } - Collections.sort(actual); - return actual.equals(expected); - } - } -} diff --git a/xds/src/test/java/io/grpc/xds/XdsNameResolverTest.java b/xds/src/test/java/io/grpc/xds/XdsNameResolverTest.java index f4475ebe37..b6f8b3c366 100644 --- a/xds/src/test/java/io/grpc/xds/XdsNameResolverTest.java +++ b/xds/src/test/java/io/grpc/xds/XdsNameResolverTest.java @@ -145,7 +145,7 @@ public class XdsNameResolverTest { private final TestChannel channel = new TestChannel(); private BootstrapInfo bootstrapInfo = BootstrapInfo.builder() .servers(ImmutableList.of(ServerInfo.create( - "td.googleapis.com", InsecureChannelCredentials.create(), true))) + "td.googleapis.com", InsecureChannelCredentials.create()))) .node(Node.newBuilder().build()) .build(); private String expectedLdsResourceName = AUTHORITY; @@ -231,7 +231,7 @@ public class XdsNameResolverTest { public void resolving_noTargetAuthority_templateWithoutXdstp() { bootstrapInfo = BootstrapInfo.builder() .servers(ImmutableList.of(ServerInfo.create( - "td.googleapis.com", InsecureChannelCredentials.create(), true))) + "td.googleapis.com", InsecureChannelCredentials.create()))) .node(Node.newBuilder().build()) .clientDefaultListenerResourceNameTemplate("%s/id=1") .build(); @@ -249,7 +249,7 @@ public class XdsNameResolverTest { public void resolving_noTargetAuthority_templateWithXdstp() { bootstrapInfo = BootstrapInfo.builder() .servers(ImmutableList.of(ServerInfo.create( - "td.googleapis.com", InsecureChannelCredentials.create(), true))) + "td.googleapis.com", InsecureChannelCredentials.create()))) .node(Node.newBuilder().build()) .clientDefaultListenerResourceNameTemplate( "xdstp://xds.authority.com/envoy.config.listener.v3.Listener/%s?id=1") diff --git a/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java b/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java index bce71c1c2b..256e3f61fe 100644 --- a/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java +++ b/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java @@ -55,7 +55,7 @@ public class XdsServerTestHelper { Bootstrapper.BootstrapInfo.builder() .servers(Arrays.asList( Bootstrapper.ServerInfo.create( - SERVER_URI, InsecureChannelCredentials.create(), true))) + SERVER_URI, InsecureChannelCredentials.create()))) .node(BOOTSTRAP_NODE) .serverListenerResourceNameTemplate("grpc/server?udpa.resource.listening_address=%s") .build(); diff --git a/xds/src/test/java/io/grpc/xds/XdsServerWrapperTest.java b/xds/src/test/java/io/grpc/xds/XdsServerWrapperTest.java index ef2f606f3f..6271ca791c 100644 --- a/xds/src/test/java/io/grpc/xds/XdsServerWrapperTest.java +++ b/xds/src/test/java/io/grpc/xds/XdsServerWrapperTest.java @@ -125,15 +125,34 @@ public class XdsServerWrapperTest { } @Test - public void testBootstrap_notV3() throws Exception { + @SuppressWarnings("unchecked") + public void testBootstrap() throws Exception { Bootstrapper.BootstrapInfo b = Bootstrapper.BootstrapInfo.builder() .servers(Arrays.asList( - Bootstrapper.ServerInfo.create("uri", InsecureChannelCredentials.create(), false))) + Bootstrapper.ServerInfo.create("uri", InsecureChannelCredentials.create()))) .node(EnvoyProtoData.Node.newBuilder().setId("id").build()) .serverListenerResourceNameTemplate("grpc/server?udpa.resource.listening_address=%s") .build(); - verifyBootstrapFail(b); + XdsClient xdsClient = mock(XdsClient.class); + XdsListenerResource listenerResource = XdsListenerResource.getInstance(); + when(xdsClient.getBootstrapInfo()).thenReturn(b); + xdsServerWrapper = new XdsServerWrapper("[::FFFF:129.144.52.38]:80", mockBuilder, listener, + selectorManager, new FakeXdsClientPoolFactory(xdsClient), filterRegistry); + Executors.newSingleThreadExecutor().execute(new Runnable() { + @Override + public void run() { + try { + xdsServerWrapper.start(); + } catch (IOException ex) { + // ignore + } + } + }); + verify(xdsClient, timeout(5000)).watchXdsResource( + eq(listenerResource), + eq("grpc/server?udpa.resource.listening_address=[::FFFF:129.144.52.38]:80"), + any(ResourceWatcher.class)); } @Test @@ -141,7 +160,7 @@ public class XdsServerWrapperTest { Bootstrapper.BootstrapInfo b = Bootstrapper.BootstrapInfo.builder() .servers(Arrays.asList( - Bootstrapper.ServerInfo.create("uri", InsecureChannelCredentials.create(), true))) + Bootstrapper.ServerInfo.create("uri", InsecureChannelCredentials.create()))) .node(EnvoyProtoData.Node.newBuilder().setId("id").build()) .build(); verifyBootstrapFail(b); @@ -181,7 +200,7 @@ public class XdsServerWrapperTest { Bootstrapper.BootstrapInfo b = Bootstrapper.BootstrapInfo.builder() .servers(Arrays.asList( Bootstrapper.ServerInfo.create( - "uri", InsecureChannelCredentials.create(), true))) + "uri", InsecureChannelCredentials.create()))) .node(EnvoyProtoData.Node.newBuilder().setId("id").build()) .serverListenerResourceNameTemplate( "xdstp://xds.authority.com/envoy.config.listener.v3.Listener/grpc/server/%s")