From 0d2152c8509f923c5209df2bcd8409b6ca8fccdb Mon Sep 17 00:00:00 2001 From: Adarsh-Shrivastava-001 Date: Tue, 21 Apr 2026 16:36:09 +0000 Subject: [PATCH 1/2] chore(spanner): accomodate experimental host in samples --- java-spanner/samples/snippets/pom.xml | 4 +-- .../spanner/MutableCredentialsExample.java | 1 + .../com/example/spanner/PgSpannerSample.java | 21 +++++++---- ...nformationSchemaDatabaseOptionsSample.java | 36 ++++++++++--------- .../example/spanner/SpannerGraphSample.java | 9 ++++- .../com/example/spanner/SpannerSample.java | 21 +++++++---- 6 files changed, 61 insertions(+), 31 deletions(-) diff --git a/java-spanner/samples/snippets/pom.xml b/java-spanner/samples/snippets/pom.xml index 23c24291e28d..d6efe02e45b2 100644 --- a/java-spanner/samples/snippets/pom.xml +++ b/java-spanner/samples/snippets/pom.xml @@ -34,7 +34,7 @@ com.google.cloud libraries-bom - 26.76.0 + 26.79.0 pom import @@ -228,7 +228,7 @@ false - com.example.spanner.admin.archived.SpannerSample + com.example.spanner.SpannerSample true lib/ diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/MutableCredentialsExample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/MutableCredentialsExample.java index fa6171180201..5a01fc2de9a2 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/MutableCredentialsExample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/MutableCredentialsExample.java @@ -33,6 +33,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; public class MutableCredentialsExample { diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java index b3ad5cd08c44..eb2f64d5303b 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java @@ -16,6 +16,9 @@ package com.example.spanner; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; + import com.google.api.gax.paging.Page; import com.google.cloud.ByteArray; import com.google.cloud.Date; @@ -1192,17 +1195,19 @@ static void queryWithNumeric(DatabaseClient dbClient) { // [START spanner_postgresql_create_client_with_query_options] static void clientWithQueryOptions(DatabaseId db) { - SpannerOptions options = - SpannerOptions.newBuilder() - .setDefaultQueryOptions( + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + builder.setDefaultQueryOptions( db, ExecuteSqlRequest.QueryOptions .newBuilder() .setOptimizerVersion("1") // The list of available statistics packages can be found by querying the // "INFORMATION_SCHEMA.spanner_postgresql_STATISTICS" table. .setOptimizerStatisticsPackage("latest") - .build()) - .build(); + .build()); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + SpannerOptions options = builder.build(); Spanner spanner = options.getService(); DatabaseClient dbClient = spanner.getDatabaseClient(db); try (ResultSet resultSet = @@ -1548,7 +1553,11 @@ public static void main(String[] args) { printUsageAndExit(); } // [START spanner_init_client] - SpannerOptions options = SpannerOptions.newBuilder().build(); + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + SpannerOptions options = builder.build(); Spanner spanner = options.getService(); DatabaseAdminClient dbAdminClient = null; try { diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java index 814c74542cba..3d8bff75cc57 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java @@ -16,7 +16,10 @@ package com.example.spanner; -//[START spanner_query_information_schema_database_options] +// [START spanner_query_information_schema_database_options] + +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; @@ -37,21 +40,23 @@ static void queryInformationSchemaDatabaseOptions() { static void queryInformationSchemaDatabaseOptions( String projectId, String instanceId, String databaseId) { - try (Spanner spanner = SpannerOptions - .newBuilder() - .setProjectId(projectId) - .build() - .getService()) { + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + builder.setProjectId(projectId); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + try (Spanner spanner = builder.build().getService()) { final DatabaseId id = DatabaseId.of(projectId, instanceId, databaseId); final DatabaseClient databaseClient = spanner.getDatabaseClient(id); - try (ResultSet resultSet = databaseClient - .singleUse() - .executeQuery(Statement.of( - "SELECT OPTION_NAME, OPTION_VALUE" - + " FROM INFORMATION_SCHEMA.DATABASE_OPTIONS" - + " WHERE OPTION_NAME = 'default_leader'") - )) { + try (ResultSet resultSet = + databaseClient + .singleUse() + .executeQuery( + Statement.of( + "SELECT OPTION_NAME, OPTION_VALUE" + + " FROM INFORMATION_SCHEMA.DATABASE_OPTIONS" + + " WHERE OPTION_NAME = 'default_leader'"))) { if (resultSet.next()) { final String optionName = resultSet.getString("OPTION_NAME"); final String optionValue = resultSet.getString("OPTION_VALUE"); @@ -59,11 +64,10 @@ static void queryInformationSchemaDatabaseOptions( System.out.println("The " + optionName + " for " + id + " is " + optionValue); } else { System.out.println( - "Database " + id + " does not have a value for option 'default_leader'" - ); + "Database " + id + " does not have a value for option 'default_leader'"); } } } } } -//[END spanner_query_information_schema_database_options] +// [END spanner_query_information_schema_database_options] diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java index ccb053133e56..258d44dc7d77 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java @@ -16,6 +16,9 @@ package com.example.spanner; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; + import com.google.cloud.Timestamp; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; @@ -554,7 +557,11 @@ public static void main(String[] args) { if (args.length != 3 && args.length != 4) { printUsageAndExit(); } - SpannerOptions options = SpannerOptions.newBuilder().build(); + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + SpannerOptions options = builder.build(); Spanner spanner = options.getService(); DatabaseAdminClient dbAdminClient = null; try { diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java index a01b00c0f6c3..6b1a872fac17 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java @@ -16,6 +16,9 @@ package com.example.spanner; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; +import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; + import static com.google.cloud.spanner.Type.StructField; import com.google.api.gax.longrunning.OperationFuture; @@ -1503,17 +1506,19 @@ static void queryWithNumeric(DatabaseClient dbClient) { // [START spanner_create_client_with_query_options] static void clientWithQueryOptions(DatabaseId db) { - SpannerOptions options = - SpannerOptions.newBuilder() - .setDefaultQueryOptions( + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + builder.setDefaultQueryOptions( db, QueryOptions .newBuilder() .setOptimizerVersion("1") // The list of available statistics packages can be found by querying the // "INFORMATION_SCHEMA.SPANNER_STATISTICS" table. .setOptimizerStatisticsPackage("latest") - .build()) - .build(); + .build()); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + SpannerOptions options = builder.build(); Spanner spanner = options.getService(); DatabaseClient dbClient = spanner.getDatabaseClient(db); try (ResultSet resultSet = @@ -2231,7 +2236,11 @@ public static void main(String[] args) { printUsageAndExit(); } // [START init_client] - SpannerOptions options = SpannerOptions.newBuilder().build(); + SpannerOptions.Builder builder = SpannerOptions.newBuilder(); + if (isExperimentalHost()) { + setExperimentalHostSpannerOptions(builder); + } + SpannerOptions options = builder.build(); Spanner spanner = options.getService(); DatabaseAdminClient dbAdminClient = null; try { From eadb6facc232524a88652d90860970c35ff6b446 Mon Sep 17 00:00:00 2001 From: Adarsh-Shrivastava-001 Date: Tue, 21 Apr 2026 19:23:36 +0000 Subject: [PATCH 2/2] refactor: create a new ExperimentalHostHelper in samples package and update import references --- .../spanner/ExperimentalHostHelper.java | 66 +++++++++++++++++++ .../com/example/spanner/PgSpannerSample.java | 4 +- ...nformationSchemaDatabaseOptionsSample.java | 4 +- .../example/spanner/SpannerGraphSample.java | 4 +- .../com/example/spanner/SpannerSample.java | 4 +- 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 java-spanner/samples/snippets/src/main/java/com/example/spanner/ExperimentalHostHelper.java diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/ExperimentalHostHelper.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/ExperimentalHostHelper.java new file mode 100644 index 000000000000..c47dca47f563 --- /dev/null +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/ExperimentalHostHelper.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.spanner; + +import com.google.cloud.spanner.SpannerOptions; +import com.google.common.base.Strings; + +public class ExperimentalHostHelper { + private static final String EXPERIMENTAL_HOST = "spanner.experimental_host"; + private static final String USE_PLAIN_TEXT = "spanner.use_plain_text"; + private static final String USE_MTLS = "spanner.mtls"; + private static final String CLIENT_CERT_PATH = "spanner.client_cert_path"; + private static final String CLIENT_CERT_KEY_PATH = "spanner.client_cert_key_path"; + + /** + * Checks whether an experimental host is being used. This is done by checking if the + * {@code spanner.experimental_host} system property is set. + * + * @return true if an experimental host is being used. Returns false otherwise. + */ + public static boolean isExperimentalHost() { + return !Strings.isNullOrEmpty(System.getProperty(EXPERIMENTAL_HOST)); + } + + public static boolean isMtlsSetup() { + return Boolean.getBoolean(USE_MTLS); + } + + public static void setExperimentalHostSpannerOptions(SpannerOptions.Builder builder) { + if (!isExperimentalHost()) { + throw new IllegalStateException(EXPERIMENTAL_HOST + " must be set to use this method"); + } + String experimentalHost = System.getProperty(EXPERIMENTAL_HOST, ""); + boolean usePlainText = Boolean.getBoolean(USE_PLAIN_TEXT); + builder.setExperimentalHost(experimentalHost); + builder.setBuiltInMetricsEnabled(false); + if (usePlainText) { + builder.usePlainText(); + } + if (isMtlsSetup()) { + String clientCertificate = System.getProperty(CLIENT_CERT_PATH, ""); + String clientKey = System.getProperty(CLIENT_CERT_KEY_PATH, ""); + if (Strings.isNullOrEmpty(clientCertificate)) { + throw new IllegalArgumentException(CLIENT_CERT_PATH + " must be set when mTLS is enabled"); + } + if (Strings.isNullOrEmpty(clientKey)) { + throw new IllegalArgumentException(CLIENT_CERT_KEY_PATH + " must be set when mTLS is enabled"); + } + builder.useClientCert(clientCertificate, clientKey); + } + } +} diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java index eb2f64d5303b..661eba4b4b60 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java @@ -16,8 +16,8 @@ package com.example.spanner; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; +import static com.example.spanner.ExperimentalHostHelper.isExperimentalHost; +import static com.example.spanner.ExperimentalHostHelper.setExperimentalHostSpannerOptions; import com.google.api.gax.paging.Page; import com.google.cloud.ByteArray; diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java index 3d8bff75cc57..9ad2da4b6286 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java @@ -18,8 +18,8 @@ // [START spanner_query_information_schema_database_options] -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; +import static com.example.spanner.ExperimentalHostHelper.isExperimentalHost; +import static com.example.spanner.ExperimentalHostHelper.setExperimentalHostSpannerOptions; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java index 258d44dc7d77..3e07638de98e 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java @@ -16,8 +16,8 @@ package com.example.spanner; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; +import static com.example.spanner.ExperimentalHostHelper.isExperimentalHost; +import static com.example.spanner.ExperimentalHostHelper.setExperimentalHostSpannerOptions; import com.google.cloud.Timestamp; import com.google.cloud.spanner.DatabaseClient; diff --git a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java index 6b1a872fac17..697e1f894729 100644 --- a/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java +++ b/java-spanner/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java @@ -16,8 +16,8 @@ package com.example.spanner; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.isExperimentalHost; -import static com.google.cloud.spanner.testing.ExperimentalHostHelper.setExperimentalHostSpannerOptions; +import static com.example.spanner.ExperimentalHostHelper.isExperimentalHost; +import static com.example.spanner.ExperimentalHostHelper.setExperimentalHostSpannerOptions; import static com.google.cloud.spanner.Type.StructField;