Skip to content

Commit 48eb043

Browse files
committed
Added refresh interval support
1 parent 0bde286 commit 48eb043

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

xds/src/main/java/io/grpc/xds/internal/TlsXdsCredentialsProvider.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@
1616

1717
package io.grpc.xds.internal;
1818

19+
import com.google.protobuf.Duration;
20+
import com.google.protobuf.util.Durations;
1921
import io.grpc.ChannelCredentials;
2022
import io.grpc.TlsChannelCredentials;
23+
import io.grpc.internal.GrpcUtil;
2124
import io.grpc.internal.JsonUtil;
2225
import io.grpc.util.AdvancedTlsX509KeyManager;
2326
import io.grpc.util.AdvancedTlsX509TrustManager;
2427
import io.grpc.xds.XdsCredentialsProvider;
2528
import java.io.File;
29+
import java.text.ParseException;
2630
import java.util.Map;
31+
import java.util.concurrent.Executors;
32+
import java.util.concurrent.ScheduledExecutorService;
33+
import java.util.concurrent.TimeUnit;
2734
import java.util.logging.Level;
2835
import java.util.logging.Logger;
2936

@@ -37,6 +44,10 @@ public final class TlsXdsCredentialsProvider extends XdsCredentialsProvider {
3744
private static final String CERT_FILE_KEY = "certificate_file";
3845
private static final String KEY_FILE_KEY = "private_key_file";
3946
private static final String ROOT_FILE_KEY = "ca_certificate_file";
47+
private static final String REFRESH_INTERVAL_KEY = "refresh_interval";
48+
private static final long REFRESH_INTERVAL_DEFAULT = 600L;
49+
private static final ScheduledExecutorServiceFactory scheduledExecutorServiceFactory =
50+
ScheduledExecutorServiceFactory.DEFAULT_INSTANCE;
4051

4152
@Override
4253
protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
@@ -46,12 +57,29 @@ protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
4657
return builder.build();
4758
}
4859

60+
// use refresh interval from bootstrap config if provided; else defaults to 600s
61+
long refreshIntervalSeconds = REFRESH_INTERVAL_DEFAULT;
62+
String refreshIntervalFromConfig = JsonUtil.getString(jsonConfig, REFRESH_INTERVAL_KEY);
63+
if (refreshIntervalFromConfig != null) {
64+
try {
65+
Duration duration = Durations.parse(refreshIntervalFromConfig);
66+
refreshIntervalSeconds = Durations.toSeconds(duration);
67+
} catch (ParseException e) {
68+
logger.log(Level.WARNING, "Unable to parse refresh interval", e);
69+
return null;
70+
}
71+
}
72+
4973
// use trust certificate file path from bootstrap config if provided; else use system default
5074
String rootCertPath = JsonUtil.getString(jsonConfig, ROOT_FILE_KEY);
5175
if (rootCertPath != null) {
5276
try {
5377
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build();
54-
trustManager.updateTrustCredentials(new File(rootCertPath));
78+
trustManager.updateTrustCredentials(
79+
new File(rootCertPath),
80+
refreshIntervalSeconds,
81+
TimeUnit.SECONDS,
82+
scheduledExecutorServiceFactory.create());
5583
builder.trustManager(trustManager);
5684
} catch (Exception e) {
5785
logger.log(Level.WARNING, "Unable to read root certificates", e);
@@ -66,7 +94,12 @@ protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
6694
if (certChainPath != null && privateKeyPath != null) {
6795
try {
6896
AdvancedTlsX509KeyManager keyManager = new AdvancedTlsX509KeyManager();
69-
keyManager.updateIdentityCredentials(new File(certChainPath), new File(privateKeyPath));
97+
keyManager.updateIdentityCredentials(
98+
new File(certChainPath),
99+
new File(privateKeyPath),
100+
refreshIntervalSeconds,
101+
TimeUnit.SECONDS,
102+
scheduledExecutorServiceFactory.create());
70103
builder.keyManager(keyManager);
71104
} catch (Exception e) {
72105
logger.log(Level.WARNING, "Unable to read certificate chain or private key", e);
@@ -95,4 +128,18 @@ public int priority() {
95128
return 5;
96129
}
97130

131+
abstract static class ScheduledExecutorServiceFactory {
132+
133+
private static final ScheduledExecutorServiceFactory DEFAULT_INSTANCE =
134+
new ScheduledExecutorServiceFactory() {
135+
136+
@Override
137+
ScheduledExecutorService create() {
138+
return Executors.newSingleThreadScheduledExecutor(
139+
GrpcUtil.getThreadFactory("grpc-certificate-files-%d", true));
140+
}
141+
};
142+
143+
abstract ScheduledExecutorService create();
144+
}
98145
}

xds/src/test/java/io/grpc/xds/internal/TlsXdsCredentialsProviderTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ public void channelCredentialsWhenNullConfig() {
6969
provider.newChannelCredentials(null).getClass());
7070
}
7171

72+
@Test
73+
public void channelCredentialsWhenInvalidRefreshInterval() {
74+
Map<String, ?> jsonConfig = ImmutableMap.of(
75+
"refresh_interval", "invalid-duration-format");
76+
assertNull(provider.newChannelCredentials(jsonConfig));
77+
}
78+
7279
@Test
7380
public void channelCredentialsWhenNotExistingTrustFileConfig() {
7481
Map<String, ?> jsonConfig = ImmutableMap.of(
@@ -100,7 +107,8 @@ public void channelCredentialsWhenValidConfig() throws Exception {
100107
Map<String, ?> jsonConfig = ImmutableMap.of(
101108
"ca_certificate_file", rootCertPath,
102109
"certificate_file", certChainPath,
103-
"private_key_file", privateKeyPath);
110+
"private_key_file", privateKeyPath,
111+
"refresh_interval", "440s");
104112

105113
ChannelCredentials creds = provider.newChannelCredentials(jsonConfig);
106114
assertSame(TlsChannelCredentials.class, creds.getClass());

0 commit comments

Comments
 (0)