From 6ff16a0ae84f7d996b24f181140cfdfb654f534a Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Mon, 16 Nov 2020 17:42:31 +0100 Subject: [PATCH] xds: add support for setting bootstrap file with java system property While most languages support setting environment variables during runtime, Java does not. In Java, the preferred approach is to use Java System Properties in order so specify configuration options. By checking for the existence of the io.grpc.xds.bootstrap property if GRPC_XDS_BOOTSTRAP is not found, it is possible to either supply the bootstrap location during runtime or as a Java argument. The environment variable still takes precedence in order to not break any existing documentation. --- examples/example-xds/README.md | 8 ++++---- xds/src/main/java/io/grpc/xds/Bootstrapper.java | 13 ++++++++++--- .../xds/XdsClientWrapperForServerSdsTestMisc.java | 8 ++++++-- .../test/java/io/grpc/xds/XdsServerBuilderTest.java | 8 ++++++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/example-xds/README.md b/examples/example-xds/README.md index f3b03673902..b80df219ca3 100644 --- a/examples/example-xds/README.md +++ b/examples/example-xds/README.md @@ -6,7 +6,7 @@ being configured with the XDS management protocol. Out-of-the-box they behave th as their hello-world version. __XDS support is incomplete and experimental, with limited compatibility. It -will be very hard to produce a working enviornment just by this example. Please +will be very hard to produce a working environment just by this example. Please refer to documentation specific for your XDS management server and environment.__ @@ -24,8 +24,8 @@ This creates the scripts `build/install/example-xds/bin/hello-world-client-xds` ### Run the example without using XDS Credentials To use XDS, you should first deploy the XDS management server in your deployment environment -and know its name. You need to set the `GRPC_XDS_BOOTSTRAP` environment variable to point to the -gRPC XDS bootstrap file (see +and know its name. You need to set the `GRPC_XDS_BOOTSTRAP` environment variable (preferred) or if that is not set then +the `io.grpc.xds.bootstrap` java system property to point to the gRPC XDS bootstrap file (see [gRFC A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md#xdsclient-and-bootstrap-file) for the bootstrap format). This is needed by both `build/install/example-xds/bin/hello-world-client-xds` and `build/install/example-xds/bin/hello-world-server-xds`. @@ -61,7 +61,7 @@ $ export GRPC_XDS_BOOTSTRAP=/path/to/bootstrap.json $ ./build/install/example-xds/bin/hello-world-server-xds 8000 my-test-xds-server --secure ``` -2. Similarly, add `--secure` on the comamnd line when you run the xDS client: +2. Similarly, add `--secure` on the command line when you run the xDS client: ``` $ export GRPC_XDS_BOOTSTRAP=/path/to/bootstrap.json $ ./build/install/example-xds/bin/hello-world-client-xds xds:///yourServersName:8000 my-test-xds-client --secure diff --git a/xds/src/main/java/io/grpc/xds/Bootstrapper.java b/xds/src/main/java/io/grpc/xds/Bootstrapper.java index 15f3eaccaf9..c33fb5bf734 100644 --- a/xds/src/main/java/io/grpc/xds/Bootstrapper.java +++ b/xds/src/main/java/io/grpc/xds/Bootstrapper.java @@ -47,6 +47,7 @@ public abstract class Bootstrapper { private static final String LOG_PREFIX = "xds-bootstrap"; private static final String BOOTSTRAP_PATH_SYS_ENV_VAR = "GRPC_XDS_BOOTSTRAP"; + private static final String BOOTSTRAP_PATH_SYS_PROPERTY_VAR = "io.grpc.xds.bootstrap"; @VisibleForTesting static final String CLIENT_FEATURE_DISABLE_OVERPROVISIONING = "envoy.lb.does_not_support_overprovisioning"; @@ -54,14 +55,20 @@ public abstract class Bootstrapper { private static final Bootstrapper DEFAULT_INSTANCE = new Bootstrapper() { @Override public BootstrapInfo readBootstrap() throws XdsInitializationException { - String filePath = System.getenv(BOOTSTRAP_PATH_SYS_ENV_VAR); + String filePathSource = BOOTSTRAP_PATH_SYS_ENV_VAR; + String filePath = System.getenv(filePathSource); + if (filePath == null) { + filePathSource = BOOTSTRAP_PATH_SYS_PROPERTY_VAR; + filePath = System.getProperty(filePathSource); + } if (filePath == null) { throw new XdsInitializationException( - "Environment variable " + BOOTSTRAP_PATH_SYS_ENV_VAR + " not defined."); + "Environment variable " + BOOTSTRAP_PATH_SYS_ENV_VAR + + " or Java System Property " + BOOTSTRAP_PATH_SYS_PROPERTY_VAR + " not defined."); } XdsLogger .withPrefix(LOG_PREFIX) - .log(XdsLogLevel.INFO, BOOTSTRAP_PATH_SYS_ENV_VAR + "={0}", filePath); + .log(XdsLogLevel.INFO, filePathSource + "={0}", filePath); String fileContent; try { fileContent = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); diff --git a/xds/src/test/java/io/grpc/xds/XdsClientWrapperForServerSdsTestMisc.java b/xds/src/test/java/io/grpc/xds/XdsClientWrapperForServerSdsTestMisc.java index 5fe70e78ff4..21519bb7cb3 100644 --- a/xds/src/test/java/io/grpc/xds/XdsClientWrapperForServerSdsTestMisc.java +++ b/xds/src/test/java/io/grpc/xds/XdsClientWrapperForServerSdsTestMisc.java @@ -201,7 +201,9 @@ public void startXdsClient_expectException() { } catch (IOException expected) { assertThat(expected) .hasMessageThat() - .contains("Environment variable GRPC_XDS_BOOTSTRAP not defined"); + .contains( + "Environment variable GRPC_XDS_BOOTSTRAP" + + " or Java System Property io.grpc.xds.bootstrap not defined."); } ArgumentCaptor argCaptor = ArgumentCaptor.forClass(null); verify(mockServerWatcher).onError(argCaptor.capture()); @@ -210,7 +212,9 @@ public void startXdsClient_expectException() { assertThat(captured.getCause()).isInstanceOf(XdsInitializationException.class); assertThat(captured.getCause()) .hasMessageThat() - .contains("Environment variable GRPC_XDS_BOOTSTRAP not defined"); + .contains( + "Environment variable GRPC_XDS_BOOTSTRAP" + + " or Java System Property io.grpc.xds.bootstrap not defined."); } private DownstreamTlsContext sendListenerUpdate( diff --git a/xds/src/test/java/io/grpc/xds/XdsServerBuilderTest.java b/xds/src/test/java/io/grpc/xds/XdsServerBuilderTest.java index 51e4e782fca..a560ad5fb54 100644 --- a/xds/src/test/java/io/grpc/xds/XdsServerBuilderTest.java +++ b/xds/src/test/java/io/grpc/xds/XdsServerBuilderTest.java @@ -236,7 +236,9 @@ public void xdsServerWithoutMockXdsClient_startError() } catch (IOException expected) { assertThat(expected) .hasMessageThat() - .contains("Environment variable GRPC_XDS_BOOTSTRAP not defined"); + .contains( + "Environment variable GRPC_XDS_BOOTSTRAP" + + " or Java System Property io.grpc.xds.bootstrap not defined."); } ArgumentCaptor argCaptor = ArgumentCaptor.forClass(null); verify(mockErrorNotifier).onError(argCaptor.capture()); @@ -245,7 +247,9 @@ public void xdsServerWithoutMockXdsClient_startError() assertThat(captured.getCause()).isInstanceOf(XdsInitializationException.class); assertThat(captured.getCause()) .hasMessageThat() - .contains("Environment variable GRPC_XDS_BOOTSTRAP not defined"); + .contains( + "Environment variable GRPC_XDS_BOOTSTRAP" + + " or Java System Property io.grpc.xds.bootstrap not defined."); } @Test