Skip to content

Commit 3656932

Browse files
feat: TPC support
1 parent 5e26596 commit 3656932

File tree

9 files changed

+167
-23
lines changed

9 files changed

+167
-23
lines changed

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: 8 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

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

Lines changed: 34 additions & 7 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,18 @@ 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+
spannerStubSettings =
785+
builder.spannerStubSettingsBuilder.setUniverseDomain(getResolvedUniverseDomain()).build();
786+
instanceAdminStubSettings =
787+
builder
788+
.instanceAdminStubSettingsBuilder
789+
.setUniverseDomain(getResolvedUniverseDomain())
790+
.build();
791+
databaseAdminStubSettings =
792+
builder
793+
.databaseAdminStubSettingsBuilder
794+
.setUniverseDomain(getResolvedUniverseDomain())
795+
.build();
786796
} catch (IOException e) {
787797
throw SpannerExceptionFactory.newSpannerException(e);
788798
}
@@ -824,6 +834,11 @@ protected SpannerOptions(Builder builder) {
824834
defaultTransactionOptions = builder.defaultTransactionOptions;
825835
}
826836

837+
private String getResolvedUniverseDomain() {
838+
String universeDomain = getUniverseDomain();
839+
return Strings.isNullOrEmpty(universeDomain) ? GOOGLE_DEFAULT_UNIVERSE : universeDomain;
840+
}
841+
827842
/**
828843
* The environment to read configuration values from. The default implementation uses environment
829844
* variables.
@@ -871,6 +886,8 @@ default boolean isEnableEndToEndTracing() {
871886
return false;
872887
}
873888

889+
@Deprecated
890+
@ObsoleteApi("This will be removed in upcoming version without breaking change release. You should use universalDomain to configure the built-in metrics endpoint for a partner universe.")
874891
default String getMonitoringHost() {
875892
return null;
876893
}
@@ -1665,6 +1682,8 @@ public Builder setBuiltInMetricsEnabled(boolean enableBuiltInMetrics) {
16651682
}
16661683

16671684
/** Sets the monitoring host to be used for Built-in client side metrics */
1685+
@Deprecated
1686+
@ObsoleteApi("This will be removed in upcoming version without breaking change release. You should use universalDomain to configure the built-in metrics endpoint for a partner universe.")
16681687
public Builder setMonitoringHost(String monitoringHost) {
16691688
this.monitoringHost = monitoringHost;
16701689
return this;
@@ -2035,7 +2054,11 @@ public ApiTracerFactory getApiTracerFactory() {
20352054
public void enablegRPCMetrics(InstantiatingGrpcChannelProvider.Builder channelProviderBuilder) {
20362055
if (SpannerOptions.environment.isEnableGRPCBuiltInMetrics()) {
20372056
this.builtInMetricsProvider.enableGrpcMetrics(
2038-
channelProviderBuilder, this.getProjectId(), getCredentials(), this.monitoringHost);
2057+
channelProviderBuilder,
2058+
this.getProjectId(),
2059+
getCredentials(),
2060+
this.monitoringHost,
2061+
getUniverseDomain());
20392062
}
20402063
}
20412064

@@ -2081,7 +2104,7 @@ private ApiTracerFactory getDefaultApiTracerFactory() {
20812104
private ApiTracerFactory createMetricsApiTracerFactory() {
20822105
OpenTelemetry openTelemetry =
20832106
this.builtInMetricsProvider.getOrCreateOpenTelemetry(
2084-
this.getProjectId(), getCredentials(), this.monitoringHost);
2107+
this.getProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
20852108

20862109
return openTelemetry != null
20872110
? new BuiltInMetricsTracerFactory(
@@ -2181,7 +2204,11 @@ public static GrpcTransportOptions getDefaultGrpcTransportOptions() {
21812204

21822205
@Override
21832206
protected String getDefaultHost() {
2184-
return DEFAULT_HOST;
2207+
String universeDomain = getUniverseDomain();
2208+
if (Strings.isNullOrEmpty(universeDomain)) {
2209+
universeDomain = GOOGLE_DEFAULT_UNIVERSE;
2210+
}
2211+
return String.format("https://%s.%s", SPANNER_SERVICE_NAME, universeDomain);
21852212
}
21862213

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

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

Lines changed: 9 additions & 3 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;
@@ -769,16 +770,14 @@ static String determineHost(
769770
boolean autoConfigEmulator,
770771
boolean usePlainText,
771772
Map<String, String> environment) {
772-
String host;
773+
String host = null;
773774
if (Objects.equals(endpoint, DEFAULT_ENDPOINT) && matcher.group(Builder.HOST_GROUP) == null) {
774775
if (autoConfigEmulator) {
775776
if (Strings.isNullOrEmpty(environment.get(SPANNER_EMULATOR_HOST_ENV_VAR))) {
776777
return DEFAULT_EMULATOR_HOST;
777778
} else {
778779
return PLAIN_TEXT_PROTOCOL + "//" + environment.get(SPANNER_EMULATOR_HOST_ENV_VAR);
779780
}
780-
} else {
781-
return DEFAULT_HOST;
782781
}
783782
} else if (!Objects.equals(endpoint, DEFAULT_ENDPOINT)) {
784783
// Add '//' at the start of the endpoint to conform to the standard URL specification.
@@ -792,6 +791,9 @@ static String determineHost(
792791
host = String.format("%s:15000", host);
793792
}
794793
}
794+
if (host == null) {
795+
return null;
796+
}
795797
if (usePlainText) {
796798
return PLAIN_TEXT_PROTOCOL + host;
797799
}
@@ -1086,6 +1088,10 @@ Boolean isEnableDirectAccess() {
10861088
return getInitialConnectionPropertyValue(ENABLE_DIRECT_ACCESS);
10871089
}
10881090

1091+
String getUniverseDomain() {
1092+
return getInitialConnectionPropertyValue(UNIVERSE_DOMAIN);
1093+
}
1094+
10891095
String getClientCertificate() {
10901096
return getInitialConnectionPropertyValue(CLIENT_CERTIFICATE);
10911097
}

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
}

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerCloudMonitoringExporterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ public void testExportingHistogramDataWithExemplars() {
454454
@Test
455455
public void getAggregationTemporality() throws IOException {
456456
SpannerCloudMonitoringExporter actualExporter =
457-
SpannerCloudMonitoringExporter.create(projectId, null, null);
457+
SpannerCloudMonitoringExporter.create(projectId, null, null, null);
458458
assertThat(actualExporter.getAggregationTemporality(InstrumentType.COUNTER))
459459
.isEqualTo(AggregationTemporality.CUMULATIVE);
460460
}

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -761,11 +761,11 @@ public void testMonitoringHost() {
761761
String metricsEndpoint = "test-endpoint:443";
762762
assertNull(SpannerOptions.newBuilder().setProjectId("p").build().getMonitoringHost());
763763
assertThat(
764-
SpannerOptions.newBuilder()
765-
.setProjectId("p")
766-
.setMonitoringHost(metricsEndpoint)
767-
.build()
768-
.getMonitoringHost())
764+
SpannerOptions.newBuilder()
765+
.setProjectId("p")
766+
.setMonitoringHost(metricsEndpoint)
767+
.build()
768+
.getMonitoringHost())
769769
.isEqualTo(metricsEndpoint);
770770
}
771771

0 commit comments

Comments
 (0)