From 8312706db6352fca05a5858b513e88f162e5de0b Mon Sep 17 00:00:00 2001 From: Joe Wang <106995533+JoeWang1127@users.noreply.github.com> Date: Tue, 2 Apr 2024 19:13:54 +0000 Subject: [PATCH 1/3] feat: add config change (#2604) In this PR: - Add `config_change.py` to get: - Changed libraries, which will be passed to `generate_repo.py` to generate libraries selectedly. - Qualified commits, which will be passed to `generate_pr_description.py` to generate PR description. - Refactor part of utility methods to `proto_path_utils.py`. - Refactor `generation_config_comparator.py` to move data class to `config_change.py`. - Refactor `utilities.py` and `utilities.sh` to `utils/utilities.py` and `utils/utilities.sh`. - Add unit tests. Follow up of #2587 For the goal of series of PRs, please refer to [improvement proposal](https://docs.google.com/document/d/1JiCcG3X7lnxaJErKe0ES_JkyU7ECb40nf2Xez3gWvuo/edit?tab=t.g3vua2kd06gx#bookmark=id.72s3ukwwzevo). --- .../generate_composed_library.py | 2 +- library_generation/generate_library.sh | 2 +- library_generation/generate_pr_description.py | 6 +- library_generation/generate_repo.py | 2 +- library_generation/model/config_change.py | 158 +++++++++++ library_generation/model/generation_config.py | 12 + library_generation/postprocess_library.sh | 2 +- library_generation/setup.py | 4 +- library_generation/test/compare_poms.py | 2 +- .../test/generate_library_unit_tests.sh | 2 +- library_generation/test/integration_tests.py | 2 +- .../test/model/config_change_unit_tests.py | 264 ++++++++++++++++++ .../test/model/generation_config_unit_test.py | 39 +++ .../test/utilities_unit_tests.py | 46 +-- ...generation_config_comparator_unit_tests.py | 176 ++++++++---- .../test/utils/proto_path_utils_unit_tests.py | 50 ++++ library_generation/utils/__init__.py | 0 .../utils/generation_config_comparator.py | 64 ++--- library_generation/utils/proto_path_utils.py | 47 ++++ library_generation/{ => utils}/utilities.py | 57 +--- library_generation/{ => utils}/utilities.sh | 0 showcase/scripts/generate_showcase.sh | 2 +- 22 files changed, 726 insertions(+), 213 deletions(-) create mode 100644 library_generation/model/config_change.py create mode 100644 library_generation/test/model/config_change_unit_tests.py create mode 100644 library_generation/test/model/generation_config_unit_test.py create mode 100644 library_generation/test/utils/proto_path_utils_unit_tests.py create mode 100644 library_generation/utils/__init__.py create mode 100644 library_generation/utils/proto_path_utils.py rename library_generation/{ => utils}/utilities.py (87%) rename library_generation/{ => utils}/utilities.sh (100%) diff --git a/library_generation/generate_composed_library.py b/library_generation/generate_composed_library.py index 4caf0c45ff1..877757e7193 100755 --- a/library_generation/generate_composed_library.py +++ b/library_generation/generate_composed_library.py @@ -30,7 +30,7 @@ import os from pathlib import Path from typing import List -import library_generation.utilities as util +import library_generation.utils.utilities as util from library_generation.model.generation_config import GenerationConfig from library_generation.model.gapic_config import GapicConfig from library_generation.model.gapic_inputs import GapicInputs diff --git a/library_generation/generate_library.sh b/library_generation/generate_library.sh index a23cf146530..a5d73ebec4e 100755 --- a/library_generation/generate_library.sh +++ b/library_generation/generate_library.sh @@ -74,7 +74,7 @@ done script_dir=$(dirname "$(readlink -f "$0")") # source utility functions -source "${script_dir}"/utilities.sh +source "${script_dir}"/utils/utilities.sh output_folder="$(get_output_folder)" if [ -z "${gapic_generator_version}" ]; then diff --git a/library_generation/generate_pr_description.py b/library_generation/generate_pr_description.py index 8048f810a4f..2af636d2fe4 100644 --- a/library_generation/generate_pr_description.py +++ b/library_generation/generate_pr_description.py @@ -19,10 +19,8 @@ import click from git import Commit, Repo from library_generation.model.generation_config import from_yaml -from library_generation.utilities import find_versioned_proto_path +from library_generation.utils.proto_path_utils import find_versioned_proto_path from library_generation.utils.commit_message_formatter import format_commit_message -from library_generation.utilities import get_file_paths -from library_generation.utils.commit_message_formatter import wrap_nested_commit from library_generation.utils.commit_message_formatter import wrap_override_commit @@ -87,7 +85,7 @@ def generate_pr_descriptions( baseline_commit: str, ) -> str: config = from_yaml(generation_config_yaml) - paths = get_file_paths(config) + paths = config.get_proto_path_to_library_name() return __get_commit_messages( repo_url=repo_url, latest_commit=config.googleapis_commitish, diff --git a/library_generation/generate_repo.py b/library_generation/generate_repo.py index a4a4a826f22..9af3a08c564 100755 --- a/library_generation/generate_repo.py +++ b/library_generation/generate_repo.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import library_generation.utilities as util +import library_generation.utils.utilities as util import click import os from library_generation.generate_composed_library import generate_composed_library diff --git a/library_generation/model/config_change.py b/library_generation/model/config_change.py new file mode 100644 index 00000000000..5b1a97d22ad --- /dev/null +++ b/library_generation/model/config_change.py @@ -0,0 +1,158 @@ +# 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. +import os +import shutil +from enum import Enum +from typing import Optional +from git import Commit, Repo +from library_generation.model.generation_config import GenerationConfig +from library_generation.model.library_config import LibraryConfig +from library_generation.utils.utilities import sh_util +from library_generation.utils.proto_path_utils import find_versioned_proto_path + + +class ChangeType(Enum): + GOOGLEAPIS_COMMIT = 1 + REPO_LEVEL_CHANGE = 2 + LIBRARIES_ADDITION = 3 + # As of Mar. 2024, we decide not to produce this type of change because we + # still need to manually remove the libray. + # LIBRARIES_REMOVAL = 4 + LIBRARY_LEVEL_CHANGE = 5 + GAPIC_ADDITION = 6 + # As of Mar. 2024, we decide not to produce this type of change because we + # still need to manually remove the libray. + # GAPIC_REMOVAL = 7 + + +class HashLibrary: + """ + Data class to group a LibraryConfig object and its hash value together. + """ + + def __init__(self, hash_value: int, library: LibraryConfig): + self.hash_value = hash_value + self.library = library + + +class LibraryChange: + def __init__(self, changed_param: str, latest_value: str, library_name: str = ""): + self.changed_param = changed_param + self.latest_value = latest_value + self.library_name = library_name + + +class QualifiedCommit: + def __init__(self, commit: Commit, libraries: set[str]): + self.commit = commit + self.libraries = libraries + + +class ConfigChange: + ALL_LIBRARIES_CHANGED = None + + def __init__( + self, + change_to_libraries: dict[ChangeType, list[LibraryChange]], + baseline_config: GenerationConfig, + latest_config: GenerationConfig, + ): + self.change_to_libraries = change_to_libraries + self.baseline_config = baseline_config + self.latest_config = latest_config + + def get_changed_libraries(self) -> Optional[list[str]]: + """ + Returns a unique, sorted list of library name of changed libraries. + None if there is a repository level change, which means all libraries + in the latest_config will be generated. + :return: library names of change libraries. + """ + if ChangeType.REPO_LEVEL_CHANGE in self.change_to_libraries: + return ConfigChange.ALL_LIBRARIES_CHANGED + library_names = set() + for change_type, library_changes in self.change_to_libraries.items(): + if change_type == ChangeType.GOOGLEAPIS_COMMIT: + library_names.update(self.__get_library_names_from_qualified_commits()) + else: + library_names.update( + [library_change.library_name for library_change in library_changes] + ) + return sorted(list(library_names)) + + def get_qualified_commits( + self, + repo_url: str = "https://github.com/googleapis/googleapis.git", + ) -> list[QualifiedCommit]: + """ + Returns qualified commits from configuration change. + + A qualified commit is a commit that changes at least one file (excluding + BUILD.bazel) within a versioned proto path in the given proto_paths. + :param repo_url: the repository contains the commit history. + :return: QualifiedCommit objects. + """ + tmp_dir = sh_util("get_output_folder") + shutil.rmtree(tmp_dir, ignore_errors=True) + os.mkdir(tmp_dir) + # we only need commit history, thus shadow clone is enough. + repo = Repo.clone_from(url=repo_url, to_path=tmp_dir, filter=["blob:none"]) + commit = repo.commit(self.latest_config.googleapis_commitish) + proto_paths = self.latest_config.get_proto_path_to_library_name() + qualified_commits = [] + while str(commit.hexsha) != self.baseline_config.googleapis_commitish: + qualified_commit = ConfigChange.__create_qualified_commit( + proto_paths=proto_paths, commit=commit + ) + if qualified_commit is not None: + qualified_commits.append(qualified_commit) + commit_parents = commit.parents + if len(commit_parents) == 0: + break + commit = commit_parents[0] + shutil.rmtree(tmp_dir, ignore_errors=True) + return qualified_commits + + def __get_library_names_from_qualified_commits(self) -> list[str]: + qualified_commits = self.get_qualified_commits() + library_names = [] + for qualified_commit in qualified_commits: + library_names.extend(qualified_commit.libraries) + return library_names + + @staticmethod + def __create_qualified_commit( + proto_paths: dict[str, str], commit: Commit + ) -> Optional[QualifiedCommit]: + """ + Returns a qualified commit from the given Commit object; otherwise None. + + :param proto_paths: a mapping from versioned proto_path to library_name + :param commit: a GitHub commit object. + :return: qualified commits. + """ + libraries = set() + for file in commit.stats.files.keys(): + if file.endswith("BUILD.bazel"): + continue + versioned_proto_path = find_versioned_proto_path(file) + if versioned_proto_path in proto_paths: + # Even though a commit usually only changes one + # library, we don't want to miss generating a + # library because the commit may change multiple + # libraries. + libraries.add(proto_paths[versioned_proto_path]) + if len(libraries) == 0: + return None + return QualifiedCommit(commit=commit, libraries=libraries) diff --git a/library_generation/model/generation_config.py b/library_generation/model/generation_config.py index 22823b903d3..b37b24b5cb6 100644 --- a/library_generation/model/generation_config.py +++ b/library_generation/model/generation_config.py @@ -49,6 +49,18 @@ def __init__( # monorepos have more than one library defined in the config yaml self.is_monorepo = len(libraries) > 1 + def get_proto_path_to_library_name(self) -> dict[str, str]: + """ + Get versioned proto_path to library_name mapping from configuration. + + :return: versioned proto_path to library_name mapping + """ + paths = {} + for library in self.libraries: + for gapic_config in library.gapic_configs: + paths[gapic_config.proto_path] = library.get_library_name() + return paths + def from_yaml(path_to_yaml: str) -> GenerationConfig: """ diff --git a/library_generation/postprocess_library.sh b/library_generation/postprocess_library.sh index c6a5b4020d0..480b7e51704 100755 --- a/library_generation/postprocess_library.sh +++ b/library_generation/postprocess_library.sh @@ -34,7 +34,7 @@ synthtool_commitish=$6 is_monorepo=$7 configuration_yaml_path=$8 -source "${scripts_root}"/utilities.sh +source "${scripts_root}"/utils/utilities.sh declare -a required_inputs=("postprocessing_target" "versions_file" "owlbot_cli_image_sha" "synthtool_commitish" "is_monorepo") for required_input in "${required_inputs[@]}"; do diff --git a/library_generation/setup.py b/library_generation/setup.py index 477346e7113..bd17cc5fcf8 100755 --- a/library_generation/setup.py +++ b/library_generation/setup.py @@ -12,7 +12,9 @@ }, package_data={ "library_generation": [ - "*.sh", + "generate_library.sh", + "postprocess_library.sh", + "utils/utilities.sh", "templates/*.j2", "gapic-generator-java-wrapper", "requirements.*", diff --git a/library_generation/test/compare_poms.py b/library_generation/test/compare_poms.py index f58953505d0..a1ef4437994 100644 --- a/library_generation/test/compare_poms.py +++ b/library_generation/test/compare_poms.py @@ -4,7 +4,7 @@ The only comparison points are: element path (e.g. project/dependencies) and element text There is a special case for `dependency`, where the maven coordinates are prepared as well """ -from library_generation.utilities import eprint +from library_generation.utils.utilities import eprint import xml.etree.ElementTree as et from collections import Counter import sys diff --git a/library_generation/test/generate_library_unit_tests.sh b/library_generation/test/generate_library_unit_tests.sh index e9f4954298c..ac499435c81 100755 --- a/library_generation/test/generate_library_unit_tests.sh +++ b/library_generation/test/generate_library_unit_tests.sh @@ -5,7 +5,7 @@ set -xeo pipefail # Unit tests against ../utilities.sh script_dir=$(dirname "$(readlink -f "$0")") source "${script_dir}"/test_utilities.sh -source "${script_dir}"/../utilities.sh +source "${script_dir}"/../utils/utilities.sh # Unit tests extract_folder_name_test() { diff --git a/library_generation/test/integration_tests.py b/library_generation/test/integration_tests.py index 35cbf565ac7..9c1d84a33c6 100755 --- a/library_generation/test/integration_tests.py +++ b/library_generation/test/integration_tests.py @@ -28,7 +28,7 @@ from library_generation.generate_repo import generate_from_yaml from library_generation.model.generation_config import from_yaml, GenerationConfig from library_generation.test.compare_poms import compare_xml -from library_generation.utilities import ( +from library_generation.utils.utilities import ( sh_util as shell_call, run_process_and_print_output, ) diff --git a/library_generation/test/model/config_change_unit_tests.py b/library_generation/test/model/config_change_unit_tests.py new file mode 100644 index 00000000000..d6309c98c1e --- /dev/null +++ b/library_generation/test/model/config_change_unit_tests.py @@ -0,0 +1,264 @@ +# 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. +import unittest + +from library_generation.model.config_change import ChangeType +from library_generation.model.config_change import ConfigChange +from library_generation.model.config_change import LibraryChange +from library_generation.model.gapic_config import GapicConfig +from library_generation.model.generation_config import GenerationConfig +from library_generation.model.library_config import LibraryConfig + + +class ConfigChangeTest(unittest.TestCase): + def test_get_changed_libraries_with_repo_level_change_returns_all_libraries_changed( + self, + ): + config_change = ConfigChange( + change_to_libraries={ + ChangeType.REPO_LEVEL_CHANGE: [], + # add a library level change to verify this type of change has + # no impact on the result. + ChangeType.LIBRARY_LEVEL_CHANGE: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="test-library", + ) + ], + }, + baseline_config=ConfigChangeTest.__get_a_gen_config(), + latest_config=ConfigChangeTest.__get_a_gen_config(), + ) + self.assertEqual( + ConfigChange.ALL_LIBRARIES_CHANGED, + config_change.get_changed_libraries(), + ) + + def test_get_changed_libraries_with_library_level_change_returns_list(self): + config_change = ConfigChange( + change_to_libraries={ + ChangeType.LIBRARY_LEVEL_CHANGE: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="a-library", + ), + LibraryChange( + changed_param="test", + latest_value="test", + library_name="another-library", + ), + ], + ChangeType.LIBRARIES_ADDITION: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="new-library", + ), + ], + ChangeType.GAPIC_ADDITION: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="library-with-new-version", + ), + ], + }, + baseline_config=ConfigChangeTest.__get_a_gen_config(), + latest_config=ConfigChangeTest.__get_a_gen_config(), + ) + self.assertEqual( + ["a-library", "another-library", "library-with-new-version", "new-library"], + config_change.get_changed_libraries(), + ) + + def test_get_changed_libraries_with_duplicated_library_name_returns_unique_name( + self, + ): + config_change = ConfigChange( + change_to_libraries={ + ChangeType.LIBRARY_LEVEL_CHANGE: [ + LibraryChange( + changed_param="a-param", + latest_value="new_test", + library_name="a-library", + ), + LibraryChange( + changed_param="another-param", + latest_value="new_value", + library_name="a-library", + ), + ], + }, + baseline_config=ConfigChangeTest.__get_a_gen_config(), + latest_config=ConfigChangeTest.__get_a_gen_config(), + ) + self.assertEqual( + ["a-library"], + config_change.get_changed_libraries(), + ) + + def test_get_changed_libraries_with_mix_changes_returns_list(self): + baseline_commit = "277145d108819fa30fbed3a7cbbb50f91eb6155e" + latest_commit = "8984ddb508dea0e673b724c58338e810b1d8aee3" + config_change = ConfigChange( + change_to_libraries={ + ChangeType.GOOGLEAPIS_COMMIT: [], + ChangeType.LIBRARY_LEVEL_CHANGE: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="a-library", + ) + ], + ChangeType.LIBRARIES_ADDITION: [ + LibraryChange( + changed_param="test", + latest_value="test", + library_name="new-library", + ), + ], + }, + baseline_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=baseline_commit + ), + latest_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=latest_commit, + libraries=[ + ConfigChangeTest.__get_a_library_config( + library_name="gke-backup", + gapic_configs=[ + GapicConfig(proto_path="google/cloud/gkebackup/v1") + ], + ), + ], + ), + ) + + self.assertEqual( + ["a-library", "gke-backup", "new-library"], + sorted(config_change.get_changed_libraries()), + ) + + def test_get_qualified_commits_success(self): + baseline_commit = "277145d108819fa30fbed3a7cbbb50f91eb6155e" + latest_commit = "8984ddb508dea0e673b724c58338e810b1d8aee3" + gke_backup_commit = "b8691edb3f1d3c1583aa9cd89240eb359eebe9c7" + aiplatform_commit = "b82095baef02e525bee7bb1c48911c33b66acdf0" + network_management_commit = "efad09c9f0d46ae0786d810a88024363e06c6ca3" + config_change = ConfigChange( + change_to_libraries={}, + baseline_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=baseline_commit + ), + latest_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=latest_commit, + libraries=[ + ConfigChangeTest.__get_a_library_config( + library_name="gke-backup", + gapic_configs=[ + GapicConfig(proto_path="google/cloud/gkebackup/v1") + ], + ), + ConfigChangeTest.__get_a_library_config( + library_name="aiplatform", + gapic_configs=[ + GapicConfig(proto_path="google/cloud/aiplatform/v1beta1") + ], + ), + ConfigChangeTest.__get_a_library_config( + library_name="network-management", + gapic_configs=[ + GapicConfig(proto_path="google/cloud/networkmanagement/v1"), + GapicConfig( + proto_path="google/cloud/networkmanagement/v1beta1" + ), + ], + ), + ], + ), + ) + qualified_commits = config_change.get_qualified_commits() + self.assertEqual(3, len(qualified_commits)) + self.assertEqual({"gke-backup"}, qualified_commits[0].libraries) + self.assertEqual( + gke_backup_commit, + qualified_commits[0].commit.hexsha, + ) + self.assertEqual({"aiplatform"}, qualified_commits[1].libraries) + self.assertEqual( + aiplatform_commit, + qualified_commits[1].commit.hexsha, + ) + self.assertEqual({"network-management"}, qualified_commits[2].libraries) + self.assertEqual( + network_management_commit, + qualified_commits[2].commit.hexsha, + ) + + def test_get_qualified_commits_build_only_commit_returns_empty_list(self): + baseline_commit = "bdda0174f68a738518ec311e05e6fd9bbe19cd78" + latest_commit = "c9a5050ef225b0011603e1109cf53ab1de0a8e53" + config_change = ConfigChange( + change_to_libraries={}, + baseline_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=baseline_commit + ), + latest_config=ConfigChangeTest.__get_a_gen_config( + googleapis_commitish=latest_commit, + libraries=[ + ConfigChangeTest.__get_a_library_config( + library_name="chat", + gapic_configs=[GapicConfig(proto_path="google/chat/v1")], + ) + ], + ), + ) + # one commit between latest_commit and baseline_commit which only + # changed BUILD.bazel. + self.assertTrue(len(config_change.get_qualified_commits()) == 0) + + @staticmethod + def __get_a_gen_config( + googleapis_commitish="", libraries: list[LibraryConfig] = None + ) -> GenerationConfig: + if libraries is None: + libraries = [] + return GenerationConfig( + gapic_generator_version="", + googleapis_commitish=googleapis_commitish, + owlbot_cli_image="", + synthtool_commitish="", + template_excludes=[], + path_to_yaml="", + grpc_version="", + protobuf_version="", + libraries=libraries, + ) + + @staticmethod + def __get_a_library_config( + library_name: str, gapic_configs: list[GapicConfig] = None + ) -> LibraryConfig: + if gapic_configs is None: + gapic_configs = [] + return LibraryConfig( + api_shortname="existing_library", + api_description="", + name_pretty="", + product_documentation="", + gapic_configs=gapic_configs, + library_name=library_name, + ) diff --git a/library_generation/test/model/generation_config_unit_test.py b/library_generation/test/model/generation_config_unit_test.py new file mode 100644 index 00000000000..b056c709798 --- /dev/null +++ b/library_generation/test/model/generation_config_unit_test.py @@ -0,0 +1,39 @@ +# 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. +import os +import unittest +from pathlib import Path + +from library_generation.model.generation_config import from_yaml + +script_dir = os.path.dirname(os.path.realpath(__file__)) +resources_dir = os.path.join(script_dir, "..", "resources") +test_config_dir = Path(os.path.join(resources_dir, "test-config")).resolve() + + +class GenerationConfigTest(unittest.TestCase): + def test_get_proto_path_to_library_name_success(self): + paths = from_yaml( + f"{test_config_dir}/generation_config.yaml" + ).get_proto_path_to_library_name() + self.assertEqual( + { + "google/cloud/asset/v1": "asset", + "google/cloud/asset/v1p1beta1": "asset", + "google/cloud/asset/v1p2beta1": "asset", + "google/cloud/asset/v1p5beta1": "asset", + "google/cloud/asset/v1p7beta1": "asset", + }, + paths, + ) diff --git a/library_generation/test/utilities_unit_tests.py b/library_generation/test/utilities_unit_tests.py index 3d114f977f4..706570ccc18 100644 --- a/library_generation/test/utilities_unit_tests.py +++ b/library_generation/test/utilities_unit_tests.py @@ -22,7 +22,7 @@ import contextlib from pathlib import Path from parameterized import parameterized -from library_generation import utilities as util +from library_generation.utils import utilities as util from library_generation.model.gapic_config import GapicConfig from library_generation.model.generation_config import GenerationConfig from library_generation.model.gapic_inputs import parse as parse_build_file @@ -30,8 +30,6 @@ from library_generation.model.library_config import LibraryConfig from library_generation.test.test_utils import FileComparator from library_generation.test.test_utils import cleanup -from library_generation.utilities import find_versioned_proto_path -from library_generation.utilities import get_file_paths script_dir = os.path.dirname(os.path.realpath(__file__)) resources_dir = os.path.join(script_dir, "resources") @@ -217,36 +215,6 @@ def test_from_yaml_succeeds(self): self.assertEqual("google/cloud/asset/v1p5beta1", gapics[3].proto_path) self.assertEqual("google/cloud/asset/v1p7beta1", gapics[4].proto_path) - def test_get_file_paths_from_yaml_success(self): - paths = get_file_paths(from_yaml(f"{test_config_dir}/generation_config.yaml")) - self.assertEqual( - { - "google/cloud/asset/v1": "asset", - "google/cloud/asset/v1p1beta1": "asset", - "google/cloud/asset/v1p2beta1": "asset", - "google/cloud/asset/v1p5beta1": "asset", - "google/cloud/asset/v1p7beta1": "asset", - }, - paths, - ) - - @parameterized.expand( - [ - ( - "google/cloud/aiplatform/v1/schema/predict/params/image_classification.proto", - "google/cloud/aiplatform/v1", - ), - ( - "google/cloud/asset/v1p2beta1/assets.proto", - "google/cloud/asset/v1p2beta1", - ), - ("google/type/color.proto", "google/type/color.proto"), - ] - ) - def test_find_versioned_proto_path(self, file_path, expected): - proto_path = find_versioned_proto_path(file_path) - self.assertEqual(expected, proto_path) - @parameterized.expand( [ ("BUILD_no_additional_protos.bazel", " "), @@ -379,18 +347,6 @@ def test_gapic_inputs_parse_no_service_yaml_returns_empty_string(self): ) self.assertEqual("", parsed.service_yaml) - def test_remove_version_from_returns_non_versioned_path(self): - proto_path = "google/cloud/aiplatform/v1" - self.assertEqual( - "google/cloud/aiplatform", util.remove_version_from(proto_path) - ) - - def test_remove_version_from_returns_self(self): - proto_path = "google/cloud/aiplatform" - self.assertEqual( - "google/cloud/aiplatform", util.remove_version_from(proto_path) - ) - def test_generate_prerequisite_files_non_monorepo_success(self): library_path = self.__setup_prerequisite_files( num_libraries=1, library_type="GAPIC_COMBO" diff --git a/library_generation/test/utils/generation_config_comparator_unit_tests.py b/library_generation/test/utils/generation_config_comparator_unit_tests.py index c2c025c5791..e526d6856b9 100644 --- a/library_generation/test/utils/generation_config_comparator_unit_tests.py +++ b/library_generation/test/utils/generation_config_comparator_unit_tests.py @@ -64,7 +64,7 @@ def test_compare_config_not_change(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result) == 0) + self.assertTrue(len(result.change_to_libraries) == 0) def test_compare_config_googleapis_update(self): self.baseline_config.googleapis_commitish = ( @@ -77,7 +77,7 @@ def test_compare_config_googleapis_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertEqual({ChangeType.GOOGLEAPIS_COMMIT: []}, result) + self.assertEqual({ChangeType.GOOGLEAPIS_COMMIT: []}, result.change_to_libraries) def test_compare_config_generator_update(self): self.baseline_config.gapic_generator_version = "1.2.3" @@ -86,8 +86,10 @@ def test_compare_config_generator_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("gapic_generator_version", config_change.changed_param) self.assertEqual("1.2.4", config_change.latest_value) @@ -98,8 +100,10 @@ def test_compare_config_owlbot_cli_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("owlbot_cli_image", config_change.changed_param) self.assertEqual("image_version_456", config_change.latest_value) @@ -110,8 +114,10 @@ def test_compare_config_synthtool_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("synthtool_commitish", config_change.changed_param) self.assertEqual("commit456", config_change.latest_value) @@ -122,8 +128,10 @@ def test_compare_protobuf_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("protobuf_version", config_change.changed_param) self.assertEqual("3.27.0", config_change.latest_value) @@ -134,8 +142,10 @@ def test_compare_config_grpc_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("grpc_version", config_change.changed_param) self.assertEqual("1.61.0", config_change.latest_value) @@ -151,8 +161,10 @@ def test_compare_config_template_excludes_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.REPO_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.REPO_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.REPO_LEVEL_CHANGE][0] self.assertEqual("template_excludes", config_change.changed_param) self.assertEqual( [ @@ -178,8 +190,10 @@ def test_compare_config_library_addition(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARIES_ADDITION]) == 1) - config_change = result[ChangeType.LIBRARIES_ADDITION][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARIES_ADDITION]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARIES_ADDITION][0] self.assertEqual("new_library", config_change.library_name) def test_compare_config_api_shortname_update_without_library_name(self): @@ -188,8 +202,10 @@ def test_compare_config_api_shortname_update_without_library_name(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARIES_ADDITION]) == 1) - config_change = result[ChangeType.LIBRARIES_ADDITION][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARIES_ADDITION]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARIES_ADDITION][0] self.assertEqual("new_api_shortname", config_change.library_name) def test_compare_config_api_shortname_update_with_library_name_raise_error(self): @@ -210,8 +226,10 @@ def test_compare_config_library_name_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARIES_ADDITION]) == 1) - config_change = result[ChangeType.LIBRARIES_ADDITION][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARIES_ADDITION]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARIES_ADDITION][0] self.assertEqual("new_library_name", config_change.library_name) def test_compare_config_api_description_update(self): @@ -220,8 +238,10 @@ def test_compare_config_api_description_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("api_description", config_change.changed_param) self.assertEqual("updated description", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -232,8 +252,10 @@ def test_compare_config_name_pretty_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("name_pretty", config_change.changed_param) self.assertEqual("new name", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -244,8 +266,10 @@ def test_compare_config_product_docs_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("product_documentation", config_change.changed_param) self.assertEqual("new docs", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -256,8 +280,10 @@ def test_compare_config_library_type_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("library_type", config_change.changed_param) self.assertEqual("GAPIC_COMBO", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -268,8 +294,10 @@ def test_compare_config_release_level_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("release_level", config_change.changed_param) self.assertEqual("STABLE", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -280,8 +308,10 @@ def test_compare_config_api_id_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("api_id", config_change.changed_param) self.assertEqual("new_id", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -292,8 +322,10 @@ def test_compare_config_api_reference_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("api_reference", config_change.changed_param) self.assertEqual("new api_reference", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -304,8 +336,10 @@ def test_compare_config_code_owner_team_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("codeowner_team", config_change.changed_param) self.assertEqual("new team", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -316,8 +350,10 @@ def test_compare_config_excluded_deps_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("excluded_dependencies", config_change.changed_param) self.assertEqual("group:artifact", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -328,8 +364,10 @@ def test_compare_config_excluded_poms_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("excluded_poms", config_change.changed_param) self.assertEqual("pom.xml", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -340,8 +378,10 @@ def test_compare_config_client_docs_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("client_documentation", config_change.changed_param) self.assertEqual("new client docs", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -352,8 +392,10 @@ def test_compare_config_distribution_name_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("distribution_name", config_change.changed_param) self.assertEqual("new_group:new_artifact", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -364,8 +406,10 @@ def test_compare_config_group_id_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("group_id", config_change.changed_param) self.assertEqual("new_group", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -376,8 +420,10 @@ def test_compare_config_issue_tracker_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("issue_tracker", config_change.changed_param) self.assertEqual("new issue tracker", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -388,8 +434,10 @@ def test_compare_config_rest_docs_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("rest_documentation", config_change.changed_param) self.assertEqual("new rest docs", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -400,8 +448,10 @@ def test_compare_config_rpc_docs_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("rpc_documentation", config_change.changed_param) self.assertEqual("new rpc docs", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -412,8 +462,10 @@ def test_compare_config_cloud_api_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("cloud_api", config_change.changed_param) self.assertEqual(False, config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -424,8 +476,10 @@ def test_compare_config_requires_billing_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("requires_billing", config_change.changed_param) self.assertEqual(False, config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -436,8 +490,10 @@ def test_compare_config_extra_versioned_mod_update(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1) - config_change = result[ChangeType.LIBRARY_LEVEL_CHANGE][0] + self.assertTrue( + len(result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE]) == 1 + ) + config_change = result.change_to_libraries[ChangeType.LIBRARY_LEVEL_CHANGE][0] self.assertEqual("extra_versioned_modules", config_change.changed_param) self.assertEqual("extra module", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) @@ -450,8 +506,8 @@ def test_compare_config_version_addition(self): baseline_config=self.baseline_config, latest_config=self.latest_config, ) - self.assertTrue(len(result[ChangeType.GAPIC_ADDITION]) == 1) - config_change = result[ChangeType.GAPIC_ADDITION][0] + self.assertTrue(len(result.change_to_libraries[ChangeType.GAPIC_ADDITION]) == 1) + config_change = result.change_to_libraries[ChangeType.GAPIC_ADDITION][0] self.assertEqual("", config_change.changed_param) self.assertEqual("google/new/library/v1", config_change.latest_value) self.assertEqual("existing_library", config_change.library_name) diff --git a/library_generation/test/utils/proto_path_utils_unit_tests.py b/library_generation/test/utils/proto_path_utils_unit_tests.py new file mode 100644 index 00000000000..2e23c2b4036 --- /dev/null +++ b/library_generation/test/utils/proto_path_utils_unit_tests.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# 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. +import os +import unittest +from pathlib import Path +from library_generation.utils.proto_path_utils import ( + find_versioned_proto_path, + remove_version_from, +) + +script_dir = os.path.dirname(os.path.realpath(__file__)) +resources_dir = os.path.join(script_dir, "..", "resources") +test_config_dir = Path(os.path.join(resources_dir, "test-config")).resolve() + + +class ProtoPathsUtilsTest(unittest.TestCase): + def test_find_versioned_proto_path_nested_version_success(self): + proto_path = "google/cloud/aiplatform/v1/schema/predict/params/image_classification.proto" + expected = "google/cloud/aiplatform/v1" + self.assertEqual(expected, find_versioned_proto_path(proto_path)) + + def test_find_versioned_proto_path_success(self): + proto_path = "google/cloud/asset/v1p2beta1/assets.proto" + expected = "google/cloud/asset/v1p2beta1" + self.assertEqual(expected, find_versioned_proto_path(proto_path)) + + def test_find_versioned_proto_without_version_return_itself(self): + proto_path = "google/type/color.proto" + expected = "google/type/color.proto" + self.assertEqual(expected, find_versioned_proto_path(proto_path)) + + def test_remove_version_from_returns_non_versioned_path(self): + proto_path = "google/cloud/aiplatform/v1" + self.assertEqual("google/cloud/aiplatform", remove_version_from(proto_path)) + + def test_remove_version_from_returns_self(self): + proto_path = "google/cloud/aiplatform" + self.assertEqual("google/cloud/aiplatform", remove_version_from(proto_path)) diff --git a/library_generation/utils/__init__.py b/library_generation/utils/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/library_generation/utils/generation_config_comparator.py b/library_generation/utils/generation_config_comparator.py index 4fe8358230a..79a5f3c1aa9 100644 --- a/library_generation/utils/generation_config_comparator.py +++ b/library_generation/utils/generation_config_comparator.py @@ -12,51 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. from collections import defaultdict -from enum import Enum from typing import Any - from typing import Dict from typing import List - +from library_generation.model.config_change import ChangeType +from library_generation.model.config_change import ConfigChange +from library_generation.model.config_change import LibraryChange +from library_generation.model.config_change import HashLibrary from library_generation.model.gapic_config import GapicConfig from library_generation.model.generation_config import GenerationConfig from library_generation.model.library_config import LibraryConfig -class ChangeType(Enum): - GOOGLEAPIS_COMMIT = 1 - REPO_LEVEL_CHANGE = 2 - LIBRARIES_ADDITION = 3 - # As of Mar. 2024, we decide not to produce this type of change because we - # still need to manually remove the libray. - # LIBRARIES_REMOVAL = 4 - LIBRARY_LEVEL_CHANGE = 5 - GAPIC_ADDITION = 6 - # As of Mar. 2024, we decide not to produce this type of change because we - # still need to manually remove the libray. - # GAPIC_REMOVAL = 7 - - -class HashLibrary: - """ - Data class to group a LibraryConfig object and its hash value together. - """ - - def __init__(self, hash_value: int, library: LibraryConfig): - self.hash_value = hash_value - self.library = library - - -class ConfigChange: - def __init__(self, changed_param: str, latest_value: str, library_name: str = ""): - self.changed_param = changed_param - self.latest_value = latest_value - self.library_name = library_name - - def compare_config( baseline_config: GenerationConfig, latest_config: GenerationConfig -) -> Dict[ChangeType, list[ConfigChange]]: +) -> ConfigChange: """ Compare two GenerationConfig object and output a mapping from ConfigChange to a list of ConfigChange objects. @@ -65,9 +35,9 @@ def compare_config( :param baseline_config: the baseline GenerationConfig object :param latest_config: the latest GenerationConfig object - :return: a mapping from ConfigChange to a list of ConfigChange objects. + :return: a ConfigChange objects. """ - diff = defaultdict(list[ConfigChange]) + diff = defaultdict(list[LibraryChange]) baseline_params = __convert_params_to_sorted_list(baseline_config) latest_params = __convert_params_to_sorted_list(latest_config) for baseline_param, latest_param in zip(baseline_params, latest_params): @@ -76,7 +46,7 @@ def compare_config( if baseline_param[0] == "googleapis_commitish": diff[ChangeType.GOOGLEAPIS_COMMIT] = [] else: - config_change = ConfigChange( + config_change = LibraryChange( changed_param=latest_param[0], latest_value=latest_param[1], ) @@ -87,11 +57,15 @@ def compare_config( baseline_library_configs=baseline_config.libraries, latest_library_configs=latest_config.libraries, ) - return diff + return ConfigChange( + change_to_libraries=diff, + baseline_config=baseline_config, + latest_config=latest_config, + ) def __compare_libraries( - diff: Dict[ChangeType, list[ConfigChange]], + diff: Dict[ChangeType, list[LibraryChange]], baseline_library_configs: List[LibraryConfig], latest_library_configs: List[LibraryConfig], ) -> None: @@ -132,7 +106,7 @@ def __compare_libraries( # a library is added to latest_libraries if the library_name # is not in baseline_libraries. if library_name not in baseline_libraries: - config_change = ConfigChange( + config_change = LibraryChange( changed_param="", latest_value="", library_name=library_name ) diff[ChangeType.LIBRARIES_ADDITION].append(config_change) @@ -163,7 +137,7 @@ def __convert_to_hashed_library_dict( def __compare_changed_libraries( - diff: Dict[ChangeType, list[ConfigChange]], + diff: Dict[ChangeType, list[LibraryChange]], baseline_libraries: Dict[str, HashLibrary], latest_libraries: Dict[str, HashLibrary], changed_libraries: List[str], @@ -193,7 +167,7 @@ def __compare_changed_libraries( f"{library_name}: api_shortname must not change when library_name remains the same." ) else: - config_change = ConfigChange( + config_change = LibraryChange( changed_param=latest_param[0], latest_value=latest_param[1], library_name=library_name, @@ -212,7 +186,7 @@ def __compare_changed_libraries( def __compare_gapic_configs( - diff: Dict[ChangeType, list[ConfigChange]], + diff: Dict[ChangeType, list[LibraryChange]], library_name: str, baseline_gapic_configs: List[GapicConfig], latest_gapic_configs: List[GapicConfig], @@ -236,7 +210,7 @@ def __compare_gapic_configs( for proto_path in latest_proto_paths: if proto_path in baseline_proto_paths: continue - config_change = ConfigChange( + config_change = LibraryChange( changed_param="", latest_value=proto_path, library_name=library_name ) diff[ChangeType.GAPIC_ADDITION].append(config_change) diff --git a/library_generation/utils/proto_path_utils.py b/library_generation/utils/proto_path_utils.py new file mode 100644 index 00000000000..d2ae25f6021 --- /dev/null +++ b/library_generation/utils/proto_path_utils.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# 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. +import re + + +def remove_version_from(proto_path: str) -> str: + """ + Remove the version of a proto_path + :param proto_path: versioned proto_path + :return: the proto_path without version + """ + version_pattern = "^v[1-9]" + index = proto_path.rfind("/") + version = proto_path[index + 1 :] + if re.match(version_pattern, version): + return proto_path[:index] + return proto_path + + +def find_versioned_proto_path(proto_path: str) -> str: + """ + Returns a versioned proto_path from a given proto_path; or proto_path itself + if it doesn't contain a versioned proto_path. + :param proto_path: a proto file path + :return: the versioned proto_path + """ + version_regex = re.compile(r"^v[1-9].*") + directories = proto_path.split("/") + for directory in directories: + result = version_regex.search(directory) + if result: + version = result[0] + idx = proto_path.find(version) + return proto_path[:idx] + version + return proto_path diff --git a/library_generation/utilities.py b/library_generation/utils/utilities.py similarity index 87% rename from library_generation/utilities.py rename to library_generation/utils/utilities.py index fb7e8938d22..8ab1a11b7cc 100755 --- a/library_generation/utilities.py +++ b/library_generation/utils/utilities.py @@ -18,12 +18,12 @@ import shutil import re from pathlib import Path -from typing import Dict from library_generation.model.generation_config import GenerationConfig from library_generation.model.library_config import LibraryConfig from typing import List from library_generation.model.repo_config import RepoConfig from library_generation.utils.file_render import render +from library_generation.utils.proto_path_utils import remove_version_from script_dir = os.path.dirname(os.path.realpath(__file__)) @@ -57,7 +57,7 @@ def run_process_and_print_output(arguments: List[str], job_name: str = "Job"): def sh_util(statement: str, **kwargs) -> str: """ - Calls a function defined in library_generation/utilities.sh + Calls a function defined in library_generation/utils/utilities.sh """ if "stdout" not in kwargs: kwargs["stdout"] = subprocess.PIPE @@ -65,7 +65,11 @@ def sh_util(statement: str, **kwargs) -> str: kwargs["stderr"] = subprocess.PIPE output = "" with subprocess.Popen( - ["bash", "-exc", f"source {script_dir}/utilities.sh && {statement}"], + [ + "bash", + "-exc", + f"source {script_dir}/utilities.sh && {statement}", + ], **kwargs, ) as proc: print("command stderr:") @@ -93,20 +97,6 @@ def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) -def remove_version_from(proto_path: str) -> str: - """ - Remove the version of a proto_path - :param proto_path: versioned proto_path - :return: the proto_path without version - """ - version_pattern = "^v[1-9]" - index = proto_path.rfind("/") - version = proto_path[index + 1 :] - if re.match(version_pattern, version): - return proto_path[:index] - return proto_path - - def prepare_repo( gen_config: GenerationConfig, library_config: List[LibraryConfig], @@ -314,36 +304,3 @@ def generate_prerequisite_files( should_include_templates=True, template_excludes=config.template_excludes, ) - - -def get_file_paths(config: GenerationConfig) -> Dict[str, str]: - """ - Get versioned proto_path to library_name mapping from configuration file. - - :param config: a GenerationConfig object. - :return: versioned proto_path to library_name mapping - """ - paths = {} - for library in config.libraries: - for gapic_config in library.gapic_configs: - paths[gapic_config.proto_path] = library.get_library_name() - return paths - - -def find_versioned_proto_path(file_path: str) -> str: - """ - Returns a versioned proto_path from a given file_path; or file_path itself - if it doesn't contain a versioned proto_path. - - :param file_path: a proto file path - :return: the versioned proto_path - """ - version_regex = re.compile(r"^v[1-9].*") - directories = file_path.split("/") - for directory in directories: - result = version_regex.search(directory) - if result: - version = result[0] - idx = file_path.find(version) - return file_path[:idx] + version - return file_path diff --git a/library_generation/utilities.sh b/library_generation/utils/utilities.sh similarity index 100% rename from library_generation/utilities.sh rename to library_generation/utils/utilities.sh diff --git a/showcase/scripts/generate_showcase.sh b/showcase/scripts/generate_showcase.sh index 1c1b1f58ded..d524aaa77f7 100755 --- a/showcase/scripts/generate_showcase.sh +++ b/showcase/scripts/generate_showcase.sh @@ -8,7 +8,7 @@ set -ex readonly SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) lib_gen_scripts_dir="${SCRIPT_DIR}/../../library_generation/" source "${lib_gen_scripts_dir}/test/test_utilities.sh" -source "${lib_gen_scripts_dir}/utilities.sh" +source "${lib_gen_scripts_dir}/utils/utilities.sh" readonly perform_cleanup=$1 cd "${SCRIPT_DIR}" From 4942bc17e9c7261242ba3d03d85cd8b131ca2e5e Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Apr 2024 20:12:59 +0000 Subject: [PATCH 2/3] feat: Client/StubSettings' getEndpoint() returns the resolved endpoint (#2440) ## Changes - Client|StubSettings `getEndpoint()` will now return the fully resolved endpoint - Client|StubSettings `getUniverseDomain()` will not return the fully resolved universe domain - Remove the generated `getEndpoint()` method in the {Client}StubSettings class. The call to `getEndpoint()` will now always hit the parent StubSettings and return the fully resolved endpoint. --------- Co-authored-by: Blake Li --- .../comment/SettingsCommentComposer.java | 3 - ...tractServiceStubSettingsClassComposer.java | 41 -- .../DeprecatedServiceStubSettings.golden | 18 - .../grpc/goldens/EchoStubSettings.golden | 18 - .../LoggingServiceV2StubSettings.golden | 18 - .../grpc/goldens/PublisherStubSettings.golden | 18 - .../grpcrest/goldens/EchoStubSettings.golden | 18 - .../goldens/WickedStubSettings.golden | 18 - .../goldens/ComplianceStubSettings.golden | 18 - .../google/api/gax/grpc/GrpcCallContext.java | 11 +- .../api/gax/httpjson/HttpJsonCallContext.java | 11 +- gax-java/gax/clirr-ignored-differences.xml | 5 + .../com/google/api/gax/rpc/ClientContext.java | 68 +-- .../google/api/gax/rpc/EndpointContext.java | 5 + .../com/google/api/gax/rpc/StubSettings.java | 117 +++-- .../google/api/gax/rpc/ClientContextTest.java | 12 +- .../api/gax/rpc/ClientSettingsTest.java | 8 +- .../api/gax/rpc/testing/FakeCallContext.java | 8 +- .../v1beta1/stub/ComplianceStubSettings.java | 18 - .../v1beta1/stub/EchoStubSettings.java | 18 - .../v1beta1/stub/IdentityStubSettings.java | 18 - .../v1beta1/stub/MessagingStubSettings.java | 18 - .../stub/SequenceServiceStubSettings.java | 18 - .../v1beta1/stub/TestingStubSettings.java | 18 - .../v1beta1/it/ITEndpointContext.java | 440 ++++++++++++++++-- .../it/util/TestClientInitializer.java | 34 +- .../stub/ConnectionServiceStubSettings.java | 18 - .../v1/stub/TetherStubSettings.java | 18 - .../v1/stub/AssetServiceStubSettings.java | 18 - .../data/v2/stub/BigtableStubSettings.java | 18 - .../v1small/stub/AddressesStubSettings.java | 18 - .../stub/RegionOperationsStubSettings.java | 18 - .../v1/stub/IamCredentialsStubSettings.java | 18 - .../iam/v1/stub/IAMPolicyStubSettings.java | 18 - .../KeyManagementServiceStubSettings.java | 18 - .../v1/stub/LibraryServiceStubSettings.java | 18 - .../v2/stub/ConfigServiceV2StubSettings.java | 18 - .../v2/stub/LoggingServiceV2StubSettings.java | 18 - .../v2/stub/MetricsServiceV2StubSettings.java | 18 - .../pubsub/v1/stub/PublisherStubSettings.java | 18 - .../v1/stub/SchemaServiceStubSettings.java | 18 - .../v1/stub/SubscriberStubSettings.java | 18 - .../v1beta1/stub/CloudRedisStubSettings.java | 18 - .../storage/v2/stub/StorageStubSettings.java | 18 - 44 files changed, 569 insertions(+), 752 deletions(-) diff --git a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java index aaad982c666..649ee62e77e 100644 --- a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java +++ b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java @@ -52,9 +52,6 @@ public class SettingsCommentComposer { private static final String CLASS_HEADER_DEFAULTS_RETRIES_DESCRIPTION = "Retries are configured for idempotent methods but not for non-idempotent methods."; - public static final CommentStatement GET_ENDPOINT_COMMENT = - toSimpleComment( - "Returns the endpoint set by the user or the the service's default endpoint."); public static final CommentStatement DEFAULT_SCOPES_COMMENT = toSimpleComment("The default scopes of the service."); diff --git a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index a64992df898..f8c00131bee 100644 --- a/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java +++ b/gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -999,7 +999,6 @@ private List createClassMethods( javaMethods.addAll( createMethodSettingsGetterMethods(methodSettingsMemberVarExprs, deprecatedSettingVarNames)); javaMethods.add(createCreateStubMethod(service, typeStore)); - javaMethods.add(createGetEndpointMethod()); javaMethods.addAll(createDefaultHelperAndGetterMethods(service, typeStore)); javaMethods.addAll( createNewBuilderMethods( @@ -1013,45 +1012,6 @@ private List createClassMethods( return javaMethods; } - // Helper method to create the getEndpoint method in the ServiceStubSettings class - private MethodDefinition createGetEndpointMethod() { - Expr getEndpointExpr = - MethodInvocationExpr.builder() - .setMethodName("getEndpoint") - .setExprReferenceExpr( - ValueExpr.withValue( - SuperObjectValue.withType( - TypeNode.withReference(ConcreteReference.withClazz(StubSettings.class))))) - .setReturnType(TypeNode.STRING) - .build(); - Expr isNotNullCheck = - RelationalOperationExpr.notEqualToWithExprs(getEndpointExpr, ValueExpr.createNullExpr()); - - IfStatement ifStatement = - IfStatement.builder() - .setConditionExpr(isNotNullCheck) - .setBody(ImmutableList.of(ExprStatement.withExpr(ReturnExpr.withExpr(getEndpointExpr)))) - .build(); - - Expr getDefaultEndpointExpr = - MethodInvocationExpr.builder() - .setMethodName("getDefaultEndpoint") - .setReturnType(TypeNode.STRING) - .build(); - ReturnExpr returnExpr = ReturnExpr.withExpr(getDefaultEndpointExpr); - - return MethodDefinition.builder() - .setHeaderCommentStatements(SettingsCommentComposer.GET_ENDPOINT_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(false) - .setAnnotations(ImmutableList.of(AnnotationNode.OVERRIDE)) - .setReturnType(TypeNode.STRING) - .setName("getEndpoint") - .setBody(ImmutableList.of(ifStatement)) - .setReturnExpr(returnExpr) - .build(); - } - private static List createMethodSettingsGetterMethods( Map methodSettingsMemberVarExprs, final Set deprecatedSettingVarNames) { @@ -1497,7 +1457,6 @@ private List createNestedClassMethods( nestedClassMethods.addAll( createNestedClassSettingsBuilderGetterMethods( nestedMethodSettingsMemberVarExprs, nestedDeprecatedSettingVarNames)); - nestedClassMethods.add(createGetEndpointMethod()); nestedClassMethods.add(createNestedClassBuildMethod(service, typeStore)); return nestedClassMethods; } diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden index 4c397ec405d..d5bbe0d8932 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden @@ -101,15 +101,6 @@ public class DeprecatedServiceStubSettings extends StubSettings { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -635,15 +626,6 @@ public class EchoStubSettings extends StubSettings { return collideNameSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public EchoStubSettings build() throws IOException { return new EchoStubSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden index 9aafbdc9c97..264f6da6ff5 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden @@ -421,15 +421,6 @@ public class LoggingServiceV2StubSettings extends StubSettings { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -810,15 +801,6 @@ public class PublisherStubSettings extends StubSettings { return detachSubscriptionSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public PublisherStubSettings build() throws IOException { return new PublisherStubSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoStubSettings.golden index 6b8181e8a09..fefa7643bab 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoStubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoStubSettings.golden @@ -301,15 +301,6 @@ public class EchoStubSettings extends StubSettings { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -694,15 +685,6 @@ public class EchoStubSettings extends StubSettings { return updateCaseSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public EchoStubSettings build() throws IOException { return new EchoStubSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/WickedStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/WickedStubSettings.golden index 216cf65dc37..9a376f484a1 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/WickedStubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/WickedStubSettings.golden @@ -99,15 +99,6 @@ public class WickedStubSettings extends StubSettings { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -284,15 +275,6 @@ public class WickedStubSettings extends StubSettings { return persuadeEvilPlanSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public WickedStubSettings build() throws IOException { return new WickedStubSettings(this); diff --git a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden index 9efb8395a1f..21420a6a2ec 100644 --- a/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden +++ b/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden @@ -131,15 +131,6 @@ public class ComplianceStubSettings extends StubSettings "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -417,15 +408,6 @@ public class ComplianceStubSettings extends StubSettings return verifyEnumSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public ComplianceStubSettings build() throws IOException { return new ComplianceStubSettings(this); diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java index 886beda4ec6..3de00ec6719 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallContext.java @@ -140,7 +140,7 @@ private GrpcCallContext( ApiCallContextOptions options, @Nullable RetrySettings retrySettings, @Nullable Set retryableCodes, - EndpointContext endpointContext) { + @Nullable EndpointContext endpointContext) { this.channel = channel; this.credentials = credentials; this.callOptions = Preconditions.checkNotNull(callOptions); @@ -152,7 +152,14 @@ private GrpcCallContext( this.options = Preconditions.checkNotNull(options); this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); - this.endpointContext = endpointContext; + // 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. + try { + this.endpointContext = + endpointContext == null ? EndpointContext.newBuilder().build() : endpointContext; + } catch (IOException ex) { + throw new RuntimeException(ex); + } } /** diff --git a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java index 890c205a611..bb208110580 100644 --- a/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java +++ b/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonCallContext.java @@ -121,7 +121,7 @@ private HttpJsonCallContext( ApiTracer tracer, RetrySettings defaultRetrySettings, Set defaultRetryableCodes, - EndpointContext endpointContext) { + @Nullable EndpointContext endpointContext) { this.channel = channel; this.callOptions = callOptions; this.timeout = timeout; @@ -133,7 +133,14 @@ private HttpJsonCallContext( this.retrySettings = defaultRetrySettings; this.retryableCodes = defaultRetryableCodes == null ? null : ImmutableSet.copyOf(defaultRetryableCodes); - this.endpointContext = endpointContext; + // 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. + try { + this.endpointContext = + endpointContext == null ? EndpointContext.newBuilder().build() : endpointContext; + } catch (IOException ex) { + throw new RuntimeException(ex); + } } /** diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml index c8e68444ff0..b08615ef138 100644 --- a/gax-java/gax/clirr-ignored-differences.xml +++ b/gax-java/gax/clirr-ignored-differences.xml @@ -42,4 +42,9 @@ com/google/api/gax/rpc/ApiCallContext * validateUniverseDomain() + + 7009 + com/google/api/gax/rpc/StubSettings + * getServiceName() + 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 409dbbada16..afe6ab0655d 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 @@ -100,10 +100,6 @@ public abstract class ClientContext { @Nonnull public abstract Duration getStreamWatchdogCheckInterval(); - // Package-Private scope for internal use only. Shared between StubSettings and ClientContext - @Nullable - abstract String getServiceName(); - @Nullable public abstract String getUniverseDomain(); @@ -113,6 +109,9 @@ public abstract class ClientContext { @Nullable public abstract String getQuotaProjectId(); + /** Package-Private as this is to be shared to StubSettings */ + abstract EndpointContext getEndpointContext(); + /** Gets the {@link ApiTracerFactory} that will be used to generate traces for operations. */ @BetaApi("The surface for tracing is not stable yet and may change in the future.") @Nonnull @@ -125,18 +124,26 @@ public abstract class ClientContext { @Nullable public abstract String getGdchApiAudience(); + /** Create a new ClientContext with default values */ public static Builder newBuilder() { - return new AutoValue_ClientContext.Builder() - .setBackgroundResources(Collections.emptyList()) - .setExecutor(Executors.newScheduledThreadPool(0)) - .setHeaders(Collections.emptyMap()) - .setInternalHeaders(Collections.emptyMap()) - .setClock(NanoClock.getDefaultClock()) - .setStreamWatchdog(null) - .setStreamWatchdogCheckInterval(Duration.ZERO) - .setTracerFactory(BaseApiTracerFactory.getInstance()) - .setQuotaProjectId(null) - .setGdchApiAudience(null); + try { + return new AutoValue_ClientContext.Builder() + .setBackgroundResources(Collections.emptyList()) + .setExecutor(Executors.newScheduledThreadPool(0)) + .setHeaders(Collections.emptyMap()) + .setInternalHeaders(Collections.emptyMap()) + .setClock(NanoClock.getDefaultClock()) + .setStreamWatchdog(null) + .setStreamWatchdogCheckInterval(Duration.ZERO) + .setTracerFactory(BaseApiTracerFactory.getInstance()) + .setQuotaProjectId(null) + .setGdchApiAudience(null) + // Attempt to create an empty, non-functioning EndpointContext by default. This is + // not exposed to the user via getters/setters. + .setEndpointContext(EndpointContext.newBuilder().build()); + } catch (IOException e) { + throw new RuntimeException(e); + } } public abstract Builder toBuilder(); @@ -159,23 +166,20 @@ public static ClientContext create(StubSettings settings) throws IOException { ExecutorProvider backgroundExecutorProvider = settings.getBackgroundExecutorProvider(); final ScheduledExecutorService backgroundExecutor = backgroundExecutorProvider.getExecutor(); - Credentials credentials = settings.getCredentialsProvider().getCredentials(); - boolean usingGDCH = credentials instanceof GdchCredentials; - EndpointContext endpointContext = - EndpointContext.newBuilder() - .setServiceName(settings.getServiceName()) - .setUniverseDomain(settings.getUniverseDomain()) - .setClientSettingsEndpoint(settings.getUserSetEndpoint()) - .setTransportChannelProviderEndpoint( - settings.getTransportChannelProvider().getEndpoint()) - .setMtlsEndpoint(settings.getMtlsEndpoint()) - .setSwitchToMtlsEndpointAllowed(settings.getSwitchToMtlsEndpointAllowed()) - .setUsingGDCH(usingGDCH) - .build(); + // A valid EndpointContext should have been created in the StubSettings + EndpointContext endpointContext = settings.getEndpointContext(); String endpoint = endpointContext.resolvedEndpoint(); 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 + // is resolved in the ClientContext and must be passed to the EndpointContext. Rebuild the + // endpointContext only on GDC-H flows. + endpointContext = endpointContext.withGDCH(); + // 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)) { @@ -270,13 +274,13 @@ public static ClientContext create(StubSettings settings) throws IOException { .setInternalHeaders(ImmutableMap.copyOf(settings.getInternalHeaderProvider().getHeaders())) .setClock(clock) .setDefaultCallContext(defaultCallContext) - .setServiceName(settings.getServiceName()) .setUniverseDomain(settings.getUniverseDomain()) .setEndpoint(settings.getEndpoint()) .setQuotaProjectId(settings.getQuotaProjectId()) .setStreamWatchdog(watchdog) .setStreamWatchdogCheckInterval(settings.getStreamWatchdogCheckInterval()) .setTracerFactory(settings.getTracerFactory()) + .setEndpointContext(endpointContext) .build(); } @@ -337,9 +341,6 @@ public abstract static class Builder { public abstract Builder setDefaultCallContext(ApiCallContext defaultCallContext); - // Package-Private scope for internal use only. Shared between StubSettings and ClientContext - abstract Builder setServiceName(String serviceName); - public abstract Builder setUniverseDomain(String universeDomain); public abstract Builder setEndpoint(String endpoint); @@ -369,6 +370,9 @@ public abstract static class Builder { */ public abstract Builder setGdchApiAudience(String gdchApiAudience); + /** Package-Private as this is to be shared to StubSettings */ + abstract Builder setEndpointContext(EndpointContext endpointContext); + public abstract ClientContext build(); } } 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 5b1f14fdaf0..c2f3ad50ab1 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 @@ -105,6 +105,11 @@ public static Builder newBuilder() { .setUsingGDCH(false); } + /** Configure the existing EndpointContext to be using GDC-H */ + EndpointContext withGDCH() throws IOException { + return toBuilder().setUsingGDCH(true).build(); + } + /** * Check that the User configured universe domain matches the Credentials' universe domain. The * status code parameter is passed in to this method as it's a limitation of Gax's modules. The 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 962443e5d2f..0e37c12cadc 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 @@ -71,9 +71,6 @@ public abstract class StubSettings> { private final HeaderProvider internalHeaderProvider; private final TransportChannelProvider transportChannelProvider; private final ApiClock clock; - private final String serviceName; - private final String endpoint; - private final String mtlsEndpoint; private final String quotaProjectId; @Nullable private final String gdchApiAudience; @Nullable private final WatchdogProvider streamWatchdogProvider; @@ -81,7 +78,7 @@ public abstract class StubSettings> { @Nonnull private final ApiTracerFactory tracerFactory; // Track if deprecated setExecutorProvider is called private boolean deprecatedExecutorProviderSet; - private final String universeDomain; + @Nonnull private final EndpointContext endpointContext; /** * Indicate when creating transport whether it is allowed to use mTLS endpoint instead of the @@ -99,9 +96,6 @@ protected StubSettings(Builder builder) { this.headerProvider = builder.headerProvider; this.internalHeaderProvider = builder.internalHeaderProvider; this.clock = builder.clock; - this.serviceName = builder.serviceName; - this.endpoint = builder.endpoint; - this.mtlsEndpoint = builder.mtlsEndpoint; this.switchToMtlsEndpointAllowed = builder.switchToMtlsEndpointAllowed; this.quotaProjectId = builder.quotaProjectId; this.streamWatchdogProvider = builder.streamWatchdogProvider; @@ -109,7 +103,28 @@ protected StubSettings(Builder builder) { this.tracerFactory = builder.tracerFactory; this.deprecatedExecutorProviderSet = builder.deprecatedExecutorProviderSet; this.gdchApiAudience = builder.gdchApiAudience; - this.universeDomain = builder.universeDomain; + this.endpointContext = buildEndpointContext(builder); + } + + /** + * Attempt to build the EndpointContext from the Builder based on all the user configurations + * passed in. + * + * @throws RuntimeException if there is an issue building the EndpointContext + */ + private EndpointContext buildEndpointContext(Builder builder) { + try { + return EndpointContext.newBuilder() + .setServiceName(getServiceName()) + .setClientSettingsEndpoint(builder.clientSettingsEndpoint) + .setTransportChannelProviderEndpoint(builder.transportChannelProviderEndpoint) + .setMtlsEndpoint(builder.mtlsEndpoint) + .setSwitchToMtlsEndpointAllowed(builder.switchToMtlsEndpointAllowed) + .setUniverseDomain(builder.universeDomain) + .build(); + } catch (IOException e) { + throw new RuntimeException(e); + } } /** @deprecated Please use {@link #getBackgroundExecutorProvider()}. */ @@ -142,34 +157,36 @@ public final ApiClock getClock() { return clock; } - // Intended for Internal Use and Overriden by generated ServiceStubSettings classes. - // Meant to be shared between StubSettings and ClientContext. + /** + * Marked with Internal Api and meant to overriden by the generated subclasses. This getter is + * used to set the serviceName to the EndpointContext. The value in generated StubSettings + * subclasses comes from the proto files. + * + *

This should be effectively treated as an abstract method. + */ @InternalApi - public String getServiceName() { + protected String getServiceName() { return ""; } + /** @return the fully resolved universe domain used by the client */ public final String getUniverseDomain() { - return universeDomain; + return endpointContext.resolvedUniverseDomain(); } + /** @return the fully resolved endpoint used by the client */ public String getEndpoint() { - return endpoint; + return endpointContext.resolvedEndpoint(); } - /** - * This is an internal api meant to either return the user set endpoint or null. The difference - * between this method and {@link #getEndpoint()}} is that {@link #getEndpoint()} is reimplemented - * by the child class and will return the default service endpoint if the user did not set an - * endpoint (does not return null). - */ + /** @return the newly created EndpointContext */ @InternalApi - String getUserSetEndpoint() { - return endpoint; + final EndpointContext getEndpointContext() { + return endpointContext; } public final String getMtlsEndpoint() { - return mtlsEndpoint; + return endpointContext.mtlsEndpoint(); } /** Limit the visibility to this package only since only this package needs it. */ @@ -216,9 +233,9 @@ public String toString() { .add("headerProvider", headerProvider) .add("internalHeaderProvider", internalHeaderProvider) .add("clock", clock) - .add("universeDomain", universeDomain) - .add("endpoint", endpoint) - .add("mtlsEndpoint", mtlsEndpoint) + .add("universeDomain", endpointContext.resolvedUniverseDomain()) + .add("endpoint", endpointContext.resolvedEndpoint()) + .add("mtlsEndpoint", endpointContext.mtlsEndpoint()) .add("switchToMtlsEndpointAllowed", switchToMtlsEndpointAllowed) .add("quotaProjectId", quotaProjectId) .add("streamWatchdogProvider", streamWatchdogProvider) @@ -239,8 +256,8 @@ public abstract static class Builder< private HeaderProvider internalHeaderProvider; private TransportChannelProvider transportChannelProvider; private ApiClock clock; - private String serviceName; - private String endpoint; + private String clientSettingsEndpoint; + private String transportChannelProviderEndpoint; private String mtlsEndpoint; private String quotaProjectId; @Nullable private String gdchApiAudience; @@ -266,9 +283,6 @@ protected Builder(StubSettings settings) { this.headerProvider = settings.headerProvider; this.internalHeaderProvider = settings.internalHeaderProvider; this.clock = settings.clock; - this.serviceName = settings.serviceName; - this.endpoint = settings.endpoint; - this.mtlsEndpoint = settings.mtlsEndpoint; this.switchToMtlsEndpointAllowed = settings.switchToMtlsEndpointAllowed; this.quotaProjectId = settings.quotaProjectId; this.streamWatchdogProvider = settings.streamWatchdogProvider; @@ -276,7 +290,16 @@ protected Builder(StubSettings settings) { this.tracerFactory = settings.tracerFactory; this.deprecatedExecutorProviderSet = settings.deprecatedExecutorProviderSet; this.gdchApiAudience = settings.gdchApiAudience; - this.universeDomain = settings.universeDomain; + + // The follow settings will be set to the original user configurations as the + // EndpointContext will be rebuilt in the constructor. + this.clientSettingsEndpoint = settings.getEndpointContext().clientSettingsEndpoint(); + this.transportChannelProviderEndpoint = + settings.getEndpointContext().transportChannelProviderEndpoint(); + this.mtlsEndpoint = settings.getEndpointContext().mtlsEndpoint(); + this.switchToMtlsEndpointAllowed = + settings.getEndpointContext().switchToMtlsEndpointAllowed(); + this.universeDomain = settings.getEndpointContext().universeDomain(); } /** Get Quota Project ID from Client Context * */ @@ -304,8 +327,8 @@ protected Builder(ClientContext clientContext) { this.headerProvider = new NoHeaderProvider(); this.internalHeaderProvider = new NoHeaderProvider(); this.clock = NanoClock.getDefaultClock(); - this.serviceName = null; - this.endpoint = null; + this.clientSettingsEndpoint = null; + this.transportChannelProviderEndpoint = null; this.mtlsEndpoint = null; this.quotaProjectId = null; this.streamWatchdogProvider = InstantiatingWatchdogProvider.create(); @@ -326,18 +349,22 @@ protected Builder(ClientContext clientContext) { this.internalHeaderProvider = FixedHeaderProvider.create(clientContext.getInternalHeaders()); this.clock = clientContext.getClock(); - this.serviceName = clientContext.getServiceName(); - this.endpoint = clientContext.getEndpoint(); - if (this.endpoint != null) { - this.mtlsEndpoint = this.endpoint.replace("googleapis.com", "mtls.googleapis.com"); - } this.streamWatchdogProvider = FixedWatchdogProvider.create(clientContext.getStreamWatchdog()); this.streamWatchdogCheckInterval = clientContext.getStreamWatchdogCheckInterval(); this.tracerFactory = clientContext.getTracerFactory(); this.quotaProjectId = getQuotaProjectIdFromClientContext(clientContext); this.gdchApiAudience = clientContext.getGdchApiAudience(); - this.universeDomain = clientContext.getUniverseDomain(); + + // The follow settings will be set to the original user configurations as the + // EndpointContext will be rebuilt in the constructor. + this.clientSettingsEndpoint = clientContext.getEndpointContext().clientSettingsEndpoint(); + this.transportChannelProviderEndpoint = + clientContext.getEndpointContext().transportChannelProviderEndpoint(); + this.mtlsEndpoint = clientContext.getEndpointContext().mtlsEndpoint(); + this.switchToMtlsEndpointAllowed = + clientContext.getEndpointContext().switchToMtlsEndpointAllowed(); + this.universeDomain = clientContext.getEndpointContext().universeDomain(); } } @@ -427,6 +454,7 @@ protected B setInternalHeaderProvider(HeaderProvider internalHeaderProvider) { */ public B setTransportChannelProvider(TransportChannelProvider transportChannelProvider) { this.transportChannelProvider = transportChannelProvider; + this.transportChannelProviderEndpoint = transportChannelProvider.getEndpoint(); return self(); } @@ -456,10 +484,11 @@ public B setUniverseDomain(String universeDomain) { } public B setEndpoint(String endpoint) { - this.endpoint = endpoint; + this.clientSettingsEndpoint = endpoint; this.switchToMtlsEndpointAllowed = false; - if (this.endpoint != null && this.mtlsEndpoint == null) { - this.mtlsEndpoint = this.endpoint.replace("googleapis.com", "mtls.googleapis.com"); + if (this.clientSettingsEndpoint != null && this.mtlsEndpoint == null) { + this.mtlsEndpoint = + this.clientSettingsEndpoint.replace("googleapis.com", "mtls.googleapis.com"); } return self(); } @@ -556,7 +585,7 @@ public ApiClock getClock() { } public String getEndpoint() { - return endpoint; + return clientSettingsEndpoint; } public String getMtlsEndpoint() { @@ -605,7 +634,7 @@ public String toString() { .add("internalHeaderProvider", internalHeaderProvider) .add("clock", clock) .add("universeDomain", universeDomain) - .add("endpoint", endpoint) + .add("endpoint", clientSettingsEndpoint) .add("mtlsEndpoint", mtlsEndpoint) .add("switchToMtlsEndpointAllowed", switchToMtlsEndpointAllowed) .add("quotaProjectId", quotaProjectId) 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 cad4a7869a1..2f824895282 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 @@ -976,6 +976,7 @@ public void testCreateClientContext_SetEndpointViaClientSettings() throws IOExce @Test public void testCreateClientContext_SetEndpointViaTransportChannelProvider() throws IOException { + String transportChannelProviderEndpoint = "transport.endpoint.com"; TransportChannelProvider transportChannelProvider = new FakeTransportProvider( FakeTransportChannel.create(new FakeChannel()), @@ -983,7 +984,7 @@ public void testCreateClientContext_SetEndpointViaTransportChannelProvider() thr true, null, null, - DEFAULT_ENDPOINT); + transportChannelProviderEndpoint); StubSettings settings = new FakeStubSettings.Builder() .setEndpoint(null) @@ -995,8 +996,7 @@ public void testCreateClientContext_SetEndpointViaTransportChannelProvider() thr FixedCredentialsProvider.create(Mockito.mock(Credentials.class))); ClientSettings clientSettings = clientSettingsBuilder.build(); ClientContext clientContext = ClientContext.create(clientSettings); - // ClientContext.getEndpoint() currently always refers to the ClientSettingsEndpoint value - assertThat(clientContext.getEndpoint()).isEqualTo(null); + assertThat(clientContext.getEndpoint()).isEqualTo(transportChannelProviderEndpoint); assertThat(clientContext.getUniverseDomain()).isEqualTo(DEFAULT_UNIVERSE_DOMAIN); } @@ -1024,8 +1024,10 @@ public void testCreateClientContext_SetEndpointViaClientSettingsAndTransportChan FixedCredentialsProvider.create(Mockito.mock(Credentials.class))); ClientSettings clientSettings = clientSettingsBuilder.build(); ClientContext clientContext = ClientContext.create(clientSettings); - // ClientContext.getEndpoint() currently always refers to the ClientSettingsEndpoint value - assertThat(clientContext.getEndpoint()).isEqualTo(clientSettingsEndpoint); + // ClientContext.getEndpoint() is the resolved endpoint. If both the client settings + // and transport channel provider's endpoints are set, the resolved endpoint will be + // the transport channel provider's endpoint. + assertThat(clientContext.getEndpoint()).isEqualTo(transportChannelProviderEndpoint); assertThat(clientContext.getUniverseDomain()).isEqualTo(DEFAULT_UNIVERSE_DOMAIN); } 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 b39d59cbd55..bbbda6f93a5 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 @@ -205,7 +205,9 @@ public void testBuilder() throws Exception { public void testBuilderFromClientContext() throws Exception { final String QUOTA_PROJECT_ID_FROM_CONTEXT = "some_quota_project_id_from_context"; ApiClock clock = Mockito.mock(ApiClock.class); - ApiCallContext callContext = FakeCallContext.createDefault(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + ApiCallContext callContext = + FakeCallContext.createDefault().withEndpointContext(endpointContext); Map headers = Collections.singletonMap("spiffykey", "spiffyvalue"); Watchdog watchdog = Watchdog.create( @@ -442,7 +444,9 @@ public Credentials getCredentials() throws IOException { @Test public void testBuilderFromClientContext_QuotaProjectId() { - ApiCallContext callContext = FakeCallContext.createDefault(); + EndpointContext endpointContext = Mockito.mock(EndpointContext.class); + ApiCallContext callContext = + FakeCallContext.createDefault().withEndpointContext(endpointContext); ClientContext clientContextQuotaOnly = ClientContext.newBuilder() diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java index e7c6c90b1ea..77ae3d1fcad 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/testing/FakeCallContext.java @@ -44,6 +44,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Set; @@ -87,7 +88,12 @@ private FakeCallContext( this.tracer = tracer; this.retrySettings = retrySettings; this.retryableCodes = retryableCodes == null ? null : ImmutableSet.copyOf(retryableCodes); - this.endpointContext = endpointContext; + try { + this.endpointContext = + endpointContext == null ? EndpointContext.newBuilder().build() : endpointContext; + } catch (IOException e) { + throw new RuntimeException(e); + } } public static FakeCallContext createDefault() { diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/ComplianceStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/ComplianceStubSettings.java index 4b340156769..70cc559f7e0 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/ComplianceStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/ComplianceStubSettings.java @@ -273,15 +273,6 @@ public ComplianceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -715,15 +706,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public ComplianceStubSettings build() throws IOException { return new ComplianceStubSettings(this); diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/EchoStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/EchoStubSettings.java index 07a8e93d6b8..1e659ed8d71 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/EchoStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/EchoStubSettings.java @@ -432,15 +432,6 @@ public EchoStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -920,15 +911,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public EchoStubSettings build() throws IOException { return new EchoStubSettings(this); diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/IdentityStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/IdentityStubSettings.java index 69e1f50e23d..dd33ed84fb9 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/IdentityStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/IdentityStubSettings.java @@ -303,15 +303,6 @@ public IdentityStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -672,15 +663,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public IdentityStubSettings build() throws IOException { return new IdentityStubSettings(this); diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/MessagingStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/MessagingStubSettings.java index 529e1365afe..276255c45e7 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/MessagingStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/MessagingStubSettings.java @@ -445,15 +445,6 @@ public MessagingStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -994,15 +985,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public MessagingStubSettings build() throws IOException { return new MessagingStubSettings(this); diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/SequenceServiceStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/SequenceServiceStubSettings.java index f4ced6f3896..78f7af2c999 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/SequenceServiceStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/SequenceServiceStubSettings.java @@ -268,15 +268,6 @@ public SequenceServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -669,15 +660,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public SequenceServiceStubSettings build() throws IOException { return new SequenceServiceStubSettings(this); diff --git a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/TestingStubSettings.java b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/TestingStubSettings.java index 5239263cfd5..f03f92651c8 100644 --- a/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/TestingStubSettings.java +++ b/showcase/gapic-showcase/src/main/java/com/google/showcase/v1beta1/stub/TestingStubSettings.java @@ -385,15 +385,6 @@ public TestingStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns a builder for the default ExecutorProvider for this service. */ public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { return InstantiatingExecutorProvider.newBuilder(); @@ -793,15 +784,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public TestingStubSettings build() throws IOException { return new TestingStubSettings(this); 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 c7589f8e0db..ad44622471f 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 @@ -1,85 +1,429 @@ package com.google.showcase.v1beta1.it; +import static org.junit.Assert.assertThrows; + +import com.google.api.gax.core.CredentialsProvider; import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.UnauthenticatedException; +import com.google.auth.Credentials; +import com.google.auth.oauth2.GoogleCredentials; import com.google.common.truth.Truth; 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.TestClientInitializer; +import com.google.showcase.v1beta1.stub.EchoStub; +import com.google.showcase.v1beta1.stub.EchoStubSettings; +import io.grpc.ManagedChannelBuilder; import java.io.IOException; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; +import org.junit.After; import org.junit.Test; /** * This IT tests the different user configurations allowed and their effects on endpoint and * universe domain resolution. * - *

This test will be enhanced in the future when the settings are able to return the resolved - * endpoint and universe domain values. + *

In these tests, the client is not initialized with the default configuration: + * `EchoClient.create()`. For showcase tests run in CI, the client must be supplied explicitly + * supplied with a Credentials value. The tests use a wrapped Credentials and Credentials Provider + * (UniverseDomainCredentials and UniverseDomainCredentialsProvider) which allow for testing this. + * + *

Endpoint resolution has the same behavior for both gRPC and HttpJson. The showcase tests below + * only use the gRPC transport for testing. HttpJson functionality exists inside the wrapper + * classes, but is not being used. */ public class ITEndpointContext { - public static final String SHOWCASE_DEFAULT_ENDPOINT = "localhost:7469"; + /** + * Inside the test cases below, we must explicitly configure serviceName. Normally this should not + * be configured at all, but showcase clients do not have a serviceName. The ExtendStubSettings + * wrapper return the serviceName by overriding the `getServiceName()` result. + */ + private static class ExtendedEchoStubSettings extends EchoStubSettings { - // Default (no configuration) - // This test is very similar to `endpointResolution_userConfiguration`. This test is kept - // as future enhancements could allow this test to not have to explicitly set the endpoint. - @Test - public void endpointResolution_default() throws InterruptedException, IOException { - EchoClient echoClient = null; - try { - // This is not how a client is created by default: - // 1. The default usage is EchoClient.create(), but for showcase tests run in CI, the - // client must be supplied with Credentials. - // 2. The default configuration does not set an endpoint. Showcase clients do not have - // a serviceName (and this cannot be configured by the user). Set the endpoint - // to simulate the endpointContext creating it with a proper serviceName. - EchoSettings echoSettings = - EchoSettings.newBuilder() - .setCredentialsProvider(NoCredentialsProvider.create()) - .setEndpoint(SHOWCASE_DEFAULT_ENDPOINT) - .build(); - echoClient = EchoClient.create(echoSettings); - Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo(SHOWCASE_DEFAULT_ENDPOINT); - } finally { - if (echoClient != null) { - echoClient.close(); - echoClient.awaitTermination( - TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + private static final String DUMMY_MTLS_ENDPOINT = "mtls.googleapis.com:443"; + + protected ExtendedEchoStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + @Override + public String getServiceName() { + return "test"; + } + + public static ExtendedEchoStubSettings.Builder newBuilder() { + return ExtendedEchoStubSettings.Builder.createDefault(); + } + + public static ExtendedEchoStubSettings.Builder newHttpJsonBuilder() { + return ExtendedEchoStubSettings.Builder.createHttpJsonDefault(); + } + + public static class Builder extends EchoStubSettings.Builder { + + protected Builder(ClientContext clientContext) { + super(clientContext); + } + + private static ExtendedEchoStubSettings.Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setMtlsEndpoint(DUMMY_MTLS_ENDPOINT); + builder.setSwitchToMtlsEndpointAllowed(true); + return builder; + } + + private static ExtendedEchoStubSettings.Builder createHttpJsonDefault() { + Builder builder = new Builder(((ClientContext) null)); + builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setMtlsEndpoint(DUMMY_MTLS_ENDPOINT); + builder.setSwitchToMtlsEndpointAllowed(true); + return builder; + } + + @Override + public ExtendedEchoStubSettings build() throws IOException { + return new ExtendedEchoStubSettings(this); } } } + /** + * Without this ClientSettings wrapper, we must expose a serviceName setter to + * (Client|Stub)Settings and pass the StubSettings to the client. However, this will result in a + * null ClientSettings (See {@link EchoClient#create(EchoStub)}). Passing the stub to the Client + * will result in a NPE when doing `Client.getSettings().get(Endpoint|UniverseDomain)` as the + * ClientSettings is stored as null. + */ + private static class ExtendedEchoSettings extends EchoSettings { + + protected ExtendedEchoSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + public static EchoSettings.Builder newBuilder() { + return ExtendedEchoSettings.Builder.createDefault(); + } + + public static EchoSettings.Builder newHttpJsonBuilder() { + return ExtendedEchoSettings.Builder.createHttpJsonDefault(); + } + + public static class Builder extends EchoSettings.Builder { + protected Builder() throws IOException {} + + private static ExtendedEchoSettings.Builder createDefault() { + return new ExtendedEchoSettings.Builder(ExtendedEchoStubSettings.newBuilder()); + } + + private static ExtendedEchoSettings.Builder createHttpJsonDefault() { + return new ExtendedEchoSettings.Builder(ExtendedEchoStubSettings.newHttpJsonBuilder()); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + } + + protected Builder(EchoSettings settings) { + super(settings); + } + + protected Builder(ExtendedEchoStubSettings.Builder stubSettings) { + super(stubSettings); + } + } + } + + /** + * Credentials Wrapper for showcase testing which is used to override the Universe Domain value. + * + *

For the tests below, it will act as a valid Credentials and is used to test the flows where + * the user passes in a Credentials (i.e. ServiceAccount, AccessToken, Oauth, etc.) + */ + private static class UniverseDomainCredentials extends Credentials { + + private final String universeDomain; + + private UniverseDomainCredentials(String universeDomain) { + this.universeDomain = universeDomain; + } + + @Override + public String getAuthenticationType() { + return null; + } + + @Override + public Map> getRequestMetadata(URI uri) { + return new HashMap<>(); + } + + @Override + public boolean hasRequestMetadata() { + return false; + } + + @Override + public boolean hasRequestMetadataOnly() { + return false; + } + + @Override + public void refresh() { + // no-op + } + + @Override + public String getUniverseDomain() { + return universeDomain; + } + } + + /** + * CredentialsProvider wrapper to return the wrapped Universe Domain Credentials. This will return + * the custom Universe Domain value. + */ + private static class UniverseDomainCredentialsProvider implements CredentialsProvider { + + private final String universeDomain; + + public UniverseDomainCredentialsProvider(String universeDomain) { + this.universeDomain = universeDomain; + } + + public static UniverseDomainCredentialsProvider create() { + return new UniverseDomainCredentialsProvider(GoogleCredentials.GOOGLE_DEFAULT_UNIVERSE); + } + + public static UniverseDomainCredentialsProvider create(String universeDomain) { + return new UniverseDomainCredentialsProvider(universeDomain); + } + + @Override + public Credentials getCredentials() { + return new UniverseDomainCredentials(universeDomain); + } + } + + private static final String DEFAULT_ENDPOINT = "test.googleapis.com:443"; + private static final EchoRequest DEFAULT_REQUEST = + EchoRequest.newBuilder().setContent("echo").build(); + + private EchoClient echoClient; + + @After + public void cleanup() throws InterruptedException { + if (echoClient != null) { + echoClient.close(); + echoClient.awaitTermination( + TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + } + } + + // Default (no configuration) + @Test + public void endpointResolution_default() throws IOException { + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create()) + .build(); + echoClient = EchoClient.create(echoSettings); + Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo(DEFAULT_ENDPOINT); + Truth.assertThat(echoClient.getSettings().getUniverseDomain()) + .isEqualTo(GoogleCredentials.GOOGLE_DEFAULT_UNIVERSE); + } + // User configuration @Test - public void endpointResolution_userConfiguration() throws InterruptedException, IOException { + public void endpointResolution_userSetEndpoint() throws IOException { String customEndpoint = "test.com:123"; - EchoClient echoClient = null; - try { - EchoSettings echoSettings = - EchoSettings.newBuilder() - .setCredentialsProvider(NoCredentialsProvider.create()) - .setEndpoint(customEndpoint) - .build(); - echoClient = EchoClient.create(echoSettings); - Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo(customEndpoint); - } finally { - if (echoClient != null) { - echoClient.close(); - echoClient.awaitTermination( - TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); - } - } + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create()) + .setEndpoint(customEndpoint) + .build(); + echoClient = EchoClient.create(echoSettings); + Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo(customEndpoint); + Truth.assertThat(echoClient.getSettings().getUniverseDomain()) + .isEqualTo(GoogleCredentials.GOOGLE_DEFAULT_UNIVERSE); + } + + @Test + public void endpointResolution_userSetUniverseDomainAndNoUserSetEndpoint() throws IOException { + String customUniverseDomain = "random.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create()) + .setUniverseDomain(customUniverseDomain) + .build(); + echoClient = EchoClient.create(echoSettings); + // If user configured the universe domain, the endpoint is constructed from it + Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo("test.random.com:443"); + Truth.assertThat(echoClient.getSettings().getUniverseDomain()).isEqualTo(customUniverseDomain); + } + + @Test + public void endpointResolution_userSetEndpointAndUniverseDomain() throws IOException { + String customEndpoint = "custom.endpoint.com:443"; + String customUniverseDomain = "random.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create()) + .setEndpoint(customEndpoint) + .setUniverseDomain(customUniverseDomain) + .build(); + echoClient = EchoClient.create(echoSettings); + // Custom Endpoint sets the endpoint for the client to use + Truth.assertThat(echoClient.getSettings().getEndpoint()).isEqualTo(customEndpoint); + // The universe domain doesn't match the endpoint. The call will fail validation when RPC is + // called. + Truth.assertThat(echoClient.getSettings().getUniverseDomain()).isEqualTo(customUniverseDomain); + } + + @Test + public void universeDomainValidation_credentialsGDU_noUserConfiguration() throws IOException { + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create()) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + // Does not throw an error + echoClient.echo(DEFAULT_REQUEST); + } + + @Test + public void universeDomainValidation_credentialsNonGDU_noUserConfiguration() throws IOException { + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create("random.com")) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + UnauthenticatedException exception = + assertThrows(UnauthenticatedException.class, () -> echoClient.echo(DEFAULT_REQUEST)); + Truth.assertThat(exception.getMessage()) + .contains( + "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (random.com)."); + } + + @Test + public void universeDomainValidation_credentialsNonGDUMatchesUserConfiguration() + throws IOException { + String universeDomain = "random.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create(universeDomain)) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setUniverseDomain(universeDomain) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + // Does not throw an error + echoClient.echo(DEFAULT_REQUEST); + } + + @Test + public void universeDomainValidation_credentialsNonGDUDoesNotMatchUserConfiguration() + throws IOException { + String universeDomain = "random.com"; + String userConfigurationUniverseDomain = "test.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(UniverseDomainCredentialsProvider.create(universeDomain)) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setUniverseDomain(userConfigurationUniverseDomain) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + UnauthenticatedException exception = + assertThrows(UnauthenticatedException.class, () -> echoClient.echo(DEFAULT_REQUEST)); + Truth.assertThat(exception.getMessage()) + .contains( + "The configured universe domain (test.com) does not match the universe domain found in the credentials (random.com)."); + } + + // This test uses NoCredentialsProvider (will default to GDU) + @Test + public void universeDomainValidation_noCredentials_noUserSetUniverseDomain() throws IOException { + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(NoCredentialsProvider.create()) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + // Does not throw an error + echoClient.echo(DEFAULT_REQUEST); + } + + // This test uses NoCredentialsProvider (will default to GDU) + @Test + public void universeDomainValidation_noCredentials_userSetUniverseDomain() throws IOException { + String universeDomain = "random.com"; + EchoSettings echoSettings = + ExtendedEchoSettings.newBuilder() + .setCredentialsProvider(NoCredentialsProvider.create()) + .setEndpoint(TestClientInitializer.DEFAULT_GRPC_ENDPOINT) + .setUniverseDomain(universeDomain) + .setTransportChannelProvider( + EchoSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .build()) + .build(); + echoClient = EchoClient.create(echoSettings); + + UnauthenticatedException exception = + assertThrows(UnauthenticatedException.class, () -> echoClient.echo(DEFAULT_REQUEST)); + Truth.assertThat(exception.getMessage()) + .contains( + "The configured universe domain (random.com) does not match the universe domain found in the credentials (googleapis.com)."); } // Default in Builder (no configuration) @Test - public void endpointResolution_defaultBuilder() { + public void endpointResolution_defaultViaBuilder() { EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder(); - Truth.assertThat(echoSettingsBuilder.getEndpoint()).isEqualTo(SHOWCASE_DEFAULT_ENDPOINT); + // The getter in the builder returns the user set value. No configuration + // means the getter will return null + Truth.assertThat(echoSettingsBuilder.getEndpoint()).isEqualTo(null); } // User configuration in Builder @Test - public void endpointResolution_userConfigurationBuilder() { + public void endpointResolution_userConfigurationViaBuilder() { String customEndpoint = "test.com:123"; EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder().setEndpoint(customEndpoint); diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java index f396a0fc6fd..f8912fdefaf 100644 --- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java +++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java @@ -44,6 +44,12 @@ public class TestClientInitializer { public static final int AWAIT_TERMINATION_SECONDS = 10; + // gRPC's endpoint must follow the format of {host}:{port} + public static final String DEFAULT_GRPC_ENDPOINT = "localhost:7469"; + // httpjson's endpoint uses `https://` by default if the scheme is not specified + // local test requires `http://` as not SSL/TLS has been set up for showcase + public static final String DEFAULT_HTTPJSON_ENDPOINT = "http://localhost:7469"; + public static EchoClient createGrpcEchoClient() throws Exception { return createGrpcEchoClient(ImmutableList.of()); } @@ -58,7 +64,7 @@ public static EchoClient createGrpcEchoClient(List intercepto .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .setInterceptorProvider(() -> interceptorList) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return EchoClient.create(grpcEchoSettings); } @@ -83,7 +89,7 @@ public static EchoClient createGrpcEchoClientWithRetrySettings( .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .setInterceptorProvider(() -> interceptorList) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return EchoClient.create(grpcEchoSettings); } @@ -101,7 +107,7 @@ public static EchoClient createHttpJsonEchoClient(List interceptorList) .build()) .build(); @@ -128,7 +134,7 @@ public static EchoClient createHttpJsonEchoClientWithRetrySettings( .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) .setInterceptorProvider(() -> interceptorList) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .build()) .build(); return EchoClient.create(httpJsonEchoSettings); @@ -150,7 +156,7 @@ public static EchoClient createGrpcEchoClientCustomBlockSettings( EchoSettings.defaultGrpcTransportProviderBuilder() .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return EchoClient.create(grpcEchoSettings); } @@ -171,7 +177,7 @@ public static EchoClient createHttpJsonEchoClientCustomBlockSettings( EchoSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .build()) .build(); return EchoClient.create(httpJsonEchoSettings); @@ -197,7 +203,7 @@ public static EchoClient createGrpcEchoClientCustomWaitSettings( EchoSettings.defaultGrpcTransportProviderBuilder() .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return EchoClient.create(grpcEchoSettings); } @@ -222,7 +228,7 @@ public static EchoClient createHttpJsonEchoClientCustomWaitSettings( EchoSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .build()) .build(); return EchoClient.create(httpJsonEchoSettings); @@ -236,7 +242,7 @@ public static IdentityClient createGrpcIdentityClient() throws Exception { IdentitySettings.defaultGrpcTransportProviderBuilder() .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return IdentityClient.create(grpcIdentitySettings); } @@ -249,7 +255,7 @@ public static IdentityClient createHttpJsonIdentityClient() throws Exception { EchoSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .build()) .build(); return IdentityClient.create(httpjsonIdentitySettings); @@ -266,7 +272,7 @@ public static ComplianceClient createGrpcComplianceClient(List interceptorList) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); return ComplianceClient.create(grpcComplianceSettings); } @@ -280,7 +286,7 @@ public static ComplianceClient createHttpJsonComplianceClient( EchoSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .setInterceptorProvider(() -> interceptorList) .build()) .build(); @@ -297,7 +303,7 @@ public static EchoClient createGrpcEchoClientOpentelemetry(ApiTracerFactory metr EchoSettings.defaultGrpcTransportProviderBuilder() .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .build()) - .setEndpoint("localhost:7469") + .setEndpoint(DEFAULT_GRPC_ENDPOINT) .build(); EchoStubSettings echoStubSettings = @@ -322,7 +328,7 @@ public static EchoClient createHttpJsonEchoClientOpentelemetry( EchoSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport( new NetHttpTransport.Builder().doNotValidateCertificate().build()) - .setEndpoint("http://localhost:7469") + .setEndpoint(DEFAULT_HTTPJSON_ENDPOINT) .build()) .build(); diff --git a/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/ConnectionServiceStubSettings.java b/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/ConnectionServiceStubSettings.java index c0c4b6f1d23..413e4a74e32 100644 --- a/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/ConnectionServiceStubSettings.java +++ b/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/ConnectionServiceStubSettings.java @@ -182,15 +182,6 @@ public ConnectionServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -405,15 +396,6 @@ public Builder applyToAllUnaryMethods( return listConnectionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public ConnectionServiceStubSettings build() throws IOException { return new ConnectionServiceStubSettings(this); diff --git a/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/TetherStubSettings.java b/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/TetherStubSettings.java index 37975bc147d..f12b23a81d5 100644 --- a/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/TetherStubSettings.java +++ b/test/integration/goldens/apigeeconnect/src/com/google/cloud/apigeeconnect/v1/stub/TetherStubSettings.java @@ -101,15 +101,6 @@ public TetherStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -266,15 +257,6 @@ public StreamingCallSettings.Builder egressSettin return egressSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public TetherStubSettings build() throws IOException { return new TetherStubSettings(this); diff --git a/test/integration/goldens/asset/src/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java b/test/integration/goldens/asset/src/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java index 576f6ec1a29..1133cadb5c0 100644 --- a/test/integration/goldens/asset/src/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java +++ b/test/integration/goldens/asset/src/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java @@ -571,15 +571,6 @@ public AssetServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -1292,15 +1283,6 @@ public UnaryCallSettings.Builder deleteSavedQuer return batchGetEffectiveIamPoliciesSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public AssetServiceStubSettings build() throws IOException { return new AssetServiceStubSettings(this); diff --git a/test/integration/goldens/bigtable/src/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java b/test/integration/goldens/bigtable/src/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java index c0957a1c5d6..410c6637d66 100644 --- a/test/integration/goldens/bigtable/src/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java +++ b/test/integration/goldens/bigtable/src/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java @@ -165,15 +165,6 @@ public BigtableStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -493,15 +484,6 @@ public UnaryCallSettings.Builder mutateRowS return readModifyWriteRowSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public BigtableStubSettings build() throws IOException { return new BigtableStubSettings(this); diff --git a/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/AddressesStubSettings.java b/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/AddressesStubSettings.java index 51eff66198f..fdc5e7201d8 100644 --- a/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/AddressesStubSettings.java +++ b/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/AddressesStubSettings.java @@ -288,15 +288,6 @@ public AddressesStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -600,15 +591,6 @@ public UnaryCallSettings.Builder insertSettings return listSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public AddressesStubSettings build() throws IOException { return new AddressesStubSettings(this); diff --git a/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/RegionOperationsStubSettings.java b/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/RegionOperationsStubSettings.java index 77fb5672b3a..3d8580ad27e 100644 --- a/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/RegionOperationsStubSettings.java +++ b/test/integration/goldens/compute/src/com/google/cloud/compute/v1small/stub/RegionOperationsStubSettings.java @@ -113,15 +113,6 @@ public RegionOperationsStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -320,15 +311,6 @@ public UnaryCallSettings.Builder waitSett return waitSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public RegionOperationsStubSettings build() throws IOException { return new RegionOperationsStubSettings(this); diff --git a/test/integration/goldens/credentials/src/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java b/test/integration/goldens/credentials/src/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java index a29f5a33e5e..d8b9ff9466b 100644 --- a/test/integration/goldens/credentials/src/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java +++ b/test/integration/goldens/credentials/src/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java @@ -140,15 +140,6 @@ public IamCredentialsStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -413,15 +404,6 @@ public UnaryCallSettings.Builder signJwtSetting return signJwtSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public IamCredentialsStubSettings build() throws IOException { return new IamCredentialsStubSettings(this); diff --git a/test/integration/goldens/iam/src/com/google/iam/v1/stub/IAMPolicyStubSettings.java b/test/integration/goldens/iam/src/com/google/iam/v1/stub/IAMPolicyStubSettings.java index 7cd4b77680f..f44ac7c3630 100644 --- a/test/integration/goldens/iam/src/com/google/iam/v1/stub/IAMPolicyStubSettings.java +++ b/test/integration/goldens/iam/src/com/google/iam/v1/stub/IAMPolicyStubSettings.java @@ -118,15 +118,6 @@ public IAMPolicyStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -329,15 +320,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public IAMPolicyStubSettings build() throws IOException { return new IAMPolicyStubSettings(this); diff --git a/test/integration/goldens/kms/src/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java b/test/integration/goldens/kms/src/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java index cffe8d0f1b2..2dc17089fca 100644 --- a/test/integration/goldens/kms/src/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java +++ b/test/integration/goldens/kms/src/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java @@ -638,15 +638,6 @@ public KeyManagementServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -1302,15 +1293,6 @@ public UnaryCallSettings.Builder getLocationSettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public KeyManagementServiceStubSettings build() throws IOException { return new KeyManagementServiceStubSettings(this); diff --git a/test/integration/goldens/library/src/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java b/test/integration/goldens/library/src/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java index 1a9e248aac3..eca61c2fb11 100644 --- a/test/integration/goldens/library/src/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java +++ b/test/integration/goldens/library/src/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java @@ -306,15 +306,6 @@ public LibraryServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -707,15 +698,6 @@ public UnaryCallSettings.Builder moveBookSettings() { return moveBookSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public LibraryServiceStubSettings build() throws IOException { return new LibraryServiceStubSettings(this); diff --git a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java index 2d27a6965db..c4f2a621a43 100644 --- a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java +++ b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java @@ -546,15 +546,6 @@ public ConfigServiceV2Stub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -1205,15 +1196,6 @@ public UnaryCallSettings.Builder copyLogEntrie return copyLogEntriesOperationSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public ConfigServiceV2StubSettings build() throws IOException { return new ConfigServiceV2StubSettings(this); diff --git a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java index 7f8e5453d81..f994abe3766 100644 --- a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java +++ b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java @@ -437,15 +437,6 @@ public LoggingServiceV2Stub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -754,15 +745,6 @@ public UnaryCallSettings.Builder deleteLogSettings() { return tailLogEntriesSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public LoggingServiceV2StubSettings build() throws IOException { return new LoggingServiceV2StubSettings(this); diff --git a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java index 8b156880994..f8df3e60156 100644 --- a/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java +++ b/test/integration/goldens/logging/src/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java @@ -205,15 +205,6 @@ public MetricsServiceV2Stub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -471,15 +462,6 @@ public UnaryCallSettings.Builder deleteLogMetricS return deleteLogMetricSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public MetricsServiceV2StubSettings build() throws IOException { return new MetricsServiceV2StubSettings(this); diff --git a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java index 2906f095e27..11baddd298d 100644 --- a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java +++ b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java @@ -471,15 +471,6 @@ public PublisherStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -901,15 +892,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public PublisherStubSettings build() throws IOException { return new PublisherStubSettings(this); diff --git a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java index b94de2050a7..95a895f4190 100644 --- a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java +++ b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java @@ -330,15 +330,6 @@ public SchemaServiceStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -714,15 +705,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public SchemaServiceStubSettings build() throws IOException { return new SchemaServiceStubSettings(this); diff --git a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java index 8de5f77641d..18e54d37b18 100644 --- a/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java +++ b/test/integration/goldens/pubsub/src/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java @@ -376,15 +376,6 @@ public SubscriberStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -895,15 +886,6 @@ public UnaryCallSettings.Builder getIamPolicySettin return testIamPermissionsSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public SubscriberStubSettings build() throws IOException { return new SubscriberStubSettings(this); diff --git a/test/integration/goldens/redis/src/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java b/test/integration/goldens/redis/src/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java index 3b256b283c6..1d5130e20bc 100644 --- a/test/integration/goldens/redis/src/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java +++ b/test/integration/goldens/redis/src/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java @@ -323,15 +323,6 @@ public CloudRedisStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -991,15 +982,6 @@ public UnaryCallSettings.Builder deleteInstanc return rescheduleMaintenanceOperationSettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public CloudRedisStubSettings build() throws IOException { return new CloudRedisStubSettings(this); diff --git a/test/integration/goldens/storage/src/com/google/storage/v2/stub/StorageStubSettings.java b/test/integration/goldens/storage/src/com/google/storage/v2/stub/StorageStubSettings.java index 253690acea0..11482952a20 100644 --- a/test/integration/goldens/storage/src/com/google/storage/v2/stub/StorageStubSettings.java +++ b/test/integration/goldens/storage/src/com/google/storage/v2/stub/StorageStubSettings.java @@ -588,15 +588,6 @@ public StorageStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - /** Returns the default service name. */ @Override public String getServiceName() { @@ -1271,15 +1262,6 @@ public UnaryCallSettings.Builder getHmacKeyS return updateHmacKeySettings; } - /** Returns the endpoint set by the user or the the service's default endpoint. */ - @Override - public String getEndpoint() { - if (super.getEndpoint() != null) { - return super.getEndpoint(); - } - return getDefaultEndpoint(); - } - @Override public StorageStubSettings build() throws IOException { return new StorageStubSettings(this); From d0c5191525d5d157812cae9551fc15bb70caab7e Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 2 Apr 2024 20:13:35 +0000 Subject: [PATCH 3/3] feat: Add ChannelPoolSettings Getter for gRPC's ChannelProvider (#2612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2610 ☕️ --------- Co-authored-by: Joe Wang <106995533+JoeWang1127@users.noreply.github.com> --- .../api/gax/grpc/InstantiatingGrpcChannelProvider.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 bf8ffc81da7..5969ed4693e 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 @@ -473,6 +473,12 @@ public Integer getMaxInboundMetadataSize() { return maxInboundMetadataSize; } + /** The configured channel pool settings used for gRPC's ChannelProvider */ + @BetaApi("Channel pool sizing api is not yet stable") + public ChannelPoolSettings getChannelPoolSettings() { + return channelPoolSettings; + } + @Override public boolean shouldAutoClose() { return true;