Skip to content

Commit

Permalink
chore: remove double client lib token header (#2681)
Browse files Browse the repository at this point in the history
* chore: remove double client lib token header

Removes the double inclusion of the standard client lib token when no
custom client lib token has been set. Also reuses more of the standard
feature for setting the client lib token, instaed of appending the
standard token at the moment that we are creating the gRPC stub. This
should reduce the probability that anyone who might be using a custom
header or custom client in some way will get it wrong.

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* test: modify expected outcome to match the new behavior

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
olavloite and gcf-owl-bot[bot] committed Oct 19, 2023
1 parent 9f1f047 commit 712c65f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 14 deletions.
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies:
If you are using Gradle 5.x or later, add this to your dependencies:

```Groovy
implementation platform('com.google.cloud:libraries-bom:26.24.0')
implementation platform('com.google.cloud:libraries-bom:26.25.0')
implementation 'com.google.cloud:google-cloud-spanner'
```
If you are using Gradle without BOM, add this to your dependencies:

```Groovy
implementation 'com.google.cloud:google-cloud-spanner:6.50.1'
implementation 'com.google.cloud:google-cloud-spanner:6.51.0'
```

If you are using SBT, add this to your dependencies:

```Scala
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.50.1"
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.51.0"
```
<!-- {x-version-update-end} -->

Expand Down Expand Up @@ -432,7 +432,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner/java11.html
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-spanner.svg
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.50.1
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.51.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
Expand Down
Expand Up @@ -17,6 +17,7 @@
package com.google.cloud.spanner;

import com.google.api.core.ApiFunction;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.ExecutorProvider;
import com.google.api.gax.grpc.GrpcCallContext;
import com.google.api.gax.grpc.GrpcInterceptorProvider;
Expand Down Expand Up @@ -686,10 +687,10 @@ public static class Builder
private final ImmutableSet<String> allowedClientLibTokens =
ImmutableSet.of(
ServiceOptions.getGoogApiClientLibName(),
JDBC_API_CLIENT_LIB_TOKEN,
HIBERNATE_API_CLIENT_LIB_TOKEN,
LIQUIBASE_API_CLIENT_LIB_TOKEN,
PG_ADAPTER_CLIENT_LIB_TOKEN);
createCustomClientLibToken(JDBC_API_CLIENT_LIB_TOKEN),
createCustomClientLibToken(HIBERNATE_API_CLIENT_LIB_TOKEN),
createCustomClientLibToken(LIQUIBASE_API_CLIENT_LIB_TOKEN),
createCustomClientLibToken(PG_ADAPTER_CLIENT_LIB_TOKEN));
private TransportChannelProvider channelProvider;

@SuppressWarnings("rawtypes")
Expand Down Expand Up @@ -725,6 +726,10 @@ public static class Builder
private String emulatorHost = System.getenv("SPANNER_EMULATOR_HOST");
private boolean leaderAwareRoutingEnabled = true;

private static String createCustomClientLibToken(String token) {
return token + " " + ServiceOptions.getGoogApiClientLibName();
}

