@@ -73,28 +73,33 @@ static BootstrapInfo parseConfig(String rawData) throws IOException {
7373 @ SuppressWarnings ("unchecked" )
7474 Map <String , ?> rawBootstrap = (Map <String , ?>) JsonParser .parse (rawData );
7575
76- Map <String , ?> rawServerConfig = JsonUtil .getObject (rawBootstrap , "xds_server" );
77- if (rawServerConfig == null ) {
78- throw new IOException ("Invalid bootstrap: 'xds_server' does not exist." );
76+ List <ServerInfo > servers = new ArrayList <>();
77+ List <?> rawServerConfigs = JsonUtil .getList (rawBootstrap , "xds_servers" );
78+ if (rawServerConfigs == null ) {
79+ throw new IOException ("Invalid bootstrap: 'xds_servers' does not exist." );
7980 }
80- // Field "server_uri" is required.
81- String serverUri = JsonUtil .getString (rawServerConfig , "server_uri" );
82- if (serverUri == null ) {
83- throw new IOException ("Invalid bootstrap: 'xds_server : server_uri' does not exist." );
84- }
85- List <ChannelCreds > channelCredsOptions = new ArrayList <>();
86- List <?> rawChannelCredsList = JsonUtil .getList (rawServerConfig , "channel_creds" );
87- // List of channel creds is optional.
88- if (rawChannelCredsList != null ) {
89- List <Map <String , ?>> channelCredsList = JsonUtil .checkObjectList (rawChannelCredsList );
90- for (Map <String , ?> channelCreds : channelCredsList ) {
91- String type = JsonUtil .getString (channelCreds , "type" );
92- if (type == null ) {
93- throw new IOException ("Invalid bootstrap: 'channel_creds' contains unknown type." );
81+ List <Map <String , ?>> serverConfigList = JsonUtil .checkObjectList (rawServerConfigs );
82+ for (Map <String , ?> serverConfig : serverConfigList ) {
83+ String serverUri = JsonUtil .getString (serverConfig , "server_uri" );
84+ if (serverUri == null ) {
85+ throw new IOException ("Invalid bootstrap: 'xds_servers' contains unknown server." );
86+ }
87+ List <ChannelCreds > channelCredsOptions = new ArrayList <>();
88+ List <?> rawChannelCredsList = JsonUtil .getList (serverConfig , "channel_creds" );
89+ // List of channel creds is optional.
90+ if (rawChannelCredsList != null ) {
91+ List <Map <String , ?>> channelCredsList = JsonUtil .checkObjectList (rawChannelCredsList );
92+ for (Map <String , ?> channelCreds : channelCredsList ) {
93+ String type = JsonUtil .getString (channelCreds , "type" );
94+ if (type == null ) {
95+ throw new IOException ("Invalid bootstrap: 'xds_servers' contains server with "
96+ + "unknown type 'channel_creds'." );
97+ }
98+ ChannelCreds creds = new ChannelCreds (type , JsonUtil .getObject (channelCreds , "config" ));
99+ channelCredsOptions .add (creds );
94100 }
95- ChannelCreds creds = new ChannelCreds (type , JsonUtil .getObject (channelCreds , "config" ));
96- channelCredsOptions .add (creds );
97101 }
102+ servers .add (new ServerInfo (serverUri , channelCredsOptions ));
98103 }
99104
100105 Node .Builder nodeBuilder = Node .newBuilder ();
@@ -133,7 +138,7 @@ static BootstrapInfo parseConfig(String rawData) throws IOException {
133138 }
134139 nodeBuilder .setBuildVersion (GrpcUtil .getGrpcBuildVersion ());
135140
136- return new BootstrapInfo (serverUri , channelCredsOptions , nodeBuilder .build ());
141+ return new BootstrapInfo (servers , nodeBuilder .build ());
137142 }
138143
139144 /**
@@ -203,26 +208,48 @@ String getType() {
203208 }
204209
205210 /**
206- * Data class containing the results of reading bootstrap.
211+ * Data class containing xDS server information, such as server URI and channel credential
212+ * options to be used for communication.
207213 */
208214 @ Immutable
209- public static class BootstrapInfo {
215+ static class ServerInfo {
210216 private final String serverUri ;
211217 private final List <ChannelCreds > channelCredsList ;
212- private final Node node ;
213218
214219 @ VisibleForTesting
215- BootstrapInfo (String serverUri , List <ChannelCreds > channelCredsList , Node node ) {
220+ ServerInfo (String serverUri , List <ChannelCreds > channelCredsList ) {
216221 this .serverUri = serverUri ;
217222 this .channelCredsList = channelCredsList ;
223+ }
224+
225+ String getServerUri () {
226+ return serverUri ;
227+ }
228+
229+ List <ChannelCreds > getChannelCredentials () {
230+ return Collections .unmodifiableList (channelCredsList );
231+ }
232+ }
233+
234+ /**
235+ * Data class containing the results of reading bootstrap.
236+ */
237+ @ Immutable
238+ public static class BootstrapInfo {
239+ private List <ServerInfo > servers ;
240+ private final Node node ;
241+
242+ @ VisibleForTesting
243+ BootstrapInfo (List <ServerInfo > servers , Node node ) {
244+ this .servers = servers ;
218245 this .node = node ;
219246 }
220247
221248 /**
222- * Returns the URI the traffic director to be connected to.
249+ * Returns the list of xDS servers to be connected to.
223250 */
224- String getServerUri () {
225- return serverUri ;
251+ List < ServerInfo > getServers () {
252+ return Collections . unmodifiableList ( servers ) ;
226253 }
227254
228255 /**
@@ -232,11 +259,5 @@ public Node getNode() {
232259 return node ;
233260 }
234261
235- /**
236- * Returns the credentials to use when communicating with the xDS server.
237- */
238- List <ChannelCreds > getChannelCredentials () {
239- return Collections .unmodifiableList (channelCredsList );
240- }
241262 }
242263}
0 commit comments