4242import io .grpc .ServerServiceDefinition ;
4343import io .grpc .Status ;
4444import io .grpc .StatusException ;
45+ import io .grpc .StatusOr ;
4546import io .grpc .SynchronizationContext ;
4647import io .grpc .SynchronizationContext .ScheduledHandle ;
4748import io .grpc .internal .GrpcUtil ;
@@ -382,18 +383,30 @@ private DiscoveryState(String resourceName) {
382383 }
383384
384385 @ Override
385- public void onChanged (final LdsUpdate update ) {
386+ public void onResourceChanged (final StatusOr < LdsUpdate > update ) {
386387 if (stopped ) {
387388 return ;
388389 }
389- logger .log (Level .FINEST , "Received Lds update {0}" , update );
390- if (update .listener () == null ) {
391- onResourceDoesNotExist ("Non-API" );
390+
391+ if (!update .hasValue ()) {
392+ Status status = update .getStatus ();
393+ StatusException statusException = Status .UNAVAILABLE .withDescription (
394+ String .format ("Listener %s unavailable: %s" , resourceName , status .getDescription ()))
395+ .withCause (status .asException ())
396+ .asException ();
397+ handleConfigNotFoundOrMismatch (statusException );
392398 return ;
393399 }
394400
395- String ldsAddress = update .listener ().address ();
396- if (ldsAddress == null || update .listener ().protocol () != Protocol .TCP
401+ final LdsUpdate ldsUpdate = update .getValue ();
402+ logger .log (Level .FINEST , "Received Lds update {0}" , ldsUpdate );
403+ if (ldsUpdate .listener () == null ) {
404+ handleConfigNotFoundOrMismatch (
405+ Status .NOT_FOUND .withDescription ("Listener is null in LdsUpdate" ).asException ());
406+ return ;
407+ }
408+ String ldsAddress = ldsUpdate .listener ().address ();
409+ if (ldsAddress == null || ldsUpdate .listener ().protocol () != Protocol .TCP
397410 || !ipAddressesMatch (ldsAddress )) {
398411 handleConfigNotFoundOrMismatch (
399412 Status .UNKNOWN .withDescription (
@@ -402,16 +415,14 @@ public void onChanged(final LdsUpdate update) {
402415 listenerAddress , ldsAddress )).asException ());
403416 return ;
404417 }
418+
405419 if (!pendingRds .isEmpty ()) {
406- // filter chain state has not yet been applied to filterChainSelectorManager and there
407- // are two sets of sslContextProviderSuppliers, so we release the old ones.
408420 releaseSuppliersInFlight ();
409421 pendingRds .clear ();
410422 }
411423
412- filterChains = update .listener ().filterChains ();
413- defaultFilterChain = update .listener ().defaultFilterChain ();
414- // Filters are loaded even if the server isn't serving yet.
424+ filterChains = ldsUpdate .listener ().filterChains ();
425+ defaultFilterChain = ldsUpdate .listener ().defaultFilterChain ();
415426 updateActiveFilters ();
416427
417428 List <FilterChain > allFilterChains = filterChains ;
@@ -450,43 +461,33 @@ public void onChanged(final LdsUpdate update) {
450461 }
451462 }
452463
453- private boolean ipAddressesMatch (String ldsAddress ) {
454- HostAndPort ldsAddressHnP = HostAndPort .fromString (ldsAddress );
455- HostAndPort listenerAddressHnP = HostAndPort .fromString (listenerAddress );
456- if (!ldsAddressHnP .hasPort () || !listenerAddressHnP .hasPort ()
457- || ldsAddressHnP .getPort () != listenerAddressHnP .getPort ()) {
458- return false ;
459- }
460- InetAddress listenerIp = InetAddresses .forString (listenerAddressHnP .getHost ());
461- InetAddress ldsIp = InetAddresses .forString (ldsAddressHnP .getHost ());
462- return listenerIp .equals (ldsIp );
463- }
464-
465- @ Override
466- public void onResourceDoesNotExist (final String resourceName ) {
467- if (stopped ) {
468- return ;
469- }
470- StatusException statusException = Status .UNAVAILABLE .withDescription (
471- String .format ("Listener %s unavailable, xDS node ID: %s" , resourceName ,
472- xdsClient .getBootstrapInfo ().node ().getId ())).asException ();
473- handleConfigNotFoundOrMismatch (statusException );
474- }
475-
476464 @ Override
477- public void onError (final Status error ) {
465+ public void onAmbientError (final Status error ) {
478466 if (stopped ) {
479467 return ;
480468 }
481469 String description = error .getDescription () == null ? "" : error .getDescription () + " " ;
482470 Status errorWithNodeId = error .withDescription (
483471 description + "xDS node ID: " + xdsClient .getBootstrapInfo ().node ().getId ());
484472 logger .log (Level .FINE , "Error from XdsClient" , errorWithNodeId );
473+
485474 if (!isServing ) {
486475 listener .onNotServing (errorWithNodeId .asException ());
487476 }
488477 }
489478
479+ private boolean ipAddressesMatch (String ldsAddress ) {
480+ HostAndPort ldsAddressHnP = HostAndPort .fromString (ldsAddress );
481+ HostAndPort listenerAddressHnP = HostAndPort .fromString (listenerAddress );
482+ if (!ldsAddressHnP .hasPort () || !listenerAddressHnP .hasPort ()
483+ || ldsAddressHnP .getPort () != listenerAddressHnP .getPort ()) {
484+ return false ;
485+ }
486+ InetAddress listenerIp = InetAddresses .forString (listenerAddressHnP .getHost ());
487+ InetAddress ldsIp = InetAddresses .forString (ldsAddressHnP .getHost ());
488+ return listenerIp .equals (ldsIp );
489+ }
490+
490491 private void shutdown () {
491492 stopped = true ;
492493 cleanUpRouteDiscoveryStates ();
@@ -775,54 +776,42 @@ private RouteDiscoveryState(String resourceName) {
775776 }
776777
777778 @ Override
778- public void onChanged (final RdsUpdate update ) {
779- syncContext .execute (new Runnable () {
780- @ Override
781- public void run () {
782- if (!routeDiscoveryStates .containsKey (resourceName )) {
783- return ;
784- }
785- if (savedVirtualHosts == null && !isPending ) {
786- logger .log (Level .WARNING , "Received valid Rds {0} configuration." , resourceName );
787- }
788- savedVirtualHosts = ImmutableList .copyOf (update .virtualHosts );
789- updateRdsRoutingConfig ();
790- maybeUpdateSelector ();
779+ public void onResourceChanged (final StatusOr <RdsUpdate > update ) {
780+ syncContext .execute (() -> {
781+ if (!routeDiscoveryStates .containsKey (resourceName )) {
782+ return ; // Watcher has been cancelled.
791783 }
792- });
793- }
794784
795- @ Override
796- public void onResourceDoesNotExist (final String resourceName ) {
797- syncContext .execute (new Runnable () {
798- @ Override
799- public void run () {
800- if (!routeDiscoveryStates .containsKey (resourceName )) {
801- return ;
785+ if (update .hasValue ()) {
786+ if (savedVirtualHosts == null && !isPending ) {
787+ logger .log (Level .WARNING , "Received valid Rds {0} configuration." , resourceName );
802788 }
803- logger .log (Level .WARNING , "Rds {0} unavailable" , resourceName );
789+ savedVirtualHosts = ImmutableList .copyOf (update .getValue ().virtualHosts );
790+ } else {
791+ logger .log (Level .WARNING , "Rds {0} unavailable: {1}" ,
792+ new Object []{resourceName , update .getStatus ()});
804793 savedVirtualHosts = null ;
805- updateRdsRoutingConfig ();
806- maybeUpdateSelector ();
807794 }
795+ // In both cases, a change has occurred that requires a config update.
796+ updateRdsRoutingConfig ();
797+ maybeUpdateSelector ();
808798 });
809799 }
810800
811801 @ Override
812- public void onError (final Status error ) {
813- syncContext .execute (new Runnable () {
814- @ Override
815- public void run () {
816- if (!routeDiscoveryStates .containsKey (resourceName )) {
817- return ;
818- }
819- String description = error .getDescription () == null ? "" : error .getDescription () + " " ;
820- Status errorWithNodeId = error .withDescription (
821- description + "xDS node ID: " + xdsClient .getBootstrapInfo ().node ().getId ());
822- logger .log (Level .WARNING , "Error loading RDS resource {0} from XdsClient: {1}." ,
823- new Object []{resourceName , errorWithNodeId });
824- maybeUpdateSelector ();
802+ public void onAmbientError (final Status error ) {
803+ syncContext .execute (() -> {
804+ if (!routeDiscoveryStates .containsKey (resourceName )) {
805+ return ; // Watcher has been cancelled.
825806 }
807+ String description = error .getDescription () == null ? "" : error .getDescription () + " " ;
808+ Status errorWithNodeId = error .withDescription (
809+ description + "xDS node ID: " + xdsClient .getBootstrapInfo ().node ().getId ());
810+ logger .log (Level .WARNING , "Error loading RDS resource {0} from XdsClient: {1}." ,
811+ new Object []{resourceName , errorWithNodeId });
812+
813+ // Per gRFC A88, ambient errors should not trigger a configuration change.
814+ // Therefore, we do NOT call maybeUpdateSelector() here.
826815 });
827816 }
828817
0 commit comments