private Builder() {
// Manually set retry and polling settings that work.
OperationTimedPollAlgorithm longRunningPollingAlgorithm =
Expand Down Expand Up @@ -795,6 +800,13 @@ protected Set<String> getAllowedClientLibTokens() {
return allowedClientLibTokens;
}

@InternalApi
@Override
public SpannerOptions.Builder setClientLibToken(String clientLibToken) {
return super.setClientLibToken(
clientLibToken + " " + ServiceOptions.getGoogApiClientLibName());
}

/**
* Sets the {@code ChannelProvider}. {@link GapicSpannerRpc} would create a default one if none
* is provided.
Expand Down
Expand Up @@ -55,7 +55,6 @@
import com.google.api.pathtemplate.PathTemplate;
import com.google.cloud.RetryHelper;
import com.google.cloud.RetryHelper.RetryHelperException;
import com.google.cloud.ServiceOptions;
import com.google.cloud.grpc.GcpManagedChannelBuilder;
import com.google.cloud.grpc.GcpManagedChannelOptions;
import com.google.cloud.grpc.GcpManagedChannelOptions.GcpMetricsOptions;
Expand Down Expand Up @@ -297,8 +296,7 @@ public GapicSpannerRpc(final SpannerOptions options) {
ApiClientHeaderProvider internalHeaderProvider =
internalHeaderProviderBuilder
.setClientLibToken(
options.getClientLibToken() + " " + ServiceOptions.getGoogApiClientLibName(),
GaxProperties.getLibraryVersion(options.getClass()))
options.getClientLibToken(), GaxProperties.getLibraryVersion(options.getClass()))
.setTransportToken(
GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion())
.build();
Expand Down
Expand Up @@ -516,23 +516,25 @@ public void testSetClientLibToken() {
.setCredentials(NoCredentials.getInstance())
.setClientLibToken(jdbcToken)
.build();
assertThat(options.getClientLibToken()).isEqualTo(jdbcToken);
// Verify that the client lib token that will actually be used contains both the JDBC token and
// the standard Java client library token ('gccl').
assertEquals("sp-jdbc gccl", options.getClientLibToken());

options =
SpannerOptions.newBuilder()
.setProjectId("some-project")
.setCredentials(NoCredentials.getInstance())
.setClientLibToken(hibernateToken)
.build();
assertThat(options.getClientLibToken()).isEqualTo(hibernateToken);
assertEquals("sp-hib gccl", options.getClientLibToken());

options =
SpannerOptions.newBuilder()
.setProjectId("some-project")
.setCredentials(NoCredentials.getInstance())
.setClientLibToken(pgAdapterToken)
.build();
assertEquals(options.getClientLibToken(), pgAdapterToken);
assertEquals("pg-adapter gccl", options.getClientLibToken());

options =
SpannerOptions.newBuilder()
Expand Down
Expand Up @@ -583,6 +583,35 @@ public void testRouteToLeaderHeaderWithLeaderAwareRoutingDisabled() {
assertFalse(isRouteToLeader);
}

@Test
public void testClientLibToken() {
SpannerOptions options = createSpannerOptions();
try (Spanner spanner = options.getService()) {
DatabaseClient databaseClient =
spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"));
TransactionRunner runner = databaseClient.readWriteTransaction();
runner.run(transaction -> transaction.executeUpdate(UPDATE_FOO_STATEMENT));
}
Key<String> key = Key.of("x-goog-api-client", Metadata.ASCII_STRING_MARSHALLER);
assertTrue(lastSeenHeaders.containsKey(key));
assertTrue(
lastSeenHeaders.get(key),
Objects.requireNonNull(lastSeenHeaders.get(key))
.contains(ServiceOptions.getGoogApiClientLibName() + "/"));
// Check that the default header value is only included once in the header.
// We do this by splitting the entire header by the default header value. The resulting array
// should have 2 elements.
assertEquals(
lastSeenHeaders.get(key),
2,
Objects.requireNonNull(lastSeenHeaders.get(key))
.split(ServiceOptions.getGoogApiClientLibName())
.length);
assertTrue(
lastSeenHeaders.get(key),
Objects.requireNonNull(lastSeenHeaders.get(key)).contains("gl-java/"));
}

@Test
public void testCustomClientLibToken_alsoContainsDefaultToken() {
SpannerOptions options =
Expand All @@ -602,6 +631,9 @@ public void testCustomClientLibToken_alsoContainsDefaultToken() {
lastSeenHeaders.get(key),
Objects.requireNonNull(lastSeenHeaders.get(key))
.contains(ServiceOptions.getGoogApiClientLibName() + "/"));
assertTrue(
lastSeenHeaders.get(key),
Objects.requireNonNull(lastSeenHeaders.get(key)).contains("gl-java/"));
}

private SpannerOptions createSpannerOptions() {
Expand Down

0 comments on commit 712c65f

Please sign in to comment.