diff --git a/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kms.yaml b/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kms.yaml index 48ac44b3fa..8b1efeb01e 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kms.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kms.yaml @@ -15,7 +15,7 @@ timeout: 7200s # 2 hours substitutions: _SHARED_DEPENDENCIES_VERSION: '3.30.1-SNAPSHOT' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kmsinventory.yaml b/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kmsinventory.yaml index b07bfffc2f..9aab5964fd 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kmsinventory.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-a-downstream-kmsinventory.yaml @@ -15,7 +15,7 @@ timeout: 7200s # 2 hours substitutions: _SHARED_DEPENDENCIES_VERSION: '3.30.1-SNAPSHOT' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild-test-a.yaml b/.cloudbuild/graalvm/cloudbuild-test-a.yaml index 48a949aba2..771d8f8190 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-a.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-a.yaml @@ -14,8 +14,8 @@ timeout: 7200s # 2 hours substitutions: - _SHARED_DEPENDENCIES_VERSION: '3.36.1' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _SHARED_DEPENDENCIES_VERSION: '3.37.0' # {x-version-update:google-cloud-shared-dependencies:current} + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kms.yaml b/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kms.yaml index d9c6bfa990..7d5bdc407f 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kms.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kms.yaml @@ -15,7 +15,7 @@ timeout: 7200s # 2 hours substitutions: _SHARED_DEPENDENCIES_VERSION: '3.30.1-SNAPSHOT' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kmsinventory.yaml b/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kmsinventory.yaml index 2ab7a7ba03..4f25eeef12 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kmsinventory.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-b-downstream-kmsinventory.yaml @@ -15,7 +15,7 @@ timeout: 7200s # 2 hours substitutions: _SHARED_DEPENDENCIES_VERSION: '3.30.1-SNAPSHOT' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild-test-b.yaml b/.cloudbuild/graalvm/cloudbuild-test-b.yaml index 812d940260..c44e119cba 100644 --- a/.cloudbuild/graalvm/cloudbuild-test-b.yaml +++ b/.cloudbuild/graalvm/cloudbuild-test-b.yaml @@ -14,8 +14,8 @@ timeout: 7200s # 2 hours substitutions: - _SHARED_DEPENDENCIES_VERSION: '3.36.1' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _SHARED_DEPENDENCIES_VERSION: '3.37.0' # {x-version-update:google-cloud-shared-dependencies:current} + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' options: machineType: 'E2_HIGHCPU_8' steps: diff --git a/.cloudbuild/graalvm/cloudbuild.yaml b/.cloudbuild/graalvm/cloudbuild.yaml index 208cc5692d..b97d542b11 100644 --- a/.cloudbuild/graalvm/cloudbuild.yaml +++ b/.cloudbuild/graalvm/cloudbuild.yaml @@ -14,8 +14,8 @@ timeout: 7200s # 2 hours substitutions: - _SHARED_DEPENDENCIES_VERSION: '3.36.1' # {x-version-update:google-cloud-shared-dependencies:current} - _JAVA_SHARED_CONFIG_VERSION: '1.11.2' + _SHARED_DEPENDENCIES_VERSION: '3.37.0' # {x-version-update:google-cloud-shared-dependencies:current} + _JAVA_SHARED_CONFIG_VERSION: '1.11.3' steps: # GraalVM A build - name: gcr.io/cloud-builders/docker diff --git a/.cloudbuild/library_generation/cloudbuild-library-generation-push-prod.yaml b/.cloudbuild/library_generation/cloudbuild-library-generation-push-prod.yaml new file mode 100644 index 0000000000..81691fa572 --- /dev/null +++ b/.cloudbuild/library_generation/cloudbuild-library-generation-push-prod.yaml @@ -0,0 +1,40 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +timeout: 7200s # 2 hours +substitutions: + _IMAGE_NAME: "us-docker.pkg.dev/java-hermetic-build-prod/private-resources/java-library-generation" + _GAPIC_GENERATOR_JAVA_VERSION: '2.46.2-SNAPSHOT' # {x-version-update:gapic-generator-java:current} + _SHA_IMAGE_ID: "${_IMAGE_NAME}:${COMMIT_SHA}" + _LATEST_IMAGE_ID: "${_IMAGE_NAME}:latest" + _VERSIONED_IMAGE_ID: "${_IMAGE_NAME}:${_GAPIC_GENERATOR_JAVA_VERSION}" +steps: + # Library generation build + - name: gcr.io/cloud-builders/docker + args: [ + "build", + "-t", "${_SHA_IMAGE_ID}", + "-t", "${_LATEST_IMAGE_ID}", + "-t", "${_VERSIONED_IMAGE_ID}", + "--file", ".cloudbuild/library_generation/library_generation.Dockerfile", "."] + id: library-generation-build + waitFor: ["-"] + +options: + logging: CLOUD_LOGGING_ONLY + +images: + - ${_SHA_IMAGE_ID} + - ${_LATEST_IMAGE_ID} + - ${_VERSIONED_IMAGE_ID} diff --git a/.cloudbuild/library_generation/cloudbuild-library-generation-push.yaml b/.cloudbuild/library_generation/cloudbuild-library-generation-push.yaml index 7faea25272..5ecc2cf897 100644 --- a/.cloudbuild/library_generation/cloudbuild-library-generation-push.yaml +++ b/.cloudbuild/library_generation/cloudbuild-library-generation-push.yaml @@ -15,7 +15,7 @@ timeout: 7200s # 2 hours substitutions: _IMAGE_NAME: "gcr.io/cloud-devrel-public-resources/java-library-generation" - _GAPIC_GENERATOR_JAVA_VERSION: '2.46.1' # {x-version-update:gapic-generator-java:current} + _GAPIC_GENERATOR_JAVA_VERSION: '2.47.0' # {x-version-update:gapic-generator-java:current} _SHA_IMAGE_ID: "${_IMAGE_NAME}:${COMMIT_SHA}" _LATEST_IMAGE_ID: "${_IMAGE_NAME}:latest" _VERSIONED_IMAGE_ID: "${_IMAGE_NAME}:${_GAPIC_GENERATOR_JAVA_VERSION}" diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index 77e09de7e6..315dd612c2 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -19,7 +19,7 @@ FROM gcr.io/cloud-devrel-public-resources/java21 AS ggj-build WORKDIR /sdk-platform-java COPY . . # {x-version-update-start:gapic-generator-java:current} -ENV DOCKER_GAPIC_GENERATOR_VERSION="2.46.1" +ENV DOCKER_GAPIC_GENERATOR_VERSION="2.47.0" # {x-version-update-end} RUN mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip @@ -32,9 +32,9 @@ FROM gcr.io/cloud-devrel-public-resources/python SHELL [ "/bin/bash", "-c" ] -ARG OWLBOT_CLI_COMMITTISH=ac84fa5c423a0069bbce3d2d869c9730c8fdf550 +ARG OWLBOT_CLI_COMMITTISH=38fe6f89a2339ee75c77739b31b371f601b01bb3 ARG PROTOC_VERSION=25.5 -ARG GRPC_VERSION=1.68.0 +ARG GRPC_VERSION=1.67.1 ENV HOME=/home ENV OS_ARCHITECTURE="linux-x86_64" diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index e003740d5d..32f4a9e84e 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -1,3 +1,34 @@ rebaseMergeAllowed: true squashMergeAllowed: true mergeCommitAllowed: false +branchProtectionRules: +- pattern: main + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - build(8) except for gapic-generator-java + - build(8) for gapic-generator-java + - build (11) + - build (17) + - cla/google + - compatibility + - graalvm-presubmit-sdk-platform-java-a (cloud-devrel-kokoro-resources) + - graalvm-presubmit-sdk-platform-java-b (cloud-devrel-kokoro-resources) + - library_generation + - library-generation-integration-tests + - library-generation-lint-python + - library-generation-lint-shell + - library-generation-unit-tests + - lint + - should-run-library-generation-tests + - showcase (11) + - showcase (17) +permissionRules: +- team: yoshi-admins + permission: admin +- team: yoshi-java-admins + permission: admin +- team: yoshi-java + permission: push diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4a35930714..cbe7bd9bd6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -330,7 +330,7 @@ jobs: run: | mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip - name: Validate gapic-generator-java-bom - uses: googleapis/java-cloud-bom/tests/validate-bom@e7d890994c34781d161e2629c7e15cf8fd755de5 + uses: googleapis/java-cloud-bom/tests/validate-bom@0cd97b7151b36465390bd5e31d017ec015a4bae9 with: bom-path: gapic-generator-java-bom/pom.xml diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 09f35adc2f..3ab3b9e3de 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.46.1" + ".": "2.47.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a475694ee..25ee0b0b41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## [2.47.0](https://github.com/googleapis/sdk-platform-java/compare/v2.46.1...v2.47.0) (2024-10-04) + + +### Features + +* **gax:** add API key authentication to ClientSettings ([#3137](https://github.com/googleapis/sdk-platform-java/issues/3137)) ([df08956](https://github.com/googleapis/sdk-platform-java/commit/df08956a26fa63b287241f3a37058c689c34d245)) +* **gax:** append cred-type header for auth metrics ([#3186](https://github.com/googleapis/sdk-platform-java/issues/3186)) ([ca3ec24](https://github.com/googleapis/sdk-platform-java/commit/ca3ec24f506f0d43623a92ba0eed908f874fe488)) + + +### Bug Fixes + +* address incorrect universe domain validation when quota project id is set ([#3257](https://github.com/googleapis/sdk-platform-java/issues/3257)) ([6e70c37](https://github.com/googleapis/sdk-platform-java/commit/6e70c3705280576278a790a4228476ac996ef9da)), closes [#3256](https://github.com/googleapis/sdk-platform-java/issues/3256) +* Disable automatically retrieving Universe Domain from Metadata Server ([#3272](https://github.com/googleapis/sdk-platform-java/issues/3272)) ([f4402bf](https://github.com/googleapis/sdk-platform-java/commit/f4402bfa717831507e9e54d057d11ff69594e46b)) + + +### Dependencies + +* update dependency com.fasterxml.jackson:jackson-bom to v2.18.0 ([#3248](https://github.com/googleapis/sdk-platform-java/issues/3248)) ([821e83d](https://github.com/googleapis/sdk-platform-java/commit/821e83d8cef94594f8c8e832c40e319c232cb1b9)) +* update dependency com.google.errorprone:error_prone_annotations to v2.33.0 ([#3265](https://github.com/googleapis/sdk-platform-java/issues/3265)) ([94450a9](https://github.com/googleapis/sdk-platform-java/commit/94450a9699d94a078e5f5fa106f4d1ce4282a605)) +* update dependency com.google.errorprone:error_prone_annotations to v2.33.0 ([#3266](https://github.com/googleapis/sdk-platform-java/issues/3266)) ([8235463](https://github.com/googleapis/sdk-platform-java/commit/8235463dc2bc05382359d09702be55e2063f4908)) +* update dependency com.google.guava:guava to v33.3.1-jre ([#3228](https://github.com/googleapis/sdk-platform-java/issues/3228)) ([4e76207](https://github.com/googleapis/sdk-platform-java/commit/4e762078a59e6fd92453bb5a1395730f6f442524)) +* update dependency net.bytebuddy:byte-buddy to v1.15.3 ([#3246](https://github.com/googleapis/sdk-platform-java/issues/3246)) ([2aad71d](https://github.com/googleapis/sdk-platform-java/commit/2aad71dda5fe2bb0cdbe823392cccb36cfea6abb)) +* update google api dependencies ([#3242](https://github.com/googleapis/sdk-platform-java/issues/3242)) ([02aae9d](https://github.com/googleapis/sdk-platform-java/commit/02aae9d919b5c7170eb88d08d0ee79f71a0c5762)) +* update google auth library dependencies to v1.28.0 ([#3267](https://github.com/googleapis/sdk-platform-java/issues/3267)) ([6d85864](https://github.com/googleapis/sdk-platform-java/commit/6d85864779ae61cecddc3eaa9d8991ed4053a253)) +* update googleapis/java-cloud-bom digest to 0cd97b7 ([#3260](https://github.com/googleapis/sdk-platform-java/issues/3260)) ([2d54a5d](https://github.com/googleapis/sdk-platform-java/commit/2d54a5d2825e0956c76f68e22426bbb7665fdb12)) +* update grpc dependencies to v1.67.1 ([#3258](https://github.com/googleapis/sdk-platform-java/issues/3258)) ([e08906c](https://github.com/googleapis/sdk-platform-java/commit/e08906cd86146bfa4f62bbc5e507bf04a0956a37)) +* update grpc dependencies to v1.67.1 in dependencies.properties ([#3279](https://github.com/googleapis/sdk-platform-java/issues/3279)) ([5b46e70](https://github.com/googleapis/sdk-platform-java/commit/5b46e7036d65f350c21a5c922997b4d38532f994)) +* update junit5 monorepo to v5.11.2 ([#3276](https://github.com/googleapis/sdk-platform-java/issues/3276)) ([6b10f94](https://github.com/googleapis/sdk-platform-java/commit/6b10f94c56e8769ff41bb58c77b8c45dafeacc45)) +* update netty dependencies to v4.1.114.final ([#3263](https://github.com/googleapis/sdk-platform-java/issues/3263)) ([8bd83d9](https://github.com/googleapis/sdk-platform-java/commit/8bd83d9ed0794f2aa2f771d6f28d492ecb98500f)) + ## [2.46.1](https://github.com/googleapis/sdk-platform-java/compare/v2.46.0...v2.46.1) (2024-09-25) diff --git a/README.md b/README.md index fab565aac1..6617753a07 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ For more information, please refer to [rename a repository](https://docs.github. This repository consists of the following modules: - **[gapic-generator-java](./gapic-generator-java/README.md)**: the Protobuf compiler plugin to generate Java code. - See [gapic-generator-java/DEVELOPMENT.md](./gapic-generator-java/README.md) for setup. + See [gapic-generator-java/DEVELOPMENT.md](./gapic-generator-java/DEVELOPMENT.md) for setup. - **[gax-java](./gax-java/README.md)**: the runtime library required for Google Cloud client libraries, including the ones generated by gapic-generator-java. - **[java-common-protos](./java-common-protos/README.md)** and **[api-common-java](./api-common-java/README.md)**: Protobuf-generated common diff --git a/WORKSPACE b/WORKSPACE index 408f9ceca2..dec5a43d6c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -58,7 +58,7 @@ load("@rules_jvm_external//:defs.bzl", "maven_install") load("@io_grpc_grpc_java//:repositories.bzl", "IO_GRPC_GRPC_JAVA_ARTIFACTS") load("@io_grpc_grpc_java//:repositories.bzl", "IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS") -_gapic_generator_java_version = "2.46.1" # {x-version-update:gapic-generator-java:current} +_gapic_generator_java_version = "2.47.0" # {x-version-update:gapic-generator-java:current} maven_install( artifacts = [ diff --git a/api-common-java/pom.xml b/api-common-java/pom.xml index d3e59e2464..2a1c4b8623 100644 --- a/api-common-java/pom.xml +++ b/api-common-java/pom.xml @@ -5,14 +5,14 @@ com.google.api api-common jar - 2.37.1 + 2.38.0 API Common Common utilities for Google APIs in Java com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent diff --git a/coverage-report/pom.xml b/coverage-report/pom.xml index 266d45ef1b..fede32d68f 100644 --- a/coverage-report/pom.xml +++ b/coverage-report/pom.xml @@ -31,22 +31,22 @@ com.google.api gax - 2.54.1 + 2.55.0 com.google.api gax-grpc - 2.54.1 + 2.55.0 com.google.api gax-httpjson - 2.54.1 + 2.55.0 com.google.api api-common - 2.37.1 + 2.38.0 diff --git a/gapic-generator-java-bom/pom.xml b/gapic-generator-java-bom/pom.xml index f94fd0ceee..58d66a4d6e 100644 --- a/gapic-generator-java-bom/pom.xml +++ b/gapic-generator-java-bom/pom.xml @@ -4,7 +4,7 @@ com.google.api gapic-generator-java-bom pom - 2.46.1 + 2.47.0 GAPIC Generator Java BOM BOM for the libraries in gapic-generator-java repository. Users should not @@ -15,7 +15,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -75,61 +75,61 @@ com.google.api api-common - 2.37.1 + 2.38.0 com.google.api gax-bom - 2.54.1 + 2.55.0 pom import com.google.api gapic-generator-java - 2.46.1 + 2.47.0 com.google.api.grpc grpc-google-common-protos - 2.45.1 + 2.46.0 com.google.api.grpc proto-google-common-protos - 2.45.1 + 2.46.0 com.google.api.grpc proto-google-iam-v1 - 1.40.1 + 1.41.0 com.google.api.grpc proto-google-iam-v2 - 1.40.1 + 1.41.0 com.google.api.grpc proto-google-iam-v2beta - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v1 - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v2 - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v2beta - 1.40.1 + 1.41.0 diff --git a/gapic-generator-java-pom-parent/pom.xml b/gapic-generator-java-pom-parent/pom.xml index 0f0ae63089..264a1690d6 100644 --- a/gapic-generator-java-pom-parent/pom.xml +++ b/gapic-generator-java-pom-parent/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 pom GAPIC Generator Java POM Parent https://github.com/googleapis/sdk-platform-java @@ -15,7 +15,7 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 @@ -26,18 +26,18 @@ 1.3.2 - 1.68.0 - 1.27.0 + 1.67.1 + 1.28.0 1.45.0 2.11.0 - 33.3.0-jre + 33.3.1-jre 3.25.5 1.42.1 8 - 2.32.0 + 2.33.0 3.0.0 1.7.0 - 5.11.1 + 5.11.2 diff --git a/gapic-generator-java/pom.xml b/gapic-generator-java/pom.xml index 50d0371fc1..b1a64f7ff2 100644 --- a/gapic-generator-java/pom.xml +++ b/gapic-generator-java/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.google.api gapic-generator-java - 2.46.1 + 2.47.0 GAPIC Generator Java GAPIC generator Java @@ -22,7 +22,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -31,7 +31,7 @@ com.google.api gapic-generator-java-bom - 2.46.1 + 2.47.0 pom import diff --git a/gax-java/README.md b/gax-java/README.md index e9db47fd52..d62dc0b32c 100644 --- a/gax-java/README.md +++ b/gax-java/README.md @@ -34,27 +34,27 @@ If you are using Maven, add this to your pom.xml file com.google.api gax - 2.54.1 + 2.55.0 com.google.api gax-grpc - 2.54.1 + 2.55.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.api:gax:2.54.1', - 'com.google.api:gax-grpc:2.54.1' +compile 'com.google.api:gax:2.55.0', + 'com.google.api:gax-grpc:2.55.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.api" % "gax" % "2.54.1" -libraryDependencies += "com.google.api" % "gax-grpc" % "2.54.1" +libraryDependencies += "com.google.api" % "gax" % "2.55.0" +libraryDependencies += "com.google.api" % "gax-grpc" % "2.55.0" ``` [//]: # ({x-version-update-end}) diff --git a/gax-java/dependencies.properties b/gax-java/dependencies.properties index b5ea1f04e6..6943ad61e7 100644 --- a/gax-java/dependencies.properties +++ b/gax-java/dependencies.properties @@ -8,16 +8,16 @@ # Versions of oneself # {x-version-update-start:gax:current} -version.gax=2.54.1 +version.gax=2.55.0 # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_grpc=2.54.1 +version.gax_grpc=2.55.0 # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_bom=2.54.1 +version.gax_bom=2.55.0 # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_httpjson=2.54.1 +version.gax_httpjson=2.55.0 # {x-version-update-end} # Versions for dependencies which actual artifacts differ between Bazel and Gradle. @@ -28,33 +28,33 @@ version.gax_httpjson=2.54.1 version.com_google_protobuf=3.25.5 version.google_java_format=1.15.0 -version.io_grpc=1.66.0 +version.io_grpc=1.67.1 # Maven artifacts. # Note, the actual name of each property matters (bazel build scripts depend on it). # It should be constructed the following way: # 1) Take full artifact id (including the group and classifier (if any) portions) and remove version portion. # 2) Replace all characters which are neither alphabetic nor digits with the underscore ('_') character -maven.com_google_api_grpc_proto_google_common_protos=com.google.api.grpc:proto-google-common-protos:2.45.0 -maven.com_google_api_grpc_grpc_google_common_protos=com.google.api.grpc:grpc-google-common-protos:2.45.0 -maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:1.27.0 -maven.com_google_auth_google_auth_library_credentials=com.google.auth:google-auth-library-credentials:1.27.0 +maven.com_google_api_grpc_proto_google_common_protos=com.google.api.grpc:proto-google-common-protos:2.45.1 +maven.com_google_api_grpc_grpc_google_common_protos=com.google.api.grpc:grpc-google-common-protos:2.45.1 +maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:1.28.0 +maven.com_google_auth_google_auth_library_credentials=com.google.auth:google-auth-library-credentials:1.28.0 maven.io_opentelemetry_opentelemetry_api=io.opentelemetry:opentelemetry-api:1.42.1 maven.io_opencensus_opencensus_api=io.opencensus:opencensus-api:0.31.1 maven.io_opencensus_opencensus_contrib_grpc_metrics=io.opencensus:opencensus-contrib-grpc-metrics:0.31.1 maven.io_opencensus_opencensus_contrib_http_util=io.opencensus:opencensus-contrib-http-util:0.31.1 maven.io_netty_netty_tcnative_boringssl_static=io.netty:netty-tcnative-boringssl-static:2.0.66.Final -maven.io_netty_netty_handler=io.netty:netty-handler:4.1.113.Final -maven.io_netty_netty_common=io.netty:netty-common:4.1.113.Final -maven.io_netty_netty_codec_socks=io.netty:netty-codec-socks:4.1.113.Final -maven.io_netty_netty_codec_http2=io.netty:netty-codec-http2:4.1.113.Final -maven.io_netty_netty_codec_http=io.netty:netty-codec-http:4.1.113.Final -maven.io_netty_netty_codec=io.netty:netty-codec:4.1.113.Final -maven.io_netty_netty_buffer=io.netty:netty-buffer:4.1.113.Final -maven.io_netty_netty_resolver=io.netty:netty-resolver:4.1.113.Final -maven.io_netty_netty_transport=io.netty:netty-transport:4.1.113.Final -maven.io_netty_netty_handler_proxy=io.netty:netty-handler-proxy:4.1.113.Final -maven.io_netty_netty_transport_native_unix_common=io.netty:netty-transport-native-unix-common:4.1.113.Final +maven.io_netty_netty_handler=io.netty:netty-handler:4.1.114.Final +maven.io_netty_netty_common=io.netty:netty-common:4.1.114.Final +maven.io_netty_netty_codec_socks=io.netty:netty-codec-socks:4.1.114.Final +maven.io_netty_netty_codec_http2=io.netty:netty-codec-http2:4.1.114.Final +maven.io_netty_netty_codec_http=io.netty:netty-codec-http:4.1.114.Final +maven.io_netty_netty_codec=io.netty:netty-codec:4.1.114.Final +maven.io_netty_netty_buffer=io.netty:netty-buffer:4.1.114.Final +maven.io_netty_netty_resolver=io.netty:netty-resolver:4.1.114.Final +maven.io_netty_netty_transport=io.netty:netty-transport:4.1.114.Final +maven.io_netty_netty_handler_proxy=io.netty:netty-handler-proxy:4.1.114.Final +maven.io_netty_netty_transport_native_unix_common=io.netty:netty-transport-native-unix-common:4.1.114.Final maven.io_perfmark_perfmark_api=io.perfmark:perfmark-api:0.27.0 maven.org_apache_tomcat_annotations_api=org.apache.tomcat:annotations-api:6.0.53 maven.com_google_code_gson_gson=com.google.code.gson:gson:2.11.0 @@ -63,14 +63,14 @@ maven.com_google_guava_failureaccess=com.google.guava:failureaccess:1.0.2 maven.org_apache_commons_commons_lang3=org.apache.commons:commons-lang3:3.17.0 maven.com_google_android_annotations=com.google.android:annotations:4.1.1.4 maven.com_google_code_findbugs_jsr305=com.google.code.findbugs:jsr305:3.0.2 -maven.com_google_errorprone_error_prone_annotations=com.google.errorprone:error_prone_annotations:2.32.0 +maven.com_google_errorprone_error_prone_annotations=com.google.errorprone:error_prone_annotations:2.33.0 maven.com_google_j2objc_j2objc_annotations=com.google.j2objc:j2objc-annotations:2.8 maven.com_google_auto_value_auto_value=com.google.auto.value:auto-value:1.11.0 maven.com_google_auto_value_auto_value_annotations=com.google.auto.value:auto-value-annotations:1.11.0 -maven.com_google_api_api_common=com.google.api:api-common:2.37.0 +maven.com_google_api_api_common=com.google.api:api-common:2.37.1 maven.org_threeten_threetenbp=org.threeten:threetenbp:1.7.0 -maven.com_google_api_grpc_grpc_google_iam_v1=com.google.api.grpc:grpc-google-iam-v1:1.40.0 -maven.com_google_api_grpc_proto_google_iam_v1=com.google.api.grpc:proto-google-iam-v1:1.40.0 +maven.com_google_api_grpc_grpc_google_iam_v1=com.google.api.grpc:grpc-google-iam-v1:1.40.1 +maven.com_google_api_grpc_proto_google_iam_v1=com.google.api.grpc:proto-google-iam-v1:1.40.1 maven.com_google_http_client_google_http_client=com.google.http-client:google-http-client:1.45.0 maven.com_google_http_client_google_http_client_gson=com.google.http-client:google-http-client-gson:1.45.0 maven.org_codehaus_mojo_animal_sniffer_annotations=org.codehaus.mojo:animal-sniffer-annotations:1.24 @@ -84,7 +84,7 @@ maven.org_mockito_mockito_junit_jupiter=org.mockito:mockito-junit-jupiter:4.11.0 maven.org_hamcrest_hamcrest_core=org.hamcrest:hamcrest-core:1.3 maven.com_google_truth_truth=com.google.truth:truth:1.4.4 maven.com_googlecode_java_diff_utils_diffutils=com.googlecode.java-diff-utils:diffutils:1.3.0 -maven.net_bytebuddy_byte_buddy=net.bytebuddy:byte-buddy:1.15.2 +maven.net_bytebuddy_byte_buddy=net.bytebuddy:byte-buddy:1.15.3 maven.org_objenesis_objenesis=org.objenesis:objenesis:2.6 -maven.org_junit_jupiter_junit_jupiter_api=org.junit.jupiter:junit-jupiter-api:5.11.1 -maven.org_junit_jupiter_junit_jupiter_params=org.junit.jupiter:junit-jupiter-params:5.11.1 +maven.org_junit_jupiter_junit_jupiter_api=org.junit.jupiter:junit-jupiter-api:5.11.2 +maven.org_junit_jupiter_junit_jupiter_params=org.junit.jupiter:junit-jupiter-params:5.11.2 diff --git a/gax-java/gax-bom/pom.xml b/gax-java/gax-bom/pom.xml index 8b460d0501..6357abb36c 100644 --- a/gax-java/gax-bom/pom.xml +++ b/gax-java/gax-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.api gax-bom - 2.54.1 + 2.55.0 pom GAX (Google Api eXtensions) for Java (BOM) Google Api eXtensions for Java (BOM) @@ -11,7 +11,7 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 @@ -43,55 +43,55 @@ com.google.api gax - 2.54.1 + 2.55.0 com.google.api gax - 2.54.1 + 2.55.0 test-jar testlib com.google.api gax - 2.54.1 + 2.55.0 testlib com.google.api gax-grpc - 2.54.1 + 2.55.0 com.google.api gax-grpc - 2.54.1 + 2.55.0 test-jar testlib com.google.api gax-grpc - 2.54.1 + 2.55.0 testlib com.google.api gax-httpjson - 2.54.1 + 2.55.0 com.google.api gax-httpjson - 2.54.1 + 2.55.0 test-jar testlib com.google.api gax-httpjson - 2.54.1 + 2.55.0 testlib diff --git a/gax-java/gax-grpc/pom.xml b/gax-java/gax-grpc/pom.xml index 7bd1c5e525..3caaeec2b2 100644 --- a/gax-java/gax-grpc/pom.xml +++ b/gax-java/gax-grpc/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gax-grpc - 2.54.1 + 2.55.0 jar GAX (Google Api eXtensions) for Java (gRPC) Google Api eXtensions for Java (gRPC) @@ -11,7 +11,7 @@ com.google.api gax-parent - 2.54.1 + 2.55.0 diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java index 5d601e8fa6..ae4d7f9e51 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java @@ -43,6 +43,7 @@ import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.gax.rpc.internal.EnvironmentProvider; import com.google.api.gax.rpc.mtls.MtlsProvider; +import com.google.auth.ApiKeyCredentials; import com.google.auth.Credentials; import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.common.annotations.VisibleForTesting; @@ -63,6 +64,8 @@ import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; @@ -123,6 +126,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP @Nullable private final Boolean allowNonDefaultServiceAccount; @VisibleForTesting final ImmutableMap directPathServiceConfig; @Nullable private final MtlsProvider mtlsProvider; + @VisibleForTesting final Map headersWithDuplicatesRemoved = new HashMap<>(); @Nullable private final ApiFunction channelConfigurator; @@ -408,7 +412,8 @@ ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSec private ManagedChannel createSingleChannel() throws IOException { GrpcHeaderInterceptor headerInterceptor = - new GrpcHeaderInterceptor(headerProvider.getHeaders()); + new GrpcHeaderInterceptor(headersWithDuplicatesRemoved); + GrpcMetadataHandlerInterceptor metadataHandlerInterceptor = new GrpcMetadataHandlerInterceptor(); @@ -496,6 +501,28 @@ private ManagedChannel createSingleChannel() throws IOException { return managedChannel; } + /* Remove provided headers that will also get set by {@link com.google.auth.ApiKeyCredentials}. They will be added as part of the grpc call when performing auth + * {@link io.grpc.auth.GoogleAuthLibraryCallCredentials#applyRequestMetadata}. GRPC does not dedup headers {@link https://github.com/grpc/grpc-java/blob/a140e1bb0cfa662bcdb7823d73320eb8d49046f1/api/src/main/java/io/grpc/Metadata.java#L504} so we must before initiating the call. + * + * Note: This is specific for ApiKeyCredentials as duplicate API key headers causes a failure on the back end. At this time we are not sure of the behavior for other credentials. + */ + private void removeApiKeyCredentialDuplicateHeaders() { + if (headerProvider != null) { + headersWithDuplicatesRemoved.putAll(headerProvider.getHeaders()); + } + if (credentials != null && credentials instanceof ApiKeyCredentials) { + try { + Map> credentialRequestMetatData = credentials.getRequestMetadata(); + if (credentialRequestMetatData != null) { + headersWithDuplicatesRemoved.keySet().removeAll(credentialRequestMetatData.keySet()); + } + } catch (IOException e) { + // unreachable, there is no scenario that getRequestMetatData for ApiKeyCredentials will + // throw an IOException + } + } + } + /** * Marked as Internal Api and intended for internal use. DirectPath must be enabled via the * settings and a few other configurations/settings must also be valid for the request to go @@ -883,7 +910,10 @@ public Builder setDirectPathServiceConfig(Map serviceConfig) { } public InstantiatingGrpcChannelProvider build() { - return new InstantiatingGrpcChannelProvider(this); + InstantiatingGrpcChannelProvider instantiatingGrpcChannelProvider = + new InstantiatingGrpcChannelProvider(this); + instantiatingGrpcChannelProvider.removeApiKeyCredentialDuplicateHeaders(); + return instantiatingGrpcChannelProvider; } /** diff --git a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java index a4bcb65a1a..a58f9b8173 100644 --- a/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java +++ b/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java @@ -34,17 +34,21 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder; +import com.google.api.gax.rpc.FixedHeaderProvider; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.TransportChannel; import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.gax.rpc.internal.EnvironmentProvider; import com.google.api.gax.rpc.mtls.AbstractMtlsTransportChannelTest; import com.google.api.gax.rpc.mtls.MtlsProvider; +import com.google.auth.ApiKeyCredentials; import com.google.auth.Credentials; +import com.google.auth.http.AuthHttpConstants; import com.google.auth.oauth2.CloudShellCredentials; import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.common.collect.ImmutableList; @@ -79,6 +83,8 @@ class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest { private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; + private static final String API_KEY_HEADER_VALUE = "fake_api_key_2"; + private static final String API_KEY_AUTH_HEADER_KEY = "x-goog-api-key"; private static String originalOSName; private ComputeEngineCredentials computeEngineCredentials; @@ -877,6 +883,103 @@ public void canUseDirectPath_nonGDUUniverseDomain() { Truth.assertThat(provider.canUseDirectPath()).isFalse(); } + @Test + void providerInitializedWithNonConflictingHeaders_retainsHeaders() { + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder() + .setHeaderProvider(getHeaderProviderWithApiKeyHeader()) + .setEndpoint("test.random.com:443"); + + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(1, provider.headersWithDuplicatesRemoved.size()); + assertEquals( + API_KEY_HEADER_VALUE, provider.headersWithDuplicatesRemoved.get(API_KEY_AUTH_HEADER_KEY)); + } + + @Test + void providersInitializedWithConflictingApiKeyCredentialHeaders_removesDuplicates() { + String correctApiKey = "fake_api_key"; + ApiKeyCredentials apiKeyCredentials = ApiKeyCredentials.create(correctApiKey); + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder() + .setCredentials(apiKeyCredentials) + .setHeaderProvider(getHeaderProviderWithApiKeyHeader()) + .setEndpoint("test.random.com:443"); + + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(0, provider.headersWithDuplicatesRemoved.size()); + assertNull(provider.headersWithDuplicatesRemoved.get(API_KEY_AUTH_HEADER_KEY)); + } + + @Test + void providersInitializedWithConflictingNonApiKeyCredentialHeaders_doesNotRemoveDuplicates() { + String authProvidedHeader = "Bearer token"; + Map header = new HashMap<>(); + header.put(AuthHttpConstants.AUTHORIZATION, authProvidedHeader); + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder() + .setCredentials(computeEngineCredentials) + .setHeaderProvider(FixedHeaderProvider.create(header)) + .setEndpoint("test.random.com:443"); + + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(1, provider.headersWithDuplicatesRemoved.size()); + assertEquals( + authProvidedHeader, + provider.headersWithDuplicatesRemoved.get(AuthHttpConstants.AUTHORIZATION)); + } + + @Test + void buildProvider_handlesNullHeaderProvider() { + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder().setEndpoint("test.random.com:443"); + + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(0, provider.headersWithDuplicatesRemoved.size()); + } + + @Test + void buildProvider_handlesNullCredentialsMetadataRequest() throws IOException { + Credentials credentials = Mockito.mock(Credentials.class); + Mockito.when(credentials.getRequestMetadata()).thenReturn(null); + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder() + .setHeaderProvider(getHeaderProviderWithApiKeyHeader()) + .setEndpoint("test.random.com:443"); + + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(1, provider.headersWithDuplicatesRemoved.size()); + assertEquals( + API_KEY_HEADER_VALUE, provider.headersWithDuplicatesRemoved.get(API_KEY_AUTH_HEADER_KEY)); + } + + @Test + void buildProvider_handlesErrorRetrievingCredentialsMetadataRequest() throws IOException { + Credentials credentials = Mockito.mock(Credentials.class); + Mockito.when(credentials.getRequestMetadata()) + .thenThrow(new IOException("Error getting request metadata")); + InstantiatingGrpcChannelProvider.Builder builder = + InstantiatingGrpcChannelProvider.newBuilder() + .setHeaderProvider(getHeaderProviderWithApiKeyHeader()) + .setEndpoint("test.random.com:443"); + InstantiatingGrpcChannelProvider provider = builder.build(); + + assertEquals(1, provider.headersWithDuplicatesRemoved.size()); + assertEquals( + API_KEY_HEADER_VALUE, provider.headersWithDuplicatesRemoved.get(API_KEY_AUTH_HEADER_KEY)); + } + + private FixedHeaderProvider getHeaderProviderWithApiKeyHeader() { + Map header = new HashMap<>(); + header.put(API_KEY_AUTH_HEADER_KEY, API_KEY_HEADER_VALUE); + return FixedHeaderProvider.create(header); + } + private static class FakeLogHandler extends Handler { List records = new ArrayList<>(); diff --git a/gax-java/gax-httpjson/pom.xml b/gax-java/gax-httpjson/pom.xml index 796d44989e..f1309e7c18 100644 --- a/gax-java/gax-httpjson/pom.xml +++ b/gax-java/gax-httpjson/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gax-httpjson - 2.54.1 + 2.55.0 jar GAX (Google Api eXtensions) for Java (HTTP JSON) Google Api eXtensions for Java (HTTP JSON) @@ -11,7 +11,7 @@ com.google.api gax-parent - 2.54.1 + 2.55.0 diff --git a/gax-java/gax/pom.xml b/gax-java/gax/pom.xml index 02b4bfc669..7b204e8a66 100644 --- a/gax-java/gax/pom.xml +++ b/gax-java/gax/pom.xml @@ -3,7 +3,7 @@ 4.0.0 gax - 2.54.1 + 2.55.0 jar GAX (Google Api eXtensions) for Java (Core) Google Api eXtensions for Java (Core) @@ -11,7 +11,7 @@ com.google.api gax-parent - 2.54.1 + 2.55.0 diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java index 09c05b7838..5bce1ac6bb 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java @@ -43,9 +43,12 @@ import com.google.api.gax.rpc.internal.QuotaProjectIdHidingCredentials; import com.google.api.gax.tracing.ApiTracerFactory; import com.google.api.gax.tracing.BaseApiTracerFactory; +import com.google.auth.ApiKeyCredentials; +import com.google.auth.CredentialTypeForMetrics; import com.google.auth.Credentials; import com.google.auth.oauth2.GdchCredentials; import com.google.auto.value.AutoValue; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; @@ -175,9 +178,9 @@ public static ClientContext create(StubSettings settings) throws IOException { // A valid EndpointContext should have been created in the StubSettings EndpointContext endpointContext = settings.getEndpointContext(); String endpoint = endpointContext.resolvedEndpoint(); - + Credentials credentials = getCredentials(settings); + // check if need to adjust credentials/endpoint/endpointContext for GDC-H String settingsGdchApiAudience = settings.getGdchApiAudience(); - Credentials credentials = settings.getCredentialsProvider().getCredentials(); boolean usingGDCH = credentials instanceof GdchCredentials; if (usingGDCH) { // Can only determine if the GDC-H is being used via the Credentials. The Credentials object @@ -187,22 +190,7 @@ public static ClientContext create(StubSettings settings) throws IOException { // Resolve the new endpoint with the GDC-H flow endpoint = endpointContext.resolvedEndpoint(); // We recompute the GdchCredentials with the audience - String audienceString; - if (!Strings.isNullOrEmpty(settingsGdchApiAudience)) { - audienceString = settingsGdchApiAudience; - } else if (!Strings.isNullOrEmpty(endpoint)) { - audienceString = endpoint; - } else { - throw new IllegalArgumentException("Could not infer GDCH api audience from settings"); - } - - URI gdchAudienceUri; - try { - gdchAudienceUri = URI.create(audienceString); - } catch (IllegalArgumentException ex) { // thrown when passing a malformed uri string - throw new IllegalArgumentException("The GDC-H API audience string is not a valid URI", ex); - } - credentials = ((GdchCredentials) credentials).createWithGdchAudience(gdchAudienceUri); + credentials = getGdchCredentials(settingsGdchApiAudience, endpoint, credentials); } else if (!Strings.isNullOrEmpty(settingsGdchApiAudience)) { throw new IllegalArgumentException( "GDC-H API audience can only be set when using GdchCredentials"); @@ -223,7 +211,8 @@ public static ClientContext create(StubSettings settings) throws IOException { if (transportChannelProvider.needsExecutor() && settings.getExecutorProvider() != null) { transportChannelProvider = transportChannelProvider.withExecutor(backgroundExecutor); } - Map headers = getHeadersFromSettings(settings); + + Map headers = getHeaders(settings, credentials); if (transportChannelProvider.needsHeaders()) { transportChannelProvider = transportChannelProvider.withHeaders(headers); } @@ -291,11 +280,51 @@ public static ClientContext create(StubSettings settings) throws IOException { .build(); } + /** Determines which credentials to use. API key overrides credentials provided by provider. */ + private static Credentials getCredentials(StubSettings settings) throws IOException { + Credentials credentials; + if (settings.getApiKey() != null) { + // if API key exists it becomes the default credential + credentials = ApiKeyCredentials.create(settings.getApiKey()); + } else { + credentials = settings.getCredentialsProvider().getCredentials(); + } + return credentials; + } + + /** + * Constructs a new {@link com.google.auth.Credentials} object based on credentials provided with + * a GDC-H audience + */ + @VisibleForTesting + static GdchCredentials getGdchCredentials( + String settingsGdchApiAudience, String endpoint, Credentials credentials) throws IOException { + String audienceString; + if (!Strings.isNullOrEmpty(settingsGdchApiAudience)) { + audienceString = settingsGdchApiAudience; + } else if (!Strings.isNullOrEmpty(endpoint)) { + audienceString = endpoint; + } else { + throw new IllegalArgumentException("Could not infer GDCH api audience from settings"); + } + + URI gdchAudienceUri; + try { + gdchAudienceUri = URI.create(audienceString); + } catch (IllegalArgumentException ex) { // thrown when passing a malformed uri string + throw new IllegalArgumentException("The GDC-H API audience string is not a valid URI", ex); + } + return ((GdchCredentials) credentials).createWithGdchAudience(gdchAudienceUri); + } + /** * Getting a header map from HeaderProvider and InternalHeaderProvider from settings with Quota * Project Id. + * + *

