xds: close SslContexrProviderSupplier when the CDS LoadBalancer is shut down to prevent leakage (#8240)

diff --git a/xds/src/main/java/io/grpc/xds/ClusterImplLoadBalancer.java b/xds/src/main/java/io/grpc/xds/ClusterImplLoadBalancer.java
index 38eb571..5beefc3 100644
--- a/xds/src/main/java/io/grpc/xds/ClusterImplLoadBalancer.java
+++ b/xds/src/main/java/io/grpc/xds/ClusterImplLoadBalancer.java
@@ -153,7 +153,10 @@
     }
     if (childLb != null) {
       childLb.shutdown();
-      childLbHelper = null;
+      if (childLbHelper != null) {
+        childLbHelper.updateSslContextProviderSupplier(null);
+        childLbHelper = null;
+      }
     }
     if (xdsClient != null) {
       xdsClient = xdsClientPool.returnObject(xdsClient);
diff --git a/xds/src/main/java/io/grpc/xds/internal/sds/SslContextProviderSupplier.java b/xds/src/main/java/io/grpc/xds/internal/sds/SslContextProviderSupplier.java
index 900d3b9..3902569 100644
--- a/xds/src/main/java/io/grpc/xds/internal/sds/SslContextProviderSupplier.java
+++ b/xds/src/main/java/io/grpc/xds/internal/sds/SslContextProviderSupplier.java
@@ -19,6 +19,7 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
 import io.grpc.xds.EnvoyServerProtoData.BaseTlsContext;
 import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
@@ -100,6 +101,10 @@
         : tlsContextManager.findOrCreateServerSslContextProvider((DownstreamTlsContext) tlsContext);
   }
 
+  @VisibleForTesting public boolean isShutdown() {
+    return shutdown;
+  }
+
   /** Called by consumer when tlsContext changes. */
   @Override
   public synchronized void close() {
diff --git a/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java b/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java
index 5a55b2a..47926ca 100644
--- a/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java
+++ b/xds/src/test/java/io/grpc/xds/ClusterImplLoadBalancerTest.java
@@ -138,7 +138,9 @@
 
   @After
   public void tearDown() {
-    loadBalancer.shutdown();
+    if (loadBalancer != null) {
+      loadBalancer.shutdown();
+    }
     assertThat(xdsClientRefs).isEqualTo(0);
     assertThat(downstreamBalancers).isEmpty();
   }
@@ -553,11 +555,21 @@
       SslContextProviderSupplier supplier =
           eag.getAttributes().get(InternalXdsAttributes.ATTR_SSL_CONTEXT_PROVIDER_SUPPLIER);
       if (enableSecurity) {
+        assertThat(supplier.isShutdown()).isFalse();
         assertThat(supplier.getTlsContext()).isEqualTo(upstreamTlsContext);
       } else {
         assertThat(supplier).isNull();
       }
     }
+    loadBalancer.shutdown();
+    for (EquivalentAddressGroup eag : subchannel.getAllAddresses()) {
+      SslContextProviderSupplier supplier =
+              eag.getAttributes().get(InternalXdsAttributes.ATTR_SSL_CONTEXT_PROVIDER_SUPPLIER);
+      if (enableSecurity) {
+        assertThat(supplier.isShutdown()).isTrue();
+      }
+    }
+    loadBalancer = null;
   }
 
   private void deliverAddressesAndConfig(List<EquivalentAddressGroup> addresses,