diff --git a/xds/src/main/java/io/grpc/xds/Bootstrapper.java b/xds/src/main/java/io/grpc/xds/Bootstrapper.java index a0bacd4190b..ea59498a272 100644 --- a/xds/src/main/java/io/grpc/xds/Bootstrapper.java +++ b/xds/src/main/java/io/grpc/xds/Bootstrapper.java @@ -101,19 +101,20 @@ public static BootstrapInfo parseConfig(String rawData) throws IOException { logger.log(XdsLogLevel.INFO, "xDS server URI: {0}", serverUri); List channelCredsOptions = new ArrayList<>(); List rawChannelCredsList = JsonUtil.getList(serverConfig, "channel_creds"); - // List of channel creds is optional. - if (rawChannelCredsList != null) { - List> channelCredsList = JsonUtil.checkObjectList(rawChannelCredsList); - for (Map channelCreds : channelCredsList) { - String type = JsonUtil.getString(channelCreds, "type"); - if (type == null) { - throw new IOException("Invalid bootstrap: 'xds_servers' contains server with " - + "unknown type 'channel_creds'."); - } - logger.log(XdsLogLevel.INFO, "Channel credentials option: {0}", type); - ChannelCreds creds = new ChannelCreds(type, JsonUtil.getObject(channelCreds, "config")); - channelCredsOptions.add(creds); + if (rawChannelCredsList == null || rawChannelCredsList.isEmpty()) { + throw new IOException( + "Invalid bootstrap: server " + serverUri + " 'channel_creds' required"); + } + List> channelCredsList = JsonUtil.checkObjectList(rawChannelCredsList); + for (Map channelCreds : channelCredsList) { + String type = JsonUtil.getString(channelCreds, "type"); + if (type == null) { + throw new IOException( + "Invalid bootstrap: server " + serverUri + " with 'channel_creds' type unspecified"); } + logger.log(XdsLogLevel.INFO, "Channel credentials option: {0}", type); + ChannelCreds creds = new ChannelCreds(type, JsonUtil.getObject(channelCreds, "config")); + channelCredsOptions.add(creds); } List serverFeatures = JsonUtil.getListOfStrings(serverConfig, "server_features"); if (serverFeatures != null) { diff --git a/xds/src/test/java/io/grpc/xds/BootstrapperTest.java b/xds/src/test/java/io/grpc/xds/BootstrapperTest.java index 17f42aad73b..75b250f4f04 100644 --- a/xds/src/test/java/io/grpc/xds/BootstrapperTest.java +++ b/xds/src/test/java/io/grpc/xds/BootstrapperTest.java @@ -24,6 +24,7 @@ import io.grpc.internal.GrpcUtil; import io.grpc.internal.GrpcUtil.GrpcBuildVersion; import io.grpc.xds.Bootstrapper.BootstrapInfo; +import io.grpc.xds.Bootstrapper.ChannelCreds; import io.grpc.xds.Bootstrapper.ServerInfo; import io.grpc.xds.EnvoyProtoData.Locality; import io.grpc.xds.EnvoyProtoData.Node; @@ -121,7 +122,9 @@ public void parseBootstrap_validData_multipleXdsServers() throws IOException { + " },\n" + " {\n" + " \"server_uri\": \"trafficdirector-bar.googleapis.com:443\",\n" - + " \"channel_creds\": []\n" + + " \"channel_creds\": [\n" + + " {\"type\": \"insecure\"}" + + " ]\n" + " }\n" + " ]\n" + "}"; @@ -142,7 +145,9 @@ public void parseBootstrap_validData_multipleXdsServers() throws IOException { assertThat(serverInfoList.get(0).getServerFeatures()).contains("xds_v3"); assertThat(serverInfoList.get(1).getServerUri()) .isEqualTo("trafficdirector-bar.googleapis.com:443"); - assertThat(serverInfoList.get(1).getChannelCredentials()).isEmpty(); + assertThat(serverInfoList.get(1).getChannelCredentials().get(0).getType()) + .isEqualTo("insecure"); + assertThat(serverInfoList.get(0).getChannelCredentials().get(0).getConfig()).isNull(); assertThat(info.getNode()).isEqualTo( getNodeBuilder() .setId("ENVOY_NODE_ID") @@ -234,7 +239,10 @@ public void parseBootstrap_minimalUsableData() throws IOException { String rawData = "{\n" + " \"xds_servers\": [\n" + " {\n" - + " \"server_uri\": \"trafficdirector.googleapis.com:443\"\n" + + " \"server_uri\": \"trafficdirector.googleapis.com:443\",\n" + + " \"channel_creds\": [\n" + + " {\"type\": \"insecure\"}\n" + + " ]\n" + " }\n" + " ]\n" + "}"; @@ -243,7 +251,10 @@ public void parseBootstrap_minimalUsableData() throws IOException { assertThat(info.getServers()).hasSize(1); ServerInfo serverInfo = Iterables.getOnlyElement(info.getServers()); assertThat(serverInfo.getServerUri()).isEqualTo("trafficdirector.googleapis.com:443"); - assertThat(serverInfo.getChannelCredentials()).isEmpty(); + assertThat(serverInfo.getChannelCredentials()).hasSize(1); + ChannelCreds creds = Iterables.getOnlyElement(serverInfo.getChannelCredentials()); + assertThat(creds.getType()).isEqualTo("insecure"); + assertThat(creds.getConfig()).isNull(); assertThat(info.getNode()).isEqualTo(getNodeBuilder().build()); }