Then if credentials is present and its type for metrics is not {@code + * CredentialTypeForMetrics.DO_NOT_SEND}, append this type info to x-goog-api-client header. */ - private static Map getHeadersFromSettings(StubSettings settings) { + private static Map getHeaders(StubSettings settings, Credentials credentials) { // Resolve conflicts when merging headers from multiple sources Map userHeaders = settings.getHeaderProvider().getHeaders(); Map internalHeaders = settings.getInternalHeaderProvider().getHeaders(); @@ -322,6 +351,20 @@ private static Map getHeadersFromSettings(StubSettings settings) effectiveHeaders.putAll(userHeaders); effectiveHeaders.putAll(conflictResolution); + return appendCredentialTypeToHeaderIfPresent(effectiveHeaders, credentials); + } + + private static Map appendCredentialTypeToHeaderIfPresent( + Map effectiveHeaders, Credentials credentials) { + CredentialTypeForMetrics credentialTypeForMetrics = + credentials == null + ? CredentialTypeForMetrics.DO_NOT_SEND + : credentials.getMetricsCredentialType(); + if (credentialTypeForMetrics != CredentialTypeForMetrics.DO_NOT_SEND) { + effectiveHeaders.computeIfPresent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + (key, value) -> value + " cred-type/" + credentialTypeForMetrics.getLabel()); + } return ImmutableMap.copyOf(effectiveHeaders); } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java index b5e54484dd..234fd4d19d 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientSettings.java @@ -112,6 +112,11 @@ public final WatchdogProvider getWatchdogProvider() { return stubSettings.getStreamWatchdogProvider(); } + /** Gets the API Key that should be used for authentication. */ + public final String getApiKey() { + return stubSettings.getApiKey(); + } + /** This method is obsolete. Use {@link #getWatchdogCheckIntervalDuration()} instead. */ @Nonnull @ObsoleteApi("Use getWatchdogCheckIntervalDuration() instead") @@ -144,6 +149,7 @@ public String toString() { .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckInterval()) .add("gdchApiAudience", getGdchApiAudience()) + .add("apiKey", getApiKey()) .toString(); } @@ -302,6 +308,21 @@ public B setGdchApiAudience(@Nullable String gdchApiAudience) { return self(); } + /** + * Sets the API key. The API key will get translated to an {@link + * com.google.auth.ApiKeyCredentials} and stored in {@link ClientContext}. + * + *

API Key authorization is not supported for every product. Please check the documentation + * for each product to confirm if it is supported. + * + *

Note: If you set an API key and {@link CredentialsProvider} in the same ClientSettings the + * API key will override any credentials provided. + */ + public B setApiKey(String apiKey) { + stubSettings.setApiKey(apiKey); + return self(); + } + /** * Gets the ExecutorProvider that was previously set on this Builder. This ExecutorProvider is * to use for running asynchronous API call logic (such as retries and long-running operations), @@ -364,6 +385,11 @@ public WatchdogProvider getWatchdogProvider() { return stubSettings.getStreamWatchdogProvider(); } + /** Gets the API Key that was previously set on this Builder. */ + public String getApiKey() { + return stubSettings.getApiKey(); + } + /** This method is obsolete. Use {@link #getWatchdogCheckIntervalDuration()} instead */ @Nullable @ObsoleteApi("Use getWatchdogCheckIntervalDuration() instead") @@ -405,6 +431,7 @@ public String toString() { .add("watchdogProvider", getWatchdogProvider()) .add("watchdogCheckInterval", getWatchdogCheckIntervalDuration()) .add("gdchApiAudience", getGdchApiAudience()) + .add("apiKey", getApiKey()) .toString(); } } diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java index efe0f517f5..dd6c199b35 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java @@ -32,6 +32,7 @@ import com.google.api.core.InternalApi; import com.google.api.gax.rpc.mtls.MtlsProvider; import com.google.auth.Credentials; +import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.auto.value.AutoValue; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; @@ -145,6 +146,11 @@ public void validateUniverseDomain( // GDC-H has no universe domain, return return; } + // (TODO: b/349488459) - Disable automatic requests to MDS until 01/2025 + // If MDS is required for Universe Domain, do not do any validation + if (credentials instanceof ComputeEngineCredentials) { + return; + } String credentialsUniverseDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE; // If credentials is not NoCredentialsProvider, use the Universe Domain inside Credentials if (credentials != null) { diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java index daeda4c445..03c9519e38 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java @@ -82,6 +82,7 @@ public abstract class StubSettings> { // Track if deprecated setExecutorProvider is called private boolean deprecatedExecutorProviderSet; @Nonnull private final EndpointContext endpointContext; + private final String apiKey; /** * Indicate when creating transport whether it is allowed to use mTLS endpoint instead of the @@ -107,6 +108,7 @@ protected StubSettings(Builder builder) { this.deprecatedExecutorProviderSet = builder.deprecatedExecutorProviderSet; this.gdchApiAudience = builder.gdchApiAudience; this.endpointContext = buildEndpointContext(builder); + this.apiKey = builder.apiKey; } /** @@ -234,6 +236,11 @@ public final String getGdchApiAudience() { return gdchApiAudience; } + /** Gets the API Key that should be used for authentication. */ + public final String getApiKey() { + return apiKey; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -252,6 +259,7 @@ public String toString() { .add("streamWatchdogCheckInterval", streamWatchdogCheckInterval) .add("tracerFactory", tracerFactory) .add("gdchApiAudience", gdchApiAudience) + .add("apiKey", apiKey) .toString(); } @@ -277,6 +285,7 @@ public abstract static class Builder< private boolean deprecatedExecutorProviderSet; private String universeDomain; private final EndpointContext endpointContext; + private String apiKey; /** * Indicate when creating transport whether it is allowed to use mTLS endpoint instead of the @@ -301,6 +310,7 @@ protected Builder(StubSettings settings) { this.tracerFactory = settings.tracerFactory; this.deprecatedExecutorProviderSet = settings.deprecatedExecutorProviderSet; this.gdchApiAudience = settings.gdchApiAudience; + this.apiKey = settings.apiKey; // The follow settings will be set to the original user configurations as the // EndpointContext will be rebuilt in the constructor. @@ -353,6 +363,7 @@ protected Builder(ClientContext clientContext) { this.mtlsEndpoint = null; this.switchToMtlsEndpointAllowed = false; this.universeDomain = null; + this.apiKey = null; // Attempt to create an empty, non-functioning EndpointContext by default. The client will // have // a valid EndpointContext with user configurations after the client has been initialized. @@ -574,6 +585,21 @@ public B setTracerFactory(@Nonnull ApiTracerFactory tracerFactory) { return self(); } + /** + * Sets the API key. The API key will get translated to an {@link + * com.google.auth.ApiKeyCredentials} and stored in {@link ClientContext}. + * + *

API Key authorization is not supported for every product. Please check the documentation + * for each product to confirm if it is supported. + * + *

Note: If you set an API key and {@link CredentialsProvider} in the same ClientSettings the + * API key will override any credentials provided. + */ + public B setApiKey(String apiKey) { + this.apiKey = apiKey; + return self(); + } + /** @deprecated Please use {@link #getBackgroundExecutorProvider()}. */ @Deprecated public ExecutorProvider getExecutorProvider() { @@ -616,6 +642,11 @@ public ApiClock getClock() { return clock; } + /** Gets the API Key that was previously set on this Builder. */ + public final String getApiKey() { + return apiKey; + } + /** * @return the resolved endpoint when the Builder was created. If invoked after * `StubSettings.newBuilder()` is called, it will return the clientSettingsEndpoint value. diff --git a/gax-java/gax/src/main/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentials.java b/gax-java/gax/src/main/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentials.java index 51bbade9a0..8c9d2c5799 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentials.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentials.java @@ -89,4 +89,9 @@ public boolean hasRequestMetadataOnly() { public void refresh() throws IOException { this.wrappedCredentials.refresh(); } + + @Override + public String getUniverseDomain() throws IOException { + return this.wrappedCredentials.getUniverseDomain(); + } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java index 5efce3fbe9..826864a49c 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientContextTest.java @@ -39,6 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.api.core.ApiClock; import com.google.api.gax.core.BackgroundResource; @@ -52,6 +53,8 @@ import com.google.api.gax.rpc.testing.FakeClientSettings; import com.google.api.gax.rpc.testing.FakeStubSettings; import com.google.api.gax.rpc.testing.FakeTransportChannel; +import com.google.auth.ApiKeyCredentials; +import com.google.auth.CredentialTypeForMetrics; import com.google.auth.Credentials; import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.auth.oauth2.GdchCredentials; @@ -205,9 +208,6 @@ public TransportChannelProvider withPoolSize(int size) { @Override public TransportChannel getTransportChannel() throws IOException { - if (needsCredentials()) { - throw new IllegalStateException("Needs Credentials"); - } transport.setExecutor(executor); return transport; } @@ -679,6 +679,86 @@ void testUserAgentConcat() throws Exception { .containsEntry("user-agent", "user-supplied-agent internal-agent"); } + @Test + void testApiClientHeaderAppendsCredType() throws Exception { + GoogleCredentials googleCredentials = Mockito.mock(GoogleCredentials.class); + when(googleCredentials.getMetricsCredentialType()) + .thenReturn(CredentialTypeForMetrics.USER_CREDENTIALS); + + Map headers = + setupTestForCredentialTokenUsageMetricsAndGetTransportChannelHeaders( + FixedCredentialsProvider.create(googleCredentials), + FixedHeaderProvider.create("x-goog-api-client", "internal-agent")); + + assertThat(headers).containsEntry("x-goog-api-client", "internal-agent cred-type/u"); + } + + @Test + void testApiClientHeaderDoNotAppendsCredType_whenNoApiClientHeader() throws Exception { + GoogleCredentials googleCredentials = Mockito.mock(GoogleCredentials.class); + when(googleCredentials.getMetricsCredentialType()) + .thenReturn(CredentialTypeForMetrics.USER_CREDENTIALS); + + Map headers = + setupTestForCredentialTokenUsageMetricsAndGetTransportChannelHeaders( + FixedCredentialsProvider.create(googleCredentials), + FixedHeaderProvider.create("some-other-header", "internal-agent")); + + assertThat(headers).doesNotContainKey("x-goog-api-client"); + assertThat(headers).containsEntry("some-other-header", "internal-agent"); + } + + @Test + void testApiClientHeaderDoNotAppendsCredType_whenNullCredentials() throws IOException { + Map headers = + setupTestForCredentialTokenUsageMetricsAndGetTransportChannelHeaders( + NoCredentialsProvider.create(), + FixedHeaderProvider.create("x-goog-api-client", "internal-agent")); + + assertThat(headers).containsKey("x-goog-api-client"); + assertThat(headers.get("x-goog-api-client")).doesNotContain("cred-type/"); + } + + @Test + void testApiClientHeaderDoNotAppendsCredType_whenCredTypeDoNotSend() throws Exception { + GoogleCredentials googleCredentials = Mockito.mock(GoogleCredentials.class); + when(googleCredentials.getMetricsCredentialType()) + .thenReturn(CredentialTypeForMetrics.DO_NOT_SEND); + + Map headers = + setupTestForCredentialTokenUsageMetricsAndGetTransportChannelHeaders( + FixedCredentialsProvider.create(googleCredentials), + FixedHeaderProvider.create("x-goog-api-client", "internal-agent")); + + assertThat(headers).containsKey("x-goog-api-client"); + assertThat(headers.get("x-goog-api-client")).doesNotContain("cred-type/"); + } + + private Map setupTestForCredentialTokenUsageMetricsAndGetTransportChannelHeaders( + CredentialsProvider credentialsProvider, HeaderProvider headerProvider) throws IOException { + TransportChannelProvider transportChannelProvider = + new FakeTransportProvider( + FakeTransportChannel.create(new FakeChannel()), + null, + true, + null, + null, + DEFAULT_ENDPOINT); + + ClientSettings.Builder builder = + new FakeClientSettings.Builder() + .setExecutorProvider( + FixedExecutorProvider.create(Mockito.mock(ScheduledExecutorService.class))) + .setTransportChannelProvider(transportChannelProvider) + .setCredentialsProvider(credentialsProvider) + .setInternalHeaderProvider(headerProvider); + + ClientContext clientContext = ClientContext.create(builder.build()); + FakeTransportChannel transportChannel = + (FakeTransportChannel) clientContext.getTransportChannel(); + return transportChannel.getHeaders(); + } + private static String endpoint = "https://foo.googleapis.com"; private static String mtlsEndpoint = "https://foo.mtls.googleapis.com"; @@ -1074,4 +1154,46 @@ public void testStreamWatchdogInterval_backportMethodsBehaveCorrectly() { ct -> ct.getStreamWatchdogCheckIntervalDuration(), ct -> ct.getStreamWatchdogCheckInterval()); } + + @Test + void testSetApiKey_createsApiCredentials() throws IOException { + String apiKey = "key"; + FakeStubSettings.Builder builder = new FakeStubSettings.Builder(); + InterceptingExecutor executor = new InterceptingExecutor(1); + FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); + FakeTransportProvider transportProvider = + new FakeTransportProvider( + transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); + builder.setTransportChannelProvider(transportProvider); + HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); + Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); + builder.setHeaderProvider(headerProvider); + builder.setApiKey(apiKey); + + ClientContext context = ClientContext.create(builder.build()); + + FakeCallContext fakeCallContext = (FakeCallContext) context.getDefaultCallContext(); + assertThat(fakeCallContext.getCredentials()).isInstanceOf(ApiKeyCredentials.class); + } + + @Test + void testSetApiKey_withDefaultCredentials_overridesCredentials() throws IOException { + String apiKey = "key"; + FakeStubSettings.Builder builder = FakeStubSettings.newBuilder(); + InterceptingExecutor executor = new InterceptingExecutor(1); + FakeTransportChannel transportChannel = FakeTransportChannel.create(new FakeChannel()); + FakeTransportProvider transportProvider = + new FakeTransportProvider( + transportChannel, executor, true, ImmutableMap.of(), null, DEFAULT_ENDPOINT); + builder.setTransportChannelProvider(transportProvider); + HeaderProvider headerProvider = Mockito.mock(HeaderProvider.class); + Mockito.when(headerProvider.getHeaders()).thenReturn(ImmutableMap.of()); + builder.setHeaderProvider(headerProvider); + builder.setApiKey(apiKey); + + ClientContext context = ClientContext.create(builder.build()); + + FakeCallContext fakeCallContext = (FakeCallContext) context.getDefaultCallContext(); + assertThat(fakeCallContext.getCredentials()).isInstanceOf(ApiKeyCredentials.class); + } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientSettingsTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientSettingsTest.java index 3e99f7471c..e48df7af54 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientSettingsTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/ClientSettingsTest.java @@ -120,6 +120,7 @@ void testEmptyBuilder() throws Exception { Truth.assertThat(builder.getWatchdogCheckIntervalDuration()) .isGreaterThan(java.time.Duration.ZERO); Truth.assertThat(builder.getQuotaProjectId()).isNull(); + Truth.assertThat(builder.getApiKey()).isNull(); FakeClientSettings settings = builder.build(); Truth.assertThat(settings.getExecutorProvider()) @@ -150,6 +151,7 @@ void testEmptyBuilder() throws Exception { Truth.assertThat(settingsString).contains("watchdogProvider"); Truth.assertThat(settingsString).contains("watchdogCheckInterval"); Truth.assertThat(settingsString).contains(("quotaProjectId")); + Truth.assertThat(settingsString).contains(("apiKey")); } @Test @@ -165,6 +167,7 @@ void testBuilder() throws Exception { WatchdogProvider watchdogProvider = Mockito.mock(WatchdogProvider.class); java.time.Duration watchdogCheckInterval = java.time.Duration.ofSeconds(13); String quotaProjectId = "test_quota_project_id"; + String apiKey = "api_key"; builder.setExecutorProvider(executorProvider); builder.setTransportChannelProvider(transportProvider); @@ -175,6 +178,7 @@ void testBuilder() throws Exception { builder.setWatchdogProvider(watchdogProvider); builder.setWatchdogCheckIntervalDuration(watchdogCheckInterval); builder.setQuotaProjectId(quotaProjectId); + builder.setApiKey(apiKey); // For backward compatibility, backgroundExecutorProvider is set to executorProvider Truth.assertThat(builder.getExecutorProvider()).isSameInstanceAs(executorProvider); @@ -188,6 +192,7 @@ void testBuilder() throws Exception { Truth.assertThat(builder.getWatchdogCheckIntervalDuration()) .isSameInstanceAs(watchdogCheckInterval); Truth.assertThat(builder.getQuotaProjectId()).isEqualTo(quotaProjectId); + Truth.assertThat(builder.getApiKey()).isEqualTo(apiKey); String builderString = builder.toString(); Truth.assertThat(builderString).contains("executorProvider"); @@ -200,6 +205,7 @@ void testBuilder() throws Exception { Truth.assertThat(builderString).contains("watchdogProvider"); Truth.assertThat(builderString).contains("watchdogCheckInterval"); Truth.assertThat(builderString).contains("quotaProjectId"); + Truth.assertThat(builderString).contains("apiKey"); } @Test diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java index 98a32bc05a..3276e4a73e 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java @@ -29,12 +29,14 @@ */ package com.google.api.gax.rpc; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.rpc.mtls.MtlsProvider; import com.google.api.gax.rpc.testing.FakeMtlsProvider; import com.google.auth.Credentials; +import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.common.truth.Truth; import io.grpc.Status; import java.io.IOException; @@ -437,4 +439,19 @@ void hasValidUniverseDomain_credentialsInGDU_configNonGDU() throws IOException { UnauthenticatedException.class, () -> endpointContext.validateUniverseDomain(credentials, statusCode)); } + + // (TODO: b/349488459) - Disable automatic requests to MDS until 01/2025 + // Test is to ensure that no validation is being run for ComputeEngineCredentials + @Test + void hasValidUniverseDomain_computeEngineCredentials_noValidationOnUniverseDomain() + throws IOException { + Credentials credentials = Mockito.mock(ComputeEngineCredentials.class); + Mockito.when(credentials.getUniverseDomain()).thenReturn(Credentials.GOOGLE_DEFAULT_UNIVERSE); + EndpointContext endpointContext = + defaultEndpointContextBuilder + // Set a custom Universe Domain that doesn't match + .setUniverseDomain("test.com") + .build(); + assertDoesNotThrow(() -> endpointContext.validateUniverseDomain(credentials, statusCode)); + } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentialsTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentialsTest.java index 9a02bd13dd..0d9d357115 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentialsTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/internal/QuotaProjectIdHidingCredentialsTest.java @@ -101,4 +101,15 @@ void quotaProjectIdHidingCredentials_getAuthenticationType() throws IOException Mockito.verify(credentials, Mockito.atLeastOnce()).refresh(); } + + @Test + void quotaProjectIdHidingCredentials_getUniverseDomain() throws IOException { + Credentials credentials = Mockito.mock(GoogleCredentials.class); + Mockito.when(credentials.getUniverseDomain()).thenReturn("example.com"); + + QuotaProjectIdHidingCredentials quotaProjectIdHidingCredentials = + new QuotaProjectIdHidingCredentials(credentials); + + assertEquals(quotaProjectIdHidingCredentials.getUniverseDomain(), "example.com"); + } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeStubSettings.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeStubSettings.java index c5f0cc81f4..4004a24404 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeStubSettings.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeStubSettings.java @@ -30,17 +30,26 @@ package com.google.api.gax.rpc.testing; import com.google.api.core.InternalApi; +import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.StubSettings; +import com.google.common.collect.ImmutableList; import java.io.IOException; @InternalApi("for testing") public class FakeStubSettings extends StubSettings { + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder().build(); + private FakeStubSettings(Builder builder) throws IOException { super(builder); } + public static Builder newBuilder() { + return Builder.createDefault(); + } + @Override public String getServiceName() { return "test"; @@ -69,5 +78,20 @@ public Builder() { public com.google.api.gax.rpc.testing.FakeStubSettings build() throws IOException { return new com.google.api.gax.rpc.testing.FakeStubSettings(this); } + + /** Returns default settings values. */ + public static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder()); + return builder; + } + + /** Returns default credentials provider. */ + public static GoogleCredentialsProvider defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true) + .build(); + } } } diff --git a/gax-java/pom.xml b/gax-java/pom.xml index a7e173cfde..2c8dcc34da 100644 --- a/gax-java/pom.xml +++ b/gax-java/pom.xml @@ -4,14 +4,14 @@ com.google.api gax-parent pom - 2.54.1 + 2.55.0 GAX (Google Api eXtensions) for Java (Parent) Google Api eXtensions for Java (Parent) com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -50,7 +50,7 @@ com.google.api api-common - 2.37.1 + 2.38.0 com.google.auth @@ -98,24 +98,24 @@ com.google.api gax - 2.54.1 + 2.55.0 com.google.api gax - 2.54.1 + 2.55.0 test-jar testlib com.google.api.grpc proto-google-common-protos - 2.45.1 + 2.46.0 com.google.api.grpc grpc-google-common-protos - 2.45.1 + 2.46.0 io.grpc diff --git a/generation_config.yaml b/generation_config.yaml index 089160fb1c..55bd2c6314 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,4 +1,4 @@ -googleapis_commitish: 5c181aaf78bd1ae2e08c3a2971cd9e87b6e00986 +googleapis_commitish: b6a27d13a2f0223051ef720e4e9d0d52323560e6 # the libraries are ordered with respect to library name, which is # java-{library.library_name} or java-{library.api-shortname} when # library.library_name is not defined. diff --git a/java-common-protos/grpc-google-common-protos/pom.xml b/java-common-protos/grpc-google-common-protos/pom.xml index 516d6b2e5e..f14a7791cc 100644 --- a/java-common-protos/grpc-google-common-protos/pom.xml +++ b/java-common-protos/grpc-google-common-protos/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-common-protos - 2.45.1 + 2.46.0 grpc-google-common-protos GRPC library for grpc-google-common-protos com.google.api.grpc google-common-protos-parent - 2.45.1 + 2.46.0 diff --git a/java-common-protos/pom.xml b/java-common-protos/pom.xml index aba56f536e..e6a27843a8 100644 --- a/java-common-protos/pom.xml +++ b/java-common-protos/pom.xml @@ -4,7 +4,7 @@ com.google.api.grpc google-common-protos-parent pom - 2.45.1 + 2.46.0 Google Common Protos Parent Java idiomatic client for Google Cloud Platform services. @@ -13,7 +13,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -61,7 +61,7 @@ com.google.cloud third-party-dependencies - 3.36.1 + 3.37.0 pom import @@ -75,7 +75,7 @@ com.google.api.grpc grpc-google-common-protos - 2.45.1 + 2.46.0 io.grpc @@ -87,7 +87,7 @@ com.google.api.grpc proto-google-common-protos - 2.45.1 + 2.46.0 com.google.guava diff --git a/java-common-protos/proto-google-common-protos/pom.xml b/java-common-protos/proto-google-common-protos/pom.xml index e7cc2eaa48..d6a8babcae 100644 --- a/java-common-protos/proto-google-common-protos/pom.xml +++ b/java-common-protos/proto-google-common-protos/pom.xml @@ -3,13 +3,13 @@ 4.0.0 com.google.api.grpc proto-google-common-protos - 2.45.1 + 2.46.0 proto-google-common-protos PROTO library for proto-google-common-protos com.google.api.grpc google-common-protos-parent - 2.45.1 + 2.46.0 diff --git a/java-core/google-cloud-core-bom/pom.xml b/java-core/google-cloud-core-bom/pom.xml index 58fc917f55..f913ca9a4e 100644 --- a/java-core/google-cloud-core-bom/pom.xml +++ b/java-core/google-cloud-core-bom/pom.xml @@ -3,13 +3,13 @@ 4.0.0 com.google.cloud google-cloud-core-bom - 2.44.1 + 2.45.0 pom com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../../gapic-generator-java-pom-parent @@ -23,17 +23,17 @@ com.google.cloud google-cloud-core - 2.44.1 + 2.45.0 com.google.cloud google-cloud-core-grpc - 2.44.1 + 2.45.0 com.google.cloud google-cloud-core-http - 2.44.1 + 2.45.0 diff --git a/java-core/google-cloud-core-grpc/pom.xml b/java-core/google-cloud-core-grpc/pom.xml index d55e952667..bb6f207460 100644 --- a/java-core/google-cloud-core-grpc/pom.xml +++ b/java-core/google-cloud-core-grpc/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-core-grpc - 2.44.1 + 2.45.0 jar Google Cloud Core gRPC @@ -12,7 +12,7 @@ com.google.cloud google-cloud-core-parent - 2.44.1 + 2.45.0 google-cloud-core-grpc diff --git a/java-core/google-cloud-core-http/pom.xml b/java-core/google-cloud-core-http/pom.xml index 1adffec65c..40e4804403 100644 --- a/java-core/google-cloud-core-http/pom.xml +++ b/java-core/google-cloud-core-http/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-core-http - 2.44.1 + 2.45.0 jar Google Cloud Core HTTP @@ -12,7 +12,7 @@ com.google.cloud google-cloud-core-parent - 2.44.1 + 2.45.0 google-cloud-core-http diff --git a/java-core/google-cloud-core/pom.xml b/java-core/google-cloud-core/pom.xml index 5e0bc1d913..b15e18e90c 100644 --- a/java-core/google-cloud-core/pom.xml +++ b/java-core/google-cloud-core/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-core - 2.44.1 + 2.45.0 jar Google Cloud Core @@ -12,7 +12,7 @@ com.google.cloud google-cloud-core-parent - 2.44.1 + 2.45.0 google-cloud-core diff --git a/java-core/pom.xml b/java-core/pom.xml index a3e7d4ff01..c45011ee29 100644 --- a/java-core/pom.xml +++ b/java-core/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-core-parent pom - 2.44.1 + 2.45.0 Google Cloud Core Parent Java idiomatic client for Google Cloud Platform services. @@ -13,7 +13,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -33,7 +33,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.36.1 + 3.37.0 pom import diff --git a/java-iam/grpc-google-iam-v1/pom.xml b/java-iam/grpc-google-iam-v1/pom.xml index 8dae78fe1b..8d15ee1a5b 100644 --- a/java-iam/grpc-google-iam-v1/pom.xml +++ b/java-iam/grpc-google-iam-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-iam-v1 - 1.40.1 + 1.41.0 grpc-google-iam-v1 GRPC library for grpc-google-iam-v1 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-iam/grpc-google-iam-v2/pom.xml b/java-iam/grpc-google-iam-v2/pom.xml index 67af13d6bb..16f4f38b3e 100644 --- a/java-iam/grpc-google-iam-v2/pom.xml +++ b/java-iam/grpc-google-iam-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-iam-v2 - 1.40.1 + 1.41.0 grpc-google-iam-v2 GRPC library for proto-google-iam-v2 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-iam/grpc-google-iam-v2beta/pom.xml b/java-iam/grpc-google-iam-v2beta/pom.xml index d22aa91876..a69d2b2f9f 100644 --- a/java-iam/grpc-google-iam-v2beta/pom.xml +++ b/java-iam/grpc-google-iam-v2beta/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-iam-v2beta - 1.40.1 + 1.41.0 grpc-google-iam-v2beta GRPC library for proto-google-iam-v1 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-iam/pom.xml b/java-iam/pom.xml index bae0163891..6c7301fa02 100644 --- a/java-iam/pom.xml +++ b/java-iam/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-iam-parent pom - 1.40.1 + 1.41.0 Google IAM Parent Java idiomatic client for Google Cloud Platform services. @@ -13,7 +13,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -60,7 +60,7 @@ com.google.cloud third-party-dependencies - 3.36.1 + 3.37.0 pom import @@ -88,44 +88,44 @@ com.google.api gax-bom - 2.54.1 + 2.55.0 pom import com.google.api.grpc proto-google-iam-v2 - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v2 - 1.40.1 + 1.41.0 com.google.api.grpc proto-google-common-protos - 2.45.1 + 2.46.0 com.google.api.grpc proto-google-iam-v2beta - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v1 - 1.40.1 + 1.41.0 com.google.api.grpc grpc-google-iam-v2beta - 1.40.1 + 1.41.0 com.google.api.grpc proto-google-iam-v1 - 1.40.1 + 1.41.0 javax.annotation diff --git a/java-iam/proto-google-iam-v1/pom.xml b/java-iam/proto-google-iam-v1/pom.xml index 5abf9490b6..82c3236340 100644 --- a/java-iam/proto-google-iam-v1/pom.xml +++ b/java-iam/proto-google-iam-v1/pom.xml @@ -3,13 +3,13 @@ 4.0.0 com.google.api.grpc proto-google-iam-v1 - 1.40.1 + 1.41.0 proto-google-iam-v1 PROTO library for proto-google-iam-v1 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-iam/proto-google-iam-v2/pom.xml b/java-iam/proto-google-iam-v2/pom.xml index 909f7fbfec..89b21be4f2 100644 --- a/java-iam/proto-google-iam-v2/pom.xml +++ b/java-iam/proto-google-iam-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-iam-v2 - 1.40.1 + 1.41.0 proto-google-iam-v2 Proto library for proto-google-iam-v1 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-iam/proto-google-iam-v2beta/pom.xml b/java-iam/proto-google-iam-v2beta/pom.xml index f189969584..826887b14e 100644 --- a/java-iam/proto-google-iam-v2beta/pom.xml +++ b/java-iam/proto-google-iam-v2beta/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-iam-v2beta - 1.40.1 + 1.41.0 proto-google-iam-v2beta Proto library for proto-google-iam-v1 com.google.cloud google-iam-parent - 1.40.1 + 1.41.0 diff --git a/java-shared-dependencies/README.md b/java-shared-dependencies/README.md index 501f11178d..64dff9f91c 100644 --- a/java-shared-dependencies/README.md +++ b/java-shared-dependencies/README.md @@ -14,7 +14,7 @@ If you are using Maven, add this to the `dependencyManagement` section. com.google.cloud google-cloud-shared-dependencies - 3.36.1 + 3.37.0 pom import diff --git a/java-shared-dependencies/dependency-analyzer/pom.xml b/java-shared-dependencies/dependency-analyzer/pom.xml index 3254fe7eef..fb2aa307ac 100644 --- a/java-shared-dependencies/dependency-analyzer/pom.xml +++ b/java-shared-dependencies/dependency-analyzer/pom.xml @@ -62,13 +62,13 @@ com.google.guava guava - 33.3.0-jre + 33.3.1-jre org.mockito mockito-core - 5.13.0 + 5.14.1 test diff --git a/java-shared-dependencies/dependency-convergence-check/pom.xml b/java-shared-dependencies/dependency-convergence-check/pom.xml index 069905305c..ce285dcea5 100644 --- a/java-shared-dependencies/dependency-convergence-check/pom.xml +++ b/java-shared-dependencies/dependency-convergence-check/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud shared-dependencies-dependency-convergence-test - 3.36.1 + 3.37.0 Dependency convergence test for certain artifacts in Google Cloud Shared Dependencies An dependency convergence test case for the shared dependencies BOM. A failure of this test case means diff --git a/java-shared-dependencies/first-party-dependencies/pom.xml b/java-shared-dependencies/first-party-dependencies/pom.xml index 4083da5cfc..18f2c1679d 100644 --- a/java-shared-dependencies/first-party-dependencies/pom.xml +++ b/java-shared-dependencies/first-party-dependencies/pom.xml @@ -6,7 +6,7 @@ com.google.cloud first-party-dependencies pom - 3.36.1 + 3.37.0 Google Cloud First-party Shared Dependencies Shared first-party dependencies for Google Cloud Java libraries. @@ -15,7 +15,7 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 @@ -33,7 +33,7 @@ com.google.api gapic-generator-java-bom - 2.46.1 + 2.47.0 pom import @@ -45,7 +45,7 @@ com.google.cloud google-cloud-core-bom - 2.44.1 + 2.45.0 pom import @@ -69,13 +69,13 @@ com.google.cloud google-cloud-core - 2.44.1 + 2.45.0 test-jar com.google.cloud google-cloud-core - 2.44.1 + 2.45.0 tests diff --git a/java-shared-dependencies/pom.xml b/java-shared-dependencies/pom.xml index 79a1bd15e0..a17c36b278 100644 --- a/java-shared-dependencies/pom.xml +++ b/java-shared-dependencies/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-shared-dependencies pom - 3.36.1 + 3.37.0 first-party-dependencies third-party-dependencies @@ -17,7 +17,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../gapic-generator-java-pom-parent @@ -31,14 +31,14 @@ com.google.cloud first-party-dependencies - 3.36.1 + 3.37.0 pom import com.google.cloud third-party-dependencies - 3.36.1 + 3.37.0 pom import diff --git a/java-shared-dependencies/third-party-dependencies/pom.xml b/java-shared-dependencies/third-party-dependencies/pom.xml index 2ffb57ad8c..49473690c6 100644 --- a/java-shared-dependencies/third-party-dependencies/pom.xml +++ b/java-shared-dependencies/third-party-dependencies/pom.xml @@ -6,7 +6,7 @@ com.google.cloud third-party-dependencies pom - 3.36.1 + 3.37.0 Google Cloud Third-party Shared Dependencies Shared third-party dependencies for Google Cloud Java libraries. @@ -15,7 +15,7 @@ com.google.api gapic-generator-java-pom-parent - 2.46.1 + 2.47.0 ../../gapic-generator-java-pom-parent @@ -27,8 +27,8 @@ 1.24 0.31.1 3.0.2 - 2.17.2 - 2.32.0 + 2.18.0 + 2.33.0 1.17.1 4.4.16 4.5.14 diff --git a/java-shared-dependencies/upper-bound-check/pom.xml b/java-shared-dependencies/upper-bound-check/pom.xml index 2cddd53e6a..4978d1ea48 100644 --- a/java-shared-dependencies/upper-bound-check/pom.xml +++ b/java-shared-dependencies/upper-bound-check/pom.xml @@ -4,7 +4,7 @@ com.google.cloud shared-dependencies-upper-bound-test pom - 3.36.1 + 3.37.0 Upper bound test for Google Cloud Shared Dependencies An upper bound test case for the shared dependencies BOM. A failure of this test case means @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 @@ -30,7 +30,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.36.1 + 3.37.0 pom import diff --git a/library_generation/owlbot/templates/java_library/renovate.json b/library_generation/owlbot/templates/java_library/renovate.json index 57929084fd..cb92a78173 100644 --- a/library_generation/owlbot/templates/java_library/renovate.json +++ b/library_generation/owlbot/templates/java_library/renovate.json @@ -44,6 +44,16 @@ ], "depNameTemplate": "com.google.cloud:sdk-platform-java-config", "datasourceTemplate": "maven" + }, + { + "fileMatch": [ + "^.github/workflows/hermetic_library_generation.yaml$" + ], + "matchStrings": [ + "uses: googleapis/sdk-platform-java/.github/scripts@v(?.+?)\\n" + ], + "depNameTemplate": "com.google.api:gapic-generator-java", + "datasourceTemplate": "maven" } ], "packageRules": [ @@ -104,6 +114,13 @@ "^com.fasterxml.jackson.core" ], "groupName": "jackson dependencies" + }, + { + "matchPackagePatterns": [ + "^com.google.api:gapic-generator-java", + "^com.google.cloud:sdk-platform-java-config" + ], + "groupName": "SDK platform Java dependencies" } ], "semanticCommits": true, diff --git a/library_generation/requirements.in b/library_generation/requirements.in index 0d95852e61..e5e6487246 100644 --- a/library_generation/requirements.in +++ b/library_generation/requirements.in @@ -3,21 +3,21 @@ absl-py==2.1.0 attr==0.3.2 attrs==23.2.0 -black==24.4.2 +black==24.8.0 click==8.1.7 gitdb==4.0.11 GitPython==3.1.43 -lxml==5.2.2 +lxml==5.3.0 MarkupSafe==2.1.5 mypy-extensions==1.0.0 packaging==23.2 pathspec==0.12.1 -PyYAML==6.0.1 +PyYAML==6.0.2 smmap==5.0.1 typing==3.7.4.3 parameterized==0.9.0 # used in parameterized test colorlog==6.8.2 -watchdog==4.0.1 +watchdog==4.0.2 nox==2024.4.15 requests==2.32.3 setuptools==65.5.1 diff --git a/library_generation/requirements.txt b/library_generation/requirements.txt index fd987f45db..5407b68e05 100644 --- a/library_generation/requirements.txt +++ b/library_generation/requirements.txt @@ -415,7 +415,7 @@ platformdirs==4.3.6 \ # via # black # virtualenv -PyYAML==6.0.2 \ +pyyaml==6.0.2 \ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ @@ -498,9 +498,9 @@ urllib3==2.2.3 \ --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 # via requests -virtualenv==20.26.5 \ - --hash=sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6 \ - --hash=sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4 +virtualenv==20.26.6 \ + --hash=sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48 \ + --hash=sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2 # via nox watchdog==4.0.2 \ --hash=sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4 \ diff --git a/sdk-platform-java-config/pom.xml b/sdk-platform-java-config/pom.xml index e285868239..14ec0603ba 100644 --- a/sdk-platform-java-config/pom.xml +++ b/sdk-platform-java-config/pom.xml @@ -4,7 +4,7 @@ com.google.cloud sdk-platform-java-config pom - 3.36.1 + 3.37.0 SDK Platform For Java Configurations Shared build configuration for Google Cloud Java libraries. @@ -13,10 +13,10 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 - 3.36.1 + 3.37.0 \ No newline at end of file diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiKeyCredentials.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiKeyCredentials.java new file mode 100644 index 0000000000..5867bcfea9 --- /dev/null +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITApiKeyCredentials.java @@ -0,0 +1,219 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.showcase.v1beta1.it; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.gax.rpc.FixedHeaderProvider; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.auth.http.AuthHttpConstants; +import com.google.common.collect.ImmutableList; +import com.google.showcase.v1beta1.EchoClient; +import com.google.showcase.v1beta1.EchoRequest; +import com.google.showcase.v1beta1.EchoSettings; +import com.google.showcase.v1beta1.it.util.GrpcCapturingClientInterceptor; +import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor; +import com.google.showcase.v1beta1.it.util.TestClientInitializer; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Metadata; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Test suite to confirm a client can be instantiated with API key credentials and correct + * authorization sent via headers to back end + */ +class ITApiKeyCredentials { + + private static final String API_KEY = "fake_api_key"; + private static final String API_KEY_AUTH_HEADER = "x-goog-api-key"; + private static final String HTTP_RESPONSE_HEADER_STRING = + "x-showcase-request-" + API_KEY_AUTH_HEADER; + private static final String GRPC_ENDPOINT = "localhost:7469"; + private static final String HTTP_ENDPOINT = "http://localhost:7469"; + + private static HttpJsonCapturingClientInterceptor httpJsonInterceptor; + private static EchoClient grpcClient; + private static EchoClient httpJsonClient; + private static GrpcCapturingClientInterceptor grpcInterceptor; + + @BeforeEach + void setup() throws IOException { + grpcInterceptor = new GrpcCapturingClientInterceptor(); + httpJsonInterceptor = new HttpJsonCapturingClientInterceptor(); + } + + @AfterEach + void tearDown() throws InterruptedException { + if (httpJsonClient != null) { + httpJsonClient.close(); + httpJsonClient.awaitTermination( + TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + } + if (grpcClient != null) { + grpcClient.close(); + grpcClient.awaitTermination( + TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + } + } + + @Test + void testCreateGrpcClient_withApiKey_sendsApiHeaderToServer() throws IOException { + Metadata.Key apiKeyAuthHeader = + Metadata.Key.of(API_KEY_AUTH_HEADER, Metadata.ASCII_STRING_MARSHALLER); + Metadata.Key defaultAuthorizationHeader = + Metadata.Key.of(AuthHttpConstants.AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER); + EchoSettings.Builder echoBuilder = + EchoSettings.newBuilder() + .setApiKey(API_KEY) + .setEndpoint(GRPC_ENDPOINT) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .setInterceptorProvider(() -> ImmutableList.of(grpcInterceptor)) + .build()); + EchoSettings settings = echoBuilder.build(); + grpcClient = EchoClient.create(settings); + + grpcClient.echo(EchoRequest.newBuilder().build()); + + assertThat(echoBuilder.getApiKey()).isEqualTo(API_KEY); + assertThat(settings.getApiKey()).isEqualTo(API_KEY); + String headerValue = grpcInterceptor.metadata.get(apiKeyAuthHeader); + assertThat(headerValue).isEqualTo(API_KEY); + String defaultAuthorizationHeaderValue = + grpcInterceptor.metadata.get(defaultAuthorizationHeader); + assertThat(defaultAuthorizationHeaderValue).isNull(); + } + + @Test + void testCreateGrpcClient_withApiKeySetViaSetterAndHeader_dedupsHeader() throws IOException { + String apiHeaderKey = "fake_api_key_2"; + Metadata.Key apiKeyAuthHeader = + Metadata.Key.of(API_KEY_AUTH_HEADER, Metadata.ASCII_STRING_MARSHALLER); + Metadata.Key defaultAuthorizationHeader = + Metadata.Key.of(AuthHttpConstants.AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER); + Map header = + new HashMap() { + { + put(API_KEY_AUTH_HEADER, apiHeaderKey); + } + }; + FixedHeaderProvider headerProvider = FixedHeaderProvider.create(header); + + TransportChannelProvider transportChannelProvider = + EchoSettings.defaultGrpcTransportProviderBuilder() + .setHeaderProvider(headerProvider) + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .setInterceptorProvider(() -> ImmutableList.of(grpcInterceptor)) + .build(); + EchoSettings settings = + EchoSettings.newBuilder() + .setApiKey(API_KEY) + .setEndpoint(GRPC_ENDPOINT) + .setTransportChannelProvider(transportChannelProvider) + .build(); + grpcClient = EchoClient.create(settings); + + grpcClient.echo(EchoRequest.newBuilder().build()); + + Iterable matchingHeaders = grpcInterceptor.metadata.getAll(apiKeyAuthHeader); + List matchingHeadersList = + StreamSupport.stream(matchingHeaders.spliterator(), false).collect(Collectors.toList()); + + String headerValue = matchingHeadersList.get(0); + assertThat(headerValue).isEqualTo(API_KEY); + assertThat(matchingHeadersList.size()).isEqualTo(1); + } + + @Test + void testCreateHttpClient_withApiKey_sendsApiHeaderToServer() throws Exception { + EchoSettings httpJsonEchoSettings = + EchoSettings.newHttpJsonBuilder() + .setApiKey(API_KEY) + .setTransportChannelProvider( + EchoSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport( + new NetHttpTransport.Builder().doNotValidateCertificate().build()) + .setEndpoint(HTTP_ENDPOINT) + .setInterceptorProvider(() -> ImmutableList.of(httpJsonInterceptor)) + .build()) + .build(); + httpJsonClient = EchoClient.create(httpJsonEchoSettings); + + httpJsonClient.echo(EchoRequest.newBuilder().build()); + + ArrayList headerValues = + (ArrayList) + httpJsonInterceptor.metadata.getHeaders().get(HTTP_RESPONSE_HEADER_STRING); + String headerValue = headerValues.get(0); + assertThat(headerValue).isEqualTo(API_KEY); + } + + @Test + void testCreateHttpClient_withApiKeySetViaSetterAndHeader_dedupsHeader() throws Exception { + String apiHeaderKey = "fake_api_key_2"; + Metadata.Key apiKeyAuthHeader = + Metadata.Key.of(API_KEY_AUTH_HEADER, Metadata.ASCII_STRING_MARSHALLER); + Metadata.Key defaultAuthorizationHeader = + Metadata.Key.of(AuthHttpConstants.AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER); + Map header = + new HashMap() { + { + put(API_KEY_AUTH_HEADER, apiHeaderKey); + } + }; + FixedHeaderProvider headerProvider = FixedHeaderProvider.create(header); + + TransportChannelProvider transportChannelProvider = + EchoSettings.defaultHttpJsonTransportProviderBuilder() + .setHeaderProvider(headerProvider) + .setInterceptorProvider(() -> ImmutableList.of(httpJsonInterceptor)) + .build(); + EchoSettings httpJsonEchoSettings = + EchoSettings.newHttpJsonBuilder() + .setApiKey(API_KEY) + .setTransportChannelProvider( + EchoSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport( + new NetHttpTransport.Builder().doNotValidateCertificate().build()) + .setEndpoint(HTTP_ENDPOINT) + .setInterceptorProvider(() -> ImmutableList.of(httpJsonInterceptor)) + .build()) + .build(); + httpJsonClient = EchoClient.create(httpJsonEchoSettings); + + httpJsonClient.echo(EchoRequest.newBuilder().build()); + + ArrayList headerValues = + (ArrayList) + httpJsonInterceptor.metadata.getHeaders().get(HTTP_RESPONSE_HEADER_STRING); + String headerValue = headerValues.get(0); + assertThat(headerValue).isEqualTo(API_KEY); + assertThat(headerValues.size()).isEqualTo(1); + } +} 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/ITApiVersionHeaders.java index 5f892c5886..cb823db498 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/ITApiVersionHeaders.java @@ -24,6 +24,8 @@ import com.google.api.gax.rpc.StubSettings; import com.google.common.collect.ImmutableList; import com.google.showcase.v1beta1.*; +import com.google.showcase.v1beta1.it.util.GrpcCapturingClientInterceptor; +import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor; import com.google.showcase.v1beta1.it.util.TestClientInitializer; import com.google.showcase.v1beta1.stub.ComplianceStubSettings; import com.google.showcase.v1beta1.stub.EchoStubSettings; @@ -52,102 +54,6 @@ class ITApiVersionHeaders { "Header provider can't override the header: " + ApiClientHeaderProvider.API_VERSION_HEADER_KEY; - // Implement a client interceptor to retrieve the trailing metadata from response. - private static class GrpcCapturingClientInterceptor implements ClientInterceptor { - private Metadata metadata; - - @Override - public ClientCall interceptCall( - MethodDescriptor method, final CallOptions callOptions, Channel next) { - ClientCall call = next.newCall(method, callOptions); - return new ForwardingClientCall.SimpleForwardingClientCall(call) { - @Override - public void start(Listener responseListener, Metadata headers) { - Listener wrappedListener = - new SimpleForwardingClientCallListener(responseListener) { - @Override - public void onClose(Status status, Metadata trailers) { - if (status.isOk()) { - metadata = trailers; - } - super.onClose(status, trailers); - } - }; - - super.start(wrappedListener, headers); - } - }; - } - } - - private static class SimpleForwardingClientCallListener - extends ClientCall.Listener { - private final ClientCall.Listener delegate; - - SimpleForwardingClientCallListener(ClientCall.Listener delegate) { - this.delegate = delegate; - } - - @Override - public void onHeaders(Metadata headers) { - delegate.onHeaders(headers); - } - - @Override - public void onMessage(RespT message) { - delegate.onMessage(message); - } - - @Override - public void onClose(Status status, Metadata trailers) { - delegate.onClose(status, trailers); - } - - @Override - public void onReady() { - delegate.onReady(); - } - } - // Implement a client interceptor to retrieve the response headers - private static class HttpJsonCapturingClientInterceptor implements HttpJsonClientInterceptor { - private HttpJsonMetadata metadata; - - @Override - public HttpJsonClientCall interceptCall( - ApiMethodDescriptor method, - HttpJsonCallOptions callOptions, - HttpJsonChannel next) { - HttpJsonClientCall call = next.newCall(method, callOptions); - return new ForwardingHttpJsonClientCall.SimpleForwardingHttpJsonClientCall< - RequestT, ResponseT>(call) { - @Override - public void start(Listener responseListener, HttpJsonMetadata requestHeaders) { - Listener forwardingResponseListener = - new ForwardingHttpJsonClientCallListener.SimpleForwardingHttpJsonClientCallListener< - ResponseT>(responseListener) { - @Override - public void onHeaders(HttpJsonMetadata responseHeaders) { - metadata = responseHeaders; - super.onHeaders(responseHeaders); - } - - @Override - public void onMessage(ResponseT message) { - super.onMessage(message); - } - - @Override - public void onClose(int statusCode, HttpJsonMetadata trailers) { - super.onClose(statusCode, trailers); - } - }; - - super.start(forwardingResponseListener, requestHeaders); - } - }; - } - } - private static HttpJsonCapturingClientInterceptor httpJsonInterceptor; private static GrpcCapturingClientInterceptor grpcInterceptor; private static HttpJsonCapturingClientInterceptor httpJsonComplianceInterceptor; diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITEndpointContext.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITEndpointContext.java index abf3844a6f..55fdd350b8 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITEndpointContext.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITEndpointContext.java @@ -444,4 +444,23 @@ void endpointResolution_builderBuilderBackToBuilder() throws IOException { echoStubSettingsBuilder = echoStubSettings.toBuilder(); Truth.assertThat(echoStubSettingsBuilder.getEndpoint()).isEqualTo(customEndpoint); } + + @Test + void universeDomainValidation_quotaProjectId_credentialsNonGDUMatchesUserConfiguration() + throws IOException { + String universeDomain = "random.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setQuotaProjectId("exampleProject") + .setCredentialsProvider(UniverseDomainCredentialsProvider.create(universeDomain)) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setUniverseDomain(universeDomain) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + Truth.assertThat(echoClient.echo(DEFAULT_REQUEST).getContent()).isEqualTo("echo"); + } } diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/GrpcCapturingClientInterceptor.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/GrpcCapturingClientInterceptor.java new file mode 100644 index 0000000000..156ee16e47 --- /dev/null +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/GrpcCapturingClientInterceptor.java @@ -0,0 +1,102 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.showcase.v1beta1.it.util; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.FixedHeaderProvider; +import com.google.api.gax.rpc.StubSettings; +import com.google.common.collect.ImmutableList; +import com.google.showcase.v1beta1.it.util.TestClientInitializer; +import com.google.showcase.v1beta1.stub.ComplianceStubSettings; +import com.google.showcase.v1beta1.stub.EchoStubSettings; +import io.grpc.CallOptions; +import io.grpc.ClientInterceptor; +import io.grpc.Channel; +import io.grpc.ClientCall; + +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonMetadata; +import io.grpc.ForwardingClientCall; +import io.grpc.Status; + +/** Implements a client interceptor to retrieve the metadata from a GRPC client request. */ +public class GrpcCapturingClientInterceptor implements ClientInterceptor { + public Metadata metadata; + + @Override + public ClientCall interceptCall( + MethodDescriptor method, final CallOptions callOptions, Channel next) { + ClientCall call = next.newCall(method, callOptions); + return new ForwardingClientCall.SimpleForwardingClientCall(call) { + @Override + public void start(Listener responseListener, Metadata headers) { + Listener wrappedListener = + new SimpleForwardingClientCallListener(responseListener) { + @Override + public void onClose(Status status, Metadata trailers) { + if (status.isOk()) { + metadata = trailers; + } + super.onClose(status, trailers); + } + }; + + super.start(wrappedListener, headers); + } + }; + } + + private static class SimpleForwardingClientCallListener + extends ClientCall.Listener { + private final ClientCall.Listener delegate; + + SimpleForwardingClientCallListener(ClientCall.Listener delegate) { + this.delegate = delegate; + } + + @Override + public void onHeaders(Metadata headers) { + delegate.onHeaders(headers); + } + + @Override + public void onMessage(RespT message) { + delegate.onMessage(message); + } + + @Override + public void onClose(Status status, Metadata trailers) { + delegate.onClose(status, trailers); + } + + @Override + public void onReady() { + delegate.onReady(); + } + } +} diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/HttpJsonCapturingClientInterceptor.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/HttpJsonCapturingClientInterceptor.java new file mode 100644 index 0000000000..777398cc96 --- /dev/null +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/HttpJsonCapturingClientInterceptor.java @@ -0,0 +1,86 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.showcase.v1beta1.it.util; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.httpjson.HttpJsonClientInterceptor; +import com.google.api.gax.rpc.FixedHeaderProvider; +import com.google.api.gax.rpc.StubSettings; +import com.google.common.collect.ImmutableList; +import com.google.showcase.v1beta1.it.util.GrpcCapturingClientInterceptor; +import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor; +import com.google.showcase.v1beta1.it.util.TestClientInitializer; +import com.google.showcase.v1beta1.stub.ComplianceStubSettings; +import com.google.showcase.v1beta1.stub.EchoStubSettings; +import com.google.api.gax.httpjson.HttpJsonMetadata; +import java.io.IOException; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import com.google.api.gax.httpjson.HttpJsonCallOptions; +import com.google.api.gax.httpjson.HttpJsonChannel; +import com.google.api.gax.httpjson.HttpJsonClientCall; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.ForwardingHttpJsonClientCall; +import com.google.api.gax.httpjson.ForwardingHttpJsonClientCallListener; +import io.grpc.Status; + +/** Implements a client interceptor to retrieve the response headers from a HTTP client request. */ +public class HttpJsonCapturingClientInterceptor implements HttpJsonClientInterceptor { + public HttpJsonMetadata metadata; + + @Override + public HttpJsonClientCall interceptCall( + ApiMethodDescriptor method, + HttpJsonCallOptions callOptions, + HttpJsonChannel next) { + HttpJsonClientCall call = next.newCall(method, callOptions); + return new ForwardingHttpJsonClientCall.SimpleForwardingHttpJsonClientCall< + RequestT, ResponseT>(call) { + @Override + public void start(Listener responseListener, HttpJsonMetadata requestHeaders) { + Listener forwardingResponseListener = + new ForwardingHttpJsonClientCallListener.SimpleForwardingHttpJsonClientCallListener< + ResponseT>(responseListener) { + @Override + public void onHeaders(HttpJsonMetadata responseHeaders) { + metadata = responseHeaders; + super.onHeaders(responseHeaders); + } + + @Override + public void onMessage(ResponseT message) { + super.onMessage(message); + } + + @Override + public void onClose(int statusCode, HttpJsonMetadata trailers) { + super.onClose(statusCode, trailers); + } + }; + + super.start(forwardingResponseListener, requestHeaders); + } + }; + } +} \ No newline at end of file diff --git a/showcase/pom.xml b/showcase/pom.xml index e16ae160c3..1dc77ab458 100644 --- a/showcase/pom.xml +++ b/showcase/pom.xml @@ -15,7 +15,7 @@ com.google.cloud google-cloud-shared-config - 1.11.2 + 1.11.3 @@ -34,7 +34,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.36.1 + 3.37.0 pom import @@ -56,7 +56,7 @@ org.junit junit-bom - 5.11.1 + 5.11.2 pom import diff --git a/versions.txt b/versions.txt index 91c87f00aa..493e46ad23 100644 --- a/versions.txt +++ b/versions.txt @@ -1,19 +1,19 @@ # Format: # module:released-version:current-version -gapic-generator-java:2.46.1:2.46.1 -api-common:2.37.1:2.37.1 -gax:2.54.1:2.54.1 -gax-grpc:2.54.1:2.54.1 -gax-httpjson:0.139.1:0.139.1 -proto-google-common-protos:2.45.1:2.45.1 -grpc-google-common-protos:2.45.1:2.45.1 -proto-google-iam-v1:1.40.1:1.40.1 -grpc-google-iam-v1:1.40.1:1.40.1 -proto-google-iam-v2beta:1.40.1:1.40.1 -grpc-google-iam-v2beta:1.40.1:1.40.1 -google-iam-policy:1.40.1:1.40.1 -proto-google-iam-v2:1.40.1:1.40.1 -grpc-google-iam-v2:1.40.1:1.40.1 -google-cloud-core:2.44.1:2.44.1 -google-cloud-shared-dependencies:3.36.1:3.36.1 +gapic-generator-java:2.47.0:2.47.0 +api-common:2.38.0:2.38.0 +gax:2.55.0:2.55.0 +gax-grpc:2.55.0:2.55.0 +gax-httpjson:0.140.0:0.140.0 +proto-google-common-protos:2.46.0:2.46.0 +grpc-google-common-protos:2.46.0:2.46.0 +proto-google-iam-v1:1.41.0:1.41.0 +grpc-google-iam-v1:1.41.0:1.41.0 +proto-google-iam-v2beta:1.41.0:1.41.0 +grpc-google-iam-v2beta:1.41.0:1.41.0 +google-iam-policy:1.41.0:1.41.0 +proto-google-iam-v2:1.41.0:1.41.0 +grpc-google-iam-v2:1.41.0:1.41.0 +google-cloud-core:2.45.0:2.45.0 +google-cloud-shared-dependencies:3.37.0:3.37.0