1616
1717package io .grpc .xds .internal ;
1818
19+ import com .google .common .base .Supplier ;
1920import com .google .common .collect .ImmutableList ;
2021import com .google .protobuf .Duration ;
2122import com .google .protobuf .util .Durations ;
@@ -73,66 +74,36 @@ protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
7374 }
7475 }
7576
76- ImmutableList .Builder <Closeable > resourcesBuilder = ImmutableList .builder ();
77- ScheduledExecutorService scheduledExecutorService = null ;
78-
7977 // use trust certificate file path from bootstrap config if provided; else use system default
8078 String rootCertPath = JsonUtil .getString (jsonConfig , ROOT_FILE_KEY );
79+ AdvancedTlsX509TrustManager trustManager = null ;
8180 if (rootCertPath != null ) {
82- try {
83- scheduledExecutorService = scheduledExecutorServiceFactory .create ();
84- AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager .newBuilder ().build ();
85- Closeable trustManagerFuture = trustManager .updateTrustCredentials (
86- new File (rootCertPath ),
87- refreshIntervalSeconds ,
88- TimeUnit .SECONDS ,
89- scheduledExecutorService );
90- resourcesBuilder .add (trustManagerFuture );
91- tlsChannelCredsBuilder .trustManager (trustManager );
92- } catch (Exception e ) {
93- logger .log (Level .WARNING , "Unable to read root certificates" , e );
94- return null ;
95- }
81+ trustManager = AdvancedTlsX509TrustManager .newBuilder ().build ();
82+ tlsChannelCredsBuilder .trustManager (trustManager );
9683 }
9784
9885 // use certificate chain and private key file paths from bootstrap config if provided. Mind that
9986 // both JSON values must be either set (mTLS case) or both unset (TLS case)
10087 String certChainPath = JsonUtil .getString (jsonConfig , CERT_FILE_KEY );
10188 String privateKeyPath = JsonUtil .getString (jsonConfig , KEY_FILE_KEY );
89+ AdvancedTlsX509KeyManager keyManager = null ;
10290 if (certChainPath != null && privateKeyPath != null ) {
103- try {
104- if (scheduledExecutorService == null ) {
105- scheduledExecutorService = scheduledExecutorServiceFactory .create ();
106- }
107- AdvancedTlsX509KeyManager keyManager = new AdvancedTlsX509KeyManager ();
108- Closeable keyManagerFuture = keyManager .updateIdentityCredentials (
109- new File (certChainPath ),
110- new File (privateKeyPath ),
111- refreshIntervalSeconds ,
112- TimeUnit .SECONDS ,
113- scheduledExecutorService );
114- resourcesBuilder .add (keyManagerFuture );
115- tlsChannelCredsBuilder .keyManager (keyManager );
116- } catch (Exception e ) {
117- logger .log (Level .WARNING , "Unable to read certificate chain or private key" , e );
118- return null ;
119- }
91+ keyManager = new AdvancedTlsX509KeyManager ();
92+ tlsChannelCredsBuilder .keyManager (keyManager );
12093 } else if (certChainPath != null || privateKeyPath != null ) {
12194 logger .log (Level .WARNING , "Certificate chain and private key must be both set or unset" );
12295 return null ;
12396 }
12497
125- // if executor was initialized, add it to allocated resource list
126- if (scheduledExecutorService != null ) {
127- resourcesBuilder .add (asCloseable (scheduledExecutorService ));
128- }
129-
13098 return ResourceAllocatingChannelCredentials .create (
131- tlsChannelCredsBuilder .build (), resourcesBuilder .build ());
132- }
133-
134- private static Closeable asCloseable (ScheduledExecutorService scheduledExecutorService ) {
135- return () -> scheduledExecutorService .shutdownNow ();
99+ tlsChannelCredsBuilder .build (),
100+ new ResourcesSupplier (
101+ refreshIntervalSeconds ,
102+ rootCertPath ,
103+ trustManager ,
104+ certChainPath ,
105+ privateKeyPath ,
106+ keyManager ));
136107 }
137108
138109 @ Override
@@ -150,6 +121,84 @@ public int priority() {
150121 return 5 ;
151122 }
152123
124+ private static final class ResourcesSupplier implements Supplier <ImmutableList <Closeable >> {
125+ private final long refreshIntervalSeconds ;
126+ private final String rootCertPath ;
127+ private final AdvancedTlsX509TrustManager trustManager ;
128+ private final String certChainPath ;
129+ private final String privateKeyPath ;
130+ private final AdvancedTlsX509KeyManager keyManager ;
131+
132+ ResourcesSupplier (
133+ long refreshIntervalSeconds ,
134+ String rootCertPath ,
135+ AdvancedTlsX509TrustManager trustManager ,
136+ String certChainPath ,
137+ String privateKeyPath ,
138+ AdvancedTlsX509KeyManager keyManager ) {
139+ this .refreshIntervalSeconds = refreshIntervalSeconds ;
140+ this .rootCertPath = rootCertPath ;
141+ this .trustManager = trustManager ;
142+ this .certChainPath = certChainPath ;
143+ this .privateKeyPath = privateKeyPath ;
144+ this .keyManager = keyManager ;
145+ }
146+
147+ @ Override
148+ public ImmutableList <Closeable > get () {
149+ ImmutableList .Builder <Closeable > resourcesBuilder = ImmutableList .builder ();
150+
151+ ScheduledExecutorService scheduledExecutorService =
152+ (trustManager != null || keyManager != null )
153+ ? scheduledExecutorService = scheduledExecutorServiceFactory .create ()
154+ : null ;
155+ if (scheduledExecutorService != null ) {
156+ resourcesBuilder .add (asCloseable (scheduledExecutorService ));
157+ }
158+
159+ if (trustManager != null ) {
160+ try {
161+ Closeable trustManagerFuture = trustManager .updateTrustCredentials (
162+ new File (rootCertPath ),
163+ refreshIntervalSeconds ,
164+ TimeUnit .SECONDS ,
165+ scheduledExecutorService );
166+ resourcesBuilder .add (trustManagerFuture );
167+ } catch (Exception e ) {
168+ cleanupResources (resourcesBuilder .build ());
169+ throw new RuntimeException ("Unable to read root certificates" , e );
170+ }
171+ }
172+
173+ if (keyManager != null ) {
174+ try {
175+ Closeable keyManagerFuture = keyManager .updateIdentityCredentials (
176+ new File (certChainPath ),
177+ new File (privateKeyPath ),
178+ refreshIntervalSeconds ,
179+ TimeUnit .SECONDS ,
180+ scheduledExecutorService );
181+ resourcesBuilder .add (keyManagerFuture );
182+ } catch (Exception e ) {
183+ cleanupResources (resourcesBuilder .build ());
184+ throw new RuntimeException ("Unable to read certificate chain or private key" , e );
185+ }
186+ }
187+
188+ return resourcesBuilder .build ();
189+ }
190+
191+ private static Closeable asCloseable (ScheduledExecutorService scheduledExecutorService ) {
192+ return () -> scheduledExecutorService .shutdownNow ();
193+ }
194+
195+ private static void cleanupResources (ImmutableList <Closeable > resources ) {
196+ for (Closeable resource : resources ) {
197+ GrpcUtil .closeQuietly (resource );
198+ }
199+ }
200+ }
201+
153202 abstract static class ScheduledExecutorServiceFactory {
154203
155204 private static final ScheduledExecutorServiceFactory DEFAULT_INSTANCE =
0 commit comments