From 31ebd95fc67a2270d8e15ec00d4e133a06395765 Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 11 Sep 2024 11:15:06 -0400 Subject: [PATCH 01/23] track protobuf version --- .../google/api/gax/core/GaxProperties.java | 32 +++++++ .../api/gax/rpc/ApiClientHeaderProvider.java | 10 ++ .../api/gax/core/GaxPropertiesTest.java | 74 ++++++++++++--- .../gax/rpc/ApiClientHeaderProviderTest.java | 95 ++++++++++--------- 4 files changed, 155 insertions(+), 56 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index 66fbaf887a..f05a3bbf79 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -32,9 +32,16 @@ import com.google.api.core.InternalApi; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import com.google.protobuf.Any; + +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Optional; import java.util.Properties; +import java.util.jar.Attributes; +import java.util.jar.JarFile; /** Provides properties of the GAX library. */ @InternalApi @@ -43,6 +50,8 @@ public class GaxProperties { private static final String DEFAULT_VERSION = ""; private static final String GAX_VERSION = getLibraryVersion(GaxProperties.class, "version.gax"); private static final String JAVA_VERSION = getRuntimeVersion(); + private static final String PROTOBUF_VERSION = getBundleVersion(Any.class).orElse(DEFAULT_VERSION); + static final String BUNDLE_VERSION_KEY = "Bundle-Version"; private GaxProperties() {} @@ -91,6 +100,11 @@ public static String getGaxVersion() { return GAX_VERSION; } + /** Returns the current version of protobuf runtime library. */ + public static String getProtobufVersion() { + return PROTOBUF_VERSION; + } + /** * Returns the current runtime version. For GraalVM the values in this method will be fetched at * build time and the values should not differ from the runtime (executable) @@ -113,4 +127,22 @@ static String getRuntimeVersion() { // with hyphens. return javaRuntimeInformation.replaceAll("[^0-9a-zA-Z_\\\\.]", "-"); } + + /** + * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's META-INF/MANIFEST. + * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION + */ + @VisibleForTesting + static Optional getBundleVersion(Class clazz) { + try { + File file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()); + try (JarFile jar = new JarFile(file.getPath())) { + Attributes attributes = jar.getManifest().getMainAttributes(); + return Optional.ofNullable(attributes.getValue(BUNDLE_VERSION_KEY)); + } + } catch (URISyntaxException | IOException e) { + // Unable to read Protobuf runtime version. Recover gracefully. + return Optional.empty(); + } + } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index a5e80e10b1..a1ccc2bd9f 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -41,6 +41,7 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { private static final long serialVersionUID = -8876627296793342119L; static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project"; + static final String PROTOBUF_VERSION_TOKEN_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; @@ -57,6 +58,7 @@ protected ApiClientHeaderProvider(Builder builder) { appendToken(apiClientHeaderValue, builder.getGeneratedLibToken()); appendToken(apiClientHeaderValue, builder.getGeneratedRuntimeToken()); appendToken(apiClientHeaderValue, builder.getTransportToken()); + appendToken(apiClientHeaderValue, builder.protobufRuntimeToken); if (apiClientHeaderValue.length() > 0) { headersBuilder.put(builder.getApiClientHeaderKey(), apiClientHeaderValue.toString()); } @@ -110,6 +112,7 @@ public static class Builder { private String generatedRuntimeToken; private String transportToken; private String quotaProjectIdToken; + private final String protobufRuntimeToken; private String resourceHeaderKey; private String resourceToken; @@ -130,6 +133,9 @@ protected Builder() { resourceToken = null; apiVersionToken = null; + + // set any default metric headers + protobufRuntimeToken = constructToken(PROTOBUF_VERSION_TOKEN_KEY, GaxProperties.getProtobufVersion()); } public String getApiClientHeaderKey() { @@ -165,6 +171,10 @@ public String getGeneratedLibToken() { public Builder setGeneratedLibToken(String name, String version) { this.generatedLibToken = constructToken(name, version); + // TODO(b:/: this is a temporary fix while waiting for new field to be added + if (name.equals("gapic")) { + this.generatedLibToken += "--" + GaxProperties.getProtobufVersion(); + } return this; } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java index c27396c6b6..042e3ab3de 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java @@ -29,29 +29,42 @@ */ package com.google.api.gax.core; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static com.google.api.gax.core.GaxProperties.BUNDLE_VERSION_KEY; +import static com.google.api.gax.core.GaxProperties.getBundleVersion; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; import com.google.common.base.Strings; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.security.CodeSource; +import java.security.ProtectionDomain; +import java.util.Optional; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; import java.util.regex.Pattern; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import org.junit.Before; class GaxPropertiesTest { + @Test void testGaxVersion() { - String gaxVersion = GaxProperties.getGaxVersion(); - assertTrue(Pattern.compile("^\\d+\\.\\d+\\.\\d+").matcher(gaxVersion).find()); - String[] versionComponents = gaxVersion.split("\\."); - // This test was added in version 1.56.0, so check that the major and minor numbers are greater - // than that. - int major = Integer.parseInt(versionComponents[0]); - int minor = Integer.parseInt(versionComponents[1]); + Version version = readVersion(GaxProperties.getGaxVersion()); - assertTrue(major >= 1); - if (major == 1) { - assertTrue(minor >= 56); + assertTrue(version.major >= 1); + if (version.major == 1) { + assertTrue(version.minor >= 56); } } @@ -159,4 +172,41 @@ void testGetJavaRuntimeInfo_nullJavaVersion() { String runtimeInfo = GaxProperties.getRuntimeVersion(); assertEquals("null__oracle__20.0.1", runtimeInfo); } + + @Test + public void testGetProtobufVersion() throws IOException { + Version version = readVersion(GaxProperties.getProtobufVersion()); + + assertTrue(version.major >= 3); + if (version.major == 3) { + assertTrue(version.minor >= 25); + } + } + + @Test + public void testGetBundleVersion_noManifestFile() throws IOException { + Optional version = getBundleVersion(GaxProperties.class); + + assertFalse(version.isPresent()); + } + + private Version readVersion(String version) { + assertTrue(Pattern.compile("^\\d+\\.\\d+\\.\\d+").matcher(version).find()); + String[] versionComponents = version.split("\\."); + // This test was added in version 1.56.0, so check that the major and minor numbers are greater + // than that. + int major = Integer.parseInt(versionComponents[0]); + int minor = Integer.parseInt(versionComponents[1]); + return new Version(major, minor); + } + + private static class Version { + public int major; + public int minor; + + public Version(int major, int minor) { + this.major = major; + this.minor = minor; + } + } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index baccb901c2..02feea62d8 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -38,86 +38,93 @@ class ApiClientHeaderProviderTest { private static final String X_GOOG_API_CLIENT = "x-goog-api-client"; private static final String CLOUD_RESOURCE_PREFIX = "google-cloud-resource-prefix"; + private static final String PROTOBUF_HEADER = ApiClientHeaderProvider.PROTOBUF_VERSION_TOKEN_KEY+"/.*"; + private static final String FULL_HEADER_MATCH = "^gl-java/.* gapic/4\\.5\\.6++__"+PROTOBUF_HEADER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"; + private static final String HEADER_WITHOUT_GAPIC_MATCH = + "^gl-java/.* gccl/1\\.2\\.3 gax/.* "+PROTOBUF_HEADER+"$"; + @Test void testServiceHeaderDefault() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().build(); assertThat(provider.getHeaders().size()).isEqualTo(1); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches("^gl-java/.* gax/.*$"); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* gax/.* "+PROTOBUF_HEADER+"$"); } @Test void testServiceHeaderManual() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setClientLibToken("gccl", "1.2.3").build(); + ApiClientHeaderProvider.newBuilder().setClientLibToken("gccl", "1.2.3").build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/1\\.2\\.3 gax/.*$"); + .matches(HEADER_WITHOUT_GAPIC_MATCH); } @Test void testServiceHeaderManualGapic() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setClientLibToken("gccl", "4.5.6") - .setGeneratedLibToken("gapic", "7.8.9") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setClientLibToken("gccl", "4.5.6") + .setGeneratedLibToken("gapic", "7.8.9") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/4\\.5\\.6 gapic/7\\.8\\.9 gax/.* grpc/1\\.2\\.3$"); + .matches( + "^gl-java/.* gccl/4\\.5\\.6 gapic/7\\.8\\.9__"+PROTOBUF_HEADER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); } @Test void testServiceHeaderManualGrpc() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setClientLibToken("gccl", "4.5.6") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setClientLibToken("gccl", "4.5.6") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/4\\.5\\.6 gax/.* grpc/1\\.2\\.3$"); + .matches("^gl-java/.* gccl/4\\.5\\.6 gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); } @Test void testServiceHeaderGapic() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gapic/4\\.5\\.6 gax/.* grpc/1\\.2\\.3$"); + .matches(FULL_HEADER_MATCH); } @Test void testCloudResourcePrefixHeader() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .setResourceToken("test-prefix") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .setResourceToken("test-prefix") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gapic/4\\.5\\.6 gax/.* grpc/1\\.2\\.3$"); + .matches(FULL_HEADER_MATCH); assertThat(provider.getHeaders().get(CLOUD_RESOURCE_PREFIX)).isEqualTo("test-prefix"); } @Test void testCustomHeaderKeys() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .setResourceToken("test-prefix") - .setApiClientHeaderKey("custom-header1") - .setResourceHeaderKey("custom-header2") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .setResourceToken("test-prefix") + .setApiClientHeaderKey("custom-header1") + .setResourceHeaderKey("custom-header2") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); assertThat(provider.getHeaders().get("custom-header1")) - .matches("^gl-java/.* gapic/4\\.5\\.6 gax/.* grpc/1\\.2\\.3$"); + .matches(FULL_HEADER_MATCH); assertThat(provider.getHeaders().get("custom-header2")).isEqualTo("test-prefix"); } @@ -125,28 +132,28 @@ void testCustomHeaderKeys() { void testQuotaProjectHeader() { String quotaProjectHeaderValue = "quota-project-id-value"; ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setClientLibToken("gccl", "1.2.3") - .setQuotaProjectIdToken(quotaProjectHeaderValue) - .build(); + ApiClientHeaderProvider.newBuilder() + .setClientLibToken("gccl", "1.2.3") + .setQuotaProjectIdToken(quotaProjectHeaderValue) + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/1\\.2\\.3 gax/.*$"); + .matches(HEADER_WITHOUT_GAPIC_MATCH); assertThat(provider.getHeaders().get(ApiClientHeaderProvider.QUOTA_PROJECT_ID_HEADER_KEY)) - .matches(quotaProjectHeaderValue); + .matches(quotaProjectHeaderValue); } @Test void testApiVersionHeader() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setApiVersionToken("fake-version-string").build(); + ApiClientHeaderProvider.newBuilder().setApiVersionToken("fake-version-string").build(); assertThat(provider.getHeaders().size()).isEqualTo(2); assertThat(provider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY)) - .matches("fake-version-string"); + .matches("fake-version-string"); ApiClientHeaderProvider emptyProvider = - ApiClientHeaderProvider.newBuilder().setApiVersionToken("").build(); + ApiClientHeaderProvider.newBuilder().setApiVersionToken("").build(); assertThat( - emptyProvider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY).isEmpty()); + emptyProvider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY).isEmpty()); } -} +} \ No newline at end of file From e6aea43815b3967b3ed0353d6339466fb48b1297 Mon Sep 17 00:00:00 2001 From: detmerl Date: Fri, 13 Sep 2024 11:47:38 -0400 Subject: [PATCH 02/23] add support for gccl --- .../api/gax/rpc/ApiClientHeaderProvider.java | 19 ++++++++---- .../gax/rpc/ApiClientHeaderProviderTest.java | 30 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index a1ccc2bd9f..888158ddf0 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -41,7 +41,9 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { private static final long serialVersionUID = -8876627296793342119L; static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project"; - static final String PROTOBUF_VERSION_TOKEN_KEY = "protobuf"; + static final String PROTOBUF_VERSION_KEY = "protobuf"; + static final String GAPIC_VERSION_KEY = "gapic"; + static final String GCCL_VERSION_KEY = "gccl"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; @@ -135,7 +137,7 @@ protected Builder() { apiVersionToken = null; // set any default metric headers - protobufRuntimeToken = constructToken(PROTOBUF_VERSION_TOKEN_KEY, GaxProperties.getProtobufVersion()); + protobufRuntimeToken = constructToken(PROTOBUF_VERSION_KEY, GaxProperties.getProtobufVersion()); } public String getApiClientHeaderKey() { @@ -162,6 +164,9 @@ public String getClientLibToken() { public Builder setClientLibToken(String name, String version) { this.clientLibToken = constructToken(name, version); + if (name.equals(GCCL_VERSION_KEY)) { + clientLibToken += getProtobufVersionToAppend(); + } return this; } @@ -171,13 +176,17 @@ public String getGeneratedLibToken() { public Builder setGeneratedLibToken(String name, String version) { this.generatedLibToken = constructToken(name, version); - // TODO(b:/: this is a temporary fix while waiting for new field to be added - if (name.equals("gapic")) { - this.generatedLibToken += "--" + GaxProperties.getProtobufVersion(); + if (name.equals(GAPIC_VERSION_KEY)) { + generatedLibToken += getProtobufVersionToAppend(); } return this; } + private String getProtobufVersionToAppend() { + // TODO(b:/366417603): appending protobuf version to gapic column is a temporary fix while waiting for dedicated field to be added + return "--" + PROTOBUF_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + } + public String getGeneratedRuntimeToken() { return generatedRuntimeToken; } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index 02feea62d8..6f3560c391 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -29,6 +29,7 @@ */ package com.google.api.gax.rpc; +import static com.google.api.gax.rpc.ApiClientHeaderProvider.PROTOBUF_VERSION_KEY; import static com.google.common.truth.Truth.assertThat; import org.junit.jupiter.api.Test; @@ -38,10 +39,11 @@ class ApiClientHeaderProviderTest { private static final String X_GOOG_API_CLIENT = "x-goog-api-client"; private static final String CLOUD_RESOURCE_PREFIX = "google-cloud-resource-prefix"; - private static final String PROTOBUF_HEADER = ApiClientHeaderProvider.PROTOBUF_VERSION_TOKEN_KEY+"/.*"; - private static final String FULL_HEADER_MATCH = "^gl-java/.* gapic/4\\.5\\.6++__"+PROTOBUF_HEADER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"; + private static final String PROTOBUF_HEADER = PROTOBUF_VERSION_KEY +"/.*"; + private static final String PROTOBUF_APPENDER = "--"+PROTOBUF_VERSION_KEY +"-.*"; + private static final String FULL_HEADER_MATCH = "^gl-java/.* gapic/4\\.5\\.6"+ PROTOBUF_APPENDER +" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"; private static final String HEADER_WITHOUT_GAPIC_MATCH = - "^gl-java/.* gccl/1\\.2\\.3 gax/.* "+PROTOBUF_HEADER+"$"; + "^gl-java/.* gccl/1\\.2\\.3"+PROTOBUF_APPENDER+" gax/.* "+PROTOBUF_HEADER+"$"; @Test void testServiceHeaderDefault() { @@ -71,7 +73,7 @@ void testServiceHeaderManualGapic() { assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) .matches( - "^gl-java/.* gccl/4\\.5\\.6 gapic/7\\.8\\.9__"+PROTOBUF_HEADER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); + "^gl-java/.* gccl/4\\.5\\.6"+ PROTOBUF_APPENDER + " gapic/7\\.8\\.9"+ PROTOBUF_APPENDER +" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); } @Test @@ -83,7 +85,7 @@ void testServiceHeaderManualGrpc() { .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/4\\.5\\.6 gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); + .matches("^gl-java/.* gccl/4\\.5\\.6"+PROTOBUF_APPENDER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); } @Test @@ -156,4 +158,22 @@ void testApiVersionHeader() { assertThat( emptyProvider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY).isEmpty()); } + + @Test + void testNonGapicGeneratedLibToken_doesNotAppend() { + ApiClientHeaderProvider provider = + ApiClientHeaderProvider.newBuilder().setGeneratedLibToken("other-token", "1.2.3").build(); + + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* other-token/1.2.3 gax/.* "+PROTOBUF_HEADER+"$"); + } + + @Test + void testNonGcclGeneratedLibToken_doesNotAppend() { + ApiClientHeaderProvider provider = + ApiClientHeaderProvider.newBuilder().setClientLibToken("other-token", "1.2.3").build(); + + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* other-token/1.2.3 gax/.* "+PROTOBUF_HEADER+"$"); + } } \ No newline at end of file From a64e14b2d08a7b934ce8f24c6eb825b686223912 Mon Sep 17 00:00:00 2001 From: detmerl Date: Fri, 13 Sep 2024 11:55:53 -0400 Subject: [PATCH 03/23] formatting fixes --- .../google/api/gax/core/GaxProperties.java | 2 +- .../api/gax/rpc/ApiClientHeaderProvider.java | 11 +- .../api/gax/core/GaxPropertiesTest.java | 1 - .../gax/rpc/ApiClientHeaderProviderTest.java | 127 ++++++++++-------- 4 files changed, 77 insertions(+), 64 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index f05a3bbf79..994f806ee6 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -130,7 +130,7 @@ static String getRuntimeVersion() { /** * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's META-INF/MANIFEST. - * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION + * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION, otherwise please use #getLibraryVersion */ @VisibleForTesting static Optional getBundleVersion(Class clazz) { diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 888158ddf0..0299ebc34f 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -136,8 +136,8 @@ protected Builder() { apiVersionToken = null; - // set any default metric headers - protobufRuntimeToken = constructToken(PROTOBUF_VERSION_KEY, GaxProperties.getProtobufVersion()); + protobufRuntimeToken = + constructToken(PROTOBUF_VERSION_KEY, GaxProperties.getProtobufVersion()); } public String getApiClientHeaderKey() { @@ -183,7 +183,8 @@ public Builder setGeneratedLibToken(String name, String version) { } private String getProtobufVersionToAppend() { - // TODO(b:/366417603): appending protobuf version to gapic column is a temporary fix while waiting for dedicated field to be added + // TODO(b:/366417603): appending protobuf version to gapic column is a temporary fix while + // waiting for dedicated field to be added return "--" + PROTOBUF_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); } @@ -205,7 +206,9 @@ public Builder setTransportToken(String name, String version) { return this; } - /** @return the quotaProjectIdToken used for quota and billing purposes. */ + /** + * @return the quotaProjectIdToken used for quota and billing purposes. + */ public String getQuotaProjectIdToken() { return quotaProjectIdToken; } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java index 042e3ab3de..88de785f1d 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java @@ -57,7 +57,6 @@ class GaxPropertiesTest { - @Test void testGaxVersion() { Version version = readVersion(GaxProperties.getGaxVersion()); diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index 6f3560c391..83d257313a 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -39,94 +39,106 @@ class ApiClientHeaderProviderTest { private static final String X_GOOG_API_CLIENT = "x-goog-api-client"; private static final String CLOUD_RESOURCE_PREFIX = "google-cloud-resource-prefix"; - private static final String PROTOBUF_HEADER = PROTOBUF_VERSION_KEY +"/.*"; - private static final String PROTOBUF_APPENDER = "--"+PROTOBUF_VERSION_KEY +"-.*"; - private static final String FULL_HEADER_MATCH = "^gl-java/.* gapic/4\\.5\\.6"+ PROTOBUF_APPENDER +" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"; + private static final String PROTOBUF_HEADER = PROTOBUF_VERSION_KEY + "/.*"; + private static final String PROTOBUF_APPENDER = "--" + PROTOBUF_VERSION_KEY + "-.*"; + private static final String FULL_HEADER_MATCH = + "^gl-java/.* gapic/4\\.5\\.6" + + PROTOBUF_APPENDER + + " gax/.* grpc/1\\.2\\.3 " + + PROTOBUF_HEADER + + "$"; private static final String HEADER_WITHOUT_GAPIC_MATCH = - "^gl-java/.* gccl/1\\.2\\.3"+PROTOBUF_APPENDER+" gax/.* "+PROTOBUF_HEADER+"$"; + "^gl-java/.* gccl/1\\.2\\.3" + PROTOBUF_APPENDER + " gax/.* " + PROTOBUF_HEADER + "$"; @Test void testServiceHeaderDefault() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gax/.* "+PROTOBUF_HEADER+"$"); + .matches("^gl-java/.* gax/.* " + PROTOBUF_HEADER + "$"); } @Test void testServiceHeaderManual() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setClientLibToken("gccl", "1.2.3").build(); + ApiClientHeaderProvider.newBuilder().setClientLibToken("gccl", "1.2.3").build(); assertThat(provider.getHeaders().size()).isEqualTo(1); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches(HEADER_WITHOUT_GAPIC_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(HEADER_WITHOUT_GAPIC_MATCH); } @Test void testServiceHeaderManualGapic() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setClientLibToken("gccl", "4.5.6") - .setGeneratedLibToken("gapic", "7.8.9") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setClientLibToken("gccl", "4.5.6") + .setGeneratedLibToken("gapic", "7.8.9") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches( - "^gl-java/.* gccl/4\\.5\\.6"+ PROTOBUF_APPENDER + " gapic/7\\.8\\.9"+ PROTOBUF_APPENDER +" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); + .matches( + "^gl-java/.* gccl/4\\.5\\.6" + + PROTOBUF_APPENDER + + " gapic/7\\.8\\.9" + + PROTOBUF_APPENDER + + " gax/.* grpc/1\\.2\\.3 " + + PROTOBUF_HEADER + + "$"); } @Test void testServiceHeaderManualGrpc() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setClientLibToken("gccl", "4.5.6") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setClientLibToken("gccl", "4.5.6") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/4\\.5\\.6"+PROTOBUF_APPENDER+" gax/.* grpc/1\\.2\\.3 "+PROTOBUF_HEADER+"$"); + .matches( + "^gl-java/.* gccl/4\\.5\\.6" + + PROTOBUF_APPENDER + + " gax/.* grpc/1\\.2\\.3 " + + PROTOBUF_HEADER + + "$"); } @Test void testServiceHeaderGapic() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(FULL_HEADER_MATCH); } @Test void testCloudResourcePrefixHeader() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .setResourceToken("test-prefix") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .setResourceToken("test-prefix") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(FULL_HEADER_MATCH); assertThat(provider.getHeaders().get(CLOUD_RESOURCE_PREFIX)).isEqualTo("test-prefix"); } @Test void testCustomHeaderKeys() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setTransportToken("grpc", "1.2.3") - .setGeneratedLibToken("gapic", "4.5.6") - .setResourceToken("test-prefix") - .setApiClientHeaderKey("custom-header1") - .setResourceHeaderKey("custom-header2") - .build(); + ApiClientHeaderProvider.newBuilder() + .setTransportToken("grpc", "1.2.3") + .setGeneratedLibToken("gapic", "4.5.6") + .setResourceToken("test-prefix") + .setApiClientHeaderKey("custom-header1") + .setResourceHeaderKey("custom-header2") + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get("custom-header1")) - .matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get("custom-header1")).matches(FULL_HEADER_MATCH); assertThat(provider.getHeaders().get("custom-header2")).isEqualTo("test-prefix"); } @@ -134,46 +146,45 @@ void testCustomHeaderKeys() { void testQuotaProjectHeader() { String quotaProjectHeaderValue = "quota-project-id-value"; ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder() - .setClientLibToken("gccl", "1.2.3") - .setQuotaProjectIdToken(quotaProjectHeaderValue) - .build(); + ApiClientHeaderProvider.newBuilder() + .setClientLibToken("gccl", "1.2.3") + .setQuotaProjectIdToken(quotaProjectHeaderValue) + .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches(HEADER_WITHOUT_GAPIC_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(HEADER_WITHOUT_GAPIC_MATCH); assertThat(provider.getHeaders().get(ApiClientHeaderProvider.QUOTA_PROJECT_ID_HEADER_KEY)) - .matches(quotaProjectHeaderValue); + .matches(quotaProjectHeaderValue); } @Test void testApiVersionHeader() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setApiVersionToken("fake-version-string").build(); + ApiClientHeaderProvider.newBuilder().setApiVersionToken("fake-version-string").build(); assertThat(provider.getHeaders().size()).isEqualTo(2); assertThat(provider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY)) - .matches("fake-version-string"); + .matches("fake-version-string"); ApiClientHeaderProvider emptyProvider = - ApiClientHeaderProvider.newBuilder().setApiVersionToken("").build(); + ApiClientHeaderProvider.newBuilder().setApiVersionToken("").build(); assertThat( - emptyProvider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY).isEmpty()); + emptyProvider.getHeaders().get(ApiClientHeaderProvider.API_VERSION_HEADER_KEY).isEmpty()); } @Test void testNonGapicGeneratedLibToken_doesNotAppend() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setGeneratedLibToken("other-token", "1.2.3").build(); + ApiClientHeaderProvider.newBuilder().setGeneratedLibToken("other-token", "1.2.3").build(); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* other-token/1.2.3 gax/.* "+PROTOBUF_HEADER+"$"); + .matches("^gl-java/.* other-token/1.2.3 gax/.* " + PROTOBUF_HEADER + "$"); } @Test void testNonGcclGeneratedLibToken_doesNotAppend() { ApiClientHeaderProvider provider = - ApiClientHeaderProvider.newBuilder().setClientLibToken("other-token", "1.2.3").build(); + ApiClientHeaderProvider.newBuilder().setClientLibToken("other-token", "1.2.3").build(); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* other-token/1.2.3 gax/.* "+PROTOBUF_HEADER+"$"); + .matches("^gl-java/.* other-token/1.2.3 gax/.* " + PROTOBUF_HEADER + "$"); } -} \ No newline at end of file +} From 0037a0a731b3b4112f4bff34f70c00d7f6e09780 Mon Sep 17 00:00:00 2001 From: detmerl Date: Fri, 13 Sep 2024 12:16:25 -0400 Subject: [PATCH 04/23] formatting fixes --- .../google/api/gax/core/GaxProperties.java | 10 ++++++---- .../api/gax/rpc/ApiClientHeaderProvider.java | 19 ++++++++----------- .../api/gax/core/GaxPropertiesTest.java | 16 ---------------- .../gax/rpc/ApiClientHeaderProviderTest.java | 10 +++++----- 4 files changed, 19 insertions(+), 36 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index 994f806ee6..eb6a679777 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -33,7 +33,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.protobuf.Any; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -50,7 +49,8 @@ public class GaxProperties { private static final String DEFAULT_VERSION = ""; private static final String GAX_VERSION = getLibraryVersion(GaxProperties.class, "version.gax"); private static final String JAVA_VERSION = getRuntimeVersion(); - private static final String PROTOBUF_VERSION = getBundleVersion(Any.class).orElse(DEFAULT_VERSION); + private static final String PROTOBUF_VERSION = + getBundleVersion(Any.class).orElse(DEFAULT_VERSION); static final String BUNDLE_VERSION_KEY = "Bundle-Version"; private GaxProperties() {} @@ -129,8 +129,10 @@ static String getRuntimeVersion() { } /** - * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's META-INF/MANIFEST. - * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION, otherwise please use #getLibraryVersion + * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's + * META-INF/MANIFEST. This should only be used if MANIFEST file does not contain a widely + * recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION, otherwise + * please use #getLibraryVersion */ @VisibleForTesting static Optional getBundleVersion(Class clazz) { diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 0299ebc34f..9a3bb58144 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -40,12 +40,11 @@ */ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { private static final long serialVersionUID = -8876627296793342119L; + private static final String GCCL_HEADER_VERSION_KEY = "gccl"; static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project"; - static final String PROTOBUF_VERSION_KEY = "protobuf"; - static final String GAPIC_VERSION_KEY = "gapic"; - static final String GCCL_VERSION_KEY = "gccl"; - + static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; + public static final String GAPIC_HEADER_VERSION_KEY = "gapic"; private final Map headers; @@ -137,7 +136,7 @@ protected Builder() { apiVersionToken = null; protobufRuntimeToken = - constructToken(PROTOBUF_VERSION_KEY, GaxProperties.getProtobufVersion()); + constructToken(PROTOBUF_HEADER_VERSION_KEY, GaxProperties.getProtobufVersion()); } public String getApiClientHeaderKey() { @@ -164,7 +163,7 @@ public String getClientLibToken() { public Builder setClientLibToken(String name, String version) { this.clientLibToken = constructToken(name, version); - if (name.equals(GCCL_VERSION_KEY)) { + if (name.equals(GCCL_HEADER_VERSION_KEY)) { clientLibToken += getProtobufVersionToAppend(); } return this; @@ -176,7 +175,7 @@ public String getGeneratedLibToken() { public Builder setGeneratedLibToken(String name, String version) { this.generatedLibToken = constructToken(name, version); - if (name.equals(GAPIC_VERSION_KEY)) { + if (name.equals(GAPIC_HEADER_VERSION_KEY)) { generatedLibToken += getProtobufVersionToAppend(); } return this; @@ -185,7 +184,7 @@ public Builder setGeneratedLibToken(String name, String version) { private String getProtobufVersionToAppend() { // TODO(b:/366417603): appending protobuf version to gapic column is a temporary fix while // waiting for dedicated field to be added - return "--" + PROTOBUF_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); } public String getGeneratedRuntimeToken() { @@ -206,9 +205,7 @@ public Builder setTransportToken(String name, String version) { return this; } - /** - * @return the quotaProjectIdToken used for quota and billing purposes. - */ + /** @return the quotaProjectIdToken used for quota and billing purposes. */ public String getQuotaProjectIdToken() { return quotaProjectIdToken; } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java index 88de785f1d..7795508f77 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java @@ -29,31 +29,15 @@ */ package com.google.api.gax.core; -import static com.google.api.gax.core.GaxProperties.BUNDLE_VERSION_KEY; import static com.google.api.gax.core.GaxProperties.getBundleVersion; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; import com.google.common.base.Strings; - -import java.io.File; import java.io.IOException; -import java.net.URISyntaxException; -import java.security.CodeSource; -import java.security.ProtectionDomain; import java.util.Optional; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.jar.Manifest; import java.util.regex.Pattern; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.junit.MockitoJUnitRunner; -import org.junit.Before; class GaxPropertiesTest { diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index 83d257313a..bdce0c9017 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -29,7 +29,7 @@ */ package com.google.api.gax.rpc; -import static com.google.api.gax.rpc.ApiClientHeaderProvider.PROTOBUF_VERSION_KEY; +import static com.google.api.gax.rpc.ApiClientHeaderProvider.PROTOBUF_HEADER_VERSION_KEY; import static com.google.common.truth.Truth.assertThat; import org.junit.jupiter.api.Test; @@ -39,8 +39,8 @@ class ApiClientHeaderProviderTest { private static final String X_GOOG_API_CLIENT = "x-goog-api-client"; private static final String CLOUD_RESOURCE_PREFIX = "google-cloud-resource-prefix"; - private static final String PROTOBUF_HEADER = PROTOBUF_VERSION_KEY + "/.*"; - private static final String PROTOBUF_APPENDER = "--" + PROTOBUF_VERSION_KEY + "-.*"; + private static final String PROTOBUF_HEADER = PROTOBUF_HEADER_VERSION_KEY + "/.*"; + private static final String PROTOBUF_APPENDER = "--" + PROTOBUF_HEADER_VERSION_KEY + "-.*"; private static final String FULL_HEADER_MATCH = "^gl-java/.* gapic/4\\.5\\.6" + PROTOBUF_APPENDER @@ -171,7 +171,7 @@ void testApiVersionHeader() { } @Test - void testNonGapicGeneratedLibToken_doesNotAppend() { + void testNonGapicGeneratedLibToken_doesNotAppendProtobufVersion() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().setGeneratedLibToken("other-token", "1.2.3").build(); @@ -180,7 +180,7 @@ void testNonGapicGeneratedLibToken_doesNotAppend() { } @Test - void testNonGcclGeneratedLibToken_doesNotAppend() { + void testNonGcclGeneratedLibToken_doesNotAppendProtobufVersion() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().setClientLibToken("other-token", "1.2.3").build(); From ea7e7ec5afe3670a470c4b82d8b5ed41c417a188 Mon Sep 17 00:00:00 2001 From: detmerl Date: Fri, 13 Sep 2024 14:19:07 -0400 Subject: [PATCH 05/23] feat(gax): add protobuf version to headers to track --- .../com/google/api/gax/rpc/ApiClientHeaderProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 9a3bb58144..d84587b919 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -40,11 +40,11 @@ */ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { private static final long serialVersionUID = -8876627296793342119L; - private static final String GCCL_HEADER_VERSION_KEY = "gccl"; static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project"; static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; public static final String GAPIC_HEADER_VERSION_KEY = "gapic"; + public static final String GCCL_HEADER_VERSION_KEY = "gccl"; private final Map headers; @@ -182,8 +182,8 @@ public Builder setGeneratedLibToken(String name, String version) { } private String getProtobufVersionToAppend() { - // TODO(b:/366417603): appending protobuf version to gapic column is a temporary fix while - // waiting for dedicated field to be added + // TODO(b:/366417603): appending protobuf version to existing client library column is a temporary fix while + // waiting for dedicated field to be added in concord return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); } From 4e18aa6a882caa7c8896724aa9574f1df9897537 Mon Sep 17 00:00:00 2001 From: detmerl Date: Fri, 13 Sep 2024 14:22:32 -0400 Subject: [PATCH 06/23] feat(gax): add protobuf version to headers to track --- .../java/com/google/api/gax/rpc/ApiClientHeaderProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index d84587b919..065d7378a4 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -182,7 +182,8 @@ public Builder setGeneratedLibToken(String name, String version) { } private String getProtobufVersionToAppend() { - // TODO(b:/366417603): appending protobuf version to existing client library column is a temporary fix while + // TODO(b:/366417603): appending protobuf version to existing client library column is a + // temporary fix while // waiting for dedicated field to be added in concord return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); } From 8d6065cd08771681ea3477286fa3ba530424355e Mon Sep 17 00:00:00 2001 From: detmerl Date: Sat, 14 Sep 2024 19:26:35 -0400 Subject: [PATCH 07/23] feat(gax): add protobuf version to headers to track --- .../api/gax/rpc/ApiClientHeaderProvider.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 065d7378a4..3519517ce5 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -32,7 +32,9 @@ import com.google.api.gax.core.GaxProperties; import com.google.common.collect.ImmutableMap; import java.io.Serializable; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * Implementation of HeaderProvider that provides headers describing the API client library making @@ -119,6 +121,7 @@ public static class Builder { private String resourceToken; private String apiVersionToken; + private final Set tokensToAppendProtobuf; protected Builder() { // Initialize with default values @@ -129,14 +132,14 @@ protected Builder() { setClientRuntimeToken(GaxProperties.getGaxVersion()); transportToken = null; quotaProjectIdToken = null; - resourceHeaderKey = getDefaultResourceHeaderKey(); resourceToken = null; - apiVersionToken = null; - protobufRuntimeToken = constructToken(PROTOBUF_HEADER_VERSION_KEY, GaxProperties.getProtobufVersion()); + tokensToAppendProtobuf = new HashSet<>(); + tokensToAppendProtobuf.add(GCCL_HEADER_VERSION_KEY); + tokensToAppendProtobuf.add(GAPIC_HEADER_VERSION_KEY); } public String getApiClientHeaderKey() { @@ -163,9 +166,7 @@ public String getClientLibToken() { public Builder setClientLibToken(String name, String version) { this.clientLibToken = constructToken(name, version); - if (name.equals(GCCL_HEADER_VERSION_KEY)) { - clientLibToken += getProtobufVersionToAppend(); - } + clientLibToken += checkAndAppendProtobufVersionIfNecessary(name); return this; } @@ -175,17 +176,18 @@ public String getGeneratedLibToken() { public Builder setGeneratedLibToken(String name, String version) { this.generatedLibToken = constructToken(name, version); - if (name.equals(GAPIC_HEADER_VERSION_KEY)) { - generatedLibToken += getProtobufVersionToAppend(); - } + generatedLibToken += checkAndAppendProtobufVersionIfNecessary(name); return this; } - private String getProtobufVersionToAppend() { + private String checkAndAppendProtobufVersionIfNecessary(String name) { // TODO(b:/366417603): appending protobuf version to existing client library column is a - // temporary fix while - // waiting for dedicated field to be added in concord - return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + // temporary fix while waiting for dedicated field to be added in concord + if (tokensToAppendProtobuf.contains(name)) { + return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + } else { + return ""; + } } public String getGeneratedRuntimeToken() { From 2dbc3a474539632430327eab8c92dc5a6ae63d06 Mon Sep 17 00:00:00 2001 From: detmerl Date: Sat, 14 Sep 2024 19:54:43 -0400 Subject: [PATCH 08/23] feat(gax): add protobuf version to headers to track --- .../api/gax/rpc/ApiClientHeaderProvider.java | 33 +++++++++---------- .../gax/rpc/ApiClientHeaderProviderTest.java | 1 - 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 3519517ce5..0a19ad8c7e 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -32,9 +32,7 @@ import com.google.api.gax.core.GaxProperties; import com.google.common.collect.ImmutableMap; import java.io.Serializable; -import java.util.HashSet; import java.util.Map; -import java.util.Set; /** * Implementation of HeaderProvider that provides headers describing the API client library making @@ -44,14 +42,18 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { private static final long serialVersionUID = -8876627296793342119L; static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project"; static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; + public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; public static final String GAPIC_HEADER_VERSION_KEY = "gapic"; public static final String GCCL_HEADER_VERSION_KEY = "gccl"; + private static final String protobufVersionStorageAppendage = "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + private static String tokensToAppendProfobufTo = ""; private final Map headers; protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); + tokensToAppendProfobufTo ="("+GCCL_HEADER_VERSION_KEY+"|"+GAPIC_HEADER_VERSION_KEY+").*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); @@ -92,6 +94,17 @@ protected static void appendToken(StringBuilder sb, String token) { sb.append(' '); } sb.append(token); + checkAndAppendProtobufVersionIfNecessary(sb, token); + } + } + + private static void checkAndAppendProtobufVersionIfNecessary(StringBuilder sb, String token) { + // TODO(b:/366417603): appending protobuf version to existing client library column is a + // temporary fix while waiting for dedicated field to be added in concord + if (token.matches(tokensToAppendProfobufTo)) { + sb.append(protobufVersionStorageAppendage); + // once protobuf version as been appended do not need to append anymore + tokensToAppendProfobufTo = ""; } } @@ -121,7 +134,6 @@ public static class Builder { private String resourceToken; private String apiVersionToken; - private final Set tokensToAppendProtobuf; protected Builder() { // Initialize with default values @@ -137,9 +149,6 @@ protected Builder() { apiVersionToken = null; protobufRuntimeToken = constructToken(PROTOBUF_HEADER_VERSION_KEY, GaxProperties.getProtobufVersion()); - tokensToAppendProtobuf = new HashSet<>(); - tokensToAppendProtobuf.add(GCCL_HEADER_VERSION_KEY); - tokensToAppendProtobuf.add(GAPIC_HEADER_VERSION_KEY); } public String getApiClientHeaderKey() { @@ -166,7 +175,6 @@ public String getClientLibToken() { public Builder setClientLibToken(String name, String version) { this.clientLibToken = constructToken(name, version); - clientLibToken += checkAndAppendProtobufVersionIfNecessary(name); return this; } @@ -176,20 +184,9 @@ public String getGeneratedLibToken() { public Builder setGeneratedLibToken(String name, String version) { this.generatedLibToken = constructToken(name, version); - generatedLibToken += checkAndAppendProtobufVersionIfNecessary(name); return this; } - private String checkAndAppendProtobufVersionIfNecessary(String name) { - // TODO(b:/366417603): appending protobuf version to existing client library column is a - // temporary fix while waiting for dedicated field to be added in concord - if (tokensToAppendProtobuf.contains(name)) { - return "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); - } else { - return ""; - } - } - public String getGeneratedRuntimeToken() { return generatedRuntimeToken; } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index bdce0c9017..bf76afa151 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -80,7 +80,6 @@ void testServiceHeaderManualGapic() { "^gl-java/.* gccl/4\\.5\\.6" + PROTOBUF_APPENDER + " gapic/7\\.8\\.9" - + PROTOBUF_APPENDER + " gax/.* grpc/1\\.2\\.3 " + PROTOBUF_HEADER + "$"); From b69684bd96851d48cb0de44601cde7854d930bd4 Mon Sep 17 00:00:00 2001 From: detmerl Date: Sat, 14 Sep 2024 19:56:50 -0400 Subject: [PATCH 09/23] feat(gax): add protobuf version to headers to track --- .../com/google/api/gax/rpc/ApiClientHeaderProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 0a19ad8c7e..51793cfa57 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -46,14 +46,16 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; public static final String GAPIC_HEADER_VERSION_KEY = "gapic"; public static final String GCCL_HEADER_VERSION_KEY = "gccl"; - private static final String protobufVersionStorageAppendage = "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); + private static final String protobufVersionStorageAppendage = + "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); private static String tokensToAppendProfobufTo = ""; private final Map headers; protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); - tokensToAppendProfobufTo ="("+GCCL_HEADER_VERSION_KEY+"|"+GAPIC_HEADER_VERSION_KEY+").*"; + tokensToAppendProfobufTo = + "(" + GCCL_HEADER_VERSION_KEY + "|" + GAPIC_HEADER_VERSION_KEY + ").*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); From 02051b3fc81f589b502f0a1742ca4c2bb941de28 Mon Sep 17 00:00:00 2001 From: detmerl Date: Sat, 14 Sep 2024 20:12:56 -0400 Subject: [PATCH 10/23] feat(gax): add protobuf version to headers to track --- .../java/com/google/api/gax/rpc/ApiClientHeaderProvider.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 51793cfa57..4cd368e0ad 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -44,8 +44,6 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; - public static final String GAPIC_HEADER_VERSION_KEY = "gapic"; - public static final String GCCL_HEADER_VERSION_KEY = "gccl"; private static final String protobufVersionStorageAppendage = "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); private static String tokensToAppendProfobufTo = ""; @@ -54,8 +52,7 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); - tokensToAppendProfobufTo = - "(" + GCCL_HEADER_VERSION_KEY + "|" + GAPIC_HEADER_VERSION_KEY + ").*"; + tokensToAppendProfobufTo = "(gccl|gapic).*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); From 31da0e50b4d6638ccfcdaa1de2a64d435afe770b Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 09:32:35 -0400 Subject: [PATCH 11/23] feat(gax): add protobuf version to headers to track --- .../api/gax/rpc/ApiClientHeaderProvider.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 4cd368e0ad..78c48a045e 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -44,15 +44,15 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; - private static final String protobufVersionStorageAppendage = + private static final String protobufVersionAppendValue = "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); - private static String tokensToAppendProfobufTo = ""; + private static String tokensToAppendProfobufVersionTo = ""; private final Map headers; protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); - tokensToAppendProfobufTo = "(gccl|gapic).*"; + tokensToAppendProfobufVersionTo = "(gccl|gapic).*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); @@ -100,10 +100,11 @@ protected static void appendToken(StringBuilder sb, String token) { private static void checkAndAppendProtobufVersionIfNecessary(StringBuilder sb, String token) { // TODO(b:/366417603): appending protobuf version to existing client library column is a // temporary fix while waiting for dedicated field to be added in concord - if (token.matches(tokensToAppendProfobufTo)) { - sb.append(protobufVersionStorageAppendage); - // once protobuf version as been appended do not need to append anymore - tokensToAppendProfobufTo = ""; + if (token.matches(tokensToAppendProfobufVersionTo)) { + sb.append(protobufVersionAppendValue); + // once protobuf version as been appended to a token do not need to append to any additional + // tokens + tokensToAppendProfobufVersionTo = ""; } } From 5a918f43cd1038db8f11f09161ca8a7ca0107c12 Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 10:05:27 -0400 Subject: [PATCH 12/23] fixed todo wording --- .../java/com/google/api/gax/rpc/ApiClientHeaderProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 78c48a045e..9461a9cfcc 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -98,7 +98,7 @@ protected static void appendToken(StringBuilder sb, String token) { } private static void checkAndAppendProtobufVersionIfNecessary(StringBuilder sb, String token) { - // TODO(b:/366417603): appending protobuf version to existing client library column is a + // TODO(b/366417603): appending protobuf version to existing client library token until resolved // temporary fix while waiting for dedicated field to be added in concord if (token.matches(tokensToAppendProfobufVersionTo)) { sb.append(protobufVersionAppendValue); From 94d3f457d7e70ed8ab272ef95c7a1b75fd261671 Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 15:30:23 -0400 Subject: [PATCH 13/23] cleaned up append token logic --- .../google/api/gax/core/GaxProperties.java | 4 +- .../api/gax/rpc/ApiClientHeaderProvider.java | 41 ++++++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index eb6a679777..78730cddd7 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -131,7 +131,7 @@ static String getRuntimeVersion() { /** * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's * META-INF/MANIFEST. This should only be used if MANIFEST file does not contain a widely - * recognized version declaration such as SPECIFIC_VERSION OR IMPLEMENTATION_VERSION, otherwise + * recognized version declaration such as Specific-Version OR Implementation-Version, otherwise * please use #getLibraryVersion */ @VisibleForTesting @@ -143,7 +143,7 @@ static Optional getBundleVersion(Class clazz) { return Optional.ofNullable(attributes.getValue(BUNDLE_VERSION_KEY)); } } catch (URISyntaxException | IOException e) { - // Unable to read Protobuf runtime version. Recover gracefully. + // Unable to read Bundle-Version from manifest. Recover gracefully. return Optional.empty(); } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 9461a9cfcc..32d7969e09 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -33,6 +33,8 @@ import com.google.common.collect.ImmutableMap; import java.io.Serializable; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Implementation of HeaderProvider that provides headers describing the API client library making @@ -52,7 +54,7 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); - tokensToAppendProfobufVersionTo = "(gccl|gapic).*"; + // tokensToAppendProfobufVersionTo = "(gccl|gapic).*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); @@ -62,9 +64,12 @@ protected ApiClientHeaderProvider(Builder builder) { appendToken(apiClientHeaderValue, builder.getGeneratedLibToken()); appendToken(apiClientHeaderValue, builder.getGeneratedRuntimeToken()); appendToken(apiClientHeaderValue, builder.getTransportToken()); - appendToken(apiClientHeaderValue, builder.protobufRuntimeToken); + appendToken(apiClientHeaderValue, builder.getProtobufRuntimeToken()); + if (apiClientHeaderValue.length() > 0) { - headersBuilder.put(builder.getApiClientHeaderKey(), apiClientHeaderValue.toString()); + headersBuilder.put( + builder.getApiClientHeaderKey(), + checkAndAppendProtobufVersionIfNecessary(apiClientHeaderValue)); } } @@ -82,6 +87,20 @@ protected ApiClientHeaderProvider(Builder builder) { this.headers = headersBuilder.build(); } + private static String checkAndAppendProtobufVersionIfNecessary( + StringBuilder apiClientHeaderValue) { + // TODO(b/366417603): appending protobuf version to existing client library token until resolved + // temporary fix while waiting for dedicated field to be added in concord + Pattern pattern = Pattern.compile("(gccl|gapic)\\S*"); + Matcher matcher = pattern.matcher(apiClientHeaderValue); + if (matcher.find()) { + return apiClientHeaderValue.substring(0, matcher.end()) + + protobufVersionAppendValue + + apiClientHeaderValue.substring(matcher.end()); + } + return apiClientHeaderValue.toString(); + } + @Override public Map getHeaders() { return headers; @@ -93,18 +112,6 @@ protected static void appendToken(StringBuilder sb, String token) { sb.append(' '); } sb.append(token); - checkAndAppendProtobufVersionIfNecessary(sb, token); - } - } - - private static void checkAndAppendProtobufVersionIfNecessary(StringBuilder sb, String token) { - // TODO(b/366417603): appending protobuf version to existing client library token until resolved - // temporary fix while waiting for dedicated field to be added in concord - if (token.matches(tokensToAppendProfobufVersionTo)) { - sb.append(protobufVersionAppendValue); - // once protobuf version as been appended to a token do not need to append to any additional - // tokens - tokensToAppendProfobufVersionTo = ""; } } @@ -243,6 +250,10 @@ public Builder setApiVersionToken(String apiVersionToken) { return this; } + public String getProtobufRuntimeToken() { + return protobufRuntimeToken; + } + private String constructToken(String name, String version) { if (version == null) { return null; From 822ac0cfab0ae5364d34f5db0aa60c0cc7db34a2 Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 15:34:41 -0400 Subject: [PATCH 14/23] cleaned up append token logic --- .../java/com/google/api/gax/rpc/ApiClientHeaderProvider.java | 2 -- .../test/java/com/google/api/gax/core/GaxPropertiesTest.java | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 32d7969e09..8017efe618 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -48,13 +48,11 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; private static final String protobufVersionAppendValue = "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); - private static String tokensToAppendProfobufVersionTo = ""; private final Map headers; protected ApiClientHeaderProvider(Builder builder) { ImmutableMap.Builder headersBuilder = ImmutableMap.builder(); - // tokensToAppendProfobufVersionTo = "(gccl|gapic).*"; if (builder.getApiClientHeaderKey() != null) { StringBuilder apiClientHeaderValue = new StringBuilder(); diff --git a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java index 7795508f77..1369ec35ae 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/core/GaxPropertiesTest.java @@ -30,7 +30,9 @@ package com.google.api.gax.core; import static com.google.api.gax.core.GaxProperties.getBundleVersion; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.common.base.Strings; import java.io.IOException; From 390c922b5d23b729be2e7191f2e58fbc02e07566 Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 15:39:07 -0400 Subject: [PATCH 15/23] cleaned up append token logic --- .../main/java/com/google/api/gax/core/GaxProperties.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index 78730cddd7..b0711fcf9e 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -131,8 +131,10 @@ static String getRuntimeVersion() { /** * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's * META-INF/MANIFEST. This should only be used if MANIFEST file does not contain a widely - * recognized version declaration such as Specific-Version OR Implementation-Version, otherwise - * please use #getLibraryVersion + * recognized version declaration such as Specific-Version OR Implementation-Version declared in + * Manifest Specification + * https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Manifest_Specification, + * otherwise please use #getLibraryVersion */ @VisibleForTesting static Optional getBundleVersion(Class clazz) { From 01eb41ab36b8f0a27a8c3ff87488a79887e5dbf2 Mon Sep 17 00:00:00 2001 From: detmerl Date: Mon, 16 Sep 2024 16:00:40 -0400 Subject: [PATCH 16/23] fixed language --- .../java/com/google/api/gax/rpc/ApiClientHeaderProvider.java | 1 - 1 file changed, 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 8017efe618..5493ab17c3 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -88,7 +88,6 @@ protected ApiClientHeaderProvider(Builder builder) { private static String checkAndAppendProtobufVersionIfNecessary( StringBuilder apiClientHeaderValue) { // TODO(b/366417603): appending protobuf version to existing client library token until resolved - // temporary fix while waiting for dedicated field to be added in concord Pattern pattern = Pattern.compile("(gccl|gapic)\\S*"); Matcher matcher = pattern.matcher(apiClientHeaderValue); if (matcher.find()) { From 92e901b53e29910e705b56adea63dca3e6946aa9 Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 14:57:58 -0400 Subject: [PATCH 17/23] added showcase tests + moved strings inline --- .../gax/httpjson/GaxHttpJsonProperties.java | 2 +- .../httpjson/GaxHttpJsonPropertiesTest.java | 2 +- .../google/api/gax/core/GaxProperties.java | 9 ++-- .../api/gax/rpc/ApiClientHeaderProvider.java | 14 ++---- .../gax/rpc/ApiClientHeaderProviderTest.java | 47 ++++++------------- ...sionHeaders.java => ITVersionHeaders.java} | 32 ++++++++++++- 6 files changed, 57 insertions(+), 49 deletions(-) rename showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/{ITApiVersionHeaders.java => ITVersionHeaders.java} (90%) diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java index fab63c320c..a12f771fdc 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java @@ -36,7 +36,7 @@ @InternalApi public class GaxHttpJsonProperties { private static final Pattern DEFAULT_API_CLIENT_HEADER_PATTERN = - Pattern.compile("gl-java/.+ gapic/.* gax/.+ rest/.*"); + Pattern.compile("gl-java/.+ gapic/.*?--protobuf-.+ gax/.+ rest/.*"); /** Returns default api client header pattern (to facilitate testing) */ public static Pattern getDefaultApiClientHeaderPattern() { diff --git a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java index 007b100577..2547ec95bd 100644 --- a/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java +++ b/gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java @@ -41,7 +41,7 @@ class GaxHttpJsonPropertiesTest { void testDefaultHeaderPattern() { assertTrue( GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() - .matcher("gl-java/1.8_00 gapic/1.2.3-alpha gax/1.5.0 rest/1.7.0") + .matcher("gl-java/1.8_00 gapic/1.2.3-alpha--protobuf-1.5.0 gax/1.5.0 rest/1.7.0") .matches()); } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index b0711fcf9e..ec8bb5c884 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -51,7 +51,6 @@ public class GaxProperties { private static final String JAVA_VERSION = getRuntimeVersion(); private static final String PROTOBUF_VERSION = getBundleVersion(Any.class).orElse(DEFAULT_VERSION); - static final String BUNDLE_VERSION_KEY = "Bundle-Version"; private GaxProperties() {} @@ -129,9 +128,9 @@ static String getRuntimeVersion() { } /** - * Returns the current library version as reported by {BUNDLE_VERSION_KEY} in library's - * META-INF/MANIFEST. This should only be used if MANIFEST file does not contain a widely - * recognized version declaration such as Specific-Version OR Implementation-Version declared in + * Returns the current library version as reported by Bundle-Version attribute in library's + * META-INF/MANIFEST for libraries using OSGi bundle manifest https://www.ibm.com/docs/en/wasdtfe?topic=overview-osgi-bundles. + * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as Specific-Version OR Implementation-Version declared in * Manifest Specification * https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Manifest_Specification, * otherwise please use #getLibraryVersion @@ -142,7 +141,7 @@ static Optional getBundleVersion(Class clazz) { File file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()); try (JarFile jar = new JarFile(file.getPath())) { Attributes attributes = jar.getManifest().getMainAttributes(); - return Optional.ofNullable(attributes.getValue(BUNDLE_VERSION_KEY)); + return Optional.ofNullable(attributes.getValue("Bundle-Version")); } } catch (URISyntaxException | IOException e) { // Unable to read Bundle-Version from manifest. Recover gracefully. diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 5493ab17c3..6645270fbc 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -46,8 +46,6 @@ public class ApiClientHeaderProvider implements HeaderProvider, Serializable { static final String PROTOBUF_HEADER_VERSION_KEY = "protobuf"; public static final String API_VERSION_HEADER_KEY = "x-goog-api-version"; - private static final String protobufVersionAppendValue = - "--" + PROTOBUF_HEADER_VERSION_KEY + "-" + GaxProperties.getProtobufVersion(); private final Map headers; @@ -62,7 +60,7 @@ protected ApiClientHeaderProvider(Builder builder) { appendToken(apiClientHeaderValue, builder.getGeneratedLibToken()); appendToken(apiClientHeaderValue, builder.getGeneratedRuntimeToken()); appendToken(apiClientHeaderValue, builder.getTransportToken()); - appendToken(apiClientHeaderValue, builder.getProtobufRuntimeToken()); + appendToken(apiClientHeaderValue, builder.protobufRuntimeToken); if (apiClientHeaderValue.length() > 0) { headersBuilder.put( @@ -92,7 +90,9 @@ private static String checkAndAppendProtobufVersionIfNecessary( Matcher matcher = pattern.matcher(apiClientHeaderValue); if (matcher.find()) { return apiClientHeaderValue.substring(0, matcher.end()) - + protobufVersionAppendValue + + "--" + + PROTOBUF_HEADER_VERSION_KEY + + "-" + GaxProperties.getProtobufVersion() + apiClientHeaderValue.substring(matcher.end()); } return apiClientHeaderValue.toString(); @@ -132,7 +132,7 @@ public static class Builder { private String generatedRuntimeToken; private String transportToken; private String quotaProjectIdToken; - private final String protobufRuntimeToken; + final private String protobufRuntimeToken; private String resourceHeaderKey; private String resourceToken; @@ -247,10 +247,6 @@ public Builder setApiVersionToken(String apiVersionToken) { return this; } - public String getProtobufRuntimeToken() { - return protobufRuntimeToken; - } - private String constructToken(String name, String version) { if (version == null) { return null; diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index bf76afa151..56bc5c2071 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -39,23 +39,12 @@ class ApiClientHeaderProviderTest { private static final String X_GOOG_API_CLIENT = "x-goog-api-client"; private static final String CLOUD_RESOURCE_PREFIX = "google-cloud-resource-prefix"; - private static final String PROTOBUF_HEADER = PROTOBUF_HEADER_VERSION_KEY + "/.*"; - private static final String PROTOBUF_APPENDER = "--" + PROTOBUF_HEADER_VERSION_KEY + "-.*"; - private static final String FULL_HEADER_MATCH = - "^gl-java/.* gapic/4\\.5\\.6" - + PROTOBUF_APPENDER - + " gax/.* grpc/1\\.2\\.3 " - + PROTOBUF_HEADER - + "$"; - private static final String HEADER_WITHOUT_GAPIC_MATCH = - "^gl-java/.* gccl/1\\.2\\.3" + PROTOBUF_APPENDER + " gax/.* " + PROTOBUF_HEADER + "$"; - @Test void testServiceHeaderDefault() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gax/.* " + PROTOBUF_HEADER + "$"); + .matches("^gl-java/.* gax/.* protobuf/.*"); } @Test @@ -63,7 +52,8 @@ void testServiceHeaderManual() { ApiClientHeaderProvider provider = ApiClientHeaderProvider.newBuilder().setClientLibToken("gccl", "1.2.3").build(); assertThat(provider.getHeaders().size()).isEqualTo(1); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(HEADER_WITHOUT_GAPIC_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* gccl/1\\.2\\.3--protobuf-.* gax/.* protobuf/.*"); } @Test @@ -76,13 +66,7 @@ void testServiceHeaderManualGapic() { .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches( - "^gl-java/.* gccl/4\\.5\\.6" - + PROTOBUF_APPENDER - + " gapic/7\\.8\\.9" - + " gax/.* grpc/1\\.2\\.3 " - + PROTOBUF_HEADER - + "$"); + .matches("^gl-java/.* gccl/4\\.5\\.6--protobuf-.* gapic/7\\.8\\.9 gax/.* grpc/1\\.2\\.3 protobuf/.*"); } @Test @@ -94,12 +78,7 @@ void testServiceHeaderManualGrpc() { .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches( - "^gl-java/.* gccl/4\\.5\\.6" - + PROTOBUF_APPENDER - + " gax/.* grpc/1\\.2\\.3 " - + PROTOBUF_HEADER - + "$"); + .matches("^gl-java/.* gccl/4\\.5\\.6--protobuf-.* gax/.* grpc/1\\.2\\.3 protobuf/.*"); } @Test @@ -110,7 +89,8 @@ void testServiceHeaderGapic() { .setGeneratedLibToken("gapic", "4.5.6") .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* gapic/4\\.5\\.6--protobuf-.* gax/.* grpc/1\\.2\\.3 protobuf/.*"); } @Test @@ -122,7 +102,8 @@ void testCloudResourcePrefixHeader() { .setResourceToken("test-prefix") .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* gapic/4\\.5\\.6--protobuf-.* gax/.* grpc/1\\.2\\.3 protobuf/.*"); assertThat(provider.getHeaders().get(CLOUD_RESOURCE_PREFIX)).isEqualTo("test-prefix"); } @@ -137,7 +118,8 @@ void testCustomHeaderKeys() { .setResourceHeaderKey("custom-header2") .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get("custom-header1")).matches(FULL_HEADER_MATCH); + assertThat(provider.getHeaders().get("custom-header1")) + .matches("^gl-java/.* gapic/4\\.5\\.6--protobuf-.* gax/.* grpc/1\\.2\\.3 protobuf/.*"); assertThat(provider.getHeaders().get("custom-header2")).isEqualTo("test-prefix"); } @@ -150,7 +132,8 @@ void testQuotaProjectHeader() { .setQuotaProjectIdToken(quotaProjectHeaderValue) .build(); assertThat(provider.getHeaders().size()).isEqualTo(2); - assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)).matches(HEADER_WITHOUT_GAPIC_MATCH); + assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) + .matches("^gl-java/.* gccl/1\\.2\\.3--protobuf-.* gax/.* protobuf/.*"); assertThat(provider.getHeaders().get(ApiClientHeaderProvider.QUOTA_PROJECT_ID_HEADER_KEY)) .matches(quotaProjectHeaderValue); } @@ -175,7 +158,7 @@ void testNonGapicGeneratedLibToken_doesNotAppendProtobufVersion() { ApiClientHeaderProvider.newBuilder().setGeneratedLibToken("other-token", "1.2.3").build(); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* other-token/1.2.3 gax/.* " + PROTOBUF_HEADER + "$"); + .matches("^gl-java/.* other-token/1.2.3 gax/.* protobuf/.*"); } @Test @@ -184,6 +167,6 @@ void testNonGcclGeneratedLibToken_doesNotAppendProtobufVersion() { ApiClientHeaderProvider.newBuilder().setClientLibToken("other-token", "1.2.3").build(); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* other-token/1.2.3 gax/.* " + PROTOBUF_HEADER + "$"); + .matches("^gl-java/.* other-token/1.2.3 gax/.* protobuf/.*"); } } diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiVersionHeaders.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java similarity index 90% rename from showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiVersionHeaders.java rename to showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java index 5f892c5886..93e72800b3 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiVersionHeaders.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java @@ -17,6 +17,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.api.gax.httpjson.*; import com.google.api.gax.rpc.ApiClientHeaderProvider; @@ -31,6 +32,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -39,13 +41,19 @@ // https://github.com/googleapis/gapic-showcase/pull/1456 // TODO: watch for showcase gRPC trailer changes suggested in // https://github.com/googleapis/gapic-showcase/pull/1509#issuecomment-2089147103 -class ITApiVersionHeaders { +class ITVersionHeaders { private static final String HTTP_RESPONSE_HEADER_STRING = "x-showcase-request-" + ApiClientHeaderProvider.API_VERSION_HEADER_KEY; + private static final String HTTP_CLIENT_API_HEADER_KEY = + "x-showcase-request-" + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(); private static final Metadata.Key API_VERSION_HEADER_KEY = Metadata.Key.of( ApiClientHeaderProvider.API_VERSION_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key API_CLIENT_HEADER_KEY = + Metadata.Key.of( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), Metadata.ASCII_STRING_MARSHALLER); + private static final String EXPECTED_ECHO_API_VERSION = "v1_20240408"; private static final String CUSTOM_API_VERSION = "user-supplied-version"; private static final String EXPECTED_EXCEPTION_MESSAGE = @@ -323,4 +331,26 @@ void testHttpJsonCompliance_userApiVersionSetSuccess() throws IOException { assertThat(headerValue).isEqualTo(CUSTOM_API_VERSION); } } + + @Test + void testGrpc_matchesClientLibVersion() { + Pattern defautlGrpcHeaderPattern = + Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ grpc/.+ protobuf/.*"); + grpcClient.echo(EchoRequest.newBuilder().build()); + String headerValue = grpcInterceptor.metadata.get(API_CLIENT_HEADER_KEY); + + assertTrue(defautlGrpcHeaderPattern.matcher(headerValue).matches()); + } + + @Test + void testHttpJson_matchesClientLibVersion() { + Pattern defautlHttpHeaderPattern = + Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ rest/ protobuf/.*"); + httpJsonClient.echo(EchoRequest.newBuilder().build()); + ArrayList headerValues = + (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); + String headerValue = (String) headerValues.get(0); + + assertTrue(defautlHttpHeaderPattern.matcher(headerValue).matches()); + } } From a202b8b4707af76c26677cd4a5038b573c6a2f94 Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 14:59:41 -0400 Subject: [PATCH 18/23] formatting fix --- .../main/java/com/google/api/gax/core/GaxProperties.java | 7 ++++--- .../com/google/api/gax/rpc/ApiClientHeaderProvider.java | 9 +++++---- .../google/api/gax/rpc/ApiClientHeaderProviderTest.java | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index ec8bb5c884..adcceb8cb3 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -129,9 +129,10 @@ static String getRuntimeVersion() { /** * Returns the current library version as reported by Bundle-Version attribute in library's - * META-INF/MANIFEST for libraries using OSGi bundle manifest https://www.ibm.com/docs/en/wasdtfe?topic=overview-osgi-bundles. - * This should only be used if MANIFEST file does not contain a widely recognized version declaration such as Specific-Version OR Implementation-Version declared in - * Manifest Specification + * META-INF/MANIFEST for libraries using OSGi bundle manifest + * https://www.ibm.com/docs/en/wasdtfe?topic=overview-osgi-bundles. This should only be used if + * MANIFEST file does not contain a widely recognized version declaration such as Specific-Version + * OR Implementation-Version declared in Manifest Specification * https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Manifest_Specification, * otherwise please use #getLibraryVersion */ diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java index 6645270fbc..35307764d2 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiClientHeaderProvider.java @@ -90,9 +90,10 @@ private static String checkAndAppendProtobufVersionIfNecessary( Matcher matcher = pattern.matcher(apiClientHeaderValue); if (matcher.find()) { return apiClientHeaderValue.substring(0, matcher.end()) - + "--" - + PROTOBUF_HEADER_VERSION_KEY - + "-" + GaxProperties.getProtobufVersion() + + "--" + + PROTOBUF_HEADER_VERSION_KEY + + "-" + + GaxProperties.getProtobufVersion() + apiClientHeaderValue.substring(matcher.end()); } return apiClientHeaderValue.toString(); @@ -132,7 +133,7 @@ public static class Builder { private String generatedRuntimeToken; private String transportToken; private String quotaProjectIdToken; - final private String protobufRuntimeToken; + private final String protobufRuntimeToken; private String resourceHeaderKey; private String resourceToken; diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java index 56bc5c2071..8dcf74fd8a 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ApiClientHeaderProviderTest.java @@ -29,7 +29,6 @@ */ package com.google.api.gax.rpc; -import static com.google.api.gax.rpc.ApiClientHeaderProvider.PROTOBUF_HEADER_VERSION_KEY; import static com.google.common.truth.Truth.assertThat; import org.junit.jupiter.api.Test; @@ -66,7 +65,8 @@ void testServiceHeaderManualGapic() { .build(); assertThat(provider.getHeaders().size()).isEqualTo(1); assertThat(provider.getHeaders().get(X_GOOG_API_CLIENT)) - .matches("^gl-java/.* gccl/4\\.5\\.6--protobuf-.* gapic/7\\.8\\.9 gax/.* grpc/1\\.2\\.3 protobuf/.*"); + .matches( + "^gl-java/.* gccl/4\\.5\\.6--protobuf-.* gapic/7\\.8\\.9 gax/.* grpc/1\\.2\\.3 protobuf/.*"); } @Test From 9849efd79de2b21d504f18d5a2d41c02884ab718 Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 15:30:16 -0400 Subject: [PATCH 19/23] formatting fix --- .../src/main/java/com/google/api/gax/core/GaxProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java index adcceb8cb3..20d5ecc0dc 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/core/GaxProperties.java @@ -129,7 +129,7 @@ static String getRuntimeVersion() { /** * Returns the current library version as reported by Bundle-Version attribute in library's - * META-INF/MANIFEST for libraries using OSGi bundle manifest + * META-INF/MANIFEST for libraries using OSGi bundle manifest specification * https://www.ibm.com/docs/en/wasdtfe?topic=overview-osgi-bundles. This should only be used if * MANIFEST file does not contain a widely recognized version declaration such as Specific-Version * OR Implementation-Version declared in Manifest Specification From 604f00da23857b3a7884be67a7fa3d517dd7182c Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 15:55:58 -0400 Subject: [PATCH 20/23] print header to debug native image --- .../com/google/showcase/v1beta1/it/ITVersionHeaders.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java index 93e72800b3..3110fafed7 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java @@ -333,24 +333,24 @@ void testHttpJsonCompliance_userApiVersionSetSuccess() throws IOException { } @Test - void testGrpc_matchesClientLibVersion() { + void testGrpcCall_sendsCorrectApiClientHeader() { Pattern defautlGrpcHeaderPattern = Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ grpc/.+ protobuf/.*"); grpcClient.echo(EchoRequest.newBuilder().build()); String headerValue = grpcInterceptor.metadata.get(API_CLIENT_HEADER_KEY); - + System.out.println(headerValue); assertTrue(defautlGrpcHeaderPattern.matcher(headerValue).matches()); } @Test - void testHttpJson_matchesClientLibVersion() { + void testHttpJson_sendsCorrectApiClientHeader() { Pattern defautlHttpHeaderPattern = Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ rest/ protobuf/.*"); httpJsonClient.echo(EchoRequest.newBuilder().build()); ArrayList headerValues = (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); String headerValue = (String) headerValues.get(0); - + System.out.println(headerValue); assertTrue(defautlHttpHeaderPattern.matcher(headerValue).matches()); } } From 9c51ec7e400f638516691aa7c7444b304b49e8d4 Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 16:30:33 -0400 Subject: [PATCH 21/23] print header to debug native image --- .../java/com/google/showcase/v1beta1/it/ITVersionHeaders.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java index 3110fafed7..1bafdc15cf 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java @@ -338,7 +338,7 @@ void testGrpcCall_sendsCorrectApiClientHeader() { Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ grpc/.+ protobuf/.*"); grpcClient.echo(EchoRequest.newBuilder().build()); String headerValue = grpcInterceptor.metadata.get(API_CLIENT_HEADER_KEY); - System.out.println(headerValue); + assertThat(headerValue).isEqualTo(CUSTOM_API_VERSION); assertTrue(defautlGrpcHeaderPattern.matcher(headerValue).matches()); } @@ -350,7 +350,7 @@ void testHttpJson_sendsCorrectApiClientHeader() { ArrayList headerValues = (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); String headerValue = (String) headerValues.get(0); - System.out.println(headerValue); + assertThat(headerValue).isEqualTo(CUSTOM_API_VERSION); assertTrue(defautlHttpHeaderPattern.matcher(headerValue).matches()); } } From a99c4b13be9b443917d0099297d42412e222908c Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 16:51:16 -0400 Subject: [PATCH 22/23] fixed native showcase test --- .../google/showcase/v1beta1/it/ITVersionHeaders.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java index 1bafdc15cf..498f493f54 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java @@ -335,22 +335,20 @@ void testHttpJsonCompliance_userApiVersionSetSuccess() throws IOException { @Test void testGrpcCall_sendsCorrectApiClientHeader() { Pattern defautlGrpcHeaderPattern = - Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ grpc/.+ protobuf/.*"); + Pattern.compile("gl-java/.* gapic/.*?--protobuf-.* gax/.* grpc/.* protobuf/.*"); grpcClient.echo(EchoRequest.newBuilder().build()); String headerValue = grpcInterceptor.metadata.get(API_CLIENT_HEADER_KEY); - assertThat(headerValue).isEqualTo(CUSTOM_API_VERSION); assertTrue(defautlGrpcHeaderPattern.matcher(headerValue).matches()); } @Test void testHttpJson_sendsCorrectApiClientHeader() { Pattern defautlHttpHeaderPattern = - Pattern.compile("gl-java/.+ gapic/.+--protobuf-.+ gax/.+ rest/ protobuf/.*"); + Pattern.compile("gl-java/.* gapic/.*?--protobuf-.* gax/.* rest/ protobuf/.*"); httpJsonClient.echo(EchoRequest.newBuilder().build()); - ArrayList headerValues = - (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); - String headerValue = (String) headerValues.get(0); - assertThat(headerValue).isEqualTo(CUSTOM_API_VERSION); + ArrayList headerValues = + (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); + String headerValue = headerValues.get(0); assertTrue(defautlHttpHeaderPattern.matcher(headerValue).matches()); } } From c7b3d2bdcd7f323208ee3ba817fb25256520bbbd Mon Sep 17 00:00:00 2001 From: detmerl Date: Wed, 18 Sep 2024 17:06:40 -0400 Subject: [PATCH 23/23] fixed formatting --- .../java/com/google/showcase/v1beta1/it/ITVersionHeaders.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java index 498f493f54..80e974c2d5 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITVersionHeaders.java @@ -347,7 +347,8 @@ void testHttpJson_sendsCorrectApiClientHeader() { Pattern.compile("gl-java/.* gapic/.*?--protobuf-.* gax/.* rest/ protobuf/.*"); httpJsonClient.echo(EchoRequest.newBuilder().build()); ArrayList headerValues = - (ArrayList) httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); + (ArrayList) + httpJsonInterceptor.metadata.getHeaders().get(HTTP_CLIENT_API_HEADER_KEY); String headerValue = headerValues.get(0); assertTrue(defautlHttpHeaderPattern.matcher(headerValue).matches()); }