Skip to content

Commit 625ed84

Browse files
authored
Merge branch 'main' into renovate/org.codehaus.mojo-build-helper-maven-plugin-3.x
2 parents 7d746a5 + 312801e commit 625ed84

File tree

62 files changed

+581
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+581
-88
lines changed

google-cloud-spanner/pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,20 @@
369369
<scope>test</scope>
370370
</dependency>
371371

372+
<!-- Used to work around https://github.com/googleapis/sdk-platform-java/issues/3911 -->
373+
<dependency>
374+
<groupId>net.bytebuddy</groupId>
375+
<artifactId>byte-buddy</artifactId>
376+
<version>1.17.7</version>
377+
<scope>test</scope>
378+
</dependency>
379+
<dependency>
380+
<groupId>net.bytebuddy</groupId>
381+
<artifactId>byte-buddy-agent</artifactId>
382+
<version>1.17.7</version>
383+
<scope>test</scope>
384+
</dependency>
385+
372386
<!-- Executor tests - The 'provided' scope is overwritten to compile time scope for the profile 'executor-tests' -->
373387
<dependency>
374388
<groupId>com.google.api.grpc</groupId>

google-cloud-spanner/src/main/java/com/google/cloud/spanner/BuiltInMetricsProvider.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,16 @@ final class BuiltInMetricsProvider {
6868
private BuiltInMetricsProvider() {}
6969

7070
OpenTelemetry getOrCreateOpenTelemetry(
71-
String projectId, @Nullable Credentials credentials, @Nullable String monitoringHost) {
71+
String projectId,
72+
@Nullable Credentials credentials,
73+
@Nullable String monitoringHost,
74+
String universeDomain) {
7275
try {
7376
if (this.openTelemetry == null) {
7477
SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder();
7578
BuiltInMetricsView.registerBuiltinMetrics(
76-
SpannerCloudMonitoringExporter.create(projectId, credentials, monitoringHost),
79+
SpannerCloudMonitoringExporter.create(
80+
projectId, credentials, monitoringHost, universeDomain),
7781
sdkMeterProviderBuilder);
7882
sdkMeterProviderBuilder.setResource(Resource.create(createResourceAttributes(projectId)));
7983
SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build();
@@ -95,10 +99,13 @@ void enableGrpcMetrics(
9599
InstantiatingGrpcChannelProvider.Builder channelProviderBuilder,
96100
String projectId,
97101
@Nullable Credentials credentials,
98-
@Nullable String monitoringHost) {
102+
@Nullable String monitoringHost,
103+
String universeDomain) {
99104
GrpcOpenTelemetry grpcOpenTelemetry =
100105
GrpcOpenTelemetry.newBuilder()
101-
.sdk(this.getOrCreateOpenTelemetry(projectId, credentials, monitoringHost))
106+
.sdk(
107+
this.getOrCreateOpenTelemetry(
108+
projectId, credentials, monitoringHost, universeDomain))
102109
.enableMetrics(BuiltInMetricsConstant.GRPC_METRICS_TO_ENABLE)
103110
// Disable gRPCs default metrics as they are not needed for Spanner.
104111
.disableMetrics(BuiltInMetricsConstant.GRPC_METRICS_ENABLED_BY_DEFAULT)

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerCloudMonitoringExporter.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.cloud.monitoring.v3.MetricServiceClient;
2828
import com.google.cloud.monitoring.v3.MetricServiceSettings;
2929
import com.google.common.annotations.VisibleForTesting;
30+
import com.google.common.base.Strings;
3031
import com.google.common.collect.Iterables;
3132
import com.google.common.util.concurrent.MoreExecutors;
3233
import com.google.monitoring.v3.CreateTimeSeriesRequest;
@@ -71,7 +72,10 @@ class SpannerCloudMonitoringExporter implements MetricExporter {
7172
private final String spannerProjectId;
7273

7374
static SpannerCloudMonitoringExporter create(
74-
String projectId, @Nullable Credentials credentials, @Nullable String monitoringHost)
75+
String projectId,
76+
@Nullable Credentials credentials,
77+
@Nullable String monitoringHost,
78+
String universeDomain)
7579
throws IOException {
7680
MetricServiceSettings.Builder settingsBuilder = MetricServiceSettings.newBuilder();
7781
CredentialsProvider credentialsProvider;
@@ -84,6 +88,9 @@ static SpannerCloudMonitoringExporter create(
8488
if (monitoringHost != null) {
8589
settingsBuilder.setEndpoint(monitoringHost);
8690
}
91+
if (!Strings.isNullOrEmpty(universeDomain)) {
92+
settingsBuilder.setUniverseDomain(universeDomain);
93+
}
8794

8895
Duration timeout = Duration.ofMinutes(1);
8996
// TODO: createServiceTimeSeries needs special handling if the request failed. Leaving
@@ -110,6 +117,11 @@ public CompletableResultCode export(@Nonnull Collection<MetricData> collection)
110117
return exportSpannerClientMetrics(collection);
111118
}
112119

120+
@VisibleForTesting
121+
MetricServiceClient getMetricServiceClient() {
122+
return client;
123+
}
124+
113125
/** Export client built in metrics */
114126
private CompletableResultCode exportSpannerClientMetrics(Collection<MetricData> collection) {
115127
// Filter spanner metrics. Only include metrics that contain a valid project.

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public class SpannerOptions extends ServiceOptions<Spanner, SpannerOptions> {
120120
private static final String PG_ADAPTER_CLIENT_LIB_TOKEN = "pg-adapter";
121121

122122
private static final String API_SHORT_NAME = "Spanner";
123-
private static final String DEFAULT_HOST = "https://spanner.googleapis.com";
123+
private static final String SPANNER_SERVICE_NAME = "spanner";
124+
private static final String GOOGLE_DEFAULT_UNIVERSE = "googleapis.com";
124125
private static final String EXPERIMENTAL_HOST_PROJECT_ID = "default";
125126

126127
private static final ImmutableSet<String> SCOPES =
@@ -780,9 +781,19 @@ protected SpannerOptions(Builder builder) {
780781
databaseRole = builder.databaseRole;
781782
sessionLabels = builder.sessionLabels;
782783
try {
783-
spannerStubSettings = builder.spannerStubSettingsBuilder.build();
784-
instanceAdminStubSettings = builder.instanceAdminStubSettingsBuilder.build();
785-
databaseAdminStubSettings = builder.databaseAdminStubSettingsBuilder.build();
784+
String resolvedUniversalDomain = getResolvedUniverseDomain();
785+
spannerStubSettings =
786+
builder.spannerStubSettingsBuilder.setUniverseDomain(resolvedUniversalDomain).build();
787+
instanceAdminStubSettings =
788+
builder
789+
.instanceAdminStubSettingsBuilder
790+
.setUniverseDomain(resolvedUniversalDomain)
791+
.build();
792+
databaseAdminStubSettings =
793+
builder
794+
.databaseAdminStubSettingsBuilder
795+
.setUniverseDomain(resolvedUniversalDomain)
796+
.build();
786797
} catch (IOException e) {
787798
throw SpannerExceptionFactory.newSpannerException(e);
788799
}
@@ -814,12 +825,21 @@ protected SpannerOptions(Builder builder) {
814825
openTelemetry = builder.openTelemetry;
815826
enableApiTracing = builder.enableApiTracing;
816827
enableExtendedTracing = builder.enableExtendedTracing;
817-
enableBuiltInMetrics = builder.enableBuiltInMetrics;
828+
if (builder.isExperimentalHost) {
829+
enableBuiltInMetrics = false;
830+
} else {
831+
enableBuiltInMetrics = builder.enableBuiltInMetrics;
832+
}
818833
enableEndToEndTracing = builder.enableEndToEndTracing;
819834
monitoringHost = builder.monitoringHost;
820835
defaultTransactionOptions = builder.defaultTransactionOptions;
821836
}
822837

838+
private String getResolvedUniverseDomain() {
839+
String universeDomain = getUniverseDomain();
840+
return Strings.isNullOrEmpty(universeDomain) ? GOOGLE_DEFAULT_UNIVERSE : universeDomain;
841+
}
842+
823843
/**
824844
* The environment to read configuration values from. The default implementation uses environment
825845
* variables.
@@ -867,6 +887,10 @@ default boolean isEnableEndToEndTracing() {
867887
return false;
868888
}
869889

890+
@Deprecated
891+
@ObsoleteApi(
892+
"This will be removed in an upcoming version without a major version bump. You should use"
893+
+ " universalDomain to configure the built-in metrics endpoint for a partner universe.")
870894
default String getMonitoringHost() {
871895
return null;
872896
}
@@ -1661,6 +1685,10 @@ public Builder setBuiltInMetricsEnabled(boolean enableBuiltInMetrics) {
16611685
}
16621686

16631687
/** Sets the monitoring host to be used for Built-in client side metrics */
1688+
@Deprecated
1689+
@ObsoleteApi(
1690+
"This will be removed in an upcoming version without a major version bump. You should use"
1691+
+ " universalDomain to configure the built-in metrics endpoint for a partner universe.")
16641692
public Builder setMonitoringHost(String monitoringHost) {
16651693
this.monitoringHost = monitoringHost;
16661694
return this;
@@ -2031,7 +2059,11 @@ public ApiTracerFactory getApiTracerFactory() {
20312059
public void enablegRPCMetrics(InstantiatingGrpcChannelProvider.Builder channelProviderBuilder) {
20322060
if (SpannerOptions.environment.isEnableGRPCBuiltInMetrics()) {
20332061
this.builtInMetricsProvider.enableGrpcMetrics(
2034-
channelProviderBuilder, this.getProjectId(), getCredentials(), this.monitoringHost);
2062+
channelProviderBuilder,
2063+
this.getProjectId(),
2064+
getCredentials(),
2065+
this.monitoringHost,
2066+
getUniverseDomain());
20352067
}
20362068
}
20372069

@@ -2077,7 +2109,7 @@ private ApiTracerFactory getDefaultApiTracerFactory() {
20772109
private ApiTracerFactory createMetricsApiTracerFactory() {
20782110
OpenTelemetry openTelemetry =
20792111
this.builtInMetricsProvider.getOrCreateOpenTelemetry(
2080-
this.getProjectId(), getCredentials(), this.monitoringHost);
2112+
this.getProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
20812113

20822114
return openTelemetry != null
20832115
? new BuiltInMetricsTracerFactory(
@@ -2177,7 +2209,11 @@ public static GrpcTransportOptions getDefaultGrpcTransportOptions() {
21772209

21782210
@Override
21792211
protected String getDefaultHost() {
2180-
return DEFAULT_HOST;
2212+
String universeDomain = getUniverseDomain();
2213+
if (Strings.isNullOrEmpty(universeDomain)) {
2214+
universeDomain = GOOGLE_DEFAULT_UNIVERSE;
2215+
}
2216+
return String.format("https://%s.%s", SPANNER_SERVICE_NAME, universeDomain);
21812217
}
21822218

21832219
private static class SpannerDefaults implements ServiceDefaults<Spanner, SpannerOptions> {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,10 @@ public final int hashCode() {
17161716
* while calculating valueHash of Float32 type. Note that this is not applicable for composite
17171717
* types containing FLOAT32.
17181718
*/
1719-
if (type.getCode() == Type.Code.FLOAT32 && !isNull && Float.isNaN(getFloat32())) {
1719+
if (type != null
1720+
&& type.getCode() == Type.Code.FLOAT32
1721+
&& !isNull
1722+
&& Float.isNaN(getFloat32())) {
17201723
typeToHash = Type.float64();
17211724
}
17221725

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,18 @@
3939
import com.google.cloud.spanner.Struct;
4040
import com.google.cloud.spanner.Type.StructField;
4141
import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement;
42-
import com.google.cloud.spanner.connection.ReadWriteTransaction.Builder;
4342
import com.google.cloud.spanner.connection.StatementExecutor.StatementTimeout;
4443
import com.google.common.base.Preconditions;
4544
import com.google.common.collect.ImmutableList;
4645
import com.google.common.util.concurrent.MoreExecutors;
4746
import io.grpc.Context;
47+
import io.grpc.Deadline;
4848
import io.grpc.MethodDescriptor;
4949
import io.grpc.Status;
5050
import io.opentelemetry.api.common.AttributeKey;
5151
import io.opentelemetry.api.trace.Span;
5252
import io.opentelemetry.context.Scope;
53+
import java.time.Duration;
5354
import java.util.Collection;
5455
import java.util.Collections;
5556
import java.util.HashSet;
@@ -358,6 +359,9 @@ <T> ApiFuture<T> executeStatementAsync(
358359
}
359360
Context context = Context.current();
360361
if (statementTimeout.hasTimeout() && !applyStatementTimeoutToMethods.isEmpty()) {
362+
Deadline deadline =
363+
Deadline.after(
364+
statementTimeout.getTimeoutValue(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
361365
context =
362366
context.withValue(
363367
SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY,
@@ -367,8 +371,14 @@ public <ReqT, RespT> ApiCallContext configure(
367371
ApiCallContext context, ReqT request, MethodDescriptor<ReqT, RespT> method) {
368372
if (statementTimeout.hasTimeout()
369373
&& applyStatementTimeoutToMethods.contains(method)) {
374+
// Calculate the remaining timeout. This method could be called multiple times
375+
// if the transaction is retried.
376+
long remainingTimeout = deadline.timeRemaining(TimeUnit.NANOSECONDS);
377+
if (remainingTimeout <= 0) {
378+
remainingTimeout = 1;
379+
}
370380
return GrpcCallContext.createDefault()
371-
.withTimeoutDuration(statementTimeout.asDuration());
381+
.withTimeoutDuration(Duration.ofNanos(remainingTimeout));
372382
}
373383
return null;
374384
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import static com.google.cloud.spanner.connection.ConnectionProperties.TRACING_PREFIX;
5050
import static com.google.cloud.spanner.connection.ConnectionProperties.TRACK_CONNECTION_LEAKS;
5151
import static com.google.cloud.spanner.connection.ConnectionProperties.TRACK_SESSION_LEAKS;
52+
import static com.google.cloud.spanner.connection.ConnectionProperties.UNIVERSE_DOMAIN;
5253
import static com.google.cloud.spanner.connection.ConnectionProperties.USER_AGENT;
5354
import static com.google.cloud.spanner.connection.ConnectionProperties.USE_AUTO_SAVEPOINTS_FOR_EMULATOR;
5455
import static com.google.cloud.spanner.connection.ConnectionProperties.USE_PLAIN_TEXT;
@@ -76,6 +77,7 @@
7677
import com.google.cloud.spanner.SpannerOptions;
7778
import com.google.cloud.spanner.connection.StatementExecutor.StatementExecutorType;
7879
import com.google.common.annotations.VisibleForTesting;
80+
import com.google.common.base.MoreObjects;
7981
import com.google.common.base.Preconditions;
8082
import com.google.common.base.Strings;
8183
import com.google.common.base.Suppliers;
@@ -769,16 +771,14 @@ static String determineHost(
769771
boolean autoConfigEmulator,
770772
boolean usePlainText,
771773
Map<String, String> environment) {
772-
String host;
774+
String host = null;
773775
if (Objects.equals(endpoint, DEFAULT_ENDPOINT) && matcher.group(Builder.HOST_GROUP) == null) {
774776
if (autoConfigEmulator) {
775777
if (Strings.isNullOrEmpty(environment.get(SPANNER_EMULATOR_HOST_ENV_VAR))) {
776778
return DEFAULT_EMULATOR_HOST;
777779
} else {
778780
return PLAIN_TEXT_PROTOCOL + "//" + environment.get(SPANNER_EMULATOR_HOST_ENV_VAR);
779781
}
780-
} else {
781-
return DEFAULT_HOST;
782782
}
783783
} else if (!Objects.equals(endpoint, DEFAULT_ENDPOINT)) {
784784
// Add '//' at the start of the endpoint to conform to the standard URL specification.
@@ -792,6 +792,9 @@ static String determineHost(
792792
host = String.format("%s:15000", host);
793793
}
794794
}
795+
if (host == null) {
796+
return null;
797+
}
795798
if (usePlainText) {
796799
return PLAIN_TEXT_PROTOCOL + host;
797800
}
@@ -968,7 +971,7 @@ public TransportChannelProvider getChannelProvider() {
968971
return null;
969972
}
970973
try {
971-
URL url = new URL(host);
974+
URL url = new URL(MoreObjects.firstNonNull(host, DEFAULT_HOST));
972975
ExternalChannelProvider provider =
973976
ExternalChannelProvider.class.cast(Class.forName(channelProvider).newInstance());
974977
return provider.getChannelProvider(url.getHost(), url.getPort());
@@ -1086,6 +1089,10 @@ Boolean isEnableDirectAccess() {
10861089
return getInitialConnectionPropertyValue(ENABLE_DIRECT_ACCESS);
10871090
}
10881091

1092+
String getUniverseDomain() {
1093+
return getInitialConnectionPropertyValue(UNIVERSE_DOMAIN);
1094+
}
1095+
10891096
String getClientCertificate() {
10901097
return getInitialConnectionPropertyValue(CLIENT_CERTIFICATE);
10911098
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ public class ConnectionProperties {
200200
BOOLEANS,
201201
BooleanConverter.INSTANCE,
202202
Context.STARTUP);
203+
static final ConnectionProperty<String> UNIVERSE_DOMAIN =
204+
create(
205+
"universeDomain",
206+
"Configure the connection to try to connect to Spanner using "
207+
+ "a different partner Google Universe than GDU (googleapis.com).",
208+
"googleapis.com",
209+
StringValueConverter.INSTANCE,
210+
Context.STARTUP);
203211
static final ConnectionProperty<Boolean> USE_AUTO_SAVEPOINTS_FOR_EMULATOR =
204212
create(
205213
"useAutoSavepointsForEmulator",

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ static class SpannerPoolKey {
165165
private final String clientCertificateKey;
166166
private final boolean isExperimentalHost;
167167
private final Boolean enableDirectAccess;
168+
private final String universeDomain;
168169

169170
@VisibleForTesting
170171
static SpannerPoolKey of(ConnectionOptions options) {
@@ -200,6 +201,7 @@ private SpannerPoolKey(ConnectionOptions options) throws IOException {
200201
this.clientCertificateKey = options.getClientCertificateKey();
201202
this.isExperimentalHost = options.isExperimentalHost();
202203
this.enableDirectAccess = options.isEnableDirectAccess();
204+
this.universeDomain = options.getUniverseDomain();
203205
}
204206

205207
@Override
@@ -226,7 +228,8 @@ public boolean equals(Object o) {
226228
&& Objects.equals(this.clientCertificate, other.clientCertificate)
227229
&& Objects.equals(this.clientCertificateKey, other.clientCertificateKey)
228230
&& Objects.equals(this.isExperimentalHost, other.isExperimentalHost)
229-
&& Objects.equals(this.enableDirectAccess, other.enableDirectAccess);
231+
&& Objects.equals(this.enableDirectAccess, other.enableDirectAccess)
232+
&& Objects.equals(this.universeDomain, other.universeDomain);
230233
}
231234

232235
@Override
@@ -249,7 +252,8 @@ public int hashCode() {
249252
this.clientCertificate,
250253
this.clientCertificateKey,
251254
this.isExperimentalHost,
252-
this.enableDirectAccess);
255+
this.enableDirectAccess,
256+
this.universeDomain);
253257
}
254258
}
255259

@@ -419,6 +423,9 @@ Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) {
419423
if (key.enableDirectAccess != null) {
420424
builder.setEnableDirectAccess(key.enableDirectAccess);
421425
}
426+
if (key.universeDomain != null) {
427+
builder.setUniverseDomain(key.universeDomain);
428+
}
422429
if (options.getConfigurator() != null) {
423430
options.getConfigurator().configure(builder);
424431
}

0 commit comments

Comments
 (0)