diff --git a/.github/snippet-bot.yml b/.github/snippet-bot.yml new file mode 100644 index 0000000000..51d12e4120 --- /dev/null +++ b/.github/snippet-bot.yml @@ -0,0 +1,2 @@ +aggregateChecks: false +alwaysCreateStatusCheck: false \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1b5b979aaf..dbf5754794 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -49,7 +49,7 @@ jobs: run: bazel --batch test $(bazel query "//src/test/..." | grep "Test$") --noshow_progress --test_output=errors - name: Integration Tests - run: bazel --batch test //test/integration:asset //test/integration:credentials //test/integration:iam //test/integration:kms //test/integration:logging //test/integration:pubsub //test/integration:redis //test/integration:library --noshow_progress + run: bazel --batch test //test/integration/... - uses: actions/upload-artifact@v2 if: ${{ failure() }} diff --git a/BUILD.bazel b/BUILD.bazel index 8823250fca..913c6d063a 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -8,14 +8,17 @@ load( package(default_visibility = ["//visibility:public"]) JAVA_SRCS = [ + "//src/main/java/com/google/api/generator/debug:debug_files", "//src/main/java/com/google/api/generator:generator_files", "//src/main/java/com/google/api/generator/engine:engine_files", "//src/main/java/com/google/api/generator/gapic:gapic_files", + "//src/main/java/com/google/api/generator/util:util_files", ] TEST_SRCS = [ "//src/test/java/com/google/api/generator/engine:engine_files", "//src/test/java/com/google/api/generator/gapic:gapic_files", + "//src/test/java/com/google/api/generator/testutils:testutils_files", "//src/test/java/com/google/api/generator/util:util_files", "//src/test/java/com/google/api/generator/test/framework:framework_files", ] @@ -45,6 +48,57 @@ java_binary( ], ) +# Request dumper binary, which dumps the CodeGeneratorRequest to a file on disk +# which will be identical to the one passed to the protoc-gen-java_gapic during +# normal execution. The dumped file then can be used to run this gapic-generator +# directly (instead of relying on protoc to start the process), which would give +# much greater flexibility in terms of debugging features, like attaching a +# debugger, easier work with stdout and stderr etc. +# +# Usage example, via the rule in a corresponding BUILD.bazel file: +# +# load("@gapic_generator_java//rules_java_gapic:java_gapic.bzl", "java_generator_request_dump") +# java_generator_request_dump( +# name = "compute_small_request_dump", +# srcs = [":compute_small_proto_with_info"], +# transport = "rest", +# ) +# +java_binary( + name = "protoc-gen-code_generator_request_dumper", + main_class = "com.google.api.generator.debug.CodeGeneratorRequestDumper", + runtime_deps = [ + "//src/main/java/com/google/api/generator", + "//src/main/java/com/google/api/generator/debug", + "//src/main/java/com/google/api/generator/gapic", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + ], +) + +# A binary similar to protoc-gen-java_gapic but reads the CodeGeneratorRequest +# directly from a file instead of relying on protoc to pipe it in. +# +# Usage example: +# +# bazel run code_generator_request_file_to_gapic_main desc-dump.bin dump.jar +# +java_binary( + name = "code_generator_request_file_to_gapic_main", + main_class = "com.google.api.generator.debug.CodeGeneratorRequestFileToGapicMain", + runtime_deps = [ + "//src/main/java/com/google/api/generator", + "//src/main/java/com/google/api/generator/debug", + "//src/main/java/com/google/api/generator/gapic", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + ], +) + # google-java-format java_binary( name = "google_java_format_binary", diff --git a/CHANGELOG.md b/CHANGELOG.md index 03abe4a067..47548ec096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,131 @@ # Changelog +## [2.1.0](https://www.github.com/googleapis/gapic-generator-java/compare/v2.0.1...v2.1.0) (2021-08-17) + + +### Features + +* enable self signed jwt for gapic clients ([#794](https://www.github.com/googleapis/gapic-generator-java/issues/794)) ([1b7ee1e](https://www.github.com/googleapis/gapic-generator-java/commit/1b7ee1e3911e1c8ecab9a94d68d7a59b437d2449)) + +### [2.0.1](https://www.github.com/googleapis/gapic-generator-java/compare/v2.0.0...v2.0.1) (2021-08-06) + + +### Bug Fixes + +* bring back unused resnames for Ads ([#821](https://www.github.com/googleapis/gapic-generator-java/issues/821)) ([7fa135c](https://www.github.com/googleapis/gapic-generator-java/commit/7fa135c9aa60c9cb15880e098d36ea81b95ea488)) +* **resnames:** ensure deterministic resname order for samplegen ([#813](https://www.github.com/googleapis/gapic-generator-java/issues/813)) ([c4709df](https://www.github.com/googleapis/gapic-generator-java/commit/c4709df5d8ed9f0074f7e25df5db93e9d9b35749)) + +## [2.0.0](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.17...v2.0.0) (2021-08-03) + + +### ⚠ BREAKING CHANGES + +* remove Exception, unused resname classes for Java major version bump (#814) + +### Features + +* Lambda-ize single-method anon classes (Java 8+) ([#815](https://www.github.com/googleapis/gapic-generator-java/issues/815)) ([19b661c](https://www.github.com/googleapis/gapic-generator-java/commit/19b661cc78757e37ce93bae96eb81cb4ac32658b)) +* remove Exception, unused resname classes for Java major version bump ([#814](https://www.github.com/googleapis/gapic-generator-java/issues/814)) ([8abece2](https://www.github.com/googleapis/gapic-generator-java/commit/8abece20dd20e9ac8134df04301ce5b6e2ab76ad)) + +### [1.0.17](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.16...v1.0.17) (2021-08-02) + + +### Features + +* **ast:** Add support for multi-catch blocks [ggj] ([#811](https://www.github.com/googleapis/gapic-generator-java/issues/811)) ([55ef1a6](https://www.github.com/googleapis/gapic-generator-java/commit/55ef1a63427683538e48050333eedb0666635568)) +* **ast:** Add support for Throwable causes [ggj] ([#801](https://www.github.com/googleapis/gapic-generator-java/issues/801)) ([7fdeece](https://www.github.com/googleapis/gapic-generator-java/commit/7fdeeced7642fefdfdc5c6e898661c72fe9d78a8)) +* **ast:** support throwing all kinds of expressions ([#810](https://www.github.com/googleapis/gapic-generator-java/issues/810)) ([0817650](https://www.github.com/googleapis/gapic-generator-java/commit/0817650b35487f32d7987ba718ce71fc7551e3a0)) + + +### Bug Fixes + +* (rest transport) Add `@BetaApi` to the generated `TransportServiceFactory` class and lro-specific method ([#787](https://www.github.com/googleapis/gapic-generator-java/issues/787)) ([ebe1aef](https://www.github.com/googleapis/gapic-generator-java/commit/ebe1aefbe860a41aabd8ced5268ccc6c7efdf791)) +* prevent hanging by call backgroundResources.close() on stub.close() [ggj] ([#804](https://www.github.com/googleapis/gapic-generator-java/issues/804)) ([428db97](https://www.github.com/googleapis/gapic-generator-java/commit/428db97c1534255a60530a8ed6137efc17ed56f4)) +* **resnames:** fallback to fully-qualified Object name upon proto typing conflicts [ggj] ([#803](https://www.github.com/googleapis/gapic-generator-java/issues/803)) ([e654bfb](https://www.github.com/googleapis/gapic-generator-java/commit/e654bfb936b571af2546f550c9a1589f8ad63d67)) + + + +### [1.0.16](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.15...v1.0.16) (2021-06-30) + + +### Bug Fixes + +* **bazel:** Eradicate monolith deps from Java µgen repo ([#778](https://www.github.com/googleapis/gapic-generator-java/issues/778)) ([86f2472](https://www.github.com/googleapis/gapic-generator-java/commit/86f2472963f020127ef6ff92be6241d12e2273af)) +* **build:** Update googleapis-discovery hash to fix compute integration test ([#782](https://www.github.com/googleapis/gapic-generator-java/issues/782)) ([46bb19a](https://www.github.com/googleapis/gapic-generator-java/commit/46bb19a7ee61da86b4be6d87a71f3cd210e753d2)) +* **protoc:** Mirror protoc's field name conflict resolution logic in client generation ([#781](https://www.github.com/googleapis/gapic-generator-java/issues/781)) ([9432979](https://www.github.com/googleapis/gapic-generator-java/commit/9432979bab59f48c8645fa47d752cdd470d4a682)) + +### [1.0.15](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.14...v1.0.15) (2021-06-22) + + +### Features + +* Implement field presence support for DIREGAPIC ([#774](https://www.github.com/googleapis/gapic-generator-java/issues/774)) ([c820361](https://www.github.com/googleapis/gapic-generator-java/commit/c82036105d299b0a1192cd0def5e68253e4f542c)) + + +### Bug Fixes + +* **service.yaml:** Remove allowlist restriction ([#776](https://www.github.com/googleapis/gapic-generator-java/issues/776)) ([8f42efd](https://www.github.com/googleapis/gapic-generator-java/commit/8f42efdb92d606a768a524517fe949c4f9112025)) + + +### Miscellaneous Chores + +* release 1.0.15 ([f752478](https://www.github.com/googleapis/gapic-generator-java/commit/f75247845344540a94c4efcd416f34f96ea0c2a3)) + +### [1.0.14](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.13...v1.0.14) (2021-06-17) + + +### Features + +* Add DIREGAPIC-specific pagination ([#767](https://www.github.com/googleapis/gapic-generator-java/issues/767)) ([1294c29](https://www.github.com/googleapis/gapic-generator-java/commit/1294c298f50cc4474ae562e6a07f37a5f94fe5b8)) + + +### Bug Fixes + +* **bazel:** Remove monolith rule deps from the Java µgen Bazel rules ([#764](https://www.github.com/googleapis/gapic-generator-java/issues/764)) ([bff3efc](https://www.github.com/googleapis/gapic-generator-java/commit/bff3efc25e43692ea5b6e769c20d25d5b9a1e3d2)) + + + +### [1.0.13](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.12...v1.0.13) (2021-06-16) + + +### Bug Fixes + +* **resnames:** Fix resname builder name conflicts in ctor with this assignment ([#769](https://www.github.com/googleapis/gapic-generator-java/issues/769)) ([edac844](https://www.github.com/googleapis/gapic-generator-java/commit/edac8447d74c43ab0db963a37f66e1029ab19f0c)) + +### [1.0.12](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.11...v1.0.12) (2021-06-10) + + +### Features + +* add mtls support ([#672](https://www.github.com/googleapis/gapic-generator-java/issues/672)) ([1e24893](https://www.github.com/googleapis/gapic-generator-java/commit/1e24893a65daf8ef067e331364c591ac973b5e02)) + + +### Bug Fixes + +* **mocks:** Use java.lang.Object if there are protos named 'Object' ([#760](https://www.github.com/googleapis/gapic-generator-java/issues/760)) ([2a7064b](https://www.github.com/googleapis/gapic-generator-java/commit/2a7064b88fe26586bd8aed43b7a7d28c7e974ec0)) +* **resnames:** Use anon resname classes when only wildcards are present ([#763](https://www.github.com/googleapis/gapic-generator-java/issues/763)) ([f0ecead](https://www.github.com/googleapis/gapic-generator-java/commit/f0ecead9f1cc645cdbb7f61cdfc820c7df95355d)) + + +### Miscellaneous Chores + +* release 1.0.12 ([02eab0e](https://www.github.com/googleapis/gapic-generator-java/commit/02eab0ec61260048a2684119cfd4fa2172f3a637)) + +### [1.0.11](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.10...v1.0.11) (2021-06-07) + + +### Features + +* DIREGAPIC initial implementation ([#746](https://www.github.com/googleapis/gapic-generator-java/issues/746)) ([81f6737](https://www.github.com/googleapis/gapic-generator-java/commit/81f6737359ac6ce5ee2b42ab4f755fbb05a3cf28)) + + +### Bug Fixes + +* **bazel:** ensure integration tests diff files recursively ([#745](https://www.github.com/googleapis/gapic-generator-java/issues/745)) ([ddc75f9](https://www.github.com/googleapis/gapic-generator-java/commit/ddc75f9f3b84d0ea50638a79a63d40cf551211e2)) +* **resnames:** filter out mixin services from resname pkg candidates ([#751](https://www.github.com/googleapis/gapic-generator-java/issues/751)) ([72fa76f](https://www.github.com/googleapis/gapic-generator-java/commit/72fa76f27379a74a143b1735f60ae3e00da4c1a6)) +* **tests:** Ensure deterministic field ordering in test classes ([#743](https://www.github.com/googleapis/gapic-generator-java/issues/743)) ([fdb705b](https://www.github.com/googleapis/gapic-generator-java/commit/fdb705b0a39443fb0b7679d879f27e0aa1c36b67)) +* **tests:** handle Java 11 set ordering differences for RPCs and fields in test/mock classes ([#750](https://www.github.com/googleapis/gapic-generator-java/issues/750)) ([eaf4592](https://www.github.com/googleapis/gapic-generator-java/commit/eaf4592e139fbc42810e7f60dc9967320195bf85)) + + ### [1.0.10](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.9...v1.0.10) (2021-05-26) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 144b904963..ce5fec73c5 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -15,17 +15,17 @@ ## Running the Plugin 1. Clone [googleapis](https://github.com/googleapis/googleapis) and - [gapic-showcase](https://github.com/googleapis/gapic-showcase/) and install - protoc. + [gapic-showcase](https://github.com/googleapis/gapic-showcase/). 2. Copy the protos from Showcase into googleapis/google/showcase. ```sh - cp gapic-showcase/schema/google/showcase/v1beta1 googleapis/google/showcase/v1beta + mkdir googleapis/google/showcase + cp -r gapic-showcase/schema/google/showcase/v1beta1 googleapis/google/showcase/v1beta1 ``` -3. Add the new microgenerator rules to the protobuf directory's `BUILD.bazel` - file as follows: +3. Add the new microgenerator rules to + `googleapis/google/showcase/v1beta1/BUILD.bazel` file as follows: ```python load( @@ -33,6 +33,22 @@ # Existing rules here. "java_gapic_assembly_gradle_pkg", "java_gapic_library", + "java_proto_library", + "proto_library_with_info", + ) + + proto_library_with_info( + name = "showcase_proto_with_info", + deps = [ + ":showcase_proto", + ], + ) + + java_proto_library( + name = "showcase_java_proto", + deps = [ + "showcase_proto", + ], ) # This should either replace the existing monolith target or have a unique name @@ -97,13 +113,6 @@ bazel run //src/test/java/com/google/api/generator/engine:JavaCodeGeneratorTest ``` -- Update goldens files based on code generation in unit test, for example - `JavaCodeGeneratorTest.java` - - ```sh - bazel run //src/test/java/com/google/api/generator/engine:JavaCodeGeneratorTest_update - ``` - - Run a single integration test for API like `Redis`, it generates Java source code using the Java microgenerator and compares them with the goldens files in `test/integration/goldens/redis`. @@ -112,10 +121,20 @@ bazel test //test/integration:redis ``` -- Update goldens files based on code generation in integration test, for - example `Redis`. It generates Java source code using the Java microgenerator - and overwrites the goldens files in `test/integration/goldens/redis` based - on code generation. +- Run all unit and integration tests. + + ```sh + bazel test $(bazel query "src/test/..." | grep "Test$") //test/integration/... + ``` + +- Update unit test golden files, for example `JavaCodeGeneratorTest.java`: + + ```sh + bazel run //src/test/java/com/google/api/generator/engine:JavaCodeGeneratorTest_update + ``` + +- Update integration test golden files, for example `Redis`. This clobbers all the + files in `test/integration/goldens/redis`. ```sh bazel run //test/integration:redis_update diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..8b58ae9c01 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. diff --git a/WORKSPACE b/WORKSPACE index 23ba819432..cd8e22e196 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,6 +1,7 @@ workspace(name = "gapic_generator_java") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_maven_import_external") # DO NOT REMOVE. # This is needed to clobber any transitively-pulled in versions of bazel_skylib so that packages @@ -14,6 +15,42 @@ http_archive( ], ) +jvm_maven_import_external( + name = "google_java_format_all_deps", + artifact = "com.google.googlejavaformat:google-java-format:jar:all-deps:1.7", + licenses = [ + "notice", + "reciprocal", + ], + server_urls = [ + "https://repo.maven.apache.org/maven2/", + "http://repo1.maven.org/maven2/", + ], +) + +# gax-java and its transitive dependencies must be imported before +# gapic-generator-java dependencies to match the order in googleapis repository, +# which in its turn, prioritizes actual generated clients runtime dependencies +# over the generator dependencies. +_gax_java_version = "2.3.0" + +http_archive( + name = "com_google_api_gax_java", + strip_prefix = "gax-java-%s" % _gax_java_version, + urls = ["https://github.com/googleapis/gax-java/archive/v%s.zip" % _gax_java_version], +) + +load("@com_google_api_gax_java//:repository_rules.bzl", "com_google_api_gax_java_properties") + +com_google_api_gax_java_properties( + name = "com_google_api_gax_java_properties", + file = "@com_google_api_gax_java//:dependencies.properties", +) + +load("@com_google_api_gax_java//:repositories.bzl", "com_google_api_gax_java_repositories") + +com_google_api_gax_java_repositories() + load("//:repository_rules.bzl", "gapic_generator_java_properties") gapic_generator_java_properties( @@ -31,14 +68,16 @@ load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") protobuf_deps() -# Java dependencies. -# Import the monolith so we can transitively use its gapic rules for googleapis. +# Bazel rules. +_rules_gapic_version = "0.5.5" + http_archive( - name = "com_google_api_codegen", - strip_prefix = "gapic-generator-2.4.6", - urls = ["https://github.com/googleapis/gapic-generator/archive/v2.4.6.zip"], + name = "rules_gapic", + strip_prefix = "rules_gapic-%s" % _rules_gapic_version, + urls = ["https://github.com/googleapis/rules_gapic/archive/v%s.tar.gz" % _rules_gapic_version], ) +# Java dependencies. load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language") switched_rules_by_language( @@ -48,25 +87,12 @@ switched_rules_by_language( java = True, ) -_gax_java_version = PROPERTIES["version.com_google_gax_java"] - -http_archive( - name = "com_google_api_gax_java", - strip_prefix = "gax-java-%s" % _gax_java_version, - urls = ["https://github.com/googleapis/gax-java/archive/v%s.zip" % _gax_java_version], -) - -load("@com_google_api_gax_java//:repository_rules.bzl", "com_google_api_gax_java_properties") - -com_google_api_gax_java_properties( - name = "com_google_api_gax_java_properties", - file = "@com_google_api_gax_java//:dependencies.properties", -) - -load("@com_google_api_gax_java//:repositories.bzl", "com_google_api_gax_java_repositories") - -com_google_api_gax_java_repositories() - load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories") grpc_java_repositories() + +http_archive( + name = "com_google_disco_to_proto3_converter", + strip_prefix = "disco-to-proto3-converter-4b0956884b1aa9b367cf41488b622dc12eb16652", + urls = ["https://github.com/googleapis/disco-to-proto3-converter/archive/4b0956884b1aa9b367cf41488b622dc12eb16652.zip"], +) diff --git a/dependencies.properties b/dependencies.properties index 841111924b..75e53a6461 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -4,14 +4,13 @@ # The properties format is the following: # [.]= -# Target workspace name: com_google_api_codegen +# Target workspace name: gapic_generator_java # Versions only, for dependencies which actual artifacts differ between Bazel and Gradle -version.com_google_protobuf=3.13.0 +version.com_google_protobuf=3.15.8 # Version of google-java-format is downgraded from 1.8 to 1.7, because 1.8 supports java 11 minimum, while our JRE is java 8. version.google_java_format=1.7 version.com_google_api_common_java=1.9.3 -version.com_google_gax_java=1.62.0 version.io_grpc_java=1.30.2 # Common deps. @@ -20,7 +19,7 @@ maven.com_google_code_findbugs_jsr305=com.google.code.findbugs:jsr305:3.0.0 maven.com_google_auto_value_auto_value=com.google.auto.value:auto-value:1.7.2 maven.com_google_auto_value_auto_value_annotations=com.google.auto.value:auto-value-annotations:1.7.2 maven.com_google_code_gson=com.google.code.gson:gson:2.8.6 -maven.com_google_protobuf_protobuf_java=com.google.protobuf:protobuf-java:3.12.2 +maven.com_google_protobuf_protobuf_java=com.google.protobuf:protobuf-java:3.15.8 maven.io_github_java_diff_utils=io.github.java-diff-utils:java-diff-utils:4.0 maven.javax_annotation_javax_annotation_api=javax.annotation:javax.annotation-api:1.3.2 maven.javax_validation_javax_validation_api=javax.validation:validation-api:2.0.1.Final @@ -33,7 +32,7 @@ maven.org_threeten_threetenbp=org.threeten:threetenbp:1.3.3 # Testing. maven.junit_junit=junit:junit:4.13.1 -# This hamcrest-core dependency is for running JUnit test manually, before JUnit 4.11 it's wrapped along with JUnit package. +# This hamcrest-core dependency is for running JUnit test manually, before JUnit 4.11 it's wrapped along with JUnit package. # But now it has to be explicitly added. maven.org_hamcrest_hamcrest_core=org.hamcrest:hamcrest-core:1.3 maven.org_mockito_mockito_core=org.mockito:mockito-core:2.21.0 diff --git a/repositories.bzl b/repositories.bzl index e246cef5cc..67493dba45 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -59,9 +59,18 @@ def gapic_generator_java_repositories(): _maybe( http_archive, name = "com_google_googleapis", - strip_prefix = "googleapis-2bea43cdc7a4443876380732980d83cd8d560582", + strip_prefix = "googleapis-efecdbf96311bb705d619459280ffc651b10844a", urls = [ - "https://github.com/googleapis/googleapis/archive/2bea43cdc7a4443876380732980d83cd8d560582.zip", + "https://github.com/googleapis/googleapis/archive/efecdbf96311bb705d619459280ffc651b10844a.zip", + ], + ) + + _maybe( + http_archive, + name = "com_google_googleapis_discovery", + strip_prefix = "googleapis-discovery-abf4cec1ce9e02e4d7d650bf66137c347cdd0d44", + urls = [ + "https://github.com/googleapis/googleapis-discovery/archive/abf4cec1ce9e02e4d7d650bf66137c347cdd0d44.zip", ], ) diff --git a/rules_bazel/java/integration_test.bzl b/rules_bazel/java/integration_test.bzl index ae07c422aa..e030b5f817 100644 --- a/rules_bazel/java/integration_test.bzl +++ b/rules_bazel/java/integration_test.bzl @@ -23,7 +23,7 @@ def _diff_integration_goldens_impl(ctx): rm -rf $(find ./ -type f -name 'PlaceholderFile.java') rm -r $(find ./ -type d -empty) cd .. - diff codegen_tmp test/integration/goldens/{api_name}/ > {diff_output} + diff -r codegen_tmp test/integration/goldens/{api_name} > {diff_output} # Bash `diff` command will return exit code 1 when there are differences between the two # folders. So we explicitly `exit 0` after the diff command to avoid build failure. exit 0 diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl index 9c2436174c..91eb4ddb56 100644 --- a/rules_java_gapic/java_gapic.bzl +++ b/rules_java_gapic/java_gapic.bzl @@ -12,9 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@com_google_api_codegen//rules_gapic:gapic.bzl", "proto_custom_library", "unzipped_srcjar") +load("@rules_gapic//:gapic.bzl", "proto_custom_library", "unzipped_srcjar") -SERVICE_YAML_ALLOWLIST = ["clouddms", "cloudkms", "datastream", "pubsub"] NO_GRPC_CONFIG_ALLOWLIST = ["library"] def _java_gapic_postprocess_srcjar_impl(ctx): @@ -119,20 +118,24 @@ def _append_dep_without_duplicates(dest_deps, new_deps): dest_deps.append(new_deps[i]) return dest_deps -def java_gapic_library( +def _java_gapic_srcjar( name, srcs, - grpc_service_config = None, - gapic_yaml = None, - service_yaml = None, - deps = [], - test_deps = [], + grpc_service_config, + gapic_yaml, + service_yaml, + # possible values are: "grpc", "rest", "grpc+rest" + transport, + # Can be used to provide a java_library with a customized generator, + # like the one which dumps descriptor to a file for future debugging. + java_generator_name = "java_gapic", + output_suffix = ".srcjar", **kwargs): file_args_dict = {} if grpc_service_config: file_args_dict[grpc_service_config] = "grpc-service-config" - else: + elif not transport or transport == "grpc": for keyword in NO_GRPC_CONFIG_ALLOWLIST: if keyword not in name: fail("Missing a gRPC service config file") @@ -140,38 +143,54 @@ def java_gapic_library( if gapic_yaml: file_args_dict[gapic_yaml] = "gapic-config" - # Check the allow-list. - # TODO: Open this up after mixins are published, and gate on - # the allowlisted "mixed-in" APIs present in Java. if service_yaml: - service_yaml_in_allowlist = False - for keyword in SERVICE_YAML_ALLOWLIST: - if keyword in service_yaml: - service_yaml_in_allowlist = True - break - if service_yaml_in_allowlist: - file_args_dict[service_yaml] = "api-service-config" - else: - fail("Service.yaml is no longer supported in the Java microgenerator") + file_args_dict[service_yaml] = "api-service-config" - srcjar_name = name + "_srcjar" - raw_srcjar_name = srcjar_name + "_raw" output_suffix = ".srcjar" + opt_args = [] + + if transport: + opt_args.append("transport=%s" % transport) # Produces the GAPIC metadata file if this flag is set. to any value. # Protoc invocation: --java_gapic_opt=metadata plugin_args = ["metadata"] - _java_generator_name = "java_gapic" proto_custom_library( - name = raw_srcjar_name, + name = name, deps = srcs, - plugin = Label("@gapic_generator_java//:protoc-gen-%s" % _java_generator_name), + plugin = Label("@gapic_generator_java//:protoc-gen-%s" % java_generator_name), plugin_args = plugin_args, plugin_file_args = {}, opt_file_args = file_args_dict, - output_type = _java_generator_name, + output_type = java_generator_name, output_suffix = output_suffix, + opt_args = opt_args, + **kwargs + ) + +def java_gapic_library( + name, + srcs, + grpc_service_config = None, + gapic_yaml = None, + service_yaml = None, + deps = [], + test_deps = [], + # possible values are: "grpc", "rest", "grpc+rest" + transport = None, + **kwargs): + srcjar_name = name + "_srcjar" + raw_srcjar_name = srcjar_name + "_raw" + + _java_gapic_srcjar( + name = raw_srcjar_name, + srcs = srcs, + grpc_service_config = grpc_service_config, + gapic_yaml = gapic_yaml, + service_yaml = service_yaml, + transport = transport, + java_generator_name = "java_gapic", **kwargs ) @@ -201,10 +220,7 @@ def java_gapic_library( "@com_google_protobuf//:protobuf_java", "@com_google_api_api_common//jar", "@com_google_api_gax_java//gax:gax", - "@com_google_api_gax_java//gax-grpc:gax_grpc", "@com_google_guava_guava//jar", - "@io_grpc_grpc_java//core:core", - "@io_grpc_grpc_java//protobuf:protobuf", "@com_google_code_findbugs_jsr305//jar", "@org_threeten_threetenbp//jar", "@io_opencensus_opencensus_api//jar", @@ -214,6 +230,26 @@ def java_gapic_library( "@javax_annotation_javax_annotation_api//jar", ] + if not transport or transport == "grpc": + actual_deps += [ + "@com_google_api_gax_java//gax-grpc:gax_grpc", + "@io_grpc_grpc_java//core:core", + "@io_grpc_grpc_java//protobuf:protobuf", + ] + elif transport == "rest": + actual_deps += [ + "@com_google_api_gax_java//gax-httpjson:gax_httpjson", + ] + elif transport == "grpc+rest": + actual_deps += [ + "@com_google_api_gax_java//gax-grpc:gax_grpc", + "@io_grpc_grpc_java//core:core", + "@io_grpc_grpc_java//protobuf:protobuf", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson", + ] + else: + fail("Unknown transport: %s" % transport) + native.java_library( name = name, srcs = ["%s.srcjar" % srcjar_name], @@ -224,15 +260,35 @@ def java_gapic_library( # Test deps. actual_test_deps = [ "@com_google_googleapis//google/type:type_java_proto", # Commonly used. - "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", "@com_google_api_gax_java//gax:gax_testlib", "@com_google_code_gson_gson//jar", - "@io_grpc_grpc_java//auth:auth", - "@io_grpc_grpc_netty_shaded//jar", - "@io_grpc_grpc_java//stub:stub", - "@io_opencensus_opencensus_contrib_grpc_metrics//jar", "@junit_junit//jar", ] + + if not transport or transport == "grpc": + actual_test_deps += [ + "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@io_grpc_grpc_java//auth:auth", + "@io_grpc_grpc_netty_shaded//jar", + "@io_grpc_grpc_java//stub:stub", + "@io_opencensus_opencensus_contrib_grpc_metrics//jar", + ] + elif transport == "rest": + actual_test_deps += [ + "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", + ] + elif transport == "grpc+rest": + actual_test_deps += [ + "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@io_grpc_grpc_java//auth:auth", + "@io_grpc_grpc_netty_shaded//jar", + "@io_grpc_grpc_java//stub:stub", + "@io_opencensus_opencensus_contrib_grpc_metrics//jar", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", + ] + else: + fail("Unknown transport: %s" % transport) + _append_dep_without_duplicates(actual_test_deps, test_deps) _append_dep_without_duplicates(actual_test_deps, actual_deps) @@ -256,3 +312,26 @@ def java_gapic_test(name, runtime_deps, test_classes, **kwargs): tests = test_classes, **kwargs ) + +# A debugging rule, to dump CodeGenereatorRequest from protoc as is to a file, +# which then can be used to run gapic-generator directly instead of relying on +# protoc to launch it. This would simplify attaching the debugger and/or +# working with stdin/stderr. +def java_generator_request_dump( + name, + srcs, + grpc_service_config = None, + gapic_yaml = None, + service_yaml = None, + transport = None, + **kwargs): + _java_gapic_srcjar( + name = name, + srcs = srcs, + grpc_service_config = grpc_service_config, + gapic_yaml = gapic_yaml, + service_yaml = service_yaml, + transport = transport, + java_generator_name = "code_generator_request_dumper", + **kwargs + ) diff --git a/rules_java_gapic/java_gapic_pkg.bzl b/rules_java_gapic/java_gapic_pkg.bzl index f06c515f72..eb109db524 100644 --- a/rules_java_gapic/java_gapic_pkg.bzl +++ b/rules_java_gapic/java_gapic_pkg.bzl @@ -301,6 +301,7 @@ def java_gapic_assembly_gradle_pkg( name, deps, assembly_name = None, + transport = None, **kwargs): package_dir = name if assembly_name: @@ -350,9 +351,16 @@ def java_gapic_assembly_gradle_pkg( grpc_target_dep = ["%s" % grpc_target] if client_deps: + if not transport or transport == "grpc": + template_label = Label("//rules_java_gapic:resources/gradle/client_grpc.gradle.tmpl") + elif transport == "rest": + template_label = Label("//rules_java_gapic:resources/gradle/client_rest.gradle.tmpl") + elif transport == "grpc+rest": + template_label = Label("//rules_java_gapic:resources/gradle/client_grpcrest.gradle.tmpl") + _java_gapic_gradle_pkg( name = client_target, - template_label = Label("//rules_java_gapic:resources/gradle/client.gradle.tmpl"), + template_label = template_label, deps = proto_target_dep + client_deps, test_deps = grpc_target_dep + client_test_deps, **kwargs diff --git a/rules_java_gapic/resources/gradle/assembly.gradle.tmpl b/rules_java_gapic/resources/gradle/assembly.gradle.tmpl index 3c0e59ee69..336a7a5c05 100644 --- a/rules_java_gapic/resources/gradle/assembly.gradle.tmpl +++ b/rules_java_gapic/resources/gradle/assembly.gradle.tmpl @@ -12,8 +12,8 @@ subprojects { apply plugin: 'java' apply plugin: 'maven' - sourceCompatibility = 1.7 - targetCompatibility = 1.7 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 test { testLogging { diff --git a/rules_java_gapic/resources/gradle/client.gradle.tmpl b/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl similarity index 95% rename from rules_java_gapic/resources/gradle/client.gradle.tmpl rename to rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl index 137f38d6f2..5ed53f6401 100644 --- a/rules_java_gapic/resources/gradle/client.gradle.tmpl +++ b/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl @@ -9,8 +9,8 @@ apply plugin: 'java' description = 'GAPIC library for {{name}}' group = 'com.google.cloud' version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 repositories { mavenCentral() diff --git a/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl b/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl new file mode 100644 index 0000000000..fe5aa44622 --- /dev/null +++ b/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl @@ -0,0 +1,63 @@ +buildscript { + repositories { + mavenCentral() + } +} + +apply plugin: 'java' + +description = 'GAPIC library for {{name}}' +group = 'com.google.cloud' +version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + mavenCentral() + mavenLocal() +} + +compileJava.options.encoding = 'UTF-8' +javadoc.options.encoding = 'UTF-8' + +dependencies { + compile 'com.google.api:gax:{{version.gax}}' + testCompile 'com.google.api:gax:{{version.gax}}:testlib' + compile 'com.google.api:gax-grpc:{{version.gax_grpc}}' + testCompile 'com.google.api:gax-grpc:{{version.gax_grpc}}:testlib' + compile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}' + testCompile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}:testlib' + testCompile 'io.grpc:grpc-netty-shaded:{{version.io_grpc}}' + testCompile '{{maven.junit_junit}}' + {{extra_deps}} +} + +task smokeTest(type: Test) { + filter { + includeTestsMatching "*SmokeTest" + setFailOnNoMatchingTests false + } +} + +test { + exclude "**/*SmokeTest*" +} + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + } +} + +clean { + delete 'all-jars' +} + +task allJars(type: Copy) { + dependsOn test, jar + into 'all-jars' + // Replace with `from configurations.testRuntime, jar` to include test dependencies + from configurations.runtime, jar +} diff --git a/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl b/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl new file mode 100644 index 0000000000..20fab62963 --- /dev/null +++ b/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl @@ -0,0 +1,60 @@ +buildscript { + repositories { + mavenCentral() + } +} + +apply plugin: 'java' + +description = 'GAPIC library for {{name}}' +group = 'com.google.cloud' +version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + mavenCentral() + mavenLocal() +} + +compileJava.options.encoding = 'UTF-8' +javadoc.options.encoding = 'UTF-8' + +dependencies { + compile 'com.google.api:gax:{{version.gax}}' + testCompile 'com.google.api:gax:{{version.gax}}:testlib' + compile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}' + testCompile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}:testlib' + testCompile '{{maven.junit_junit}}' + {{extra_deps}} +} + +task smokeTest(type: Test) { + filter { + includeTestsMatching "*SmokeTest" + setFailOnNoMatchingTests false + } +} + +test { + exclude "**/*SmokeTest*" +} + +sourceSets { + main { + java { + srcDir 'src/main/java' + } + } +} + +clean { + delete 'all-jars' +} + +task allJars(type: Copy) { + dependsOn test, jar + into 'all-jars' + // Replace with `from configurations.testRuntime, jar` to include test dependencies + from configurations.runtime, jar +} diff --git a/rules_java_gapic/resources/gradle/grpc.gradle.tmpl b/rules_java_gapic/resources/gradle/grpc.gradle.tmpl index d5dfa3f3de..fbae0add76 100644 --- a/rules_java_gapic/resources/gradle/grpc.gradle.tmpl +++ b/rules_java_gapic/resources/gradle/grpc.gradle.tmpl @@ -9,8 +9,8 @@ apply plugin: 'java' description = 'GRPC library for {{name}}' group = 'com.google.api.grpc' version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 repositories { mavenCentral() diff --git a/rules_java_gapic/resources/gradle/proto.gradle.tmpl b/rules_java_gapic/resources/gradle/proto.gradle.tmpl index ad5e20fc33..27f0bf8448 100644 --- a/rules_java_gapic/resources/gradle/proto.gradle.tmpl +++ b/rules_java_gapic/resources/gradle/proto.gradle.tmpl @@ -9,8 +9,8 @@ apply plugin: 'java' description = 'PROTO library for {{name}}' group = 'com.google.api.grpc' version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 repositories { mavenCentral() diff --git a/src/main/java/com/google/api/generator/Main.java b/src/main/java/com/google/api/generator/Main.java index 0e1e985e2f..2ad75c19ba 100644 --- a/src/main/java/com/google/api/generator/Main.java +++ b/src/main/java/com/google/api/generator/Main.java @@ -14,34 +14,18 @@ package com.google.api.generator; -import com.google.api.AnnotationsProto; -import com.google.api.ClientProto; -import com.google.api.FieldBehaviorProto; -import com.google.api.ResourceProto; import com.google.api.generator.gapic.Generator; -import com.google.longrunning.OperationsProto; -import com.google.protobuf.Descriptors.DescriptorValidationException; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; import java.io.IOException; public class Main { - public static void main(String[] args) - throws IOException, InterruptedException, DescriptorValidationException { + public static void main(String[] args) throws IOException { ExtensionRegistry registry = ExtensionRegistry.newInstance(); - registerAllExtensions(registry); + ProtoRegistry.registerAllExtensions(registry); CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(System.in, registry); CodeGeneratorResponse response = Generator.generateGapic(request); response.writeTo(System.out); } - - /** Register all extensions needed to process API protofiles. */ - private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { - OperationsProto.registerAllExtensions(extensionRegistry); - AnnotationsProto.registerAllExtensions(extensionRegistry); - ClientProto.registerAllExtensions(extensionRegistry); - ResourceProto.registerAllExtensions(extensionRegistry); - FieldBehaviorProto.registerAllExtensions(extensionRegistry); - } } diff --git a/src/main/java/com/google/api/generator/ProtoRegistry.java b/src/main/java/com/google/api/generator/ProtoRegistry.java new file mode 100644 index 0000000000..da4806bba0 --- /dev/null +++ b/src/main/java/com/google/api/generator/ProtoRegistry.java @@ -0,0 +1,33 @@ +// Copyright 2021 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. + +package com.google.api.generator; + +import com.google.api.AnnotationsProto; +import com.google.api.ClientProto; +import com.google.api.FieldBehaviorProto; +import com.google.api.ResourceProto; +import com.google.longrunning.OperationsProto; +import com.google.protobuf.ExtensionRegistry; + +public class ProtoRegistry { + /** Register all extensions needed to process API protofiles. */ + public static void registerAllExtensions(ExtensionRegistry extensionRegistry) { + OperationsProto.registerAllExtensions(extensionRegistry); + AnnotationsProto.registerAllExtensions(extensionRegistry); + ClientProto.registerAllExtensions(extensionRegistry); + ResourceProto.registerAllExtensions(extensionRegistry); + FieldBehaviorProto.registerAllExtensions(extensionRegistry); + } +} diff --git a/src/main/java/com/google/api/generator/debug/BUILD.bazel b/src/main/java/com/google/api/generator/debug/BUILD.bazel new file mode 100644 index 0000000000..048f426a23 --- /dev/null +++ b/src/main/java/com/google/api/generator/debug/BUILD.bazel @@ -0,0 +1,27 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "debug_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "debug", + srcs = [ + ":debug_files", + ], + deps = [ + "//src/main/java/com/google/api/generator", + "//src/main/java/com/google/api/generator/engine", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/gapic", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/util", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_guava_guava//jar", + "@com_google_protobuf//:protobuf_java", + ], +) diff --git a/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestDumper.java b/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestDumper.java new file mode 100644 index 0000000000..ef75a6a652 --- /dev/null +++ b/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestDumper.java @@ -0,0 +1,42 @@ +// Copyright 2021 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. + +package com.google.api.generator.debug; + +import com.google.api.generator.ProtoRegistry; +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import java.io.IOException; + +// Request dumper class, which dumps the CodeGeneratorRequest to a file on disk which will be +// identical to the one passed to the Main class during normal execution. The dumped file then can +// be used to run this gapic-generator directly (instead of relying on protoc to start the process), +// which would give much greater flexibility in terms of debugging features, like attaching a +// debugger, easier work with stdout and stderr etc. +public class CodeGeneratorRequestDumper { + public static void main(String[] args) throws IOException { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + ProtoRegistry.registerAllExtensions(registry); + CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(System.in, registry); + + CodeGeneratorResponse.Builder response = CodeGeneratorResponse.newBuilder(); + response + .setSupportedFeatures(CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL_VALUE) + .addFileBuilder() + .setName("desc-dump.bin") + .setContentBytes(request.toByteString()); + response.build().writeTo(System.out); + } +} diff --git a/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestFileToGapicMain.java b/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestFileToGapicMain.java new file mode 100644 index 0000000000..5cbbb05608 --- /dev/null +++ b/src/main/java/com/google/api/generator/debug/CodeGeneratorRequestFileToGapicMain.java @@ -0,0 +1,45 @@ +// Copyright 2021 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. + +package com.google.api.generator.debug; + +import com.google.api.generator.ProtoRegistry; +import com.google.api.generator.gapic.Generator; +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +// A generator entry point class, similar to Main but reads the CodeGeneratorRequest directly from a +// file instead of relying on protoc to pipe it in. +public class CodeGeneratorRequestFileToGapicMain { + public static void main(String[] args) throws IOException { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + ProtoRegistry.registerAllExtensions(registry); + + String inputFile = args[0]; + String outputFile = args[1]; + + try (InputStream inputStream = new FileInputStream(inputFile); + OutputStream outputStream = new FileOutputStream(outputFile)) { + CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(inputStream, registry); + CodeGeneratorResponse response = Generator.generateGapic(request); + response.writeTo(outputStream); + } + } +} diff --git a/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java b/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java index a7c69d8729..1a3412aa6c 100644 --- a/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java +++ b/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java @@ -25,7 +25,7 @@ public abstract class AnnotationNode implements AstNode { public static AnnotationNode DEPRECATED = AnnotationNode.builder().setType(annotationType(Deprecated.class)).build(); - private static TypeNode annotationType(Class clazz) { + private static TypeNode annotationType(Class clazz) { return TypeNode.withReference(ConcreteReference.withClazz(clazz)); } @@ -41,11 +41,12 @@ public void accept(AstNodeVisitor visitor) { visitor.visit(this); } + public static AnnotationNode withTypeAndDescription(TypeNode type, String description) { + return AnnotationNode.builder().setType(type).setDescription(description).build(); + } + public static AnnotationNode withSuppressWarnings(String description) { - return AnnotationNode.builder() - .setType(annotationType(SuppressWarnings.class)) - .setDescription(description) - .build(); + return withTypeAndDescription(annotationType(SuppressWarnings.class), description); } public static AnnotationNode withType(TypeNode type) { diff --git a/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java index 1a362758fd..886ec56ad4 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java @@ -24,8 +24,10 @@ public abstract class ArithmeticOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); + @Override public abstract TypeNode type(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/AssignmentExpr.java b/src/main/java/com/google/api/generator/engine/ast/AssignmentExpr.java index 9223e41783..1314505d1f 100644 --- a/src/main/java/com/google/api/generator/engine/ast/AssignmentExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/AssignmentExpr.java @@ -64,8 +64,10 @@ public AssignmentExpr build() { if (rhsType != TypeNode.NULL && !lhsType.isSupertypeOrEquals(rhsType)) { throw new TypeMismatchException( String.format( - "LHS type %s must be a supertype of the RHS type %s", - lhsType.reference().name(), rhsType.reference().name())); + "LHS type %s of variable %s must be a supertype of the RHS type %s", + lhsType.reference().name(), + assignmentExpr.variableExpr().variable().identifier(), + rhsType.reference().name())); } } diff --git a/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java index af73f0b44f..4c2cfeec2e 100644 --- a/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java @@ -23,6 +23,7 @@ public abstract class AssignmentOperationExpr implements OperationExpr { public abstract Expr valueExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/BlockComment.java b/src/main/java/com/google/api/generator/engine/ast/BlockComment.java index 00f98aa2ec..9a9bc0d0cc 100644 --- a/src/main/java/com/google/api/generator/engine/ast/BlockComment.java +++ b/src/main/java/com/google/api/generator/engine/ast/BlockComment.java @@ -18,6 +18,7 @@ @AutoValue public abstract class BlockComment implements Comment { + @Override public abstract String comment(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java index 144c4beca1..5af0dbe869 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java @@ -32,10 +32,10 @@ public abstract class ConcreteReference implements Reference { private static final String RIGHT_ANGLE = ">"; private static final String QUESTION_MARK = "?"; - private static final Class WILDCARD_CLAZZ = ReferenceWildcard.class; + private static final Class WILDCARD_CLAZZ = ReferenceWildcard.class; // Private. - abstract Class clazz(); + abstract Class clazz(); @Override public void accept(AstNodeVisitor visitor) { @@ -105,7 +105,7 @@ public ImmutableList enclosingClassNames() { } // The innermost type will be the last element in the list. ImmutableList.Builder listBuilder = new ImmutableList.Builder<>(); - Class currentClz = clazz(); + Class currentClz = clazz(); while (currentClz.getEnclosingClass() != null) { listBuilder.add(currentClz.getEnclosingClass().getSimpleName()); currentClz = currentClz.getEnclosingClass(); @@ -198,7 +198,7 @@ public Reference copyAndSetGenerics(List generics) { return toBuilder().setGenerics(generics).build(); } - public static ConcreteReference withClazz(Class clazz) { + public static ConcreteReference withClazz(Class clazz) { return builder().setClazz(clazz).build(); } @@ -222,7 +222,7 @@ public static Builder builder() { @AutoValue.Builder public abstract static class Builder { - public abstract Builder setClazz(Class clazz); + public abstract Builder setClazz(Class clazz); public abstract Builder setUseFullName(boolean useFullName); @@ -239,7 +239,7 @@ public Builder setGenerics(Reference... references) { public abstract ConcreteReference autoBuild(); // Private. - abstract Class clazz(); + abstract Class clazz(); abstract ImmutableList generics(); diff --git a/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java b/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java index 9c2c49e756..8dcf18679b 100644 --- a/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java @@ -21,6 +21,7 @@ public abstract class EnumRefExpr implements Expr { public abstract IdentifierNode identifier(); + @Override public abstract TypeNode type(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/Expr.java b/src/main/java/com/google/api/generator/engine/ast/Expr.java index 6adc7a4fa5..134d2464d8 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Expr.java +++ b/src/main/java/com/google/api/generator/engine/ast/Expr.java @@ -17,5 +17,6 @@ public interface Expr extends AstNode { TypeNode type(); + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java index 2387345d31..9210ec3593 100644 --- a/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java @@ -24,6 +24,7 @@ public abstract class LogicalOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java b/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java index 3067dfc49a..4b65d14789 100644 --- a/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java +++ b/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java @@ -244,20 +244,18 @@ public MethodDefinition build() { "Abstract methods cannot be static, final, or private"); } - // If this method overrides another, ensure that the Override annotaiton is the last one. + // If this method overrides another, ensure that the Override annotation is the last one. ImmutableList processedAnnotations = annotations(); if (isOverride()) { processedAnnotations = - annotations() - .builder() + ImmutableList.builder() .addAll(annotations()) .add(AnnotationNode.OVERRIDE) .build(); } // Remove duplicates while maintaining insertion order. setAnnotations( - new LinkedHashSet(processedAnnotations) - .stream().collect(Collectors.toList())); + new LinkedHashSet<>(processedAnnotations).stream().collect(Collectors.toList())); MethodDefinition method = autoBuild(); diff --git a/src/main/java/com/google/api/generator/engine/ast/MethodInvocationExpr.java b/src/main/java/com/google/api/generator/engine/ast/MethodInvocationExpr.java index c7970e2990..2a0c2a45c4 100644 --- a/src/main/java/com/google/api/generator/engine/ast/MethodInvocationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/MethodInvocationExpr.java @@ -126,6 +126,9 @@ public MethodInvocationExpr build() { "generics", String.format("method invocation of %s", methodInvocationExpr.methodIdentifier().name())); + // TODO(v2): If type-checking is ever added for arguments, beware of lambdas and their type + // workarounds. + return methodInvocationExpr; } } diff --git a/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java b/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java index 50fbbed983..bbba011dff 100644 --- a/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java @@ -23,6 +23,7 @@ @AutoValue public abstract class NewObjectExpr implements Expr { + @Override public abstract TypeNode type(); public abstract ImmutableList arguments(); diff --git a/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java b/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java index 49dd6abd9e..3cde72c4e9 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java +++ b/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java @@ -15,7 +15,9 @@ package com.google.api.generator.engine.ast; public interface ObjectValue extends Value { + @Override TypeNode type(); + @Override String value(); } diff --git a/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java index 924a6a6930..36473e6e97 100644 --- a/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java @@ -18,7 +18,9 @@ public interface OperationExpr extends Expr { OperatorKind operatorKind(); + @Override TypeNode type(); + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/Reference.java b/src/main/java/com/google/api/generator/engine/ast/Reference.java index fdc2c5c5ee..4dce11783f 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Reference.java +++ b/src/main/java/com/google/api/generator/engine/ast/Reference.java @@ -19,6 +19,7 @@ import javax.annotation.Nullable; public interface Reference extends AstNode { + @Override void accept(AstNodeVisitor visitor); ImmutableList generics(); diff --git a/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java b/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java index 25940b0d3d..b68ff61ded 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java @@ -28,6 +28,7 @@ public enum KeywordKind { SUPER } + @Override public abstract TypeNode type(); public abstract KeywordKind keywordKind(); @@ -73,7 +74,7 @@ public Builder setArguments(Expr... arguments) { public ReferenceConstructorExpr build() { ReferenceConstructorExpr referenceConstructorExpr = autoBuild(); Preconditions.checkState( - referenceConstructorExpr.type().isReferenceType(referenceConstructorExpr.type()), + TypeNode.isReferenceType(referenceConstructorExpr.type()), "A this/super constructor must have a reference type."); NodeValidator.checkNoNullElements( diff --git a/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java index 80f0e4711b..d143abad5e 100644 --- a/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java @@ -23,6 +23,7 @@ public abstract class RelationalOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/Statement.java b/src/main/java/com/google/api/generator/engine/ast/Statement.java index 041d5bfd0f..954b279fd7 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Statement.java +++ b/src/main/java/com/google/api/generator/engine/ast/Statement.java @@ -15,5 +15,6 @@ package com.google.api.generator.engine.ast; public interface Statement extends AstNode { + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java b/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java index c121df71c3..602c0dbf82 100644 --- a/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java +++ b/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java @@ -20,6 +20,7 @@ @AutoValue public abstract class StringObjectValue implements ObjectValue { + @Override public abstract String value(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/ThrowExpr.java b/src/main/java/com/google/api/generator/engine/ast/ThrowExpr.java index 805499b074..5e4808d28a 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ThrowExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/ThrowExpr.java @@ -22,12 +22,18 @@ public abstract class ThrowExpr implements Expr { // TODO(miraleung): Refactor with StringObjectValue and possibly with NewObjectExpr. + @Nullable + public abstract Expr throwExpr(); + @Override public abstract TypeNode type(); @Nullable public abstract Expr messageExpr(); + @Nullable + public abstract Expr causeExpr(); + @Override public void accept(AstNodeVisitor visitor) { visitor.visit(this); @@ -39,6 +45,9 @@ public static Builder builder() { @AutoValue.Builder public abstract static class Builder { + public abstract Builder setThrowExpr(Expr throwExpr); + + // No-op if setThrowExpr is called. public abstract Builder setType(TypeNode type); public Builder setMessageExpr(String message) { @@ -47,22 +56,56 @@ public Builder setMessageExpr(String message) { public abstract Builder setMessageExpr(Expr expr); + public abstract Builder setCauseExpr(Expr expr); + // Private. + abstract Expr throwExpr(); + abstract TypeNode type(); abstract Expr messageExpr(); + abstract Expr causeExpr(); + abstract ThrowExpr autoBuild(); public ThrowExpr build() { + if (throwExpr() != null) { + setType(throwExpr().type()); + Preconditions.checkState( + messageExpr() == null && causeExpr() == null, + "Only one of throwExpr or [messageExpr or causeExpr, inclusive] can be present."); + + if (throwExpr() instanceof VariableExpr) { + Preconditions.checkState( + !((VariableExpr) throwExpr()).isDecl(), "Cannot throw a variable declaration"); + } + + Preconditions.checkState( + TypeNode.isExceptionType(throwExpr().type()), + String.format("Only exception types can be thrown, found %s", throwExpr().type())); + + return autoBuild(); + } + Preconditions.checkState( TypeNode.isExceptionType(type()), String.format("Type %s must be an exception type", type())); + if (messageExpr() != null) { Preconditions.checkState( messageExpr().type().equals(TypeNode.STRING), String.format("Message expression type must be a string for exception %s", type())); } + + if (causeExpr() != null) { + Preconditions.checkState( + TypeNode.THROWABLE.reference().isSupertypeOrEquals(causeExpr().type().reference()), + String.format( + "Cause expression type must be a subclass of Throwable, but found %s", + causeExpr().type())); + } + return autoBuild(); } } diff --git a/src/main/java/com/google/api/generator/engine/ast/TryCatchStatement.java b/src/main/java/com/google/api/generator/engine/ast/TryCatchStatement.java index 3634374259..1280635e38 100644 --- a/src/main/java/com/google/api/generator/engine/ast/TryCatchStatement.java +++ b/src/main/java/com/google/api/generator/engine/ast/TryCatchStatement.java @@ -17,8 +17,10 @@ import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.Nonnull; import javax.annotation.Nullable; @AutoValue @@ -26,11 +28,12 @@ public abstract class TryCatchStatement implements Statement { // Required. public abstract ImmutableList tryBody(); + // Optional only if the sample code bit is set (i.e. this is sample code). - @Nullable - public abstract VariableExpr catchVariableExpr(); + public abstract List catchVariableExprs(); // Optional only if the sample code bit is set (i.e. this is sample code). - public abstract ImmutableList catchBody(); + public abstract List> catchBlocks(); + // Optional. @Nullable public abstract AssignmentExpr tryResourceExpr(); @@ -44,8 +47,9 @@ public void accept(AstNodeVisitor visitor) { public static Builder builder() { return new AutoValue_TryCatchStatement.Builder() - .setIsSampleCode(false) - .setCatchBody(Collections.emptyList()); + .setCatchVariableExprs(Collections.emptyList()) + .setCatchBlocks(Collections.emptyList()) + .setIsSampleCode(false); } @AutoValue.Builder @@ -54,32 +58,61 @@ public abstract static class Builder { public abstract Builder setTryBody(List body); - public abstract Builder setCatchVariableExpr(VariableExpr variableExpr); + public abstract Builder setIsSampleCode(boolean isSampleCode); - public abstract Builder setCatchBody(List body); + public Builder addCatch(@Nonnull VariableExpr variableExpr, List body) { + List catchVarExprs = new ArrayList<>(catchVariableExprs()); + catchVarExprs.add(variableExpr); + setCatchVariableExprs(catchVarExprs); - public abstract Builder setIsSampleCode(boolean isSampleCode); + List> blocks = new ArrayList<>(catchBlocks()); + blocks.add(body); + return setCatchBlocks(blocks); + } + + // Private. + abstract Builder setCatchVariableExprs(List variableExpr); + + abstract Builder setCatchBlocks(List> body); + + abstract ImmutableList tryBody(); + + abstract boolean isSampleCode(); + + abstract List catchVariableExprs(); + + abstract List> catchBlocks(); abstract TryCatchStatement autoBuild(); public TryCatchStatement build() { - TryCatchStatement tryCatchStatement = autoBuild(); - NodeValidator.checkNoNullElements(tryCatchStatement.tryBody(), "try body", "try-catch"); - NodeValidator.checkNoNullElements(tryCatchStatement.catchBody(), "catch body", "try-catch"); + NodeValidator.checkNoNullElements(tryBody(), "try body", "try-catch"); + NodeValidator.checkNoNullElements( + catchVariableExprs(), "catch variable expressions", "try-catch"); + catchBlocks() + .forEach(body -> NodeValidator.checkNoNullElements(body, "catch body", "try-catch")); - if (!tryCatchStatement.isSampleCode()) { - Preconditions.checkNotNull( - tryCatchStatement.catchVariableExpr(), + if (!isSampleCode()) { + Preconditions.checkState( + !catchVariableExprs().isEmpty(), "Catch variable expression must be set for real, non-sample try-catch blocks."); Preconditions.checkState( - tryCatchStatement.catchVariableExpr().isDecl(), - "Catch variable expression must be a declaration"); + catchVariableExprs().stream().allMatch(v -> v.isDecl()), + "Catch variable expressions must all be declarations"); Preconditions.checkState( - TypeNode.isExceptionType(tryCatchStatement.catchVariableExpr().variable().type()), - "Catch variable must be an Exception object reference"); + catchVariableExprs().stream() + .allMatch(v -> TypeNode.isExceptionType(v.variable().type())), + "Catch variables must be an Exception object references"); } - return tryCatchStatement; + // Catch any potential future breakage due to changing addCatch above. + Preconditions.checkState( + catchVariableExprs().size() == catchBlocks().size(), + String.format( + "%d catch variables found and %d blocks found, but these numbers must be equal", + catchVariableExprs().size(), catchBlocks().size())); + + return autoBuild(); } } } diff --git a/src/main/java/com/google/api/generator/engine/ast/TypeNode.java b/src/main/java/com/google/api/generator/engine/ast/TypeNode.java index 5685efb1f0..50bcc62657 100644 --- a/src/main/java/com/google/api/generator/engine/ast/TypeNode.java +++ b/src/main/java/com/google/api/generator/engine/ast/TypeNode.java @@ -81,6 +81,9 @@ public enum TypeKind { public static final TypeNode STRING = withReference(ConcreteReference.withClazz(String.class)); public static final TypeNode VOID_OBJECT = withReference(ConcreteReference.withClazz(Void.class)); + public static final TypeNode THROWABLE = + withReference(ConcreteReference.withClazz(Throwable.class)); + public static final TypeNode DEPRECATED = withReference(ConcreteReference.withClazz(Deprecated.class)); @@ -109,7 +112,7 @@ public int compareTo(TypeNode other) { return -1; } - if (this.equals(TypeNode.NULL)) { + if (equals(TypeNode.NULL)) { // Can't self-compare, so we don't need to check whether the other one is TypeNode.NULL. return other.isPrimitiveType() ? 1 : -1; } @@ -158,7 +161,7 @@ public static TypeNode withReference(Reference reference) { return TypeNode.builder().setTypeKind(TypeKind.OBJECT).setReference(reference).build(); } - public static TypeNode withExceptionClazz(Class clazz) { + public static TypeNode withExceptionClazz(Class clazz) { Preconditions.checkState(Exception.class.isAssignableFrom(clazz)); return withReference(ConcreteReference.withClazz(clazz)); } @@ -197,11 +200,11 @@ public boolean isPrimitiveType() { } public boolean isProtoPrimitiveType() { - return isPrimitiveType() || this.equals(TypeNode.STRING) || this.equals(TypeNode.BYTESTRING); + return isPrimitiveType() || equals(TypeNode.STRING) || equals(TypeNode.BYTESTRING); } public boolean isSupertypeOrEquals(TypeNode other) { - boolean oneTypeIsNull = this.equals(TypeNode.NULL) ^ other.equals(TypeNode.NULL); + boolean oneTypeIsNull = equals(TypeNode.NULL) ^ other.equals(TypeNode.NULL); return !isPrimitiveType() && !other.isPrimitiveType() && isArray() == other.isArray() @@ -253,20 +256,6 @@ boolean isBoxedTypeEquals(TypeNode other) { return Objects.equals(other, BOXED_TYPE_MAP.get(this)); } - private static TypeNode createPrimitiveType(TypeKind typeKind) { - if (!isPrimitiveType(typeKind)) { - throw new IllegalArgumentException("Object is not a primitive type."); - } - return TypeNode.builder().setTypeKind(typeKind).build(); - } - - private static TypeNode createPrimitiveArrayType(TypeKind typeKind) { - if (typeKind.equals(TypeKind.OBJECT)) { - throw new IllegalArgumentException("Object is not a primitive type."); - } - return TypeNode.builder().setTypeKind(typeKind).setIsArray(true).build(); - } - private static boolean isPrimitiveType(TypeKind typeKind) { return !typeKind.equals(TypeKind.OBJECT); } diff --git a/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java index 74bda2f21d..3a968b92e0 100644 --- a/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java @@ -22,10 +22,13 @@ public abstract class UnaryOperationExpr implements OperationExpr { public abstract Expr expr(); + @Override public abstract OperatorKind operatorKind(); + @Override public abstract TypeNode type(); + @Override public void accept(AstNodeVisitor visitor) { visitor.visit(this); } diff --git a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java index d54d1f0dfc..85274e34b9 100644 --- a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java @@ -74,7 +74,6 @@ public class ImportWriterVisitor implements AstNodeVisitor { private static final String DOT = "."; - private static final String NEWLINE = "\n"; private static final String PKG_JAVA_LANG = "java.lang"; private final Set staticImports = new TreeSet<>(); @@ -94,7 +93,7 @@ public void clear() { public void initialize(@Nonnull String currentPackage) { this.currentPackage = currentPackage; - this.currentClassName = null; + currentClassName = null; } public void initialize(@Nonnull String currentPackage, @Nonnull String currentClassName) { @@ -231,9 +230,19 @@ public void visit(AnonymousClassExpr anonymousClassExpr) { @Override public void visit(ThrowExpr throwExpr) { throwExpr.type().accept(this); + // If throwExpr is present, then messageExpr and causeExpr will not be present. Relies on AST + // build-time checks. + if (throwExpr.throwExpr() != null) { + throwExpr.throwExpr().accept(this); + return; + } + if (throwExpr.messageExpr() != null) { throwExpr.messageExpr().accept(this); } + if (throwExpr.causeExpr() != null) { + throwExpr.causeExpr().accept(this); + } } @Override @@ -352,11 +361,13 @@ public void visit(TryCatchStatement tryCatchStatement) { statements(tryCatchStatement.tryBody()); Preconditions.checkState( - !tryCatchStatement.isSampleCode() && tryCatchStatement.catchVariableExpr() != null, + !tryCatchStatement.isSampleCode() && !tryCatchStatement.catchVariableExprs().isEmpty(), "Import generation should not be invoked on sample code, but was found when visiting a" + " try-catch block"); - tryCatchStatement.catchVariableExpr().accept(this); - statements(tryCatchStatement.catchBody()); + for (int i = 0; i < tryCatchStatement.catchVariableExprs().size(); i++) { + tryCatchStatement.catchVariableExprs().get(i).accept(this); + statements(tryCatchStatement.catchBlocks().get(i)); + } } @Override diff --git a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java index 6b4cbc69d1..b1d750157e 100644 --- a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java @@ -81,7 +81,6 @@ public class JavaWriterVisitor implements AstNodeVisitor { private static final String BLOCK_COMMENT_START = "/*"; private static final String BLOCK_COMMENT_END = "*/"; private static final String DOT = "."; - private static final String ESCAPED_QUOTE = "\""; private static final String EQUALS = "="; private static final String LEFT_ANGLE = "<"; private static final String LEFT_BRACE = "{"; @@ -392,6 +391,13 @@ public void visit(AnonymousClassExpr anonymousClassExpr) { public void visit(ThrowExpr throwExpr) { buffer.append(THROW); space(); + // If throwExpr is present, then messageExpr and causeExpr will not be present. Relies on AST + // build-time checks. + if (throwExpr.throwExpr() != null) { + throwExpr.throwExpr().accept(this); + return; + } + buffer.append(NEW); space(); throwExpr.type().accept(this); @@ -399,6 +405,13 @@ public void visit(ThrowExpr throwExpr) { if (throwExpr.messageExpr() != null) { throwExpr.messageExpr().accept(this); } + if (throwExpr.causeExpr() != null) { + if (throwExpr.messageExpr() != null) { + buffer.append(COMMA); + space(); + } + throwExpr.causeExpr().accept(this); + } rightParen(); } @@ -689,17 +702,17 @@ public void visit(TryCatchStatement tryCatchStatement) { statements(tryCatchStatement.tryBody()); rightBrace(); - if (tryCatchStatement.catchVariableExpr() != null) { + for (int i = 0; i < tryCatchStatement.catchVariableExprs().size(); i++) { space(); buffer.append(CATCH); space(); leftParen(); - tryCatchStatement.catchVariableExpr().accept(this); + tryCatchStatement.catchVariableExprs().get(i).accept(this); rightParen(); space(); leftBrace(); newline(); - statements(tryCatchStatement.catchBody()); + statements(tryCatchStatement.catchBlocks().get(i)); rightBrace(); } newline(); @@ -737,6 +750,7 @@ public void visit(BreakStatement breakStatement) { } /** =============================== COMMENT =============================== */ + @Override public void visit(LineComment lineComment) { // Split comments by new line and add `//` to each line. String formattedSource = @@ -745,6 +759,7 @@ public void visit(LineComment lineComment) { buffer.append(formattedSource); } + @Override public void visit(BlockComment blockComment) { // Split comments by new line and embrace the comment block with `/* */`. StringBuilder sourceComment = new StringBuilder(); @@ -758,6 +773,7 @@ public void visit(BlockComment blockComment) { buffer.append(JavaFormatter.format(sourceComment.toString())); } + @Override public void visit(JavaDocComment javaDocComment) { StringBuilder sourceComment = new StringBuilder(); sourceComment.append(JAVADOC_COMMENT_START).append(NEWLINE); @@ -851,7 +867,6 @@ public void visit(MethodDefinition methodDefinition) { buffer.append(THROWS); space(); - int numExceptionsThrown = methodDefinition.throwsExceptions().size(); Iterator exceptionIter = methodDefinition.throwsExceptions().iterator(); while (exceptionIter.hasNext()) { TypeNode exceptionType = exceptionIter.next(); diff --git a/src/main/java/com/google/api/generator/gapic/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/BUILD.bazel index 37a314ed0b..60cbc46d03 100644 --- a/src/main/java/com/google/api/generator/gapic/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/BUILD.bazel @@ -7,8 +7,14 @@ filegroup( srcs = glob(["*.java"]) + [ "//src/main/java/com/google/api/generator/gapic/composer:composer_files", "//src/main/java/com/google/api/generator/gapic/composer/comment:comment_files", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue:defaultvalue_files", + "//src/main/java/com/google/api/generator/gapic/composer/grpc:grpc_files", + "//src/main/java/com/google/api/generator/gapic/composer/grpcrest:grpcrest_files", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename:resourcename_files", + "//src/main/java/com/google/api/generator/gapic/composer/rest:rest_files", "//src/main/java/com/google/api/generator/gapic/composer/samplecode:samplecode_files", "//src/main/java/com/google/api/generator/gapic/composer/store:store_files", + "//src/main/java/com/google/api/generator/gapic/composer/utils:utils_files", "//src/main/java/com/google/api/generator/gapic/model:model_files", "//src/main/java/com/google/api/generator/gapic/protoparser:protoparser_files", "//src/main/java/com/google/api/generator/gapic/protowriter:protowriter_files", diff --git a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel index ae08ecda8b..0f09405d04 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel @@ -21,7 +21,9 @@ java_library( "//src/main/java/com/google/api/generator/gapic/composer/common", "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", "//src/main/java/com/google/api/generator/gapic/composer/grpc", + "//src/main/java/com/google/api/generator/gapic/composer/grpcrest", "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/rest", "//src/main/java/com/google/api/generator/gapic/composer/samplecode", "//src/main/java/com/google/api/generator/gapic/composer/store", "//src/main/java/com/google/api/generator/gapic/composer/utils", diff --git a/src/main/java/com/google/api/generator/gapic/composer/Composer.java b/src/main/java/com/google/api/generator/gapic/composer/Composer.java index 8dd716eb2a..4eefc2845a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/Composer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/Composer.java @@ -15,28 +15,28 @@ package com.google.api.generator.gapic.composer; import com.google.api.generator.engine.ast.ClassDefinition; -import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.gapic.composer.comment.CommentComposer; -import com.google.api.generator.gapic.composer.common.ServiceClientClassComposer; -import com.google.api.generator.gapic.composer.common.ServiceStubClassComposer; import com.google.api.generator.gapic.composer.grpc.GrpcServiceCallableFactoryClassComposer; import com.google.api.generator.gapic.composer.grpc.GrpcServiceStubClassComposer; import com.google.api.generator.gapic.composer.grpc.MockServiceClassComposer; import com.google.api.generator.gapic.composer.grpc.MockServiceImplClassComposer; +import com.google.api.generator.gapic.composer.grpc.ServiceClientClassComposer; import com.google.api.generator.gapic.composer.grpc.ServiceClientTestClassComposer; import com.google.api.generator.gapic.composer.grpc.ServiceSettingsClassComposer; +import com.google.api.generator.gapic.composer.grpc.ServiceStubClassComposer; import com.google.api.generator.gapic.composer.grpc.ServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.grpcrest.HttpJsonServiceClientTestClassComposer; import com.google.api.generator.gapic.composer.resourcename.ResourceNameHelperClassComposer; +import com.google.api.generator.gapic.composer.rest.HttpJsonServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.rest.HttpJsonServiceStubClassComposer; import com.google.api.generator.gapic.model.GapicClass; -import com.google.api.generator.gapic.model.GapicClass.Kind; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.GapicPackageInfo; -import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.model.Transport; import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; public class Composer { @@ -44,11 +44,7 @@ public static List composeServiceClasses(GapicContext context) { List clazzes = new ArrayList<>(); clazzes.addAll(generateServiceClasses(context)); clazzes.addAll(generateMockClasses(context, context.mixinServices())); - clazzes.addAll( - generateResourceNameHelperClasses( - context.helperResourceNames().values().stream() - .map(r -> r) - .collect(Collectors.toSet()))); + clazzes.addAll(generateResourceNameHelperClasses(context)); return addApacheLicense(clazzes); } @@ -65,11 +61,11 @@ public static List generateServiceClasses(GapicContext context) { return clazzes; } - public static List generateResourceNameHelperClasses( - Set resourceNames) { - return resourceNames.stream() + public static List generateResourceNameHelperClasses(GapicContext context) { + return context.helperResourceNames().values().stream() + .distinct() .filter(r -> !r.isOnlyWildcard()) - .map(r -> ResourceNameHelperClassComposer.instance().generate(r)) + .map(r -> ResourceNameHelperClassComposer.instance().generate(r, context)) .collect(Collectors.toList()); } @@ -79,10 +75,42 @@ public static List generateStubClasses(GapicContext context) { .services() .forEach( s -> { - clazzes.add(ServiceStubClassComposer.instance().generate(context, s)); - clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); - clazzes.add(GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); - clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + clazzes.add( + com.google.api.generator.gapic.composer.rest.ServiceStubClassComposer.instance() + .generate(context, s)); + clazzes.add( + com.google.api.generator.gapic.composer.rest.ServiceStubSettingsClassComposer + .instance() + .generate(context, s)); + clazzes.add( + HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(HttpJsonServiceStubClassComposer.instance().generate(context, s)); + } else if (context.transport() == Transport.GRPC) { + clazzes.add(ServiceStubClassComposer.instance().generate(context, s)); + clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); + clazzes.add( + GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); + } else if (context.transport() == Transport.GRPC_REST) { + clazzes.add( + com.google.api.generator.gapic.composer.grpcrest.ServiceStubClassComposer + .instance() + .generate(context, s)); + clazzes.add( + com.google.api.generator.gapic.composer.grpcrest + .ServiceStubSettingsClassComposer.instance() + .generate(context, s)); + clazzes.add( + GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); + clazzes.add( + HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add( + com.google.api.generator.gapic.composer.grpcrest + .HttpJsonServiceStubClassComposer.instance() + .generate(context, s)); + } }); return clazzes; } @@ -93,8 +121,28 @@ public static List generateClientSettingsClasses(GapicContext contex .services() .forEach( s -> { - clazzes.add(ServiceClientClassComposer.instance().generate(context, s)); - clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + clazzes.add( + com.google.api.generator.gapic.composer.rest.ServiceClientClassComposer + .instance() + .generate(context, s)); + clazzes.add( + com.google.api.generator.gapic.composer.rest.ServiceSettingsClassComposer + .instance() + .generate(context, s)); + } else if (context.transport() == Transport.GRPC) { + clazzes.add(ServiceClientClassComposer.instance().generate(context, s)); + clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); + } else if (context.transport() == Transport.GRPC_REST) { + clazzes.add( + com.google.api.generator.gapic.composer.grpcrest.ServiceClientClassComposer + .instance() + .generate(context, s)); + clazzes.add( + com.google.api.generator.gapic.composer.grpcrest.ServiceSettingsClassComposer + .instance() + .generate(context, s)); + } }); return clazzes; } @@ -103,33 +151,39 @@ public static List generateMockClasses(GapicContext context, List clazzes = new ArrayList<>(); services.forEach( s -> { - clazzes.add(MockServiceClassComposer.instance().generate(context, s)); - clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + // REST transport tests donot not use mock services. + } else if (context.transport() == Transport.GRPC) { + clazzes.add(MockServiceClassComposer.instance().generate(context, s)); + clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); + } else if (context.transport() == Transport.GRPC_REST) { + clazzes.add(MockServiceClassComposer.instance().generate(context, s)); + clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); + } }); return clazzes; } public static List generateTestClasses(GapicContext context) { - return context.services().stream() - .map(s -> ServiceClientTestClassComposer.instance().generate(context, s)) - .collect(Collectors.toList()); - } - - /** ====================== HELPERS ==================== */ - // TODO(miraleung): Add method list. - private static GapicClass generateGenericClass(Kind kind, String name, Service service) { - String pakkage = service.pakkage(); - if (kind.equals(Kind.STUB)) { - pakkage += ".stub"; - } + List clazzes = new ArrayList<>(); + context + .services() + .forEach( + s -> { + if (context.transport() == Transport.REST) { + clazzes.add( + com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer + .instance() + .generate(context, s)); + } else if (context.transport() == Transport.GRPC) { + clazzes.add(ServiceClientTestClassComposer.instance().generate(context, s)); + } else if (context.transport() == Transport.GRPC_REST) { + clazzes.add(ServiceClientTestClassComposer.instance().generate(context, s)); + clazzes.add(HttpJsonServiceClientTestClassComposer.instance().generate(context, s)); + } + }); - ClassDefinition classDef = - ClassDefinition.builder() - .setPackageString(pakkage) - .setName(name) - .setScope(ScopeNode.PUBLIC) - .build(); - return GapicClass.create(kind, classDef); + return clazzes; } @VisibleForTesting diff --git a/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java index 8ffeace7c5..e8f8a05681 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java @@ -33,7 +33,6 @@ public class ServiceClientCommentComposer { // Tokens. - private static final String COLON = ":"; private static final String EMPTY_STRING = ""; private static final String API_EXCEPTION_TYPE_NAME = "com.google.api.gax.rpc.ApiException"; private static final String EXCEPTION_CONDITION = "if the remote call fails"; diff --git a/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java index 5e10eb9cd5..7f2c83e4a2 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java @@ -16,7 +16,6 @@ import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.JavaDocComment; -import com.google.api.generator.engine.ast.LineComment; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.base.Preconditions; @@ -28,7 +27,6 @@ public class SettingsCommentComposer { private static final String COLON = ":"; - private static final String STUB_PATTERN = "%sStub"; private static final String BUILDER_CLASS_DOC_PATTERN = "Builder for %s."; private static final String CALL_SETTINGS_METHOD_DOC_PATTERN = "Returns the object with the settings used for calls to %s."; @@ -61,6 +59,8 @@ public class SettingsCommentComposer { toSimpleComment("Returns a builder for the default ExecutorProvider for this service."); public static final CommentStatement DEFAULT_SERVICE_ENDPOINT_METHOD_COMMENT = toSimpleComment("Returns the default service endpoint."); + public static final CommentStatement DEFAULT_SERVICE_MTLS_ENDPOINT_METHOD_COMMENT = + toSimpleComment("Returns the default mTLS service endpoint."); public static final CommentStatement DEFAULT_SERVICE_SCOPES_METHOD_COMMENT = toSimpleComment("Returns the default service scopes."); @@ -78,7 +78,6 @@ public class SettingsCommentComposer { public static final List APPLY_TO_ALL_UNARY_METHODS_METHOD_COMMENTS = Arrays.asList( - LineComment.withComment("NEXT_MAJOR_VER: remove 'throws Exception'."), JavaDocComment.builder() .addComment( "Applies the given settings updater function to all of the unary API methods" diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java index 280c9712b2..09aa5948a0 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java @@ -44,6 +44,7 @@ import com.google.api.generator.gapic.model.Service; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import javax.annotation.Generated; @@ -102,6 +103,13 @@ protected List createClassAnnotations(Service service, TypeStore return annotations; } + /** + * Construct the type to be implemented by the generated callable factory. + * + * @param typeStore type store with common types + * @return {@code TypeNode} containing the interface to be implemented by the generated callable + * factory class. + */ protected abstract List createClassImplements(TypeStore typeStore); protected List createClassMethods(TypeStore typeStore) { @@ -185,6 +193,28 @@ protected MethodDefinition createGenericCallableMethod( List transportCallSettingsTemplateObjects, String callSettingsVariantName, List callSettingsTemplateObjects) { + return createGenericCallableMethod( + typeStore, + methodTemplateNames, + returnCallableKindName, + returnCallableTemplateNames, + methodVariantName, + transportCallSettingsTemplateObjects, + callSettingsVariantName, + callSettingsTemplateObjects, + Collections.emptyList()); + } + + protected MethodDefinition createGenericCallableMethod( + TypeStore typeStore, + List methodTemplateNames, + String returnCallableKindName, + List returnCallableTemplateNames, + String methodVariantName, + List transportCallSettingsTemplateObjects, + String callSettingsVariantName, + List callSettingsTemplateObjects, + List annotations) { String methodName = String.format("create%sCallable", methodVariantName); String callSettingsTypeName = String.format("%sCallSettings", callSettingsVariantName); @@ -227,7 +257,7 @@ protected MethodDefinition createGenericCallableMethod( .setVariable( Variable.builder() .setName("operationsStub") - .setType(getTransportContext().operationsStubType()) + .setType(getTransportContext().operationsStubTypes().get(0)) .build()) .setIsDecl(true) .build()); @@ -254,11 +284,12 @@ protected MethodDefinition createGenericCallableMethod( .setName(methodName) .setArguments(arguments) .setReturnExpr(returnExpr) + .setAnnotations(annotations) .build(); } private static TypeStore createTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( // Gax-java classes. BatchingCallSettings.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java similarity index 93% rename from src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java index 97cf85f5ad..528d24d202 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java @@ -30,7 +30,6 @@ import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.AnonymousClassExpr; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.CastExpr; import com.google.api.generator.engine.ast.ClassDefinition; @@ -38,6 +37,7 @@ import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.LambdaExpr; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; @@ -85,19 +85,21 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; -public class ServiceClientClassComposer implements ClassComposer { - private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer(); +public abstract class AbstractServiceClientClassComposer implements ClassComposer { private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; private static final String CALLABLE_NAME_PATTERN = "%sCallable"; private static final String PAGED_CALLABLE_NAME_PATTERN = "%sPagedCallable"; @@ -106,19 +108,20 @@ public class ServiceClientClassComposer implements ClassComposer { private static final Reference LIST_REFERENCE = ConcreteReference.withClazz(List.class); private static final Reference MAP_REFERENCE = ConcreteReference.withClazz(Map.class); - private static final TypeNode OBJECTS_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(Objects.class)); - private enum CallableMethodKind { REGULAR, LRO, PAGED, } - private ServiceClientClassComposer() {} + private final TransportContext transportContext; + + protected AbstractServiceClientClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } - public static ServiceClientClassComposer instance() { - return INSTANCE; + protected TransportContext getTransportContext() { + return transportContext; } @Override @@ -129,7 +132,7 @@ public GapicClass generate(GapicContext context, Service service) { String className = ClassNames.getServiceClientClassName(service); GapicClass.Kind kind = Kind.MAIN; String pakkage = service.pakkage(); - boolean hasLroClient = hasLroMethods(service); + boolean hasLroClient = service.hasLroMethods(); Map> grpcRpcsToJavaMethodNames = new HashMap<>(); @@ -198,7 +201,7 @@ private static List createClassHeaderComments( service, classMethodSampleCode, credentialsSampleCode, endpointSampleCode); } - private static List createClassMethods( + private List createClassMethods( Service service, Map messageTypes, TypeStore typeStore, @@ -216,23 +219,19 @@ private static List createClassMethods( return methods; } - private static boolean hasLroMethods(Service service) { - for (Method method : service.methods()) { - if (method.hasLro()) { - return true; - } - } - return false; - } - - private static List createFieldDeclarations( + private List createFieldDeclarations( Service service, TypeStore typeStore, boolean hasLroClient) { Map fieldNameToTypes = new HashMap<>(); fieldNameToTypes.put( "settings", typeStore.get(ClassNames.getServiceSettingsClassName(service))); fieldNameToTypes.put("stub", typeStore.get(ClassNames.getServiceStubClassName(service))); if (hasLroClient) { - fieldNameToTypes.put("operationsClient", typeStore.get("OperationsClient")); + Iterator opClientName = getTransportContext().operationsClientNames().iterator(); + Iterator opClientType = getTransportContext().operationsClientTypes().iterator(); + + while (opClientName.hasNext() && opClientType.hasNext()) { + fieldNameToTypes.put(opClientName.next(), opClientType.next()); + } } return fieldNameToTypes.entrySet().stream() @@ -352,17 +351,15 @@ private static List createStaticCreatorMethods( return methods; } - private static List createConstructorMethods( + private List createConstructorMethods( Service service, TypeStore typeStore, boolean hasLroClient) { List methods = new ArrayList<>(); String thisClientName = ClassNames.getServiceClientClassName(service); String settingsName = ClassNames.getServiceSettingsClassName(service); TypeNode thisClassType = typeStore.get(thisClientName); TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); - TypeNode operationsClientType = typeStore.get("OperationsClient"); TypeNode exceptionType = typeStore.get("IOException"); - TypeNode settingsType = typeStore.get(settingsName); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(typeStore.get(settingsName)).build()); @@ -372,9 +369,6 @@ private static List createConstructorMethods( .setType(typeStore.get(ClassNames.getServiceStubClassName(service))) .setName("stub") .build()); - VariableExpr operationsClientVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(operationsClientType).setName("operationsClient").build()); // Create the ServiceClient(ServiceSettings settings) ctor. List ctorAssignmentExprs = new ArrayList<>(); @@ -404,25 +398,10 @@ private static List createConstructorMethods( .build()) .build()); - Expr clientArgExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(stubVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setMethodName("getOperationsStub") - .build(); - AssignmentExpr operationsClientAssignExpr = - AssignmentExpr.builder() - .setVariableExpr( - operationsClientVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType(operationsClientType) - .setMethodName("create") - .setArguments(clientArgExpr) - .setReturnType(operationsClientVarExpr.type()) - .build()) - .build(); + List operationsClientAssignExprs = + createOperationsClientAssignExprs(thisExpr, stubVarExpr); if (hasLroClient) { - ctorAssignmentExprs.add(operationsClientAssignExpr); + ctorAssignmentExprs.addAll(operationsClientAssignExprs); } methods.add( @@ -453,7 +432,7 @@ private static List createConstructorMethods( .setValueExpr(stubVarExpr) .build()); if (hasLroClient) { - ctorAssignmentExprs.add(operationsClientAssignExpr); + ctorAssignmentExprs.addAll(operationsClientAssignExprs); } AnnotationNode betaAnnotation = AnnotationNode.builder() @@ -476,15 +455,70 @@ private static List createConstructorMethods( return methods; } - private static List createGetterMethods( + private List createOperationsClientAssignExprs( + Expr thisExpr, VariableExpr stubVarExpr) { + List operationsClientAssignExprs = new ArrayList<>(); + + Iterator opClientTypesIt = getTransportContext().operationsClientTypes().iterator(); + Iterator opClientNamesIt = getTransportContext().operationsClientNames().iterator(); + Iterator opStubNamesIt = + getTransportContext().transportOperationsStubNames().iterator(); + + while (opClientTypesIt.hasNext() && opClientNamesIt.hasNext() && opStubNamesIt.hasNext()) { + TypeNode operationsClientType = opClientTypesIt.next(); + String opClientName = opClientNamesIt.next(); + String opStubName = opStubNamesIt.next(); + + VariableExpr operationsClientVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(operationsClientType).setName(opClientName).build()); + + String operationsStubGetterName = + String.format("get%s", JavaStyle.toUpperCamelCase(opStubName)); + + Expr clientArgExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(stubVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setMethodName(operationsStubGetterName) + .build(); + + AssignmentExpr operationsClientAssignExpr = + AssignmentExpr.builder() + .setVariableExpr( + operationsClientVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(operationsClientType) + .setMethodName("create") + .setArguments(clientArgExpr) + .setReturnType(operationsClientVarExpr.type()) + .build()) + .build(); + operationsClientAssignExprs.add(operationsClientAssignExpr); + } + + return operationsClientAssignExprs; + } + + private List createGetterMethods( Service service, TypeStore typeStore, boolean hasLroClient) { Map methodNameToTypes = new LinkedHashMap<>(); methodNameToTypes.put( "getSettings", typeStore.get(ClassNames.getServiceSettingsClassName(service))); methodNameToTypes.put("getStub", typeStore.get(ClassNames.getServiceStubClassName(service))); - String getOperationsClientMethodName = "getOperationsClient"; + + Set getOperationsClientMethodNames = new HashSet<>(); + if (hasLroClient) { - methodNameToTypes.put(getOperationsClientMethodName, typeStore.get("OperationsClient")); + Iterator opClientNamesIt = getTransportContext().operationsClientNames().iterator(); + Iterator opClientTypesIt = getTransportContext().operationsClientTypes().iterator(); + + while (opClientNamesIt.hasNext() && opClientTypesIt.hasNext()) { + String opClientMethodName = + String.format("get%s", JavaStyle.toUpperCamelCase(opClientNamesIt.next())); + getOperationsClientMethodNames.add(opClientMethodName); + methodNameToTypes.put(opClientMethodName, opClientTypesIt.next()); + } } AnnotationNode betaStubAnnotation = AnnotationNode.builder() @@ -500,7 +534,7 @@ private static List createGetterMethods( TypeNode methodReturnType = e.getValue(); String returnVariableName = JavaStyle.toLowerCamelCase(methodName.substring(3)); MethodDefinition.Builder methodBuilder = MethodDefinition.builder(); - if (methodName.equals(getOperationsClientMethodName)) { + if (getOperationsClientMethodNames.contains(methodName)) { methodBuilder = methodBuilder.setHeaderCommentStatements( ServiceClientCommentComposer.GET_OPERATIONS_CLIENT_METHOD_COMMENT); @@ -620,7 +654,6 @@ private static List createMethodVariants( lro.responseType().reference(), lro.metadataType().reference()))); } - String methodInputTypeName = methodInputType.reference().name(); for (List signature : method.methodSignatures()) { // Get the argument list. List arguments = @@ -1042,7 +1075,7 @@ private static List createNestedPagingClasses( } // Find the repeated field. Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -1159,29 +1192,14 @@ private static ClassDefinition createNestedRpcPagedResponseClass( VariableExpr inputVarExpr = VariableExpr.withVariable( Variable.builder().setName("input").setType(methodPageType).build()); - TypeNode anonClassType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(ApiFunction.class) - .setGenerics(Arrays.asList(methodPageType.reference(), thisClassType.reference())) - .build()); + + // Overrides ApiFunction.apply. + // (https://github.com/googleapis/api-common-java/blob/debf25960dea0367b0d3b5e16d57d76c1d01947e/src/main/java/com/google/api/core/ApiFunction.java). Expr pageToTransformExpr = - AnonymousClassExpr.builder() - .setType(anonClassType) - .setMethods( - Arrays.asList( - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setReturnType(thisClassType) - .setName("apply") - .setArguments(inputVarExpr.toBuilder().setIsDecl(true).build()) - .setReturnExpr( - NewObjectExpr.builder() - .setType(thisClassType) - .setArguments(inputVarExpr) - .build()) - .build())) + LambdaExpr.builder() + .setArguments(inputVarExpr.toBuilder().setIsDecl(true).build()) + .setReturnExpr( + NewObjectExpr.builder().setType(thisClassType).setArguments(inputVarExpr).build()) .build(); // createAsync method - return expression. @@ -1534,7 +1552,7 @@ static Expr createRequestBuilderExpr( rootFields.add(rootField); } Trie updatedTrie = - rootFieldToTrie.containsKey(rootField) ? rootFieldToTrie.get(rootField) : new Trie(); + rootFieldToTrie.containsKey(rootField) ? rootFieldToTrie.get(rootField) : new Trie<>(); List nestedFieldsWithChild = new ArrayList<>(arg.nestedFields()); nestedFieldsWithChild.add(arg.field()); updatedTrie.insert(nestedFieldsWithChild); @@ -1633,7 +1651,7 @@ private static String typeToSetterMethodName(TypeNode type) { } private static TypeStore createTypes(Service service, Map messageTypes) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractPagedListResponse.class, ApiFunction.class, @@ -1690,8 +1708,6 @@ private static void createVaporTypes(Service service, TypeStore typeStore) { ClassNames.getServiceClientClassName(service)); } - // LRO Gapic-generated types. - typeStore.put("com.google.longrunning", "OperationsClient"); // Pagination types. typeStore.putAll( service.pakkage(), @@ -1736,17 +1752,6 @@ private static boolean isProtoEmptyType(TypeNode type) { && type.reference().name().equals("Empty"); } - private static void updateGapicMetadata( - GapicContext context, String protoPackage, String javaPackage) { - context.updateGapicMetadata( - context - .gapicMetadata() - .toBuilder() - .setProtoPackage(protoPackage) - .setLibraryPackage(javaPackage) - .build()); - } - private static void updateGapicMetadata( GapicContext context, Service service, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java index 7f45e974b3..1c49899d15 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java @@ -20,28 +20,19 @@ import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.InvalidArgumentException; -import com.google.api.gax.rpc.OperationCallSettings; -import com.google.api.gax.rpc.PagedCallSettings; -import com.google.api.gax.rpc.ServerStreamingCallSettings; import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.StatusCode; -import com.google.api.gax.rpc.StreamingCallSettings; -import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; -import com.google.api.generator.engine.ast.CastExpr; import com.google.api.generator.engine.ast.ClassDefinition; import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.EmptyLineStatement; -import com.google.api.generator.engine.ast.EnumRefExpr; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.InstanceofExpr; import com.google.api.generator.engine.ast.LineComment; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.ScopeNode; @@ -80,6 +71,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; import org.junit.After; @@ -98,7 +90,7 @@ public abstract class AbstractServiceClientTestClassComposer implements ClassCom protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); protected static final AnnotationNode TEST_ANNOTATION = - AnnotationNode.withType(FIXED_TYPESTORE.get("Test")); + AnnotationNode.withType(FIXED_TYPESTORE.get("Test")); private final TransportContext transportContext; @@ -112,12 +104,14 @@ public TransportContext getTransportContext() { @Override public GapicClass generate(GapicContext context, Service service) { + return generate(ClassNames.getServiceClientTestClassName(service), context, service); + } + + protected GapicClass generate(String className, GapicContext context, Service service) { Map resourceNames = context.helperResourceNames(); - Map messageTypes = context.messages(); String pakkage = service.pakkage(); TypeStore typeStore = new TypeStore(); addDynamicTypes(context, service, typeStore); - String className = ClassNames.getServiceClientTestClassName(service); GapicClass.Kind kind = Kind.MAIN; Map classMemberVarExprs = @@ -149,16 +143,35 @@ protected abstract Map createClassMemberVarExprs( protected List createClassMemberFieldDecls( Map classMemberVarExprs) { - return classMemberVarExprs.values().stream() - .map( - v -> - ExprStatement.withExpr( - v.toBuilder() - .setIsDecl(true) - .setScope(ScopeNode.PRIVATE) - .setIsStatic(v.type().reference().name().startsWith("Mock")) - .build())) - .collect(Collectors.toList()); + Function isMockVarExprFn = + v -> v.type().reference().name().startsWith("Mock"); + + // Ordering matters for pretty-printing and ensuring that test output is deterministic. + List fieldDeclStatements = new ArrayList<>(); + + // Static fields go first. + fieldDeclStatements.addAll( + classMemberVarExprs.values().stream() + .filter(v -> isMockVarExprFn.apply(v)) + .map( + v -> + ExprStatement.withExpr( + v.toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .build())) + .collect(Collectors.toList())); + + fieldDeclStatements.addAll( + classMemberVarExprs.values().stream() + .filter(v -> !isMockVarExprFn.apply(v)) + .map( + v -> + ExprStatement.withExpr( + v.toBuilder().setIsDecl(true).setScope(ScopeNode.PRIVATE).build())) + .collect(Collectors.toList())); + return fieldDeclStatements; } private List createClassMethods( @@ -180,7 +193,8 @@ private List createTestAdminMethods( TypeStore typeStore) { List javaMethods = new ArrayList<>(); javaMethods.add( - createStartStaticServerMethod(service, context, classMemberVarExprs, typeStore)); + createStartStaticServerMethod( + service, context, classMemberVarExprs, typeStore, "newBuilder")); javaMethods.add(createStopServerMethod(service, classMemberVarExprs)); javaMethods.add(createSetUpMethod(service, classMemberVarExprs, typeStore)); javaMethods.add(createTearDownMethod(service, classMemberVarExprs)); @@ -191,7 +205,8 @@ protected abstract MethodDefinition createStartStaticServerMethod( Service service, GapicContext context, Map classMemberVarExprs, - TypeStore typeStore); + TypeStore typeStore, + String newBuilderMethod); protected abstract MethodDefinition createStopServerMethod( Service service, Map classMemberVarExprs); @@ -317,15 +332,21 @@ private MethodDefinition createRpcTestMethod( String mockServiceVarName = getMockServiceVarName(rpcService); if (method.isPaged()) { Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( "No repeated field found for paged method %s with output message type %s", method.name(), methodOutputMessage.name())); - // Must be a non-repeated type. - repeatedResponseType = repeatedPagedResultsField.type(); + if (repeatedPagedResultsField.isMap()) { + repeatedResponseType = + TypeNode.withReference(repeatedPagedResultsField.type().reference().generics().get(1)); + } else { + // Must be a non-repeated type. + repeatedResponseType = repeatedPagedResultsField.type(); + } + responsesElementVarExpr = VariableExpr.withVariable( Variable.builder().setType(repeatedResponseType).setName("responsesElement").build()); @@ -348,7 +369,7 @@ private MethodDefinition createRpcTestMethod( Expr expectedResponseValExpr = null; if (method.isPaged()) { Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field firstRepeatedField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field firstRepeatedField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( firstRepeatedField, String.format( @@ -357,7 +378,10 @@ private MethodDefinition createRpcTestMethod( expectedResponseValExpr = DefaultValueComposer.createSimplePagedResponse( - method.outputType(), firstRepeatedField.name(), responsesElementVarExpr); + method.outputType(), + firstRepeatedField.name(), + responsesElementVarExpr, + firstRepeatedField.isMap()); } else { if (messageTypes.containsKey(methodOutputType.reference().fullName())) { expectedResponseValExpr = @@ -445,7 +469,7 @@ private MethodDefinition createRpcTestMethod( VariableExpr.withVariable( Variable.builder().setType(methodArg.type()).setName(methodArgName).build()); argExprs.add(varExpr); - Expr valExpr = DefaultValueComposer.createDefaultValue(methodArg, resourceNames); + Expr valExpr = createDefaultValue(methodArg, resourceNames); methodExprs.add( AssignmentExpr.builder() .setVariableExpr(varExpr.toBuilder().setIsDecl(true).build()) @@ -500,6 +524,9 @@ private MethodDefinition createRpcTestMethod( } if (method.isPaged()) { + Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); + // Assign the resources variable. VariableExpr resourcesVarExpr = VariableExpr.withVariable( @@ -508,7 +535,8 @@ private MethodDefinition createRpcTestMethod( TypeNode.withReference( ConcreteReference.builder() .setClazz(List.class) - .setGenerics(Arrays.asList(repeatedResponseType.reference())) + .setGenerics( + Arrays.asList(repeatedPagedResultsField.type().reference())) .build())) .setName("resources") .build()); @@ -554,8 +582,6 @@ private MethodDefinition createRpcTestMethod( .build()); // Assert the responses are equivalent. - Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -564,19 +590,52 @@ private MethodDefinition createRpcTestMethod( Expr zeroExpr = ValueExpr.withValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build()); - Expr expectedPagedResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(expectedResponseVarExpr) - .setMethodName( - String.format( - "get%sList", JavaStyle.toUpperCamelCase(repeatedPagedResultsField.name()))) - .build(); - expectedPagedResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(expectedPagedResponseExpr) - .setMethodName("get") - .setArguments(zeroExpr) - .build(); + + // Generated code: + // Assert.assertEquals( + // expectedResponse.getItemsMap().entrySet().iterator().next(), resources.get(0)); + // ) + Expr expectedPagedResponseExpr; + if (repeatedPagedResultsField.isMap()) { + expectedPagedResponseExpr = + MethodInvocationExpr.builder() + .setMethodName("next") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("iterator") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("entrySet") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(expectedResponseVarExpr) + .setMethodName( + String.format( + "get%sMap", + JavaStyle.toUpperCamelCase( + repeatedPagedResultsField.name()))) + .build()) + .build()) + .build()) + .build(); + + } else { + // Generated code: + // Assert.assertEquals(expectedResponse.getItemsList().get(0), resources.get(0)); + expectedPagedResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(expectedResponseVarExpr) + .setMethodName( + String.format( + "get%sList", JavaStyle.toUpperCamelCase(repeatedPagedResultsField.name()))) + .build(); + expectedPagedResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(expectedPagedResponseExpr) + .setMethodName("get") + .setArguments(zeroExpr) + .build(); + } Expr actualPagedResponseExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(resourcesVarExpr) @@ -675,6 +734,9 @@ protected abstract List createStreamingRpcExceptionTestStatements( Map resourceNames, Map messageTypes); + protected abstract Expr createDefaultValue( + MethodArgument methodArg, Map resourceNames); + protected List createRpcExceptionTestStatements( Method method, List methodSignature, @@ -706,7 +768,7 @@ protected List createRpcExceptionTestStatements( VariableExpr.withVariable( Variable.builder().setType(methodArg.type()).setName(methodArgName).build()); argVarExprs.add(varExpr); - Expr valExpr = DefaultValueComposer.createDefaultValue(methodArg, resourceNames); + Expr valExpr = createDefaultValue(methodArg, resourceNames); tryBodyExprs.add( AssignmentExpr.builder() .setVariableExpr(varExpr.toBuilder().setIsDecl(true).build()) @@ -765,8 +827,7 @@ protected List createRpcExceptionTestStatements( tryBodyExprs.stream() .map(e -> ExprStatement.withExpr(e)) .collect(Collectors.toList())) - .setCatchVariableExpr(catchExceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setCatchBody(catchBody) + .addCatch(catchExceptionVarExpr.toBuilder().setIsDecl(true).build(), catchBody) .build(); return Arrays.asList(EMPTY_LINE_STATEMENT, tryCatchBlock); @@ -781,7 +842,7 @@ protected abstract List createRpcLroExceptionTestCatchBody( */ private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, After.class, @@ -816,8 +877,10 @@ private void addDynamicTypes(GapicContext context, Service service, TypeStore ty Arrays.asList( ClassNames.getMockServiceClassName(service), ClassNames.getServiceClientClassName(service), - ClassNames.getServiceSettingsClassName(service), - getTransportContext().classNames().getTransportServiceStubClassName(service))); + ClassNames.getServiceSettingsClassName(service))); + String stubPakkage = String.format("%s.stub", service.pakkage()); + typeStore.put( + stubPakkage, getTransportContext().classNames().getTransportServiceStubClassName(service)); // Pagination types. typeStore.putAll( service.pakkage(), @@ -842,70 +905,12 @@ private void addDynamicTypes(GapicContext context, Service service, TypeStore ty } } - private static TypeNode getOperationCallSettingsTypeHelper( - Method protoMethod, boolean isBuilder) { - Preconditions.checkState( - protoMethod.hasLro(), - String.format("Cannot get OperationCallSettings on non-LRO method %s", protoMethod.name())); - Class callSettingsClazz = - isBuilder ? OperationCallSettings.Builder.class : OperationCallSettings.class; - return TypeNode.withReference( - ConcreteReference.builder() - .setClazz(callSettingsClazz) - .setGenerics( - Arrays.asList( - protoMethod.inputType().reference(), - protoMethod.lro().responseType().reference(), - protoMethod.lro().metadataType().reference())) - .build()); - } - - private static TypeNode getCallSettingsTypeHelper( - Method protoMethod, TypeStore typeStore, boolean isBuilder) { - Class callSettingsClazz = isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; - if (protoMethod.isPaged()) { - callSettingsClazz = isBuilder ? PagedCallSettings.Builder.class : PagedCallSettings.class; - } else { - switch (protoMethod.stream()) { - case CLIENT: - // Fall through. - case BIDI: - callSettingsClazz = - isBuilder ? StreamingCallSettings.Builder.class : StreamingCallSettings.class; - break; - case SERVER: - callSettingsClazz = - isBuilder - ? ServerStreamingCallSettings.Builder.class - : ServerStreamingCallSettings.class; - break; - case NONE: - // Fall through - default: - // Fall through - } - } - - List generics = new ArrayList<>(); - generics.add(protoMethod.inputType().reference()); - generics.add(protoMethod.outputType().reference()); - if (protoMethod.isPaged()) { - generics.add( - typeStore - .get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, protoMethod.name())) - .reference()); - } - - return TypeNode.withReference( - ConcreteReference.builder().setClazz(callSettingsClazz).setGenerics(generics).build()); - } - protected static TypeNode getCallableType(Method protoMethod) { Preconditions.checkState( !protoMethod.stream().equals(Method.Stream.NONE), "No callable type exists for non-streaming methods."); - Class callableClazz = ClientStreamingCallable.class; + Class callableClazz = ClientStreamingCallable.class; switch (protoMethod.stream()) { case BIDI: callableClazz = BidiStreamingCallable.class; diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java index 14e79caab9..ccf15a1d64 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java @@ -62,11 +62,13 @@ import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.longrunning.Operation; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.function.BiFunction; @@ -172,6 +174,7 @@ private List createClassMethods(Service service, TypeStore typ javaMethods.addAll(createSettingsGetterMethods(service, typeStore)); javaMethods.add(createCreatorMethod(service, typeStore)); javaMethods.addAll(createDefaultGetterMethods(service, typeStore)); + javaMethods.addAll(createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault")); javaMethods.addAll(createBuilderHelperMethods(service, typeStore)); javaMethods.add(createConstructorMethod(service, typeStore)); return javaMethods; @@ -321,7 +324,7 @@ private List createDefaultGetterMethods(Service service, TypeS .build()); BiFunction methodMakerFn = (methodDefBuilder, comment) -> methodDefBuilder.setHeaderCommentStatements(comment).build(); - Function typeMakerFn = + Function, TypeNode> typeMakerFn = c -> TypeNode.withReference(ConcreteReference.withClazz(c)); List javaMethods = new ArrayList<>(); @@ -351,12 +354,19 @@ private List createDefaultGetterMethods(Service service, TypeS "defaultCredentialsProviderBuilder", typeMakerFn.apply(GoogleCredentialsProvider.Builder.class)), SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT)); - javaMethods.add( - methodMakerFn.apply( - methodStarterFn.apply( - getTransportContext().defaultTransportProviderBuilderName(), - typeMakerFn.apply(getTransportContext().instantiatingChannelProviderClass())), - SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)); + + Iterator providerBuilderNamesIt = + getTransportContext().defaultTransportProviderBuilderNames().iterator(); + Iterator> channelProviderClassesIt = + getTransportContext().instantiatingChannelProviderBuilderClasses().iterator(); + while (providerBuilderNamesIt.hasNext() && channelProviderClassesIt.hasNext()) { + javaMethods.add( + methodMakerFn.apply( + methodStarterFn.apply( + providerBuilderNamesIt.next(), + typeMakerFn.apply(channelProviderClassesIt.next())), + SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)); + } javaMethods.add( methodStarterFn @@ -383,23 +393,31 @@ private List createDefaultGetterMethods(Service service, TypeS return javaMethods; } - private static List createBuilderHelperMethods( - Service service, TypeStore typeStore) { + protected List createNewBuilderMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); - MethodDefinition newBuilderMethodOne = + return ImmutableList.of( MethodDefinition.builder() .setHeaderCommentStatements(SettingsCommentComposer.NEW_BUILDER_METHOD_COMMENT) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(builderType) - .setName("newBuilder") + .setName(newBuilderMethodName) .setReturnExpr( MethodInvocationExpr.builder() .setStaticReferenceType(builderType) - .setMethodName("createDefault") + .setMethodName(createDefaultMethodName) .setReturnType(builderType) .build()) - .build(); + .build()); + } + + private static List createBuilderHelperMethods( + Service service, TypeStore typeStore) { + TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); VariableExpr clientContextVarExpr = VariableExpr.withVariable( @@ -439,10 +457,10 @@ private static List createBuilderHelperMethods( .build()) .build(); - return Arrays.asList(newBuilderMethodOne, newBuilderMethodTwo, toBuilderMethod); + return Arrays.asList(newBuilderMethodTwo, toBuilderMethod); } - private static ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) { + private ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) { return ClassDefinition.builder() .setHeaderCommentStatements( SettingsCommentComposer.createBuilderClassComment( @@ -466,11 +484,12 @@ private static ClassDefinition createNestedBuilderClass(Service service, TypeSto .build(); } - private static List createNestedBuilderClassMethods( + private List createNestedBuilderClassMethods( Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); javaMethods.addAll(createNestedBuilderConstructorMethods(service, typeStore)); - javaMethods.add(createNestedBuilderCreatorMethod(service, typeStore)); + javaMethods.addAll( + createNestedBuilderCreatorMethods(service, typeStore, "newBuilder", "createDefault")); javaMethods.add(createNestedBuilderStubSettingsBuilderMethod(service, typeStore)); javaMethods.add(createNestedBuilderApplyToAllUnaryMethod(service, typeStore)); javaMethods.addAll(createNestedBuilderSettingsGetterMethods(service, typeStore)); @@ -557,23 +576,28 @@ private static List createNestedBuilderConstructorMethods( return Arrays.asList(noArgCtor, clientContextCtor, settingsCtor, stubSettingsCtor); } - private static MethodDefinition createNestedBuilderCreatorMethod( - Service service, TypeStore typeStore) { + protected List createNestedBuilderCreatorMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { MethodInvocationExpr ctorArg = MethodInvocationExpr.builder() .setStaticReferenceType( typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) - .setMethodName("newBuilder") + .setMethodName(newBuilderMethodName) .build(); TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); - return MethodDefinition.builder() - .setScope(ScopeNode.PRIVATE) - .setIsStatic(true) - .setReturnType(builderType) - .setName("createDefault") - .setReturnExpr(NewObjectExpr.builder().setType(builderType).setArguments(ctorArg).build()) - .build(); + return ImmutableList.of( + MethodDefinition.builder() + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .setReturnType(builderType) + .setName(createDefaultMethodName) + .setReturnExpr( + NewObjectExpr.builder().setType(builderType).setArguments(ctorArg).build()) + .build()); } private static MethodDefinition createNestedBuilderStubSettingsBuilderMethod( @@ -648,8 +672,6 @@ private static MethodDefinition createNestedBuilderApplyToAllUnaryMethod( .setReturnType(builderType) .setName(javaMethodName) .setArguments(Arrays.asList(settingsUpdaterVarExpr.toBuilder().setIsDecl(true).build())) - .setThrowsExceptions( - Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) .setBody(Arrays.asList(ExprStatement.withExpr(applyMethodExpr))) .setReturnExpr(ValueExpr.withValue(ThisObjectValue.withType(builderType))) .build(); @@ -728,7 +750,7 @@ private static MethodDefinition createNestedBuilderClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiClientHeaderProvider.class, ApiFunction.class, @@ -793,7 +815,7 @@ private static TypeNode getOperationCallSettingsTypeHelper( Preconditions.checkState( protoMethod.hasLro(), String.format("Cannot get OperationCallSettings on non-LRO method %s", protoMethod.name())); - Class callSettingsClazz = + Class callSettingsClazz = isBuilder ? OperationCallSettings.Builder.class : OperationCallSettings.class; return TypeNode.withReference( ConcreteReference.builder() @@ -816,7 +838,8 @@ private static TypeNode getCallSettingsBuilderType(Method protoMethod, TypeStore private static TypeNode getCallSettingsTypeHelper( Method protoMethod, TypeStore typeStore, boolean isBuilder) { - Class callSettingsClazz = isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; + Class callSettingsClazz = + isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; if (protoMethod.isPaged()) { callSettingsClazz = isBuilder ? PagedCallSettings.Builder.class : PagedCallSettings.class; } else if (protoMethod.isBatching()) { diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java index 4b6e8555b1..3f80382bab 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java @@ -16,75 +16,42 @@ import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.rpc.BidiStreamingCallable; -import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.OperationCallable; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ClassDefinition; -import com.google.api.generator.engine.ast.CommentStatement; -import com.google.api.generator.engine.ast.ConcreteReference; -import com.google.api.generator.engine.ast.EmptyLineStatement; -import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.JavaDocComment; import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.NewObjectExpr; -import com.google.api.generator.engine.ast.ReferenceConstructorExpr; +import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.Statement; -import com.google.api.generator.engine.ast.ThisObjectValue; +import com.google.api.generator.engine.ast.ThrowExpr; import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; -import com.google.api.generator.engine.ast.Variable; -import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.comment.StubCommentComposer; import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.composer.utils.PackageChecker; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import com.google.longrunning.Operation; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; public abstract class AbstractServiceStubClassComposer implements ClassComposer { - private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); - - private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; - private static final String PAGED_CALLABLE_CLASS_MEMBER_PATTERN = "%sPagedCallable"; - - private static final String BACKGROUND_RESOURCES_MEMBER_NAME = "backgroundResources"; - private static final String CALLABLE_NAME = "Callable"; - private static final String CALLABLE_FACTORY_MEMBER_NAME = "callableFactory"; - private static final String CALLABLE_CLASS_MEMBER_PATTERN = "%sCallable"; - private static final String OPERATION_CALLABLE_CLASS_MEMBER_PATTERN = "%sOperationCallable"; - private static final String OPERATION_CALLABLE_NAME = "OperationCallable"; - private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub"; - private static final String PAGED_CALLABLE_NAME = "PagedCallable"; - - protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); private final TransportContext transportContext; @@ -92,252 +59,38 @@ protected AbstractServiceStubClassComposer(TransportContext transportContext) { this.transportContext = transportContext; } - public TransportContext getTransportContext() { + protected TransportContext getTransportContext() { return transportContext; } - private static TypeStore createStaticTypes() { - List concreteClazzes = - Arrays.asList( - BackgroundResource.class, - BackgroundResourceAggregation.class, - BetaApi.class, - BidiStreamingCallable.class, - ClientContext.class, - ClientStreamingCallable.class, - Generated.class, - ImmutableMap.class, - InterruptedException.class, - IOException.class, - Operation.class, - OperationCallable.class, - RequestParamsExtractor.class, - ServerStreamingCallable.class, - TimeUnit.class, - UnaryCallable.class); - return new TypeStore(concreteClazzes); - } - @Override public GapicClass generate(GapicContext context, Service service) { - String pakkage = service.pakkage() + ".stub"; - TypeStore typeStore = createDynamicTypes(service, pakkage); - String className = getTransportContext().classNames().getTransportServiceStubClassName(service); + Map messageTypes = context.messages(); + TypeStore typeStore = createTypes(service, messageTypes); + String className = ClassNames.getServiceStubClassName(service); GapicClass.Kind kind = Kind.STUB; - - Map protoMethodNameToDescriptorVarExprs = - createProtoMethodNameToDescriptorClassMembers( - service, getTransportContext().methodDescriptorClass()); - - Map callableClassMemberVarExprs = - createCallableClassMembers(service, typeStore); - - Map classMemberVarExprs = new LinkedHashMap<>(); - classMemberVarExprs.put( - BACKGROUND_RESOURCES_MEMBER_NAME, - VariableExpr.withVariable( - Variable.builder() - .setName(BACKGROUND_RESOURCES_MEMBER_NAME) - .setType(FIXED_TYPESTORE.get("BackgroundResource")) - .build())); - if (getTransportContext().transportOperationsStubType() != null) { - classMemberVarExprs.put( - OPERATIONS_STUB_MEMBER_NAME, - VariableExpr.withVariable( - Variable.builder() - .setName(OPERATIONS_STUB_MEMBER_NAME) - .setType(getTransportContext().transportOperationsStubType()) - .build())); - } - classMemberVarExprs.put( - CALLABLE_FACTORY_MEMBER_NAME, - VariableExpr.withVariable( - Variable.builder() - .setName(CALLABLE_FACTORY_MEMBER_NAME) - .setType(getTransportContext().stubCallableFactoryType()) - .build())); - - List classStatements = - createClassStatements( - service, - protoMethodNameToDescriptorVarExprs, - callableClassMemberVarExprs, - classMemberVarExprs); - - StubCommentComposer commentComposer = - new StubCommentComposer(getTransportContext().transportName()); + String pakkage = String.format("%s.stub", service.pakkage()); ClassDefinition classDef = ClassDefinition.builder() .setPackageString(pakkage) .setHeaderCommentStatements( - commentComposer.createTransportServiceStubClassHeaderComments( + StubCommentComposer.createServiceStubClassHeaderComments( service.name(), service.isDeprecated())) - .setAnnotations(createClassAnnotations(service)) - .setScope(ScopeNode.PUBLIC) + .setAnnotations(createClassAnnotations(service, typeStore)) + .setIsAbstract(true) + .setImplementsTypes(createClassImplements(typeStore)) .setName(className) - .setExtendsType( - typeStore.get(getTransportContext().classNames().getServiceStubClassName(service))) - .setStatements(classStatements) - .setMethods( - createClassMethods( - service, - typeStore, - classMemberVarExprs, - callableClassMemberVarExprs, - protoMethodNameToDescriptorVarExprs)) + .setMethods(createClassMethods(service, messageTypes, typeStore)) + .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); } - protected abstract Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr); - - protected abstract List createOperationsStubGetterMethod( - VariableExpr operationsStubVarExpr); - - protected abstract Expr createTransportSettingsInitExpr( - Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr); - - protected List createGetMethodDescriptorsMethod( - Service service, - TypeStore typeStore, - Map protoMethodNameToDescriptorVarExprs) { - return Arrays.asList(); - } - - protected List createClassStatements( - Service service, - Map protoMethodNameToDescriptorVarExprs, - Map callableClassMemberVarExprs, - Map classMemberVarExprs) { - List classStatements = new ArrayList<>(); - for (Statement statement : - createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs)) { - classStatements.add(statement); - classStatements.add(EMPTY_LINE_STATEMENT); - } - - classStatements.addAll(createClassMemberFieldDeclarations(callableClassMemberVarExprs)); - classStatements.add(EMPTY_LINE_STATEMENT); - - classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs)); - return classStatements; - } - - protected List createMethodDescriptorVariableDecls( - Service service, Map protoMethodNameToDescriptorVarExprs) { - return service.methods().stream() - .map( - m -> - createMethodDescriptorVariableDecl( - service, m, protoMethodNameToDescriptorVarExprs.get(m.name()))) - .collect(Collectors.toList()); - } - - private static List createClassMemberFieldDeclarations( - Map fieldNameToVarExprs) { - return fieldNameToVarExprs.values().stream() - .map( - v -> - ExprStatement.withExpr( - v.toBuilder() - .setIsDecl(true) - .setScope(ScopeNode.PRIVATE) - .setIsFinal(true) - .build())) - .collect(Collectors.toList()); - } - - protected Map createProtoMethodNameToDescriptorClassMembers( - Service service, Class descriptorClass) { - return service.methods().stream() - .collect( - Collectors.toMap( - Method::name, - m -> - VariableExpr.withVariable( - Variable.builder() - .setName( - String.format( - METHOD_DESCRIPTOR_NAME_PATTERN, - JavaStyle.toLowerCamelCase(m.name()))) - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(descriptorClass) - .setGenerics( - Arrays.asList( - m.inputType().reference(), - m.outputType().reference())) - .build())) - .build()))); - } - - private Map createCallableClassMembers( - Service service, TypeStore typeStore) { - Map callableClassMembers = new LinkedHashMap<>(); - // Using a for-loop because the output cardinality is not a 1:1 mapping to the input set. - for (Method protoMethod : service.methods()) { - String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name()); - String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); - callableClassMembers.put( - callableName, - VariableExpr.withVariable( - Variable.builder() - .setName(callableName) - .setType(getCallableType(protoMethod)) - .build())); - if (protoMethod.hasLro()) { - callableName = - String.format(OPERATION_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); - callableClassMembers.put( - callableName, - VariableExpr.withVariable( - Variable.builder() - .setName(callableName) - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(OperationCallable.class) - .setGenerics( - Arrays.asList( - protoMethod.inputType().reference(), - protoMethod.lro().responseType().reference(), - protoMethod.lro().metadataType().reference())) - .build())) - .build())); - } - if (protoMethod.isPaged()) { - callableName = String.format(PAGED_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); - callableClassMembers.put( - callableName, - VariableExpr.withVariable( - Variable.builder() - .setName(callableName) - .setType( - TypeNode.withReference( - getCallableType(protoMethod) - .reference() - .copyAndSetGenerics( - Arrays.asList( - protoMethod.inputType().reference(), - typeStore - .get( - String.format( - PAGED_RESPONSE_TYPE_NAME_PATTERN, - protoMethod.name())) - .reference())))) - .build())); - } - } - return callableClassMembers; - } - - protected List createClassAnnotations(Service service) { + private static List createClassAnnotations(Service service, TypeStore typeStore) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); + annotations.add(AnnotationNode.withType(typeStore.get("BetaApi"))); } if (service.isDeprecated()) { @@ -346,504 +99,153 @@ protected List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("Generated")) + .setType(typeStore.get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; } - protected List createClassMethods( - Service service, - TypeStore typeStore, - Map classMemberVarExprs, - Map callableClassMemberVarExprs, - Map protoMethodNameToDescriptorVarExprs) { - List javaMethods = new ArrayList<>(); - javaMethods.addAll(createStaticCreatorMethods(service, typeStore)); - javaMethods.addAll( - createConstructorMethods( - service, - typeStore, - classMemberVarExprs, - callableClassMemberVarExprs, - protoMethodNameToDescriptorVarExprs)); - javaMethods.addAll( - createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs)); - javaMethods.addAll( - createOperationsStubGetterMethod(classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME))); - javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs)); - javaMethods.addAll( - createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME))); - return javaMethods; + private static List createClassImplements(TypeStore typeStore) { + return Arrays.asList(typeStore.get("BackgroundResource")); } - private List createStaticCreatorMethods(Service service, TypeStore typeStore) { - TypeNode creatorMethodReturnType = - typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); - Function, MethodDefinition.Builder> creatorMethodStarterFn = - argList -> - MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setIsFinal(true) - .setReturnType(creatorMethodReturnType) - .setName("create") - .setArguments( - argList.stream() - .map(v -> v.toBuilder().setIsDecl(true).build()) - .collect(Collectors.toList())) - .setThrowsExceptions( - Arrays.asList( - TypeNode.withReference(ConcreteReference.withClazz(IOException.class)))); - - Function, Expr> instantiatorExprFn = - argList -> - NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build(); - - TypeNode stubSettingsType = - typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service)); - VariableExpr settingsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("settings").setType(stubSettingsType).build()); - - TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); - VariableExpr clientContextVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("clientContext").setType(clientContextType).build()); - - VariableExpr callableFactoryVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setName("callableFactory") - .setType(getTransportContext().stubCallableFactoryType()) - .build()); - - MethodInvocationExpr clientContextCreateMethodExpr = - MethodInvocationExpr.builder() - .setMethodName("create") - .setStaticReferenceType(clientContextType) - .setArguments(Arrays.asList(settingsVarExpr)) - .build(); - MethodInvocationExpr settingsBuilderMethodExpr = - MethodInvocationExpr.builder() - .setMethodName("newBuilder") - .setStaticReferenceType(stubSettingsType) - .build(); - settingsBuilderMethodExpr = - MethodInvocationExpr.builder() - .setMethodName("build") - .setExprReferenceExpr(settingsBuilderMethodExpr) - .build(); - - return Arrays.asList( - creatorMethodStarterFn - .apply(Arrays.asList(settingsVarExpr)) - .setReturnExpr( - instantiatorExprFn.apply( - Arrays.asList(settingsVarExpr, clientContextCreateMethodExpr))) - .build(), - creatorMethodStarterFn - .apply(Arrays.asList(clientContextVarExpr)) - .setReturnExpr( - instantiatorExprFn.apply( - Arrays.asList(settingsBuilderMethodExpr, clientContextVarExpr))) - .build(), - creatorMethodStarterFn - .apply(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) - .setReturnExpr( - instantiatorExprFn.apply( - Arrays.asList( - settingsBuilderMethodExpr, clientContextVarExpr, callableFactoryVarExpr))) - .build()); + private List createClassMethods( + Service service, Map messageTypes, TypeStore typeStore) { + boolean hasLroClient = service.hasLroMethods(); + List methods = new ArrayList<>(); + if (hasLroClient) { + methods.addAll(createOperationsStubGetters(typeStore)); + } + methods.addAll(createCallableGetters(service, messageTypes, typeStore)); + methods.addAll(createBackgroundResourceMethodOverrides()); + return methods; } - protected List createConstructorMethods( - Service service, - TypeStore typeStore, - Map classMemberVarExprs, - Map callableClassMemberVarExprs, - Map protoMethodNameToDescriptorVarExprs) { - TypeNode stubSettingsType = - typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service)); - VariableExpr settingsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("settings").setType(stubSettingsType).build()); - - TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); - VariableExpr clientContextVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("clientContext").setType(clientContextType).build()); - - VariableExpr callableFactoryVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setName("callableFactory") - .setType(getTransportContext().stubCallableFactoryType()) - .build()); - - TypeNode thisClassType = - typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); - TypeNode ioExceptionType = - TypeNode.withReference(ConcreteReference.withClazz(IOException.class)); - - BiFunction, List, MethodDefinition> ctorMakerFn = - (args, body) -> - MethodDefinition.constructorBuilder() - .setScope(ScopeNode.PROTECTED) - .setReturnType(thisClassType) - .setHeaderCommentStatements(Arrays.asList(createProtectedCtorComment(service))) - .setArguments( - args.stream() - .map(v -> v.toBuilder().setIsDecl(true).build()) - .collect(Collectors.toList())) - .setThrowsExceptions(Arrays.asList(ioExceptionType)) - .setBody(body) - .build(); - - // First constructor method. - MethodDefinition firstCtor = - ctorMakerFn.apply( - Arrays.asList(settingsVarExpr, clientContextVarExpr), - Arrays.asList( - ExprStatement.withExpr( - ReferenceConstructorExpr.thisBuilder() - .setType(thisClassType) - .setArguments( - settingsVarExpr, - clientContextVarExpr, - NewObjectExpr.builder() - .setType( - typeStore.get( - getTransportContext() - .classNames() - .getTransportServiceCallableFactoryClassName(service))) - .build()) - .build()))); - - Expr thisExpr = - ValueExpr.withValue( - ThisObjectValue.withType( - typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)))); - // Body of the second constructor method. - List secondCtorStatements = new ArrayList<>(); - List secondCtorExprs = new ArrayList<>(); - secondCtorExprs.add( - AssignmentExpr.builder() - .setVariableExpr( - classMemberVarExprs.get("callableFactory").toBuilder() - .setExprReferenceExpr(thisExpr) - .build()) - .setValueExpr(callableFactoryVarExpr) - .build()); - VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME); - if (getTransportContext().transportOperationsStubType() != null) { - secondCtorExprs.add( - AssignmentExpr.builder() - .setVariableExpr( - operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType( - getTransportContext().transportOperationsStubType()) - .setMethodName("create") - .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) - .setReturnType(operationsStubClassVarExpr.type()) - .build()) - .build()); + private List createCallableGetters( + Service service, Map messageTypes, TypeStore typeStore) { + // Use a traditional for-loop since the output cardinality is not necessarily 1:1 with that of + // service.methods(). + List javaMethods = new ArrayList<>(); + for (Method method : service.methods()) { + if (method.hasLro()) { + javaMethods.add(createOperationCallableGetter(method, typeStore)); + } + if (method.isPaged()) { + javaMethods.add(createPagedCallableGetter(method, typeStore)); + } + javaMethods.add(createCallableGetter(method, typeStore)); } - secondCtorStatements.addAll( - secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - secondCtorExprs.clear(); - secondCtorStatements.add(EMPTY_LINE_STATEMENT); + return javaMethods; + } - // Transport settings local variables. - Map javaStyleMethodNameToTransportSettingsVarExprs = - service.methods().stream() - .collect( - Collectors.toMap( - m -> JavaStyle.toLowerCamelCase(m.name()), - m -> - VariableExpr.withVariable( - Variable.builder() - .setName( - String.format( - "%sTransportSettings", - JavaStyle.toLowerCamelCase(m.name()))) - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(getTransportContext().callSettingsClass()) - .setGenerics( - Arrays.asList( - m.inputType().reference(), - m.outputType().reference())) - .build())) - .build()))); - - secondCtorExprs.addAll( - service.methods().stream() - .map( - m -> - createTransportSettingsInitExpr( - m, - javaStyleMethodNameToTransportSettingsVarExprs.get( - JavaStyle.toLowerCamelCase(m.name())), - protoMethodNameToDescriptorVarExprs.get(m.name()))) - .collect(Collectors.toList())); - secondCtorStatements.addAll( - secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - secondCtorExprs.clear(); - secondCtorStatements.add(EMPTY_LINE_STATEMENT); - - // Initialize Callable variables. - secondCtorExprs.addAll( - callableClassMemberVarExprs.entrySet().stream() - .map( - e -> - createCallableInitExpr( - e.getKey(), - e.getValue(), - callableFactoryVarExpr, - settingsVarExpr, - clientContextVarExpr, - operationsStubClassVarExpr, - thisExpr, - javaStyleMethodNameToTransportSettingsVarExprs)) - .collect(Collectors.toList())); - secondCtorStatements.addAll( - secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - secondCtorExprs.clear(); - secondCtorStatements.add(EMPTY_LINE_STATEMENT); - - // Instantiate backgroundResources. - MethodInvocationExpr getBackgroundResourcesMethodExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(clientContextVarExpr) - .setMethodName("getBackgroundResources") - .build(); - VariableExpr backgroundResourcesVarExpr = classMemberVarExprs.get("backgroundResources"); - secondCtorExprs.add( - AssignmentExpr.builder() - .setVariableExpr( - backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation")) - .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr)) - .build()) - .build()); - secondCtorStatements.addAll( - secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - secondCtorExprs.clear(); + private MethodDefinition createOperationCallableGetter(Method method, TypeStore typeStore) { + return createCallableGetterHelper(method, typeStore, true, false); + } - // Second constructor method. - MethodDefinition secondCtor = - ctorMakerFn.apply( - Arrays.asList(settingsVarExpr, clientContextVarExpr, callableFactoryVarExpr), - secondCtorStatements); + private MethodDefinition createPagedCallableGetter(Method method, TypeStore typeStore) { + return createCallableGetterHelper(method, typeStore, false, true); + } - return Arrays.asList(firstCtor, secondCtor); + private MethodDefinition createCallableGetter(Method method, TypeStore typeStore) { + return createCallableGetterHelper(method, typeStore, false, false); } - private static Expr createCallableInitExpr( - String callableVarName, - VariableExpr callableVarExpr, - VariableExpr callableFactoryVarExpr, - VariableExpr settingsVarExpr, - VariableExpr clientContextVarExpr, - VariableExpr operationsStubClassVarExpr, - Expr thisExpr, - Map javaStyleMethodNameToTransportSettingsVarExprs) { - boolean isOperation = callableVarName.endsWith(OPERATION_CALLABLE_NAME); - boolean isPaged = callableVarName.endsWith(PAGED_CALLABLE_NAME); - int sublength = 0; - if (isOperation) { - sublength = OPERATION_CALLABLE_NAME.length(); - } else if (isPaged) { - sublength = PAGED_CALLABLE_NAME.length(); - } else { - sublength = CALLABLE_NAME.length(); - } - String javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength); - List creatorMethodArgVarExprs = null; - Expr transportSettingsVarExpr = - javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName); - if (transportSettingsVarExpr == null && isOperation) { - // Try again, in case the name dtection above was inaccurate. - isOperation = false; - sublength = CALLABLE_NAME.length(); - javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength); - transportSettingsVarExpr = - javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName); + private MethodDefinition createCallableGetterHelper( + Method method, TypeStore typeStore, boolean isLroCallable, boolean isPaged) { + TypeNode returnType; + switch (method.stream()) { + case CLIENT: + returnType = typeStore.get("ClientStreamingCallable"); + break; + case SERVER: + returnType = typeStore.get("ServerStreamingCallable"); + break; + case BIDI: + returnType = typeStore.get("BidiStreamingCallable"); + break; + case NONE: + // Fall through. + default: + returnType = typeStore.get(isLroCallable ? "OperationCallable" : "UnaryCallable"); } - Preconditions.checkNotNull( - transportSettingsVarExpr, + + String methodName = String.format( - "No transport settings variable found for method name %s", javaStyleMethodName)); - if (isOperation) { - creatorMethodArgVarExprs = - Arrays.asList( - transportSettingsVarExpr, - MethodInvocationExpr.builder() - .setExprReferenceExpr(settingsVarExpr) - .setMethodName(String.format("%sOperationSettings", javaStyleMethodName)) - .build(), - clientContextVarExpr, - operationsStubClassVarExpr); + "%s%sCallable", + JavaStyle.toLowerCamelCase(method.name()), + (isLroCallable ? "Operation" : isPaged ? "Paged" : "")); + List genericRefs = new ArrayList<>(); + genericRefs.add(method.inputType().reference()); + if (method.hasLro() && isLroCallable) { + genericRefs.add(method.lro().responseType().reference()); + genericRefs.add(method.lro().metadataType().reference()); + } else if (isPaged) { + genericRefs.add( + typeStore + .get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name())) + .reference()); } else { - creatorMethodArgVarExprs = - Arrays.asList( - transportSettingsVarExpr, - MethodInvocationExpr.builder() - .setExprReferenceExpr(settingsVarExpr) - .setMethodName(String.format("%sSettings", javaStyleMethodName)) - .build(), - clientContextVarExpr); + genericRefs.add(method.outputType().reference()); } - String callableCreatorMethodName = getCallableCreatorMethodName(callableVarExpr.type()); - return AssignmentExpr.builder() - .setVariableExpr(callableVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(callableFactoryVarExpr) - .setMethodName(callableCreatorMethodName) - .setArguments(creatorMethodArgVarExprs) - .setReturnType(callableVarExpr.type()) - .build()) - .build(); + List annotations = + method.isDeprecated() + ? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED)) + : Collections.emptyList(); + + returnType = TypeNode.withReference(returnType.reference().copyAndSetGenerics(genericRefs)); + + return createCallableGetterMethodDefinition(returnType, methodName, annotations, typeStore); } - private static String getCallableCreatorMethodName(TypeNode callableVarExprType) { - final String typeName = callableVarExprType.reference().name(); - String streamName = "Unary"; + private List createOperationsStubGetters(TypeStore typeStore) { + List getters = new ArrayList<>(); - // Special handling for pagination methods. - if (callableVarExprType.reference().generics().size() == 2 - && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) { - streamName = "Paged"; - } else { - if (typeName.startsWith("Client")) { - streamName = "ClientStreaming"; - } else if (typeName.startsWith("Server")) { - streamName = "ServerStreaming"; - } else if (typeName.startsWith("Bidi")) { - streamName = "BidiStreaming"; - } else if (typeName.startsWith("Operation")) { - streamName = "Operation"; - } + Iterator operationStubNameIt = + getTransportContext().transportOperationsStubNames().iterator(); + Iterator operationStubTypeIt = getTransportContext().operationsStubTypes().iterator(); + + while (operationStubNameIt.hasNext() && operationStubTypeIt.hasNext()) { + String methodName = + String.format("get%s", JavaStyle.toUpperCamelCase(operationStubNameIt.next())); + + getters.add( + createOperationsStubGetterMethodDefinition( + operationStubTypeIt.next(), methodName, typeStore)); } - return String.format("create%sCallable", streamName); - } - private static List createCallableGetterMethods( - Map callableClassMemberVarExprs) { - return callableClassMemberVarExprs.entrySet().stream() - .map( - e -> - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setReturnType(e.getValue().type()) - .setName(e.getKey()) - .setReturnExpr(e.getValue()) - .build()) - .collect(Collectors.toList()); + return getters; } - private List createStubOverrideMethods( - VariableExpr backgroundResourcesVarExpr) { - Function methodMakerStarterFn = - methodName -> - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setName(methodName); - - Function voidMethodMakerFn = - methodName -> - methodMakerStarterFn - .apply(methodName) - .setReturnType(TypeNode.VOID) - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(backgroundResourcesVarExpr) - .setMethodName(methodName) - .build()))) - .build(); - - Function booleanMethodMakerFn = - methodName -> - methodMakerStarterFn - .apply(methodName) - .setReturnType(TypeNode.BOOLEAN) - .setReturnExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(backgroundResourcesVarExpr) - .setMethodName(methodName) - .setReturnType(TypeNode.BOOLEAN) - .build()) - .build(); - - List javaMethods = new ArrayList<>(); - javaMethods.add( - methodMakerStarterFn - .apply("close") - .setIsFinal(true) + private static List createBackgroundResourceMethodOverrides() { + MethodDefinition closeMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setIsAbstract(true) .setReturnType(TypeNode.VOID) - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder().setMethodName("shutdown").build()))) - .build()); - javaMethods.add(voidMethodMakerFn.apply("shutdown")); - javaMethods.add(booleanMethodMakerFn.apply("isShutdown")); - javaMethods.add(booleanMethodMakerFn.apply("isTerminated")); - javaMethods.add(voidMethodMakerFn.apply("shutdownNow")); - - List awaitTerminationArgs = - Arrays.asList( - VariableExpr.withVariable( - Variable.builder().setName("duration").setType(TypeNode.LONG).build()), - VariableExpr.withVariable( - Variable.builder() - .setName("unit") - .setType(FIXED_TYPESTORE.get("TimeUnit")) - .build())); - javaMethods.add( - methodMakerStarterFn - .apply("awaitTermination") - .setReturnType(TypeNode.BOOLEAN) - .setArguments( - awaitTerminationArgs.stream() - .map(v -> v.toBuilder().setIsDecl(true).build()) - .collect(Collectors.toList())) - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException"))) - .setReturnExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(backgroundResourcesVarExpr) - .setMethodName("awaitTermination") - .setArguments( - awaitTerminationArgs.stream() - .map(v -> (Expr) v) - .collect(Collectors.toList())) - .setReturnType(TypeNode.BOOLEAN) - .build()) - .build()); - return javaMethods; + .setName("close") + .build(); + return Arrays.asList(closeMethod); } - private TypeStore createDynamicTypes(Service service, String stubPakkage) { - TypeStore typeStore = new TypeStore(); - typeStore.putAll( - stubPakkage, + private static TypeStore createTypes(Service service, Map messageTypes) { + List> concreteClazzes = Arrays.asList( - getTransportContext().classNames().getTransportServiceStubClassName(service), - getTransportContext().classNames().getServiceStubSettingsClassName(service), - getTransportContext().classNames().getServiceStubClassName(service), - getTransportContext().classNames().getTransportServiceCallableFactoryClassName(service))); + BackgroundResource.class, + BetaApi.class, + BidiStreamingCallable.class, + ClientStreamingCallable.class, + Generated.class, + Operation.class, + OperationCallable.class, + ServerStreamingCallable.class, + UnaryCallable.class, + UnsupportedOperationException.class); + TypeStore typeStore = new TypeStore(concreteClazzes); + + typeStore.put("com.google.longrunning.stub", "OperationsStub"); + // Pagination types. typeStore.putAll( service.pakkage(), @@ -852,52 +254,44 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) { .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .collect(Collectors.toList()), true, - getTransportContext().classNames().getServiceClientClassName(service)); - return typeStore; - } + ClassNames.getServiceClientClassName(service)); - private static TypeNode getCallableType(Method protoMethod) { - TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable"); - switch (protoMethod.stream()) { - case CLIENT: - callableType = FIXED_TYPESTORE.get("ClientStreamingCallable"); - break; - case SERVER: - callableType = FIXED_TYPESTORE.get("ServerStreamingCallable"); - break; - case BIDI: - callableType = FIXED_TYPESTORE.get("BidiStreamingCallable"); - break; - case NONE: - // Fall through - default: - // Fall through - } - - return TypeNode.withReference( - callableType - .reference() - .copyAndSetGenerics( - Arrays.asList( - protoMethod.inputType().reference(), protoMethod.outputType().reference()))); + return typeStore; } - private CommentStatement createProtectedCtorComment(Service service) { - return CommentStatement.withComment( - JavaDocComment.withComment( - String.format( - "Constructs an instance of %s, using the given settings. This is protected so that" - + " it is easy to make a subclass, but otherwise, the static factory methods" - + " should be preferred.", - getTransportContext().classNames().getTransportServiceStubClassName(service)))); + protected MethodDefinition createCallableGetterMethodDefinition( + TypeNode returnType, + String methodName, + List annotations, + TypeStore typeStore) { + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setAnnotations(annotations) + .setName(methodName) + .setReturnType(returnType) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + ThrowExpr.builder() + .setType(typeStore.get("UnsupportedOperationException")) + .setMessageExpr(String.format("Not implemented: %s()", methodName)) + .build()))) + .build(); } - protected String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { - if (protoMethod.isMixin()) { - return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name()); - } - - return String.format( - "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); + protected MethodDefinition createOperationsStubGetterMethodDefinition( + TypeNode returnType, String methodName, TypeStore typeStore) { + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setReturnType(returnType) + .setName(methodName) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + ThrowExpr.builder() + .setType(typeStore.get("UnsupportedOperationException")) + .setMessageExpr(String.format("Not implemented: %s()", methodName)) + .build()))) + .build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index fb2d350011..7a38adba80 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -61,6 +61,7 @@ import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.ReferenceConstructorExpr; import com.google.api.generator.engine.ast.RelationalOperationExpr; @@ -104,6 +105,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -138,8 +140,6 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); - private static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = - createDefaultServiceScopesVarExpr(); private static final VariableExpr NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR = createNestedUnaryMethodSettingsBuildersVarExpr(); private static final VariableExpr NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR = @@ -149,6 +149,9 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC private final TransportContext transportContext; + protected static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = + createDefaultServiceScopesVarExpr(); + protected AbstractServiceStubSettingsClassComposer(TransportContext transportContext) { this.transportContext = transportContext; } @@ -196,11 +199,152 @@ public GapicClass generate(GapicContext context, Service service) { return GapicClass.create(GapicClass.Kind.STUB, classDef); } - protected abstract MethodDefinition createDefaultTransportTransportProviderBuilderMethod(); + protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); + MethodInvocationExpr credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) + .setMethodName("newBuilder") + .build(); + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setScopesToApply") + .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultCredentialsProviderBuilder") + .setReturnExpr(credsProviderBuilderExpr) + .build(); + } + + protected List createDefaultTransportTransportProviderBuilderMethods() { + // Create the defaultGrpcTransportProviderBuilder method. + Iterator> providerClassIt = + getTransportContext().instantiatingChannelProviderClasses().iterator(); + Iterator> providerBuilderClassIt = + getTransportContext().instantiatingChannelProviderBuilderClasses().iterator(); + Iterator builderNamesIt = + getTransportContext().defaultTransportProviderBuilderNames().iterator(); + + List methods = new ArrayList<>(); + + while (providerClassIt.hasNext() + && providerBuilderClassIt.hasNext() + && builderNamesIt.hasNext()) { + TypeNode returnType = + TypeNode.withReference(ConcreteReference.withClazz(providerBuilderClassIt.next())); + TypeNode channelProviderType = + TypeNode.withReference(ConcreteReference.withClazz(providerClassIt.next())); + + MethodInvocationExpr transportChannelProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(channelProviderType) + .setMethodName("newBuilder") + .setReturnType(returnType) + .build(); + Expr returnExpr = + initializeTransportProviderBuilder(transportChannelProviderBuilderExpr, returnType); + + MethodDefinition method = + MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName(builderNamesIt.next()) + .setReturnExpr(returnExpr) + .build(); + methods.add(method); + } + + return methods; + } + + protected Expr initializeTransportProviderBuilder( + MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) { + return transportChannelProviderBuilderExpr; + } - protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + protected abstract List createApiClientHeaderProviderBuilderMethods( Service service, TypeStore typeStore); + protected MethodDefinition createApiClientHeaderProviderBuilderMethod( + Service service, + TypeStore typeStore, + String methodName, + TypeNode gaxPropertiesType, + String getTokenMethodName, + String getVersionMethodName) { + TypeNode returnType = + TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); + MethodInvocationExpr returnExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) + .setMethodName("newBuilder") + .build(); + + MethodInvocationExpr versionArgExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("GaxProperties")) + .setMethodName("getLibraryVersion") + .setArguments( + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) + .build()) + .build(); + + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setGeneratedLibToken") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) + .build(); + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setTransportToken") + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType(gaxPropertiesType) + .setMethodName(getTokenMethodName) + .build(), + MethodInvocationExpr.builder() + .setStaticReferenceType(gaxPropertiesType) + .setMethodName(getVersionMethodName) + .build()) + .setReturnType(returnType) + .build(); + + AnnotationNode annotation = + AnnotationNode.builder() + .setType(FIXED_TYPESTORE.get("BetaApi")) + .setDescription( + "The surface for customizing headers is not stable yet and may change in the" + + " future.") + .build(); + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(annotation)) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName(methodName) + .setReturnExpr(returnExpr) + .build(); + } + public abstract MethodDefinition createDefaultTransportChannelProviderMethod(); private List createClassAnnotations(Service service) { @@ -305,8 +449,7 @@ private static List createClassStatements( // Assign DEFAULT_SERVICE_SCOPES. statements.add(SettingsCommentComposer.DEFAULT_SCOPES_COMMENT); VariableExpr defaultServiceScopesDeclVarExpr = - DEFAULT_SERVICE_SCOPES_VAR_EXPR - .toBuilder() + DEFAULT_SERVICE_SCOPES_VAR_EXPR.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -402,7 +545,7 @@ private static List createPagingStaticAssignExprs( "No method found for message type %s for method %s among %s", pagedResponseMessageKey, method.name(), messageTypes.keySet())); - Field repeatedPagedResultsField = pagedResponseMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = pagedResponseMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -511,7 +654,7 @@ private static Expr createPagedListDescriptorAssignExpr( returnExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(newBuilderExpr) - .setMethodName("setPageSize") + .setMethodName("set" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) .setArguments(pageSizeVarExpr) .build(); returnExpr = @@ -542,7 +685,7 @@ private static Expr createPagedListDescriptorAssignExpr( .setReturnExpr( MethodInvocationExpr.builder() .setExprReferenceExpr(payloadVarExpr) - .setMethodName("getPageSize") + .setMethodName("get" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName())) .setReturnType(returnType) .build()) .build()); @@ -572,29 +715,71 @@ private static Expr createPagedListDescriptorAssignExpr( .setClazz(Iterable.class) .setGenerics(Arrays.asList(repeatedResponseType.reference())) .build()); - Expr getResponsesListExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(payloadVarExpr) - .setMethodName( - String.format("get%sList", JavaStyle.toUpperCamelCase(repeatedFieldName))) - .setReturnType(returnType) - .build(); + + Expr getResponsesExpr; + Expr elseExpr; + Expr thenExpr; + if (repeatedResponseType.reference() != null + && "java.util.Map.Entry".equals(repeatedResponseType.reference().fullName())) { + getResponsesExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(payloadVarExpr) + .setMethodName( + String.format("get%sMap", JavaStyle.toUpperCamelCase(repeatedFieldName))) + .setReturnType(returnType) + .build(); + thenExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(Collections.class))) + .setGenerics(Arrays.asList(repeatedResponseType.reference())) + .setMethodName("emptySet") + .setReturnType(returnType) + .build(); + elseExpr = + MethodInvocationExpr.builder() + .setMethodName("entrySet") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(payloadVarExpr) + .setMethodName( + String.format("get%sMap", JavaStyle.toUpperCamelCase(repeatedFieldName))) + .build()) + .setReturnType(returnType) + .build(); + } else { + getResponsesExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(payloadVarExpr) + .setMethodName( + String.format("get%sList", JavaStyle.toUpperCamelCase(repeatedFieldName))) + .setReturnType(returnType) + .build(); + thenExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(ImmutableList.class))) + .setGenerics(Arrays.asList(repeatedResponseType.reference())) + .setMethodName("of") + .setReturnType(returnType) + .build(); + elseExpr = getResponsesExpr; + } + // While protobufs should not be null, this null-check is needed to protect against NPEs + // in paged iteration on clients that use legacy HTTP/JSON types, as these clients can + // actually return null instead of an empty list. + // Context: + // Original issue: https://github.com/googleapis/google-cloud-java/issues/3736 + // Relevant discussion where this check was first added: + // https://github.com/googleapis/google-cloud-java/pull/4499#discussion_r257057409 Expr conditionExpr = - RelationalOperationExpr.equalToWithExprs(getResponsesListExpr, ValueExpr.createNullExpr()); - Expr thenExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - TypeNode.withReference(ConcreteReference.withClazz(ImmutableList.class))) - .setGenerics(Arrays.asList(repeatedResponseType.reference())) - .setMethodName("of") - .setReturnType(returnType) - .build(); + RelationalOperationExpr.equalToWithExprs(getResponsesExpr, ValueExpr.createNullExpr()); returnExpr = TernaryExpr.builder() .setConditionExpr(conditionExpr) .setThenExpr(thenExpr) - .setElseExpr(getResponsesListExpr) + .setElseExpr(elseExpr) .build(); anonClassMethods.add( methodStarterBuilder @@ -614,8 +799,7 @@ private static Expr createPagedListDescriptorAssignExpr( // Declare and assign the variable. return AssignmentExpr.builder() .setVariableExpr( - pagedListDescVarExpr - .toBuilder() + pagedListDescVarExpr.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -754,8 +938,7 @@ private static Expr createPagedListResponseFactoryAssignExpr( return AssignmentExpr.builder() .setVariableExpr( - pagedListResponseFactoryVarExpr - .toBuilder() + pagedListResponseFactoryVarExpr.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -775,6 +958,7 @@ private List createClassMethods( createMethodSettingsGetterMethods(methodSettingsMemberVarExprs, deprecatedSettingVarNames)); javaMethods.add(createCreateStubMethod(service, typeStore)); javaMethods.addAll(createDefaultHelperAndGetterMethods(service, typeStore)); + javaMethods.addAll(createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault")); javaMethods.addAll(createBuilderHelperMethods(service, typeStore)); javaMethods.add(createClassConstructor(service, methodSettingsMemberVarExprs, typeStore)); return javaMethods; @@ -807,12 +991,7 @@ private static List createMethodSettingsGetterMethods( private MethodDefinition createCreateStubMethod(Service service, TypeStore typeStore) { // Set up the if-statement. - Expr tRansportNameExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - getTransportContext().transportChannelType()) - .setMethodName(getTransportContext().transportGetterName()) - .build(); + List bodyStatements = new ArrayList<>(); Expr getTransportNameExpr = MethodInvocationExpr.builder().setMethodName("getTransportChannelProvider").build(); @@ -822,30 +1001,48 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS .setMethodName("getTransportName") .build(); - Expr ifConditionExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(getTransportNameExpr) - .setMethodName("equals") - .setArguments(tRansportNameExpr) - .setReturnType(TypeNode.BOOLEAN) - .build(); + Iterator channelTypesIt = getTransportContext().transportChannelTypes().iterator(); + Iterator getterNameIt = getTransportContext().transportGetterNames().iterator(); + Iterator serivceStubClassNameIt = + getTransportContext().classNames().getTransportServiceStubClassNames(service).iterator(); - Expr createExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service))) - .setMethodName("create") - .setArguments( - ValueExpr.withValue( - ThisObjectValue.withType( - typeStore.get(ClassNames.getServiceStubSettingsClassName(service))))) - .build(); + while (channelTypesIt.hasNext() && getterNameIt.hasNext()) { + TypeNode channelType = channelTypesIt.next(); + String getterName = getterNameIt.next(); + String serivceStubClassName = serivceStubClassNameIt.next(); - IfStatement ifStatement = - IfStatement.builder() - .setConditionExpr(ifConditionExpr) - .setBody(Arrays.asList(ExprStatement.withExpr(ReturnExpr.withExpr(createExpr)))) - .build(); + Expr tRansportNameExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(channelType) + .setMethodName(getterName) + .build(); + + Expr ifConditionExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getTransportNameExpr) + .setMethodName("equals") + .setArguments(tRansportNameExpr) + .setReturnType(TypeNode.BOOLEAN) + .build(); + + Expr createExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(typeStore.get(serivceStubClassName)) + .setMethodName("create") + .setArguments( + ValueExpr.withValue( + ThisObjectValue.withType( + typeStore.get(ClassNames.getServiceStubSettingsClassName(service))))) + .build(); + + IfStatement ifStatement = + IfStatement.builder() + .setConditionExpr(ifConditionExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(ReturnExpr.withExpr(createExpr)))) + .build(); + + bodyStatements.add(ifStatement); + } // Set up exception throwing. Expr errorMessageExpr = @@ -862,6 +1059,8 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS ExprStatement.withExpr( ThrowExpr.builder().setType(exceptionType).setMessageExpr(errorMessageExpr).build()); + bodyStatements.add(throwStatement); + // Put the method together. TypeNode returnType = typeStore.get(ClassNames.getServiceStubClassName(service)); AnnotationNode annotation = @@ -877,7 +1076,7 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS .setReturnType(returnType) .setName("createStub") .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(IOException.class))) - .setBody(Arrays.asList(ifStatement, throwStatement)) + .setBody(bodyStatements) .build(); } @@ -918,77 +1117,75 @@ private List createDefaultHelperAndGetterMethods( .setReturnExpr(ValueExpr.withValue(StringObjectValue.withValue(service.defaultHost()))) .build()); - // Create the getDefaultServiceScopes method. - returnType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics(Arrays.asList(TypeNode.STRING.reference())) - .build()); + // Create the getDefaultMtlsEndpoint method. + returnType = TypeNode.STRING; javaMethods.add( MethodDefinition.builder() .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_SERVICE_SCOPES_METHOD_COMMENT) + SettingsCommentComposer.DEFAULT_SERVICE_MTLS_ENDPOINT_METHOD_COMMENT) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(returnType) - .setName("getDefaultServiceScopes") - .setReturnExpr(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setName("getDefaultMtlsEndpoint") + .setReturnExpr( + ValueExpr.withValue( + StringObjectValue.withValue( + service.defaultHost().replace(".googleapis.com", ".mtls.googleapis.com")))) .build()); - // Create the defaultCredentialsProviderBuilder method. + // Create the getDefaultServiceScopes method. returnType = TypeNode.withReference( - ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); - MethodInvocationExpr credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) - .setMethodName("newBuilder") - .build(); - credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(credsProviderBuilderExpr) - .setMethodName("setScopesToApply") - .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) - .setReturnType(returnType) - .build(); + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(TypeNode.STRING.reference())) + .build()); javaMethods.add( MethodDefinition.builder() .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) + SettingsCommentComposer.DEFAULT_SERVICE_SCOPES_METHOD_COMMENT) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(returnType) - .setName("defaultCredentialsProviderBuilder") - .setReturnExpr(credsProviderBuilderExpr) + .setName("getDefaultServiceScopes") + .setReturnExpr(DEFAULT_SERVICE_SCOPES_VAR_EXPR) .build()); - javaMethods.add(createDefaultTransportTransportProviderBuilderMethod()); + javaMethods.add(createDefaultCredentialsProviderBuilderMethod()); + javaMethods.addAll(createDefaultTransportTransportProviderBuilderMethods()); javaMethods.add(createDefaultTransportChannelProviderMethod()); - javaMethods.add(createDefaultApiClientHeaderProviderBuilderMethod(service, typeStore)); + javaMethods.addAll(createApiClientHeaderProviderBuilderMethods(service, typeStore)); return javaMethods; } - private static List createBuilderHelperMethods(Service service, TypeStore typeStore) { - List javaMethods = new ArrayList<>(); + protected List createNewBuilderMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { // Create the newBuilder() method. final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME); - javaMethods.add( + return ImmutableList.of( MethodDefinition.builder() .setHeaderCommentStatements(SettingsCommentComposer.NEW_BUILDER_METHOD_COMMENT) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(builderReturnType) - .setName("newBuilder") + .setName(newBuilderMethodName) .setReturnExpr( MethodInvocationExpr.builder() .setStaticReferenceType(builderReturnType) - .setMethodName("createDefault") + .setMethodName(createDefaultMethodName) .setReturnType(builderReturnType) .build()) .build()); + } + protected List createBuilderHelperMethods( + Service service, TypeStore typeStore) { + List javaMethods = new ArrayList<>(); + final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME); // Create the newBuilder(ClientContext) method. Function newBuilderFn = argExpr -> NewObjectExpr.builder().setType(builderReturnType).setArguments(argExpr).build(); @@ -1077,11 +1274,10 @@ private static MethodDefinition createClassConstructor( .build(); } - private static ClassDefinition createNestedBuilderClass( + private ClassDefinition createNestedBuilderClass( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. String thisClassName = ClassNames.getServiceStubSettingsClassName(service); - TypeNode outerThisClassType = typeStore.get(thisClassName); String className = "Builder"; @@ -1177,7 +1373,7 @@ private static List createNestedClassStatements( return statements; } - private static List createNestedClassMethods( + private List createNestedClassMethods( Service service, GapicServiceConfig serviceConfig, TypeNode superType, @@ -1188,7 +1384,7 @@ private static List createNestedClassMethods( nestedClassMethods.addAll( createNestedClassConstructorMethods( service, serviceConfig, nestedMethodSettingsMemberVarExprs, typeStore)); - nestedClassMethods.add(createNestedClassCreateDefaultMethod(typeStore)); + nestedClassMethods.addAll(createNestedClassCreateDefaultMethods(typeStore)); nestedClassMethods.add(createNestedClassInitDefaultsMethod(service, serviceConfig, typeStore)); nestedClassMethods.add(createNestedClassApplyToAllUnaryMethodsMethod(superType, typeStore)); nestedClassMethods.add(createNestedClassUnaryMethodSettingsBuilderGetterMethod()); @@ -1199,7 +1395,7 @@ private static List createNestedClassMethods( return nestedClassMethods; } - private static MethodDefinition createNestedClassInitDefaultsMethod( + private MethodDefinition createNestedClassInitDefaultsMethod( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. TypeNode builderType = typeStore.get(NESTED_BUILDER_CLASS_NAME); @@ -1254,7 +1450,9 @@ private static MethodDefinition createNestedClassInitDefaultsMethod( method, builderVarExpr, NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR, - NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); + NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR, + getTransportContext().operationResponseTransformerType(), + getTransportContext().operationMetadataTransformerType()))); bodyStatements.add(EMPTY_LINE_STATEMENT); } @@ -1524,7 +1722,22 @@ private static List createNestedClassConstructorMethods( return ctorMethods; } - private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) { + protected List createNestedClassCreateDefaultMethods(TypeStore typeStore) { + return Collections.singletonList( + createNestedClassCreateDefaultMethod( + typeStore, + "createDefault", + "defaultTransportChannelProvider", + null, + "defaultApiClientHeaderProviderBuilder")); + } + + protected MethodDefinition createNestedClassCreateDefaultMethod( + TypeStore typeStore, + String methodName, + String defaultTransportChannelProvider, + String defaultTransportChannelProviderBuilder, + String defaultApiClientHeaderProviderBuilder) { List bodyStatements = new ArrayList<>(); // Initialize the builder: Builder builder = new Builder((ClientContext) null); @@ -1549,15 +1762,32 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t bodyStatements.add(EMPTY_LINE_STATEMENT); List bodyExprs = new ArrayList<>(); - bodyExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(builderVarExpr) - .setMethodName("setTransportChannelProvider") - .setArguments( - MethodInvocationExpr.builder() - .setMethodName("defaultTransportChannelProvider") - .build()) - .build()); + + if (defaultTransportChannelProvider != null) { + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(builderVarExpr) + .setMethodName("setTransportChannelProvider") + .setArguments( + MethodInvocationExpr.builder() + .setMethodName(defaultTransportChannelProvider) + .build()) + .build()); + } else { + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(builderVarExpr) + .setMethodName("setTransportChannelProvider") + .setArguments( + MethodInvocationExpr.builder() + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName(defaultTransportChannelProviderBuilder) + .build()) + .setMethodName("build") + .build()) + .build()); + } bodyExprs.add( MethodInvocationExpr.builder() @@ -1581,7 +1811,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t MethodInvocationExpr.builder() .setExprReferenceExpr( MethodInvocationExpr.builder() - .setMethodName("defaultApiClientHeaderProviderBuilder") + .setMethodName(defaultApiClientHeaderProviderBuilder) .build()) .setMethodName("build") .build()) @@ -1594,6 +1824,21 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t .setArguments( MethodInvocationExpr.builder().setMethodName("getDefaultEndpoint").build()) .build()); + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(builderVarExpr) + .setMethodName("setMtlsEndpoint") + .setArguments( + MethodInvocationExpr.builder().setMethodName("getDefaultMtlsEndpoint").build()) + .build()); + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(builderVarExpr) + .setMethodName("setSwitchToMtlsEndpointAllowed") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) + .build()); bodyStatements.addAll( bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); bodyStatements.add(EMPTY_LINE_STATEMENT); @@ -1609,7 +1854,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t .setScope(ScopeNode.PRIVATE) .setIsStatic(true) .setReturnType(builderType) - .setName("createDefault") + .setName(methodName) .setBody(bodyStatements) .setReturnExpr(returnExpr) .build(); @@ -1650,7 +1895,6 @@ private static MethodDefinition createNestedClassApplyToAllUnaryMethodsMethod( .setReturnType(returnType) .setName(methodName) .setArguments(settingsUpdaterVarExpr.toBuilder().setIsDecl(true).build()) - .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) .setBody(Arrays.asList(ExprStatement.withExpr(superApplyExpr))) .setReturnExpr(returnExpr) .build(); @@ -1737,7 +1981,7 @@ private static MethodDefinition createNestedClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiCallContext.class, ApiClientHeaderProvider.class, @@ -1794,10 +2038,12 @@ private TypeStore createDynamicTypes(Service service, String pakkage) { pakkage, Arrays.asList( thisClassName, - getTransportContext().classNames().getTransportServiceStubClassName(service), ClassNames.getServiceStubSettingsClassName(service), ClassNames.getServiceStubClassName(service))); + typeStore.putAll( + pakkage, getTransportContext().classNames().getTransportServiceStubClassNames(service)); + // Nested builder class. typeStore.put(pakkage, NESTED_BUILDER_CLASS_NAME, true, thisClassName); @@ -1893,7 +2139,7 @@ private static TypeNode getCallSettingsType( TypeStore typeStore, boolean isBatchingSettings, final boolean isSettingsBuilder) { - Function typeMakerFn = + Function, TypeNode> typeMakerFn = clz -> TypeNode.withReference(ConcreteReference.withClazz(clz)); // Default: No streaming. TypeNode callSettingsType = diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java new file mode 100644 index 0000000000..7137f4f1fb --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java @@ -0,0 +1,1001 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.common; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.RequestParamsExtractor; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ClassDefinition; +import com.google.api.generator.engine.ast.CommentStatement; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EmptyLineStatement; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.JavaDocComment; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.ReferenceConstructorExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.ThisObjectValue; +import com.google.api.generator.engine.ast.ThrowExpr; +import com.google.api.generator.engine.ast.TryCatchStatement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.composer.utils.PackageChecker; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicClass.Kind; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.longrunning.Operation; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.Generated; + +public abstract class AbstractTransportServiceStubClassComposer implements ClassComposer { + private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); + + private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; + private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; + private static final String PAGED_CALLABLE_CLASS_MEMBER_PATTERN = "%sPagedCallable"; + + private static final String BACKGROUND_RESOURCES_MEMBER_NAME = "backgroundResources"; + private static final String CALLABLE_NAME = "Callable"; + private static final String CALLABLE_FACTORY_MEMBER_NAME = "callableFactory"; + private static final String CALLABLE_CLASS_MEMBER_PATTERN = "%sCallable"; + private static final String OPERATION_CALLABLE_CLASS_MEMBER_PATTERN = "%sOperationCallable"; + private static final String OPERATION_CALLABLE_NAME = "OperationCallable"; + // private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub"; + private static final String PAGED_CALLABLE_NAME = "PagedCallable"; + + protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + + private final TransportContext transportContext; + + protected AbstractTransportServiceStubClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } + + public TransportContext getTransportContext() { + return transportContext; + } + + private static TypeStore createStaticTypes() { + List> concreteClazzes = + Arrays.asList( + BackgroundResource.class, + BackgroundResourceAggregation.class, + BetaApi.class, + BidiStreamingCallable.class, + ClientContext.class, + ClientStreamingCallable.class, + Generated.class, + ImmutableMap.class, + InterruptedException.class, + IOException.class, + Operation.class, + OperationCallable.class, + RequestParamsExtractor.class, + ServerStreamingCallable.class, + TimeUnit.class, + UnaryCallable.class); + return new TypeStore(concreteClazzes); + } + + @Override + public GapicClass generate(GapicContext context, Service service) { + String pakkage = service.pakkage() + ".stub"; + TypeStore typeStore = createDynamicTypes(service, pakkage); + String className = getTransportContext().classNames().getTransportServiceStubClassName(service); + GapicClass.Kind kind = Kind.STUB; + + Map protoMethodNameToDescriptorVarExprs = + createProtoMethodNameToDescriptorClassMembers( + service, getTransportContext().methodDescriptorClass()); + + Map callableClassMemberVarExprs = + createCallableClassMembers(service, typeStore); + + Map classMemberVarExprs = new LinkedHashMap<>(); + classMemberVarExprs.put( + BACKGROUND_RESOURCES_MEMBER_NAME, + VariableExpr.withVariable( + Variable.builder() + .setName(BACKGROUND_RESOURCES_MEMBER_NAME) + .setType(FIXED_TYPESTORE.get("BackgroundResource")) + .build())); + if (generateOperationsStubLogic(service)) { + // Transport-specific service stub may have only one element of the following, thus get(0). + classMemberVarExprs.put( + getTransportContext().transportOperationsStubNames().get(0), + VariableExpr.withVariable( + Variable.builder() + .setName(getTransportContext().transportOperationsStubNames().get(0)) + .setType(getTransportContext().transportOperationsStubTypes().get(0)) + .build())); + } + classMemberVarExprs.put( + CALLABLE_FACTORY_MEMBER_NAME, + VariableExpr.withVariable( + Variable.builder() + .setName(CALLABLE_FACTORY_MEMBER_NAME) + .setType(getTransportContext().stubCallableFactoryType()) + .build())); + + List classStatements = + createClassStatements( + service, + protoMethodNameToDescriptorVarExprs, + callableClassMemberVarExprs, + classMemberVarExprs); + + StubCommentComposer commentComposer = + new StubCommentComposer(getTransportContext().transportName()); + + ClassDefinition classDef = + ClassDefinition.builder() + .setPackageString(pakkage) + .setHeaderCommentStatements( + commentComposer.createTransportServiceStubClassHeaderComments( + service.name(), service.isDeprecated())) + .setAnnotations(createClassAnnotations(service)) + .setScope(ScopeNode.PUBLIC) + .setName(className) + .setExtendsType(typeStore.get(ClassNames.getServiceStubClassName(service))) + .setStatements(classStatements) + .setMethods( + createClassMethods( + service, + typeStore, + classMemberVarExprs, + callableClassMemberVarExprs, + protoMethodNameToDescriptorVarExprs)) + .build(); + return GapicClass.create(kind, classDef); + } + + protected abstract Statement createMethodDescriptorVariableDecl( + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr); + + protected boolean generateOperationsStubLogic(Service service) { + return true; + } + + protected List createOperationsStubGetterMethod( + Service service, VariableExpr operationsStubVarExpr) { + if (!generateOperationsStubLogic(service)) { + return Collections.emptyList(); + } + + String methodName = + String.format( + "get%s", + JavaStyle.toUpperCamelCase( + getTransportContext().transportOperationsStubNames().get(0))); + + return Arrays.asList( + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setReturnType(operationsStubVarExpr.type()) + .setName(methodName) + .setReturnExpr(operationsStubVarExpr) + .build()); + } + + protected abstract Expr createTransportSettingsInitExpr( + Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr); + + protected List createGetMethodDescriptorsMethod( + Service service, + TypeStore typeStore, + Map protoMethodNameToDescriptorVarExprs) { + return Arrays.asList(); + } + + protected List createClassStatements( + Service service, + Map protoMethodNameToDescriptorVarExprs, + Map callableClassMemberVarExprs, + Map classMemberVarExprs) { + List classStatements = new ArrayList<>(); + for (Statement statement : + createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs)) { + classStatements.add(statement); + classStatements.add(EMPTY_LINE_STATEMENT); + } + + classStatements.addAll(createClassMemberFieldDeclarations(callableClassMemberVarExprs)); + classStatements.add(EMPTY_LINE_STATEMENT); + + classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs)); + return classStatements; + } + + protected List createMethodDescriptorVariableDecls( + Service service, Map protoMethodNameToDescriptorVarExprs) { + return service.methods().stream() + .map( + m -> + createMethodDescriptorVariableDecl( + service, m, protoMethodNameToDescriptorVarExprs.get(m.name()))) + .collect(Collectors.toList()); + } + + private static List createClassMemberFieldDeclarations( + Map fieldNameToVarExprs) { + return fieldNameToVarExprs.values().stream() + .map( + v -> + ExprStatement.withExpr( + v.toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsFinal(true) + .build())) + .collect(Collectors.toList()); + } + + protected Map createProtoMethodNameToDescriptorClassMembers( + Service service, Class descriptorClass) { + return service.methods().stream() + .collect( + Collectors.toMap( + Method::name, + m -> + VariableExpr.withVariable( + Variable.builder() + .setName( + String.format( + METHOD_DESCRIPTOR_NAME_PATTERN, + JavaStyle.toLowerCamelCase(m.name()))) + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(descriptorClass) + .setGenerics( + Arrays.asList( + m.inputType().reference(), + m.outputType().reference())) + .build())) + .build()), + (u, v) -> { + throw new IllegalStateException(); + }, + LinkedHashMap::new)); + } + + private Map createCallableClassMembers( + Service service, TypeStore typeStore) { + Map callableClassMembers = new LinkedHashMap<>(); + // Using a for-loop because the output cardinality is not a 1:1 mapping to the input set. + for (Method protoMethod : service.methods()) { + String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name()); + String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); + callableClassMembers.put( + callableName, + VariableExpr.withVariable( + Variable.builder() + .setName(callableName) + .setType(getCallableType(protoMethod)) + .build())); + if (protoMethod.hasLro()) { + callableName = + String.format(OPERATION_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); + callableClassMembers.put( + callableName, + VariableExpr.withVariable( + Variable.builder() + .setName(callableName) + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(OperationCallable.class) + .setGenerics( + Arrays.asList( + protoMethod.inputType().reference(), + protoMethod.lro().responseType().reference(), + protoMethod.lro().metadataType().reference())) + .build())) + .build())); + } + if (protoMethod.isPaged()) { + callableName = String.format(PAGED_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName); + callableClassMembers.put( + callableName, + VariableExpr.withVariable( + Variable.builder() + .setName(callableName) + .setType( + TypeNode.withReference( + getCallableType(protoMethod) + .reference() + .copyAndSetGenerics( + Arrays.asList( + protoMethod.inputType().reference(), + typeStore + .get( + String.format( + PAGED_RESPONSE_TYPE_NAME_PATTERN, + protoMethod.name())) + .reference())))) + .build())); + } + } + return callableClassMembers; + } + + protected List createClassAnnotations(Service service) { + List annotations = new ArrayList<>(); + if (!PackageChecker.isGaApi(service.pakkage())) { + annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); + } + + if (service.isDeprecated()) { + annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED)); + } + + annotations.add( + AnnotationNode.builder() + .setType(FIXED_TYPESTORE.get("Generated")) + .setDescription("by gapic-generator-java") + .build()); + return annotations; + } + + protected List createClassMethods( + Service service, + TypeStore typeStore, + Map classMemberVarExprs, + Map callableClassMemberVarExprs, + Map protoMethodNameToDescriptorVarExprs) { + List javaMethods = new ArrayList<>(); + javaMethods.addAll(createStaticCreatorMethods(service, typeStore, "newBuilder")); + javaMethods.addAll( + createConstructorMethods( + service, + typeStore, + classMemberVarExprs, + callableClassMemberVarExprs, + protoMethodNameToDescriptorVarExprs)); + javaMethods.addAll( + createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs)); + javaMethods.addAll( + createOperationsStubGetterMethod( + service, + classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)))); + javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs)); + javaMethods.addAll( + createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME))); + return javaMethods; + } + + protected List createStaticCreatorMethods( + Service service, TypeStore typeStore, String newBuilderMethod) { + TypeNode creatorMethodReturnType = + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); + Function, MethodDefinition.Builder> creatorMethodStarterFn = + argList -> + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setIsFinal(true) + .setReturnType(creatorMethodReturnType) + .setName("create") + .setArguments( + argList.stream() + .map(v -> v.toBuilder().setIsDecl(true).build()) + .collect(Collectors.toList())) + .setThrowsExceptions( + Arrays.asList( + TypeNode.withReference(ConcreteReference.withClazz(IOException.class)))); + + Function, Expr> instantiatorExprFn = + argList -> + NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build(); + + TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); + VariableExpr settingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("settings").setType(stubSettingsType).build()); + + TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); + VariableExpr clientContextVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("clientContext").setType(clientContextType).build()); + + VariableExpr callableFactoryVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName("callableFactory") + .setType(getTransportContext().stubCallableFactoryType()) + .build()); + + MethodInvocationExpr clientContextCreateMethodExpr = + MethodInvocationExpr.builder() + .setMethodName("create") + .setStaticReferenceType(clientContextType) + .setArguments(Arrays.asList(settingsVarExpr)) + .build(); + MethodInvocationExpr settingsBuilderMethodExpr = + MethodInvocationExpr.builder() + .setMethodName(newBuilderMethod) + .setStaticReferenceType(stubSettingsType) + .build(); + settingsBuilderMethodExpr = + MethodInvocationExpr.builder() + .setMethodName("build") + .setExprReferenceExpr(settingsBuilderMethodExpr) + .build(); + + return Arrays.asList( + creatorMethodStarterFn + .apply(Arrays.asList(settingsVarExpr)) + .setReturnExpr( + instantiatorExprFn.apply( + Arrays.asList(settingsVarExpr, clientContextCreateMethodExpr))) + .build(), + creatorMethodStarterFn + .apply(Arrays.asList(clientContextVarExpr)) + .setReturnExpr( + instantiatorExprFn.apply( + Arrays.asList(settingsBuilderMethodExpr, clientContextVarExpr))) + .build(), + creatorMethodStarterFn + .apply(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) + .setReturnExpr( + instantiatorExprFn.apply( + Arrays.asList( + settingsBuilderMethodExpr, clientContextVarExpr, callableFactoryVarExpr))) + .build()); + } + + protected List createConstructorMethods( + Service service, + TypeStore typeStore, + Map classMemberVarExprs, + Map callableClassMemberVarExprs, + Map protoMethodNameToDescriptorVarExprs) { + TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); + VariableExpr settingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("settings").setType(stubSettingsType).build()); + + TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); + VariableExpr clientContextVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("clientContext").setType(clientContextType).build()); + + VariableExpr callableFactoryVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName("callableFactory") + .setType(getTransportContext().stubCallableFactoryType()) + .build()); + + TypeNode thisClassType = + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); + TypeNode ioExceptionType = + TypeNode.withReference(ConcreteReference.withClazz(IOException.class)); + + BiFunction, List, MethodDefinition> ctorMakerFn = + (args, body) -> + MethodDefinition.constructorBuilder() + .setScope(ScopeNode.PROTECTED) + .setReturnType(thisClassType) + .setHeaderCommentStatements(Arrays.asList(createProtectedCtorComment(service))) + .setArguments( + args.stream() + .map(v -> v.toBuilder().setIsDecl(true).build()) + .collect(Collectors.toList())) + .setThrowsExceptions(Arrays.asList(ioExceptionType)) + .setBody(body) + .build(); + + // First constructor method. + MethodDefinition firstCtor = + ctorMakerFn.apply( + Arrays.asList(settingsVarExpr, clientContextVarExpr), + Arrays.asList( + ExprStatement.withExpr( + ReferenceConstructorExpr.thisBuilder() + .setType(thisClassType) + .setArguments( + settingsVarExpr, + clientContextVarExpr, + NewObjectExpr.builder() + .setType( + typeStore.get( + getTransportContext() + .classNames() + .getTransportServiceCallableFactoryClassName(service))) + .build()) + .build()))); + + Expr thisExpr = + ValueExpr.withValue( + ThisObjectValue.withType( + typeStore.get( + getTransportContext().classNames().getTransportServiceStubClassName(service)))); + // Body of the second constructor method. + List secondCtorStatements = new ArrayList<>(); + List secondCtorExprs = new ArrayList<>(); + secondCtorExprs.add( + AssignmentExpr.builder() + .setVariableExpr( + classMemberVarExprs.get("callableFactory").toBuilder() + .setExprReferenceExpr(thisExpr) + .build()) + .setValueExpr(callableFactoryVarExpr) + .build()); + VariableExpr operationsStubClassVarExpr = + classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)); + if (generateOperationsStubLogic(service)) { + secondCtorExprs.add( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + getTransportContext().transportOperationsStubTypes().get(0)) + .setMethodName("create") + .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } + secondCtorStatements.addAll( + secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + secondCtorExprs.clear(); + secondCtorStatements.add(EMPTY_LINE_STATEMENT); + + // Transport settings local variables. + Map javaStyleMethodNameToTransportSettingsVarExprs = + service.methods().stream() + .collect( + Collectors.toMap( + m -> JavaStyle.toLowerCamelCase(m.name()), + m -> + VariableExpr.withVariable( + Variable.builder() + .setName( + String.format( + "%sTransportSettings", + JavaStyle.toLowerCamelCase(m.name()))) + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(getTransportContext().callSettingsClass()) + .setGenerics( + Arrays.asList( + m.inputType().reference(), + m.outputType().reference())) + .build())) + .build()))); + + secondCtorExprs.addAll( + service.methods().stream() + .map( + m -> + createTransportSettingsInitExpr( + m, + javaStyleMethodNameToTransportSettingsVarExprs.get( + JavaStyle.toLowerCamelCase(m.name())), + protoMethodNameToDescriptorVarExprs.get(m.name()))) + .collect(Collectors.toList())); + secondCtorStatements.addAll( + secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + secondCtorExprs.clear(); + secondCtorStatements.add(EMPTY_LINE_STATEMENT); + + // Initialize Callable variables. + secondCtorExprs.addAll( + callableClassMemberVarExprs.entrySet().stream() + .map( + e -> + createCallableInitExpr( + e.getKey(), + e.getValue(), + callableFactoryVarExpr, + settingsVarExpr, + clientContextVarExpr, + operationsStubClassVarExpr, + thisExpr, + javaStyleMethodNameToTransportSettingsVarExprs)) + .collect(Collectors.toList())); + secondCtorStatements.addAll( + secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + secondCtorExprs.clear(); + secondCtorStatements.add(EMPTY_LINE_STATEMENT); + + // Instantiate backgroundResources. + MethodInvocationExpr getBackgroundResourcesMethodExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(clientContextVarExpr) + .setMethodName("getBackgroundResources") + .build(); + VariableExpr backgroundResourcesVarExpr = classMemberVarExprs.get("backgroundResources"); + secondCtorExprs.add( + AssignmentExpr.builder() + .setVariableExpr( + backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation")) + .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr)) + .build()) + .build()); + secondCtorStatements.addAll( + secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + secondCtorExprs.clear(); + + // Second constructor method. + MethodDefinition secondCtor = + ctorMakerFn.apply( + Arrays.asList(settingsVarExpr, clientContextVarExpr, callableFactoryVarExpr), + secondCtorStatements); + + return Arrays.asList(firstCtor, secondCtor); + } + + private Expr createCallableInitExpr( + String callableVarName, + VariableExpr callableVarExpr, + VariableExpr callableFactoryVarExpr, + VariableExpr settingsVarExpr, + VariableExpr clientContextVarExpr, + VariableExpr operationsStubClassVarExpr, + Expr thisExpr, + Map javaStyleMethodNameToTransportSettingsVarExprs) { + boolean isOperation = callableVarName.endsWith(OPERATION_CALLABLE_NAME); + boolean isPaged = callableVarName.endsWith(PAGED_CALLABLE_NAME); + int sublength = 0; + if (isOperation) { + sublength = OPERATION_CALLABLE_NAME.length(); + } else if (isPaged) { + sublength = PAGED_CALLABLE_NAME.length(); + } else { + sublength = CALLABLE_NAME.length(); + } + String javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength); + List creatorMethodArgVarExprs = null; + Expr transportSettingsVarExpr = + javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName); + if (transportSettingsVarExpr == null && isOperation) { + // Try again, in case the name dtection above was inaccurate. + isOperation = false; + sublength = CALLABLE_NAME.length(); + javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength); + transportSettingsVarExpr = + javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName); + } + Preconditions.checkNotNull( + transportSettingsVarExpr, + String.format( + "No transport settings variable found for method name %s", javaStyleMethodName)); + if (isOperation) { + creatorMethodArgVarExprs = + Arrays.asList( + transportSettingsVarExpr, + MethodInvocationExpr.builder() + .setExprReferenceExpr(settingsVarExpr) + .setMethodName(String.format("%sOperationSettings", javaStyleMethodName)) + .build(), + clientContextVarExpr, + operationsStubClassVarExpr); + } else { + creatorMethodArgVarExprs = + Arrays.asList( + transportSettingsVarExpr, + MethodInvocationExpr.builder() + .setExprReferenceExpr(settingsVarExpr) + .setMethodName(String.format("%sSettings", javaStyleMethodName)) + .build(), + clientContextVarExpr); + } + + Optional callableCreatorMethodName = + getCallableCreatorMethodName(callableVarExpr.type()); + + Expr initExpr; + if (callableCreatorMethodName.isPresent()) { + initExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callableFactoryVarExpr) + .setMethodName(callableCreatorMethodName.get()) + .setArguments(creatorMethodArgVarExprs) + .setReturnType(callableVarExpr.type()) + .build(); + } else { + initExpr = ValueExpr.createNullExpr(); + } + + return AssignmentExpr.builder() + .setVariableExpr(callableVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr(initExpr) + .build(); + } + + protected Optional getCallableCreatorMethodName(TypeNode callableVarExprType) { + final String typeName = callableVarExprType.reference().name(); + String streamName = "Unary"; + + // Special handling for pagination methods. + if (callableVarExprType.reference().generics().size() == 2 + && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) { + streamName = "Paged"; + } else { + if (typeName.startsWith("Client")) { + streamName = "ClientStreaming"; + } else if (typeName.startsWith("Server")) { + streamName = "ServerStreaming"; + } else if (typeName.startsWith("Bidi")) { + streamName = "BidiStreaming"; + } else if (typeName.startsWith("Operation")) { + streamName = "Operation"; + } + } + return Optional.of(String.format("create%sCallable", streamName)); + } + + private static List createCallableGetterMethods( + Map callableClassMemberVarExprs) { + return callableClassMemberVarExprs.entrySet().stream() + .map( + e -> + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setReturnType(e.getValue().type()) + .setName(e.getKey()) + .setReturnExpr(e.getValue()) + .build()) + .collect(Collectors.toList()); + } + + private List createStubOverrideMethods( + VariableExpr backgroundResourcesVarExpr) { + Function methodMakerStarterFn = + methodName -> + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setName(methodName); + + Function voidMethodMakerFn = + methodName -> + methodMakerStarterFn + .apply(methodName) + .setReturnType(TypeNode.VOID) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(backgroundResourcesVarExpr) + .setMethodName(methodName) + .build()))) + .build(); + + Function booleanMethodMakerFn = + methodName -> + methodMakerStarterFn + .apply(methodName) + .setReturnType(TypeNode.BOOLEAN) + .setReturnExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(backgroundResourcesVarExpr) + .setMethodName(methodName) + .setReturnType(TypeNode.BOOLEAN) + .build()) + .build(); + + // Generate the close() method: + // @Override + // public final void close() { + // try { + // backgroundResources.close(); + // } catch (RuntimeException e) { + // throw e; + // } catch (Exception e) { + // throw new IllegalStateException("Failed to close resource", e); + // } + // } + + VariableExpr catchRuntimeExceptionVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setType(TypeNode.withExceptionClazz(RuntimeException.class)) + .setName("e") + .build()) + .build(); + VariableExpr catchExceptionVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setType(TypeNode.withExceptionClazz(Exception.class)) + .setName("e") + .build()) + .build(); + List javaMethods = new ArrayList<>(); + javaMethods.add( + methodMakerStarterFn + .apply("close") + .setIsFinal(true) + .setReturnType(TypeNode.VOID) + .setBody( + Arrays.asList( + TryCatchStatement.builder() + .setTryBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(backgroundResourcesVarExpr) + .setMethodName("close") + .build()))) + .addCatch( + catchRuntimeExceptionVarExpr.toBuilder().setIsDecl(true).build(), + Arrays.asList( + ExprStatement.withExpr( + ThrowExpr.builder() + .setThrowExpr(catchRuntimeExceptionVarExpr) + .build()))) + .addCatch( + catchExceptionVarExpr.toBuilder().setIsDecl(true).build(), + Arrays.asList( + ExprStatement.withExpr( + ThrowExpr.builder() + .setType( + TypeNode.withExceptionClazz( + IllegalStateException.class)) + .setMessageExpr(String.format("Failed to close resource")) + .setCauseExpr(catchExceptionVarExpr) + .build()))) + .build())) + .build()); + javaMethods.add(voidMethodMakerFn.apply("shutdown")); + javaMethods.add(booleanMethodMakerFn.apply("isShutdown")); + javaMethods.add(booleanMethodMakerFn.apply("isTerminated")); + javaMethods.add(voidMethodMakerFn.apply("shutdownNow")); + + List awaitTerminationArgs = + Arrays.asList( + VariableExpr.withVariable( + Variable.builder().setName("duration").setType(TypeNode.LONG).build()), + VariableExpr.withVariable( + Variable.builder() + .setName("unit") + .setType(FIXED_TYPESTORE.get("TimeUnit")) + .build())); + javaMethods.add( + methodMakerStarterFn + .apply("awaitTermination") + .setReturnType(TypeNode.BOOLEAN) + .setArguments( + awaitTerminationArgs.stream() + .map(v -> v.toBuilder().setIsDecl(true).build()) + .collect(Collectors.toList())) + .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException"))) + .setReturnExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(backgroundResourcesVarExpr) + .setMethodName("awaitTermination") + .setArguments( + awaitTerminationArgs.stream() + .map(v -> (Expr) v) + .collect(Collectors.toList())) + .setReturnType(TypeNode.BOOLEAN) + .build()) + .build()); + return javaMethods; + } + + private TypeStore createDynamicTypes(Service service, String stubPakkage) { + TypeStore typeStore = new TypeStore(); + typeStore.putAll( + stubPakkage, + Arrays.asList( + getTransportContext().classNames().getTransportServiceStubClassName(service), + ClassNames.getServiceStubSettingsClassName(service), + ClassNames.getServiceStubClassName(service), + getTransportContext() + .classNames() + .getTransportServiceCallableFactoryClassName(service))); + // Pagination types. + typeStore.putAll( + service.pakkage(), + service.methods().stream() + .filter(m -> m.isPaged()) + .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) + .collect(Collectors.toList()), + true, + ClassNames.getServiceClientClassName(service)); + return typeStore; + } + + private static TypeNode getCallableType(Method protoMethod) { + TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable"); + switch (protoMethod.stream()) { + case CLIENT: + callableType = FIXED_TYPESTORE.get("ClientStreamingCallable"); + break; + case SERVER: + callableType = FIXED_TYPESTORE.get("ServerStreamingCallable"); + break; + case BIDI: + callableType = FIXED_TYPESTORE.get("BidiStreamingCallable"); + break; + case NONE: + // Fall through + default: + // Fall through + } + + return TypeNode.withReference( + callableType + .reference() + .copyAndSetGenerics( + Arrays.asList( + protoMethod.inputType().reference(), protoMethod.outputType().reference()))); + } + + private CommentStatement createProtectedCtorComment(Service service) { + return CommentStatement.withComment( + JavaDocComment.withComment( + String.format( + "Constructs an instance of %s, using the given settings. This is protected so that" + + " it is easy to make a subclass, but otherwise, the static factory methods" + + " should be preferred.", + getTransportContext().classNames().getTransportServiceStubClassName(service)))); + } + + protected String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { + if (protoMethod.isMixin()) { + return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name()); + } + + return String.format( + "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java index 8de7d4c9c2..dc96c7bc43 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java @@ -66,7 +66,6 @@ public class BatchingDescriptorComposer { private static final TypeNode PARTITION_KEY_TYPE = toType(PartitionKey.class); private static final String ADD_ALL_METHOD_PATTERN = "addAll%s"; - private static final String BATCH_FOO_INDEX_PATTERN = "batch%sIndex"; private static final String GET_LIST_METHOD_PATTERN = "get%sList"; private static final String GET_COUNT_METHOD_PATTERN = "get%sCount"; @@ -231,8 +230,7 @@ private static MethodDefinition createGetRequestBuilderMethod( .setStatements( Arrays.asList( ExprStatement.withExpr( - builderVarExpr - .toBuilder() + builderVarExpr.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .build()))) @@ -272,8 +270,6 @@ private static MethodDefinition createSplitResponseMethod( VariableExpr.withVariable( Variable.builder().setType(batchedRequestIssuerType).setName("responder").build()); - String upperCamelBatchedFieldName = - JavaStyle.toUpperCamelCase(batchingSettings.batchedFieldName()); VariableExpr batchMessageIndexVarExpr = VariableExpr.withVariable( Variable.builder().setType(TypeNode.INT).setName("batchMessageIndex").build()); @@ -541,7 +537,7 @@ private static MethodDefinition createCountByteSMethod(Method method) { .build(); } - private static TypeNode toType(Class clazz) { + private static TypeNode toType(Class clazz) { return TypeNode.withReference(ConcreteReference.withClazz(clazz)); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java index 4a20961399..e5e4ad4195 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java @@ -248,7 +248,9 @@ public static Expr createLroSettingsBuilderExpr( Method method, VariableExpr builderVarExpr, VariableExpr retryableCodeDefsVarExpr, - VariableExpr retryParamDefsVarExpr) { + VariableExpr retryParamDefsVarExpr, + TypeNode operationResponseTransformer, + TypeNode operationMetadataTransformer) { Preconditions.checkState( method.hasLro(), String.format( @@ -325,10 +327,7 @@ public static Expr createLroSettingsBuilderExpr( .setMethodName("setResponseTransformer") .setArguments( MethodInvocationExpr.builder() - .setStaticReferenceType( - TypeNode.withReference( - ConcreteReference.withClazz( - ProtoOperationTransformers.ResponseTransformer.class))) + .setStaticReferenceType(operationResponseTransformer) .setMethodName("create") .setArguments(classFieldRefFn.apply(method.lro().responseType())) .build()) @@ -339,10 +338,7 @@ public static Expr createLroSettingsBuilderExpr( .setMethodName("setMetadataTransformer") .setArguments( MethodInvocationExpr.builder() - .setStaticReferenceType( - TypeNode.withReference( - ConcreteReference.withClazz( - ProtoOperationTransformers.MetadataTransformer.class))) + .setStaticReferenceType(operationMetadataTransformer) .setMethodName("create") .setArguments(classFieldRefFn.apply(method.lro().metadataType())) .build()) @@ -715,7 +711,7 @@ private static MethodInvocationExpr createDurationOfMillisExpr(ValueExpr valExpr } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( BatchingSettings.class, org.threeten.bp.Duration.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java deleted file mode 100644 index 9d16f98f88..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2020 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. - -package com.google.api.generator.gapic.composer.common; - -import com.google.api.core.BetaApi; -import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.rpc.BidiStreamingCallable; -import com.google.api.gax.rpc.ClientStreamingCallable; -import com.google.api.gax.rpc.OperationCallable; -import com.google.api.gax.rpc.ServerStreamingCallable; -import com.google.api.gax.rpc.UnaryCallable; -import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.ClassDefinition; -import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.Reference; -import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.Statement; -import com.google.api.generator.engine.ast.ThrowExpr; -import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.gapic.composer.comment.StubCommentComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; -import com.google.api.generator.gapic.composer.utils.PackageChecker; -import com.google.api.generator.gapic.model.GapicClass; -import com.google.api.generator.gapic.model.GapicClass.Kind; -import com.google.api.generator.gapic.model.GapicContext; -import com.google.api.generator.gapic.model.Message; -import com.google.api.generator.gapic.model.Method; -import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.utils.JavaStyle; -import com.google.longrunning.Operation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.annotation.Generated; - -public class ServiceStubClassComposer implements ClassComposer { - private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer(); - private static final String DOT = "."; - private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; - - private ServiceStubClassComposer() {} - - public static ServiceStubClassComposer instance() { - return INSTANCE; - } - - @Override - public GapicClass generate(GapicContext context, Service service) { - Map messageTypes = context.messages(); - TypeStore typeStore = createTypes(service, messageTypes); - String className = ClassNames.getServiceStubClassName(service); - GapicClass.Kind kind = Kind.STUB; - String pakkage = String.format("%s.stub", service.pakkage()); - - ClassDefinition classDef = - ClassDefinition.builder() - .setPackageString(pakkage) - .setHeaderCommentStatements( - StubCommentComposer.createServiceStubClassHeaderComments( - service.name(), service.isDeprecated())) - .setAnnotations(createClassAnnotations(service, typeStore)) - .setIsAbstract(true) - .setImplementsTypes(createClassImplements(typeStore)) - .setName(className) - .setMethods(createClassMethods(service, messageTypes, typeStore)) - .setScope(ScopeNode.PUBLIC) - .build(); - return GapicClass.create(kind, classDef); - } - - private static List createClassAnnotations(Service service, TypeStore typeStore) { - List annotations = new ArrayList<>(); - if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(typeStore.get("BetaApi"))); - } - - if (service.isDeprecated()) { - annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED)); - } - - annotations.add( - AnnotationNode.builder() - .setType(typeStore.get("Generated")) - .setDescription("by gapic-generator-java") - .build()); - return annotations; - } - - private static List createClassImplements(TypeStore typeStore) { - return Arrays.asList(typeStore.get("BackgroundResource")); - } - - private static List createClassMethods( - Service service, Map messageTypes, TypeStore typeStore) { - boolean hasLroClient = hasLroMethods(service); - List methods = new ArrayList<>(); - if (hasLroClient) { - methods.add(createOperationsStubGetter(typeStore)); - } - methods.addAll(createCallableGetters(service, messageTypes, typeStore)); - methods.addAll(createBackgroundResourceMethodOverrides()); - return methods; - } - - private static List createCallableGetters( - Service service, Map messageTypes, TypeStore typeStore) { - // Use a traditional for-loop since the output cardinality is not necessarily 1:1 with that of - // service.methods(). - List javaMethods = new ArrayList<>(); - for (Method method : service.methods()) { - if (method.hasLro()) { - javaMethods.add(createOperationCallableGetter(method, typeStore)); - } - if (method.isPaged()) { - javaMethods.add(createPagedCallableGetter(method, typeStore)); - } - javaMethods.add(createCallableGetter(method, typeStore)); - } - return javaMethods; - } - - private static MethodDefinition createOperationCallableGetter( - Method method, TypeStore typeStore) { - return createCallableGetterHelper(method, typeStore, true, false); - } - - private static MethodDefinition createPagedCallableGetter(Method method, TypeStore typeStore) { - return createCallableGetterHelper(method, typeStore, false, true); - } - - private static MethodDefinition createCallableGetter(Method method, TypeStore typeStore) { - return createCallableGetterHelper(method, typeStore, false, false); - } - - private static MethodDefinition createCallableGetterHelper( - Method method, TypeStore typeStore, boolean isLroCallable, boolean isPaged) { - TypeNode returnType; - switch (method.stream()) { - case CLIENT: - returnType = typeStore.get("ClientStreamingCallable"); - break; - case SERVER: - returnType = typeStore.get("ServerStreamingCallable"); - break; - case BIDI: - returnType = typeStore.get("BidiStreamingCallable"); - break; - case NONE: - // Fall through. - default: - returnType = typeStore.get(isLroCallable ? "OperationCallable" : "UnaryCallable"); - } - - String methodName = - String.format( - "%s%sCallable", - JavaStyle.toLowerCamelCase(method.name()), - (isLroCallable ? "Operation" : isPaged ? "Paged" : "")); - List genericRefs = new ArrayList<>(); - genericRefs.add(method.inputType().reference()); - if (method.hasLro() && isLroCallable) { - genericRefs.add(method.lro().responseType().reference()); - genericRefs.add(method.lro().metadataType().reference()); - } else if (isPaged) { - genericRefs.add( - typeStore - .get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name())) - .reference()); - } else { - genericRefs.add(method.outputType().reference()); - } - - List annotations = - method.isDeprecated() - ? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED)) - : Collections.emptyList(); - - returnType = TypeNode.withReference(returnType.reference().copyAndSetGenerics(genericRefs)); - - return MethodDefinition.builder() - .setAnnotations(annotations) - .setScope(ScopeNode.PUBLIC) - .setReturnType(returnType) - .setName(methodName) - .setBody(createThrowUOEBody(methodName, typeStore)) - .build(); - } - - private static MethodDefinition createOperationsStubGetter(TypeStore typeStore) { - String methodName = "getOperationsStub"; - return MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setReturnType(typeStore.get("OperationsStub")) - .setName(methodName) - .setBody(createThrowUOEBody(methodName, typeStore)) - .build(); - } - - private static List createBackgroundResourceMethodOverrides() { - MethodDefinition closeMethod = - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setIsAbstract(true) - .setReturnType(TypeNode.VOID) - .setName("close") - .build(); - return Arrays.asList(closeMethod); - } - - private static boolean hasLroMethods(Service service) { - for (Method method : service.methods()) { - if (method.hasLro()) { - return true; - } - } - return false; - } - - private static TypeStore createTypes(Service service, Map messageTypes) { - List concreteClazzes = - Arrays.asList( - BackgroundResource.class, - BetaApi.class, - BidiStreamingCallable.class, - ClientStreamingCallable.class, - Generated.class, - Operation.class, - OperationCallable.class, - ServerStreamingCallable.class, - UnaryCallable.class, - UnsupportedOperationException.class); - TypeStore typeStore = new TypeStore(concreteClazzes); - - typeStore.put("com.google.longrunning.stub", "OperationsStub"); - - // Pagination types. - typeStore.putAll( - service.pakkage(), - service.methods().stream() - .filter(m -> m.isPaged()) - .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) - .collect(Collectors.toList()), - true, - ClassNames.getServiceClientClassName(service)); - - return typeStore; - } - - private static List createThrowUOEBody(String methodName, TypeStore typeStore) { - return Arrays.asList( - ExprStatement.withExpr( - ThrowExpr.builder() - .setType(typeStore.get("UnsupportedOperationException")) - .setMessageExpr(String.format("Not implemented: %s()", methodName)) - .build())); - } - - private static String getClientClassName(Service service) { - return String.format("%sClient", service.overriddenName()); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java index 4058fbafbf..507ff662ca 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java @@ -19,6 +19,7 @@ import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Transport; import com.google.auto.value.AutoValue; +import java.util.List; import javax.annotation.Nullable; @AutoValue @@ -29,36 +30,57 @@ public abstract class TransportContext { // For AbstractServiceStubClassComposer public abstract Transport transport(); + @Nullable public abstract String transportName(); + @Nullable public abstract Class callSettingsClass(); + @Nullable public abstract TypeNode stubCallableFactoryType(); + @Nullable public abstract Class methodDescriptorClass(); - @Nullable - public abstract TypeNode transportOperationsStubType(); + public abstract List transportOperationsStubTypes(); + + public abstract List transportOperationsStubNames(); // For AbstractServiceSettingsClassComposer - public abstract Class instantiatingChannelProviderClass(); + public abstract List> instantiatingChannelProviderClasses(); - public abstract String defaultTransportProviderBuilderName(); + public abstract List> instantiatingChannelProviderBuilderClasses(); + + public abstract List defaultTransportProviderBuilderNames(); + + public abstract List transportApiClientHeaderProviderBuilderNames(); // For AbstractServiceStubSettingsClassComposer - public abstract TypeNode transportChannelType(); + public abstract List transportChannelTypes(); - public abstract String transportGetterName(); + public abstract List transportGetterNames(); // For AbstractServiceCallableFactoryClassComposer + @Nullable public abstract TypeNode transportCallSettingsType(); + @Nullable public abstract TypeNode transportCallableFactoryType(); - public abstract TypeNode operationsStubType(); + public abstract List operationsStubTypes(); + @Nullable public abstract String transportCallSettingsName(); + // For RetrySettingsComposer + public abstract TypeNode operationResponseTransformerType(); + + public abstract TypeNode operationMetadataTransformerType(); + + public abstract List operationsClientTypes(); + + public abstract List operationsClientNames(); + protected static TypeNode classToType(Class clazz) { return TypeNode.withReference(ConcreteReference.withClazz(clazz)); } @@ -82,15 +104,21 @@ public abstract static class Builder { public abstract Builder setMethodDescriptorClass(Class methodDescriptorClass); - public abstract Builder setInstantiatingChannelProviderClass( - Class instantiatingChannelProviderClass); + public abstract Builder setInstantiatingChannelProviderClasses( + List> instantiatingChannelProviderClasses); + + public abstract Builder setInstantiatingChannelProviderBuilderClasses( + List> instantiatingChannelProviderBuilderClasses); + + public abstract Builder setDefaultTransportProviderBuilderNames( + List defaultTransportProviderBuilderNames); - public abstract Builder setDefaultTransportProviderBuilderName( - String defaultTransportProviderBuilderName); + public abstract Builder setTransportApiClientHeaderProviderBuilderNames( + List transportApiClientHeaderProviderBuilderNames); - public abstract Builder setTransportChannelType(TypeNode transportChannelType); + public abstract Builder setTransportChannelTypes(List transportChannelTypes); - public abstract Builder setTransportGetterName(String transportGetterName); + public abstract Builder setTransportGetterNames(List transportGetterNames); public abstract Builder setTransportCallSettingsType(TypeNode transportCallSettingsType); @@ -98,9 +126,19 @@ public abstract Builder setDefaultTransportProviderBuilderName( public abstract Builder setTransportCallSettingsName(String transportCallSettingsName); - public abstract Builder setTransportOperationsStubType(TypeNode transportOperationsStubType); + public abstract Builder setTransportOperationsStubTypes(List transportOperationsStubTypes); + + public abstract Builder setTransportOperationsStubNames(List transportOperationsStubNames); + + public abstract Builder setOperationsStubTypes(List operationsStubType); + + public abstract Builder setOperationResponseTransformerType(TypeNode operationResponseTransformerType); + + public abstract Builder setOperationMetadataTransformerType(TypeNode operationMetadataTransformerType); + + public abstract Builder setOperationsClientTypes(List operationsClientTypes); - public abstract Builder setOperationsStubType(TypeNode operationsStubType); + public abstract Builder setOperationsClientNames(List operationsClientNames); public abstract TransportContext build(); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/BUILD.bazel index 178459f813..48171ec5d3 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/BUILD.bazel @@ -17,6 +17,7 @@ java_library( "//src/main/java/com/google/api/generator/gapic/composer/resourcename", "//src/main/java/com/google/api/generator/gapic/model", "//src/main/java/com/google/api/generator/gapic/utils", + "@com_google_api_api_common", "@com_google_googleapis//google/longrunning:longrunning_java_proto", "@com_google_guava_guava//jar", "@com_google_protobuf//java/core", diff --git a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java index fec4d3050f..f697c1b4a2 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java @@ -14,11 +14,16 @@ package com.google.api.generator.gapic.composer.defaultvalue; +import com.google.api.generator.engine.ast.AnonymousClassExpr; +import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.PrimitiveValue; +import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.StringObjectValue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; @@ -31,12 +36,13 @@ import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.api.generator.gapic.utils.ResourceNameConstants; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.longrunning.Operation; import com.google.protobuf.Any; -import com.google.protobuf.ByteString; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -47,12 +53,13 @@ public class DefaultValueComposer { private static TypeNode OPERATION_TYPE = TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); private static TypeNode ANY_TYPE = TypeNode.withReference(ConcreteReference.withClazz(Any.class)); - private static TypeNode BYTESTRING_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(ByteString.class)); public static Expr createDefaultValue( - MethodArgument methodArg, Map resourceNames) { - if (methodArg.isResourceNameHelper()) { + MethodArgument methodArg, + Map resourceNames, + boolean forceResourceNameInitializer) { + if (methodArg.isResourceNameHelper() + || (forceResourceNameInitializer && methodArg.field().hasResourceReference())) { Preconditions.checkState( methodArg.field().hasResourceReference(), String.format( @@ -65,10 +72,21 @@ public static Expr createDefaultValue( String.format( "No resource name found for reference %s", methodArg.field().resourceReference().resourceTypeString())); - return createDefaultValue( - resourceName, - resourceNames.values().stream().collect(Collectors.toList()), - methodArg.field().name()); + Expr defValue = + createDefaultValue( + resourceName, + resourceNames.values().stream().collect(Collectors.toList()), + methodArg.field().name()); + + if (!methodArg.isResourceNameHelper() && methodArg.field().hasResourceReference()) { + defValue = + MethodInvocationExpr.builder() + .setExprReferenceExpr(defValue) + .setMethodName("toString") + .setReturnType(TypeNode.STRING) + .build(); + } + return defValue; } if (methodArg.type().equals(methodArg.field().type())) { @@ -157,6 +175,16 @@ static Expr createDefaultValue(Field f, boolean useExplicitInitTypeInGenerics) { public static Expr createDefaultValue( ResourceName resourceName, List resnames, String fieldOrMessageName) { + return createDefaultValueResourceHelper(resourceName, resnames, fieldOrMessageName, true); + } + + @VisibleForTesting + static Expr createDefaultValueResourceHelper( + ResourceName resourceName, + List resnames, + String fieldOrMessageName, + boolean allowAnonResourceNameClass) { + boolean hasOnePattern = resourceName.patterns().size() == 1; if (resourceName.isOnlyWildcard()) { List unexaminedResnames = new ArrayList<>(resnames); @@ -170,9 +198,11 @@ public static Expr createDefaultValue( } if (unexaminedResnames.isEmpty()) { - return ValueExpr.withValue( - StringObjectValue.withValue( - String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode()))); + return allowAnonResourceNameClass + ? createAnonymousResourceNameClass(fieldOrMessageName) + : ValueExpr.withValue( + StringObjectValue.withValue( + String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode()))); } } @@ -247,10 +277,11 @@ public static Expr createSimpleMessageBuilderExpr( if (field.hasResourceReference() && resourceNames.get(field.resourceReference().resourceTypeString()) != null) { defaultExpr = - createDefaultValue( + createDefaultValueResourceHelper( resourceNames.get(field.resourceReference().resourceTypeString()), resourceNames.values().stream().collect(Collectors.toList()), - message.name()); + message.name(), + /* allowAnonResourceNameClass = */ false); defaultExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(defaultExpr) @@ -315,7 +346,19 @@ public static Expr createSimpleOperationBuilderExpr(String name, VariableExpr re } public static Expr createSimplePagedResponse( - TypeNode responseType, String repeatedFieldName, Expr responseElementVarExpr) { + TypeNode responseType, String repeatedFieldName, Expr responseElementVarExpr, boolean isMap) { + // Code for paginated maps: + // AggregatedMessageList.newBuilder() + // .setNextPageToken("") + // .putAllItems(Collections.singletonMap("items", responsesElement)) + // .build(); + // + // Code for paginated arrays: + // MessageList expectedResponse = + // AddressList.newBuilder() + // .setNextPageToken("") + // .addAllItems(Arrays.asList(responsesElement)) + // .build(); Expr pagedResponseExpr = MethodInvocationExpr.builder() .setStaticReferenceType(responseType) @@ -327,22 +370,131 @@ public static Expr createSimplePagedResponse( .setMethodName("setNextPageToken") .setArguments(ValueExpr.withValue(StringObjectValue.withValue(""))) .build(); - pagedResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(pagedResponseExpr) - .setMethodName(String.format("addAll%s", JavaStyle.toUpperCamelCase(repeatedFieldName))) - .setArguments( - MethodInvocationExpr.builder() - .setStaticReferenceType( - TypeNode.withReference(ConcreteReference.withClazz(Arrays.class))) - .setMethodName("asList") - .setArguments(responseElementVarExpr) - .build()) - .build(); + if (isMap) { + pagedResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(pagedResponseExpr) + .setMethodName( + String.format("putAll%s", JavaStyle.toUpperCamelCase(repeatedFieldName))) + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(Collections.class))) + .setMethodName("singletonMap") + .setArguments( + ValueExpr.withValue( + StringObjectValue.withValue( + JavaStyle.toLowerCamelCase(repeatedFieldName))), + responseElementVarExpr) + .build()) + .build(); + } else { + pagedResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(pagedResponseExpr) + .setMethodName( + String.format("addAll%s", JavaStyle.toUpperCamelCase(repeatedFieldName))) + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(Arrays.class))) + .setMethodName("asList") + .setArguments(responseElementVarExpr) + .build()) + .build(); + } return MethodInvocationExpr.builder() .setExprReferenceExpr(pagedResponseExpr) .setMethodName("build") .setReturnType(responseType) .build(); } + + @VisibleForTesting + static AnonymousClassExpr createAnonymousResourceNameClass(String fieldOrMessageName) { + TypeNode stringMapType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics( + Arrays.asList( + ConcreteReference.withClazz(String.class), + ConcreteReference.withClazz(String.class))) + .build()); + + // Method code: + // @Override + // public Map getFieldValuesMap() { + // Map fieldValuesMap = new HashMap<>(); + // fieldValuesMap.put("resource", "resource-12345"); + // return fieldValuesMap; + // } + VariableExpr fieldValuesMapVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(stringMapType).setName("fieldValuesMap").build()); + StringObjectValue fieldOrMessageStringValue = + StringObjectValue.withValue( + String.format("%s%s", fieldOrMessageName, fieldOrMessageName.hashCode())); + + List bodyExprs = + Arrays.asList( + AssignmentExpr.builder() + .setVariableExpr(fieldValuesMapVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(TypeNode.withReference(ConcreteReference.withClazz(HashMap.class))) + .setIsGeneric(true) + .build()) + .build(), + MethodInvocationExpr.builder() + .setExprReferenceExpr(fieldValuesMapVarExpr) + .setMethodName("put") + .setArguments( + ValueExpr.withValue(StringObjectValue.withValue(fieldOrMessageName)), + ValueExpr.withValue(fieldOrMessageStringValue)) + .build()); + + MethodDefinition getFieldValuesMapMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setReturnType(stringMapType) + .setName("getFieldValuesMap") + .setBody( + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) + .setReturnExpr(fieldValuesMapVarExpr) + .build(); + + // Method code: + // @Override + // public String getFieldValue(String fieldName) { + // return getFieldValuesMap().get(fieldName); + // } + VariableExpr fieldNameVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(TypeNode.STRING).setName("fieldName").build()); + MethodDefinition getFieldValueMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.STRING) + .setName("getFieldValue") + .setArguments(fieldNameVarExpr.toBuilder().setIsDecl(true).build()) + .setReturnExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr( + MethodInvocationExpr.builder().setMethodName("getFieldValuesMap").build()) + .setMethodName("get") + .setArguments(fieldNameVarExpr) + .setReturnType(TypeNode.STRING) + .build()) + .build(); + + return AnonymousClassExpr.builder() + .setType( + TypeNode.withReference( + ConcreteReference.withClazz(com.google.api.resourcenames.ResourceName.class))) + .setMethods(Arrays.asList(getFieldValuesMapMethod, getFieldValueMethod)) + .build(); + } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java index 13623cfb5b..5f9b27963e 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java @@ -19,9 +19,12 @@ import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.grpc.ProtoOperationTransformers; +import com.google.api.generator.gapic.composer.common.TransportContext; import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Transport; -import com.google.api.generator.gapic.composer.common.TransportContext; +import com.google.common.collect.ImmutableList; +import com.google.longrunning.OperationsClient; import com.google.longrunning.stub.GrpcOperationsStub; import com.google.longrunning.stub.OperationsStub; import io.grpc.MethodDescriptor; @@ -36,18 +39,33 @@ public abstract class GrpcContext extends TransportContext { .setCallSettingsClass(GrpcCallSettings.class) .setStubCallableFactoryType(classToType(GrpcStubCallableFactory.class)) .setMethodDescriptorClass(MethodDescriptor.class) - .setTransportOperationsStubType(classToType(GrpcOperationsStub.class)) + .setTransportOperationsStubTypes(ImmutableList.of(classToType(GrpcOperationsStub.class))) + .setTransportOperationsStubNames(ImmutableList.of("operationsStub")) // For grpc.ServiceSettingsClassComposer - .setInstantiatingChannelProviderClass(InstantiatingGrpcChannelProvider.Builder.class) - .setDefaultTransportProviderBuilderName("defaultGrpcTransportProviderBuilder") + .setInstantiatingChannelProviderClasses( + ImmutableList.of(InstantiatingGrpcChannelProvider.class)) + .setInstantiatingChannelProviderBuilderClasses( + ImmutableList.of(InstantiatingGrpcChannelProvider.Builder.class)) + .setDefaultTransportProviderBuilderNames( + ImmutableList.of("defaultGrpcTransportProviderBuilder")) + .setTransportApiClientHeaderProviderBuilderNames( + ImmutableList.of("defaultGrpcApiClientHeaderProviderBuilder")) // For grpc.ServiceStubSettingsClassComposer - .setTransportChannelType(classToType(GrpcTransportChannel.class)) - .setTransportGetterName("getGrpcTransportName") + .setTransportChannelTypes(ImmutableList.of(classToType(GrpcTransportChannel.class))) + .setTransportGetterNames(ImmutableList.of("getGrpcTransportName")) // For grpc.GrpcServiceCallableFactoryClassComposer .setTransportCallSettingsType(classToType(GrpcCallSettings.class)) .setTransportCallableFactoryType(classToType(GrpcCallableFactory.class)) - .setOperationsStubType(classToType(OperationsStub.class)) + .setOperationsStubTypes(ImmutableList.of(classToType(OperationsStub.class))) .setTransportCallSettingsName("grpcCallSettings") + // For RetrySettingsComposer + .setOperationResponseTransformerType( + classToType(ProtoOperationTransformers.ResponseTransformer.class)) + .setOperationMetadataTransformerType( + classToType(ProtoOperationTransformers.MetadataTransformer.class)) + // For ServiceClientClassComposer + .setOperationsClientTypes(ImmutableList.of(classToType(OperationsClient.class))) + .setOperationsClientNames(ImmutableList.of("operationsClient")) .build(); public static TransportContext instance() { diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java index 5698f5a443..e953c1410a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java @@ -45,6 +45,7 @@ protected List createClassImplements(TypeStore typeStore) { return Arrays.asList(getTransportContext().stubCallableFactoryType()); } + @Override protected List createClassMethods(TypeStore typeStore) { List classMethods = new ArrayList<>(super.createClassMethods(typeStore)); classMethods.addAll( @@ -55,6 +56,7 @@ protected List createClassMethods(TypeStore typeStore) { return classMethods; } + @Override protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; @@ -75,6 +77,7 @@ protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } + @Override protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java index e7b30ebcbe..578ce02005 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java @@ -16,14 +16,12 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; -import com.google.api.gax.rpc.RequestParamsExtractor; -import com.google.api.generator.engine.ast.AnonymousClassExpr; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.EnumRefExpr; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.LambdaExpr; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; @@ -32,10 +30,9 @@ import com.google.api.generator.engine.ast.ValueExpr; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; -import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.common.AbstractTransportServiceStubClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -54,7 +51,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -public class GrpcServiceStubClassComposer extends AbstractServiceStubClassComposer { +public class GrpcServiceStubClassComposer extends AbstractTransportServiceStubClassComposer { private static final GrpcServiceStubClassComposer INSTANCE = new GrpcServiceStubClassComposer(); // Legacy support for the original reroute_to_grpc_interface option in gapic.yaml. These two APIs @@ -75,7 +72,7 @@ public static GrpcServiceStubClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GrpcCallSettings.class, GrpcOperationsStub.class, @@ -155,7 +152,8 @@ protected Statement createMethodDescriptorVariableDecl( return ExprStatement.withExpr( AssignmentExpr.builder() .setVariableExpr( - methodDescriptorVarExpr.toBuilder() + methodDescriptorVarExpr + .toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -190,18 +188,6 @@ protected EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) { .build(); } - @Override - protected List createOperationsStubGetterMethod( - VariableExpr operationsStubVarExpr) { - return Arrays.asList( - MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setReturnType(operationsStubVarExpr.type()) - .setName("getOperationsStub") - .setReturnExpr(operationsStubVarExpr) - .build()); - } - @Override protected Expr createTransportSettingsInitExpr( Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { @@ -223,7 +209,7 @@ protected Expr createTransportSettingsInitExpr( MethodInvocationExpr.builder() .setExprReferenceExpr(callSettingsBuilderExpr) .setMethodName("setParamsExtractor") - .setArguments(createRequestParamsExtractorAnonClass(method)) + .setArguments(createRequestParamsExtractorClassInstance(method)) .build(); } @@ -255,7 +241,7 @@ protected String getProtoRpcFullMethodName(Service protoService, Method protoMet return String.format("google.iam.v1.IAMPolicy/%s", protoMethod.name()); } - private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) { + private LambdaExpr createRequestParamsExtractorClassInstance(Method method) { Preconditions.checkState( method.hasHttpBindings(), String.format("Method %s has no HTTP binding", method.name())); @@ -268,9 +254,6 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) VariableExpr paramsVarExpr = VariableExpr.withVariable( Variable.builder().setName("params").setType(paramsVarType).build()); - VariableExpr reqeustVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("request").setType(method.inputType()).build()); Expr paramsAssignExpr = AssignmentExpr.builder() @@ -289,11 +272,11 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) VariableExpr.withVariable( Variable.builder().setType(method.inputType()).setName("request").build()); - for (String httpBindingFieldName : method.httpBindings()) { + for (HttpBinding httpBindingFieldBinding : method.httpBindings().pathParameters()) { // Handle foo.bar cases by descending into the subfields. MethodInvocationExpr.Builder requestFieldGetterExprBuilder = MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); - String[] descendantFields = httpBindingFieldName.split("\\."); + String[] descendantFields = httpBindingFieldBinding.name().split("\\."); for (int i = 0; i < descendantFields.length; i++) { String currFieldName = descendantFields[i]; String bindingFieldMethodName = @@ -320,7 +303,7 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) .setExprReferenceExpr(paramsVarExpr) .setMethodName("put") .setArguments( - ValueExpr.withValue(StringObjectValue.withValue(httpBindingFieldName)), + ValueExpr.withValue(StringObjectValue.withValue(httpBindingFieldBinding.name())), valueOfExpr) .build(); bodyExprs.add(paramsPutExpr); @@ -339,24 +322,13 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) .setReturnType(returnType) .build(); - MethodDefinition extractMethod = - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setReturnType(returnType) - .setName("extract") - .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) - .setBody( - bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) - .setReturnExpr(returnExpr) - .build(); - - TypeNode anonClassType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(RequestParamsExtractor.class) - .setGenerics(method.inputType().reference()) - .build()); - return AnonymousClassExpr.builder().setType(anonClassType).setMethods(extractMethod).build(); + // Overrides extract(). + // https://github.com/googleapis/gax-java/blob/8d45d186e36ae97b789a6f89d80ae5213a773b65/gax/src/main/java/com/google/api/gax/rpc/RequestParamsExtractor.java#L55 + return LambdaExpr.builder() + .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setBody( + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) + .setReturnExpr(returnExpr) + .build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java index f1ac25fd06..7227b4fe4a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java @@ -234,7 +234,7 @@ private static MethodDefinition createResetMethod(VariableExpr serviceImplVarExp } private static TypeStore createTypes(Service service) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, BetaApi.class, Generated.class, ServerServiceDefinition.class); TypeStore typeStore = new TypeStore(concreteClazzes); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java index a58601197d..e16cc875f4 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java @@ -28,6 +28,7 @@ import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.RelationalOperationExpr; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; @@ -78,17 +79,9 @@ public class MockServiceImplClassComposer implements ClassComposer { Arrays.asList(FIXED_TYPESTORE.get("AbstractMessage").reference())) .build())) .build()); - private static final VariableExpr responsesVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setName("responses") - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(Queue.class) - .setGenerics(Arrays.asList(ConcreteReference.withClazz(Object.class))) - .build())) - .build()); + + private static Reference javaObjectReference = ConcreteReference.withClazz(Object.class); + private static VariableExpr responsesVarExpr; private MockServiceImplClassComposer() {} @@ -97,12 +90,32 @@ public static MockServiceImplClassComposer instance() { } @Override - public GapicClass generate(GapicContext ignored, Service service) { + public GapicClass generate(GapicContext context, Service service) { TypeStore typeStore = createDynamicTypes(service); String className = ClassNames.getMockServiceImplClassName(service); GapicClass.Kind kind = Kind.TEST; String pakkage = service.pakkage(); + // Use the full name java.lang.Object if there is a proto message that is also named "Object". + // Affects GCS. + if (context.messages().keySet().stream() + .anyMatch(s -> s.equals("Object") || s.endsWith(".Object"))) { + javaObjectReference = + ConcreteReference.builder().setClazz(Object.class).setUseFullName(true).build(); + } + + responsesVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName("responses") + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Queue.class) + .setGenerics(Arrays.asList(javaObjectReference)) + .build())) + .build()); + ClassDefinition classDef = ClassDefinition.builder() .setPackageString(pakkage) @@ -212,8 +225,7 @@ private static MethodDefinition createSetResponsesMethod(Service service) { TypeNode.withReference( ConcreteReference.builder() .setClazz(LinkedList.class) - .setGenerics( - Arrays.asList(ConcreteReference.withClazz(Object.class))) + .setGenerics(Arrays.asList(javaObjectReference)) .build())) .setArguments(Arrays.asList(responsesArgVarExpr)) .build()) @@ -267,7 +279,7 @@ private static List createProtoMethodOverrides(Service service private static MethodDefinition createGenericProtoMethodOverride(Method protoMethod) { ConcreteReference streamObserverRef = ConcreteReference.withClazz(StreamObserver.class); - TypeNode objectType = TypeNode.withReference(ConcreteReference.withClazz(Object.class)); + TypeNode objectType = TypeNode.withReference(javaObjectReference); VariableExpr localResponseVarExpr = VariableExpr.withVariable( Variable.builder().setName("response").setType(objectType).build()); @@ -342,7 +354,7 @@ private static MethodDefinition createGenericClientStreamingProtoMethodOverride( AssignmentExpr.builder() .setVariableExpr(requestObserverVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( - createStreamObserverAnonymousClassExpr( + createStreamObserverClassInstance( protoMethod, returnType, responseObserverVarExpr, @@ -352,7 +364,7 @@ private static MethodDefinition createGenericClientStreamingProtoMethodOverride( .build(); } - private static AnonymousClassExpr createStreamObserverAnonymousClassExpr( + private static AnonymousClassExpr createStreamObserverClassInstance( Method protoMethod, TypeNode classType, VariableExpr responseObserverVarExpr, @@ -372,7 +384,7 @@ private static MethodDefinition createOnNextJavaMethod( VariableExpr valueVarExpr = VariableExpr.withVariable( Variable.builder().setName("value").setType(protoMethod.inputType()).build()); - TypeNode objectType = TypeNode.withReference(ConcreteReference.withClazz(Object.class)); + TypeNode objectType = TypeNode.withReference(javaObjectReference); Statement addValueToRequestsStatement = ExprStatement.withExpr( @@ -584,7 +596,7 @@ private static Statement createHandleObjectStatement( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, ArrayList.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java new file mode 100644 index 0000000000..9b95e9c280 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer; + +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer { + private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer(); + + protected ServiceClientClassComposer() { + super(GrpcContext.instance()); + } + + public static ServiceClientClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java index 8d06bd29a9..8cb761236a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java @@ -53,14 +53,13 @@ import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import com.google.protobuf.AbstractMessage; import io.grpc.StatusRuntimeException; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.ExecutionException; import java.util.function.BiFunction; import java.util.function.Function; @@ -73,7 +72,7 @@ public class ServiceClientTestClassComposer extends AbstractServiceClientTestCla private static final ServiceClientTestClassComposer INSTANCE = new ServiceClientTestClassComposer(); - protected static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); + private static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); private static final TypeNode LIST_TYPE = TypeNode.withReference(ConcreteReference.withClazz(List.class)); @@ -97,7 +96,7 @@ public static AbstractServiceClientTestClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, LocalChannelProvider.class, @@ -115,7 +114,8 @@ protected Map createClassMemberVarExprs( BiFunction varExprFn = (name, type) -> VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); - Map fields = new LinkedHashMap<>(); + // Keep keys sorted in alphabetical order to ensure that the test output is deterministic. + Map fields = new TreeMap<>(); fields.put( getMockServiceVarName(service), typeStore.get(ClassNames.getMockServiceClassName(service))); for (Service mixinService : context.mixinServices()) { @@ -132,8 +132,10 @@ protected Map createClassMemberVarExprs( Collectors.toMap( Map.Entry::getKey, e -> varExprFn.apply(e.getKey(), e.getValue()), - (u, v) -> {throw new IllegalStateException();}, - LinkedHashMap::new)); + (u, v) -> { + throw new IllegalStateException(); + }, + TreeMap::new)); } @Override @@ -141,7 +143,8 @@ protected MethodDefinition createStartStaticServerMethod( Service service, GapicContext context, Map classMemberVarExprs, - TypeStore typeStore) { + TypeStore typeStore, + String newBuilderMethod) { VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME); Function serviceToVarExprFn = s -> classMemberVarExprs.get(getMockServiceVarName(s)); @@ -157,7 +160,12 @@ protected MethodDefinition createStartStaticServerMethod( List mockServiceVarExprs = new ArrayList<>(); varInitExprs.add(serviceToVarInitExprFn.apply(service)); mockServiceVarExprs.add(serviceToVarExprFn.apply(service)); - for (Service mixinService : context.mixinServices()) { + // Careful: Java 8 and 11 make different ordering choices if this set is not explicitly sorted. + // Context: https://github.com/googleapis/gapic-generator-java/pull/750 + for (Service mixinService : + context.mixinServices().stream() + .sorted((s1, s2) -> s2.name().compareTo(s1.name())) + .collect(Collectors.toList())) { varInitExprs.add(serviceToVarInitExprFn.apply(mixinService)); mockServiceVarExprs.add(serviceToVarExprFn.apply(mixinService)); } @@ -1036,14 +1044,21 @@ protected List createStreamingRpcExceptionTestStatements( tryBodyExprs.stream() .map(e -> ExprStatement.withExpr(e)) .collect(Collectors.toList())) - .setCatchVariableExpr(catchExceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setCatchBody(createRpcLroExceptionTestCatchBody(catchExceptionVarExpr, true)) + .addCatch( + catchExceptionVarExpr.toBuilder().setIsDecl(true).build(), + createRpcLroExceptionTestCatchBody(catchExceptionVarExpr, true)) .build(); statements.add(tryCatchBlock); return statements; } + @Override + protected Expr createDefaultValue( + MethodArgument methodArg, Map resourceNames) { + return DefaultValueComposer.createDefaultValue(methodArg, resourceNames, false); + } + @Override protected List createRpcLroExceptionTestCatchBody( VariableExpr exceptionExpr, boolean isStreaming) { diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java index 9d4c9bc294..ff0e4ed23f 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java @@ -17,8 +17,7 @@ import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { - private static final ServiceSettingsClassComposer INSTANCE = - new ServiceSettingsClassComposer(); + private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer(); protected ServiceSettingsClassComposer() { super(GrpcContext.instance()); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java new file mode 100644 index 0000000000..1e11c5087d --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; + +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer { + private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer(); + + protected ServiceStubClassComposer() { + super(GrpcContext.instance()); + } + + public static ServiceStubClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java index 9d96aba607..a897f3003d 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java @@ -14,33 +14,33 @@ package com.google.api.generator.gapic.composer.grpc; +import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.grpc.GaxGrpcProperties; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; -import com.google.api.gax.rpc.ApiClientHeaderProvider; -import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.StringObjectValue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Service; import java.util.Arrays; +import java.util.Collections; import java.util.List; public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer { private static final ServiceStubSettingsClassComposer INSTANCE = new ServiceStubSettingsClassComposer(); - protected static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); + private static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); public static ServiceStubSettingsClassComposer instance() { return INSTANCE; @@ -51,7 +51,7 @@ protected ServiceStubSettingsClassComposer() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, GrpcTransportChannel.class, @@ -60,106 +60,74 @@ private static TypeStore createStaticTypes() { } @Override - protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() { - // Create the defaultGrpcTransportProviderBuilder method. - TypeNode returnType = - TypeNode.withReference( - ConcreteReference.withClazz(InstantiatingGrpcChannelProvider.Builder.class)); - MethodInvocationExpr transportChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_GRPC_TYPESTORE.get(InstantiatingGrpcChannelProvider.class.getSimpleName())) - .setMethodName("newBuilder") - .build(); - transportChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(transportChannelProviderBuilderExpr) - .setMethodName("setMaxInboundMessageSize") - .setArguments( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.INT).setName("MAX_VALUE").build()) - .setStaticReferenceType(TypeNode.INT_OBJECT) - .build()) - .setReturnType(returnType) - .build(); - return MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) + protected Expr initializeTransportProviderBuilder( + MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) { + return MethodInvocationExpr.builder() + .setExprReferenceExpr(transportChannelProviderBuilderExpr) + .setMethodName("setMaxInboundMessageSize") + .setArguments( + VariableExpr.builder() + .setVariable(Variable.builder().setType(TypeNode.INT).setName("MAX_VALUE").build()) + .setStaticReferenceType(TypeNode.INT_OBJECT) + .build()) .setReturnType(returnType) - .setName("defaultGrpcTransportProviderBuilder") - .setReturnExpr(transportChannelProviderBuilderExpr) .build(); } @Override - protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( - Service service, TypeStore typeStore) { - // Create the defaultApiClientHeaderProviderBuilder method. + protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { TypeNode returnType = - TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); - MethodInvocationExpr returnExpr = + TypeNode.withReference( + ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); + MethodInvocationExpr credsProviderBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) .setMethodName("newBuilder") .build(); - - MethodInvocationExpr versionArgExpr = + credsProviderBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GaxProperties")) - .setMethodName("getLibraryVersion") - .setArguments( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType( - typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) - .build()) + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setScopesToApply") + .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setReturnType(returnType) .build(); - returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setGeneratedLibToken") - .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) - .build(); - returnExpr = + // This section is specific to GAPIC clients. It sets UseJwtAccessWithScope value to true to + // enable self signed JWT feature. + credsProviderBuilderExpr = MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setTransportToken") + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setUseJwtAccessWithScope") .setArguments( - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) - .setMethodName("getGrpcTokenName") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) - .setMethodName("getGrpcVersion") - .build()) + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) .setReturnType(returnType) .build(); - AnnotationNode annotation = - AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("BetaApi")) - .setDescription( - "The surface for customizing headers is not stable yet and may change in the" - + " future.") - .build(); return MethodDefinition.builder() - .setAnnotations(Arrays.asList(annotation)) + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(returnType) - .setName("defaultApiClientHeaderProviderBuilder") - .setReturnExpr(returnExpr) + .setName("defaultCredentialsProviderBuilder") + .setReturnExpr(credsProviderBuilderExpr) .build(); } + @Override + protected List createApiClientHeaderProviderBuilderMethods( + Service service, TypeStore typeStore) { + return Collections.singletonList( + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultApiClientHeaderProviderBuilder", + FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName()), + "getGrpcTokenName", + "getGrpcVersion")); + } + @Override public MethodDefinition createDefaultTransportChannelProviderMethod() { TypeNode returnType = FIXED_TYPESTORE.get("TransportChannelProvider"); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel new file mode 100644 index 0000000000..ea77aab100 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel @@ -0,0 +1,55 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "grpcrest_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "grpcrest", + srcs = [ + ":grpcrest_files", + ], + deps = [ + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic:status_java_proto", + "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/rest", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/main/java/com/google/api/generator/gapic/composer/store", + "//src/main/java/com/google/api/generator/gapic/composer/utils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/utils", + "//src/main/java/com/google/api/generator/util", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_gax_java//gax:gax_testlib", + "@com_google_api_gax_java//gax-grpc:gax_grpc", + "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_googleapis//gapic/metadata:metadata_java_proto", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava//jar", + "@com_google_http_client_google_http_client//jar", + "@com_google_protobuf//:protobuf_java", + "@com_google_protobuf//:protobuf_java_util", + "@com_google_protobuf//java/core", + "@io_grpc_grpc_java//api", + "@io_grpc_grpc_java//protobuf", + "@io_grpc_grpc_java//stub", + "@javax_annotation_javax_annotation_api//jar", + "@junit_junit//jar", + "@org_threeten_threetenbp//jar", + ], +) diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java new file mode 100644 index 0000000000..3f84bf3c97 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java @@ -0,0 +1,95 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.grpc.ProtoOperationTransformers; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub; +import com.google.api.generator.gapic.composer.common.TransportContext; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Transport; +import com.google.common.collect.ImmutableList; +import com.google.longrunning.OperationsClient; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.longrunning.stub.OperationsStub; + +public abstract class GrpcRestContext extends TransportContext { + private static final TransportContext INSTANCE = + GrpcRestContext.builder() + .setClassNames(new ClassNames("Grpc", "HttpJson")) + .setTransport(Transport.GRPC_REST) + .setTransportName(null) + // For grpcrest.GrpcServiceStubClassComposer + .setCallSettingsClass(null) + .setStubCallableFactoryType(null) + .setMethodDescriptorClass(null) + .setTransportOperationsStubTypes( + ImmutableList.of( + classToType(GrpcOperationsStub.class), classToType(HttpJsonOperationsStub.class))) + .setTransportOperationsStubNames( + ImmutableList.of("operationsStub", "httpJsonOperationsStub")) + // For grpcrest.ServiceSettingsClassComposer + .setInstantiatingChannelProviderClasses( + ImmutableList.of( + InstantiatingGrpcChannelProvider.class, + InstantiatingHttpJsonChannelProvider.class)) + .setInstantiatingChannelProviderBuilderClasses( + ImmutableList.of( + InstantiatingGrpcChannelProvider.Builder.class, + InstantiatingHttpJsonChannelProvider.Builder.class)) + .setDefaultTransportProviderBuilderNames( + ImmutableList.of( + "defaultGrpcTransportProviderBuilder", "defaultHttpJsonTransportProviderBuilder")) + .setTransportApiClientHeaderProviderBuilderNames( + ImmutableList.of( + "defaultGrpcApiClientHeaderProviderBuilder", + "defaultHttpJsonApiClientHeaderProviderBuilder")) + // For grpcrest.ServiceStubSettingsClassComposer + .setTransportChannelTypes( + ImmutableList.of( + classToType(GrpcTransportChannel.class), + classToType(HttpJsonTransportChannel.class))) + .setTransportGetterNames( + ImmutableList.of("getGrpcTransportName", "getHttpJsonTransportName")) + // For grpcrest.GrpcServiceCallableFactoryClassComposer + .setTransportCallSettingsType(null) + .setTransportCallableFactoryType(null) + .setOperationsStubTypes( + ImmutableList.of( + classToType(OperationsStub.class), classToType(BackgroundResource.class))) + .setTransportCallSettingsName(null) + // For RetrySettingsComposer + // TODO: fix when LRO for REST RE FIXED + .setOperationResponseTransformerType( + classToType(ProtoOperationTransformers.ResponseTransformer.class)) + .setOperationMetadataTransformerType( + classToType(ProtoOperationTransformers.MetadataTransformer.class)) + // For ServiceClientClassComposer + .setOperationsClientTypes( + ImmutableList.of( + classToType(OperationsClient.class), + classToType(com.google.api.gax.httpjson.longrunning.OperationsClient.class))) + .setOperationsClientNames( + ImmutableList.of("operationsClient", "httpJsonOperationsClient")) + .build(); + + public static TransportContext instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java new file mode 100644 index 0000000000..9f9bbafc05 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java @@ -0,0 +1,57 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import java.util.Map; + +public class HttpJsonServiceClientTestClassComposer extends ServiceClientTestClassComposer { + private static final HttpJsonServiceClientTestClassComposer INSTANCE = + new HttpJsonServiceClientTestClassComposer(); + + protected HttpJsonServiceClientTestClassComposer() { + super(); + } + + public static AbstractServiceClientTestClassComposer instance() { + return INSTANCE; + } + + @Override + protected GapicClass generate(String className, GapicContext context, Service service) { + return super.generate( + getTransportContext().classNames().getServiceClientTestClassNames(service).get(0), + context, + service); + } + + @Override + protected MethodDefinition createStartStaticServerMethod( + Service service, + GapicContext context, + Map classMemberVarExprs, + TypeStore typeStore, + String newBuilderMethod) { + return super.createStartStaticServerMethod( + service, context, classMemberVarExprs, typeStore, "newHttpJsonBuilder"); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java new file mode 100644 index 0000000000..7f99c81287 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java @@ -0,0 +1,40 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.Service; +import java.util.List; + +public class HttpJsonServiceStubClassComposer + extends com.google.api.generator.gapic.composer.rest.HttpJsonServiceStubClassComposer { + private static final HttpJsonServiceStubClassComposer INSTANCE = + new HttpJsonServiceStubClassComposer(); + + protected HttpJsonServiceStubClassComposer() { + super(); + } + + public static HttpJsonServiceStubClassComposer instance() { + return INSTANCE; + } + + @Override + protected List createStaticCreatorMethods( + Service service, TypeStore typeStore, String newBuilderMethod) { + return super.createStaticCreatorMethods(service, typeStore, "newHttpJsonBuilder"); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java new file mode 100644 index 0000000000..7529b002cf --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java @@ -0,0 +1,29 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer; + +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer { + private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer(); + + protected ServiceClientClassComposer() { + super(GrpcRestContext.instance()); + } + + public static ServiceClientClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java new file mode 100644 index 0000000000..03ff5dc54a --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java @@ -0,0 +1,68 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.Service; +import java.util.ArrayList; +import java.util.List; + +public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { + private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer(); + + protected ServiceSettingsClassComposer() { + super(GrpcRestContext.instance()); + } + + public static ServiceSettingsClassComposer instance() { + return INSTANCE; + } + + @Override + protected List createNestedBuilderCreatorMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { + List methods = new ArrayList<>(); + + methods.addAll( + super.createNestedBuilderCreatorMethods(service, typeStore, "newBuilder", "createDefault")); + methods.addAll( + super.createNestedBuilderCreatorMethods( + service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault")); + + return methods; + } + + @Override + protected List createNewBuilderMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { + List methods = new ArrayList<>(); + + methods.addAll( + super.createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault")); + methods.addAll( + super.createNewBuilderMethods( + service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault")); + + return methods; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java new file mode 100644 index 0000000000..6be0ef7ac2 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.ReturnExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; + +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer { + private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer(); + + protected ServiceStubClassComposer() { + super(GrpcRestContext.instance()); + } + + public static ServiceStubClassComposer instance() { + return INSTANCE; + } + + @Override + protected MethodDefinition createOperationsStubGetterMethodDefinition( + TypeNode returnType, String methodName, TypeStore typeStore) { + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setReturnType(returnType) + .setName(methodName) + .setReturnExpr(ReturnExpr.withExpr(ValueExpr.createNullExpr())) + .build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java new file mode 100644 index 0000000000..6f65ced39c --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java @@ -0,0 +1,200 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.grpcrest; + +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Service; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.List; + +public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer { + private static final ServiceStubSettingsClassComposer INSTANCE = + new ServiceStubSettingsClassComposer(); + + public static ServiceStubSettingsClassComposer instance() { + return INSTANCE; + } + + protected ServiceStubSettingsClassComposer() { + super(GrpcRestContext.instance()); + } + + @Override + protected Expr initializeTransportProviderBuilder( + MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) { + if (!returnType.reference().isFromPackage("com.google.api.gax.grpc")) { + return transportChannelProviderBuilderExpr; + } + + return MethodInvocationExpr.builder() + .setExprReferenceExpr(transportChannelProviderBuilderExpr) + .setMethodName("setMaxInboundMessageSize") + .setArguments( + VariableExpr.builder() + .setVariable(Variable.builder().setType(TypeNode.INT).setName("MAX_VALUE").build()) + .setStaticReferenceType(TypeNode.INT_OBJECT) + .build()) + .setReturnType(returnType) + .build(); + } + + @Override + protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); + MethodInvocationExpr credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) + .setMethodName("newBuilder") + .build(); + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setScopesToApply") + .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setReturnType(returnType) + .build(); + + // This section is specific to GAPIC clients. It sets UseJwtAccessWithScope value to true to + // enable self signed JWT feature. + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setUseJwtAccessWithScope") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) + .setReturnType(returnType) + .build(); + + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultCredentialsProviderBuilder") + .setReturnExpr(credsProviderBuilderExpr) + .build(); + } + + @Override + protected List createApiClientHeaderProviderBuilderMethods( + Service service, TypeStore typeStore) { + + TypeNode returnType = + TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); + + return ImmutableList.of( + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultGrpcApiClientHeaderProviderBuilder", + TypeNode.withReference(ConcreteReference.withClazz(GaxGrpcProperties.class)), + "getGrpcTokenName", + "getGrpcVersion"), + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultHttpJsonApiClientHeaderProviderBuilder", + TypeNode.withReference(ConcreteReference.withClazz(GaxHttpJsonProperties.class)), + "getHttpJsonTokenName", + "getHttpJsonVersion"), + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultApiClientHeaderProviderBuilder") + .setReturnExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) + .setMethodName("defaultGrpcApiClientHeaderProviderBuilder") + .setReturnType(returnType) + .build()) + .build()); + } + + @Override + public MethodDefinition createDefaultTransportChannelProviderMethod() { + TypeNode returnType = FIXED_TYPESTORE.get("TransportChannelProvider"); + MethodInvocationExpr transportProviderBuilderExpr = + MethodInvocationExpr.builder().setMethodName("defaultGrpcTransportProviderBuilder").build(); + transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportProviderBuilderExpr) + .setMethodName("build") + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultTransportChannelProvider") + .setReturnExpr(transportProviderBuilderExpr) + .build(); + } + + @Override + protected List createNestedClassCreateDefaultMethods(TypeStore typeStore) { + return ImmutableList.of( + createNestedClassCreateDefaultMethod( + typeStore, + "createDefault", + "defaultTransportChannelProvider", + null, + "defaultApiClientHeaderProviderBuilder"), + createNestedClassCreateDefaultMethod( + typeStore, + "createHttpJsonDefault", + null, + "defaultHttpJsonTransportProviderBuilder", + "defaultHttpJsonApiClientHeaderProviderBuilder")); + } + + @Override + protected List createNewBuilderMethods( + Service service, + TypeStore typeStore, + String newBuilderMethodName, + String createDefaultMethodName) { + List methods = new ArrayList<>(); + methods.addAll( + super.createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault")); + methods.addAll( + super.createNewBuilderMethods( + service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault")); + return methods; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java index 28b65cd52e..f8c961ccab 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java @@ -49,6 +49,7 @@ import com.google.api.generator.gapic.composer.comment.CommentComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.api.generator.gapic.utils.ResourceNameConstants; @@ -79,8 +80,10 @@ public class ResourceNameHelperClassComposer { new ResourceNameHelperClassComposer(); private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + private static final Map FIXED_CLASS_VARS = + createFixedClassMemberVariables(); - private static Map FIXED_CLASS_VARS = createFixedClassMemberVariables(); + private static Reference javaObjectReference = ConcreteReference.withClazz(Object.class); private ResourceNameHelperClassComposer() {} @@ -88,14 +91,25 @@ public static ResourceNameHelperClassComposer instance() { return INSTANCE; } - public GapicClass generate(ResourceName resourceName) { + public GapicClass generate(ResourceName resourceName, GapicContext context) { + // Set up types. List> tokenHierarchies = ResourceNameTokenizer.parseTokenHierarchy(resourceName.patterns()); TypeStore typeStore = createDynamicTypes(resourceName, tokenHierarchies); + // Use the full name java.lang.Object if there is a proto message that is also named "Object". + // Affects GCS. + if (context.messages().keySet().stream() + .anyMatch(s -> s.equals("Object") || s.endsWith(".Object"))) { + javaObjectReference = + ConcreteReference.builder().setClazz(Object.class).setUseFullName(true).build(); + } + + // Set up variables. List templateFinalVarExprs = createTemplateClassMembers(tokenHierarchies); Map patternTokenVarExprs = createPatternTokenClassMembers(tokenHierarchies); + // Check invariants. Preconditions.checkState( patternTokenVarExprs.size() > 0, String.format("No patterns found for resource name %s", resourceName.resourceTypeString())); @@ -200,7 +214,9 @@ private static List createClassStatements( // "projects/{project}/locations/{location}/autoscalingPolicies/{autoscaling_policy}"); for (int i = 0; i < patterns.size(); i++) { VariableExpr varExpr = - templateFinalVarExprs.get(i).toBuilder() + templateFinalVarExprs + .get(i) + .toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -224,7 +240,9 @@ private static List createClassStatements( } memberVars.add( - FIXED_CLASS_VARS.get("fieldValuesMap").toBuilder() + FIXED_CLASS_VARS + .get("fieldValuesMap") + .toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsVolatile(true) @@ -1174,7 +1192,6 @@ private static MethodDefinition createGetFieldValuesMapMethod( .build(); // Outer if-block. - Expr thisExpr = ValueExpr.withValue(ThisObjectValue.withType(thisClassType)); IfStatement outerIfStatement = IfStatement.builder() .setConditionExpr(fieldValuesMapNullCheckExpr) @@ -1229,8 +1246,7 @@ private static MethodDefinition createToStringMethod( List instantiateArgExprs = new ArrayList<>(); List tokens = getTokenSet(tokenHierarchies).stream().collect(Collectors.toList()); - for (int i = 0; i < tokens.size(); i++) { - String token = tokens.get(i); + for (String token : tokens) { Preconditions.checkNotNull( patternTokenVarExprs.get(token), String.format( @@ -1288,7 +1304,11 @@ private static MethodDefinition createToStringMethod( private static MethodDefinition createEqualsMethod( ResourceName resourceName, List> tokenHierarchies, TypeStore typeStore) { // Create method definition variables. - Variable oVariable = Variable.builder().setType(TypeNode.OBJECT).setName("o").build(); + Variable oVariable = + Variable.builder() + .setType(TypeNode.withReference(javaObjectReference)) + .setName("o") + .build(); VariableExpr argVarExpr = VariableExpr.builder().setIsDecl(false).setVariable(oVariable).build(); TypeNode thisClassType = typeStore.get(getThisClassName(resourceName)); @@ -1550,7 +1570,6 @@ private static ClassDefinition createNestedBuilderClass( for (int i = 0; i < tokens.size(); i++) { String token = tokens.get(i); String upperCamelTokenName = JavaStyle.toUpperCamelCase(token); - String lowerCamelTokenName = JavaStyle.toLowerCamelCase(token); VariableExpr currClassTokenVarExpr = classMemberVarExprs.get(i); // Getter. @@ -1603,7 +1622,9 @@ private static ClassDefinition createNestedBuilderClass( .setStaticReferenceType(FIXED_TYPESTORE.get("Objects")) .setMethodName("equals") .setArguments( - FIXED_CLASS_VARS.get("pathTemplate").toBuilder() + FIXED_CLASS_VARS + .get("pathTemplate") + .toBuilder() .setExprReferenceExpr(outerClassVarExpr) .build(), templateFinalVarExpr) @@ -1623,15 +1644,15 @@ private static ClassDefinition createNestedBuilderClass( .build()); } - for (int i = 0; i < tokens.size(); i++) { - String token = tokens.get(i); - String lowerCamelTokenName = JavaStyle.toLowerCamelCase(token); - VariableExpr currClassTokenVarExpr = classMemberVarExprs.get(i); + for (VariableExpr memberVarExpr : classMemberVarExprs) { + VariableExpr currClassTokenVarExpr = + memberVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build(); builderCtorBodyExprs.add( AssignmentExpr.builder() .setVariableExpr(currClassTokenVarExpr) .setValueExpr( - currClassTokenVarExpr.toBuilder() + currClassTokenVarExpr + .toBuilder() .setExprReferenceExpr(outerClassVarExpr) .build()) .build()); @@ -1687,7 +1708,7 @@ private static ClassDefinition createNestedBuilderClass( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ArrayList.class, BetaApi.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel new file mode 100644 index 0000000000..4b9e29239c --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel @@ -0,0 +1,52 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "rest_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "rest", + srcs = [ + ":rest_files", + ], + deps = [ + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic:status_java_proto", + "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/main/java/com/google/api/generator/gapic/composer/store", + "//src/main/java/com/google/api/generator/gapic/composer/utils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/utils", + "//src/main/java/com/google/api/generator/util", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_gax_java//gax:gax_testlib", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_googleapis//gapic/metadata:metadata_java_proto", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava//jar", + "@com_google_http_client_google_http_client//jar", + "@com_google_protobuf//:protobuf_java", + "@com_google_protobuf//:protobuf_java_util", + "@com_google_protobuf//java/core", + "@io_grpc_grpc_java//api", + "@io_grpc_grpc_java//protobuf", + "@io_grpc_grpc_java//stub", + "@javax_annotation_javax_annotation_api//jar", + "@junit_junit//jar", + "@org_threeten_threetenbp//jar", + ], +) diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java new file mode 100644 index 0000000000..1ed6296cfa --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -0,0 +1,107 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class HttpJsonServiceCallableFactoryClassComposer + extends AbstractServiceCallableFactoryClassComposer { + private static final HttpJsonServiceCallableFactoryClassComposer INSTANCE = + new HttpJsonServiceCallableFactoryClassComposer(); + + private static final TypeNode MESSAGE_TYPE = + TypeNode.withReference(ConcreteReference.withClazz(ApiMessage.class)); + + private HttpJsonServiceCallableFactoryClassComposer() { + super(RestContext.instance()); + } + + public static HttpJsonServiceCallableFactoryClassComposer instance() { + return INSTANCE; + } + + @Override + protected List createClassAnnotations(Service service, TypeStore typeStore) { + List annotations = super.createClassAnnotations(service, typeStore); + // Always add @BetaApi annotation to the generated CallableFactory for now. It is a public class + // for technical reasons, end users are not expected to interact with it, but it may change + // when we add LRO support, that is why making it @BetaApi for now. + // + // Remove the @BetaApi annotation once the LRO feature is fully implemented and stabilized. + if (annotations.stream().noneMatch(a -> a.type().equals(typeStore.get("BetaApi")))) { + annotations.add(AnnotationNode.withType(typeStore.get("BetaApi"))); + } + return annotations; + } + + @Override + protected List createClassImplements(TypeStore typeStore) { + return Arrays.asList( + TypeNode.withReference( + getTransportContext() + .stubCallableFactoryType() + .reference() + .copyAndSetGenerics( + Arrays.asList( + MESSAGE_TYPE.reference(), + getTransportContext().operationsStubTypes().get(0).reference())))); + } + + @Override + protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + String methodVariantName = "Operation"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = + Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); + + // Always add @BetaApi annotation to the generated createOperationCallable() method for now, + // until LRO is fully implemented. + // + // Remove the @BetaApi annotation once the LRO feature is fully implemented and stabilized. + AnnotationNode betaAnnotation = + AnnotationNode.withTypeAndDescription( + typeStore.get("BetaApi"), + "The surface for long-running operations is not stable yet and may change in the" + + " future."); + + MethodDefinition method = + createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*httpJsonCallSettingsTemplateObjects=*/ Arrays.asList( + requestTemplateName, MESSAGE_TYPE), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + Arrays.asList(betaAnnotation)); + return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java new file mode 100644 index 0000000000..50ea1ad57e --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -0,0 +1,617 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.InternalApi; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.FieldsExtractor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.IfStatement; +import com.google.api.generator.engine.ast.LambdaExpr; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractTransportServiceStubClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class HttpJsonServiceStubClassComposer extends AbstractTransportServiceStubClassComposer { + private static final HttpJsonServiceStubClassComposer INSTANCE = + new HttpJsonServiceStubClassComposer(); + + private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); + + protected HttpJsonServiceStubClassComposer() { + super(RestContext.instance()); + } + + public static HttpJsonServiceStubClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createStaticTypes() { + return new TypeStore( + Arrays.asList( + ApiMethodDescriptor.class, + ArrayList.class, + FieldsExtractor.class, + InternalApi.class, + HashMap.class, + HttpJsonCallSettings.class, + HttpJsonStubCallableFactory.class, + Map.class, + ProtoMessageRequestFormatter.class, + ProtoMessageResponseParser.class, + ProtoRestSerializer.class)); + } + + @Override + protected boolean generateOperationsStubLogic(Service service) { + return service.hasLroMethods(); + } + + @Override + protected Statement createMethodDescriptorVariableDecl( + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setMethodName("newBuilder") + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(ApiMethodDescriptor.class.getSimpleName())) + .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) + .build(); + + BiFunction, Function> + methodMaker = getMethodMaker(); + + String codeMethodArgName = getProtoRpcFullMethodName(service, protoMethod); + expr = + methodMaker + .apply( + "setFullMethodName", + Arrays.asList(ValueExpr.withValue(StringObjectValue.withValue(codeMethodArgName)))) + .apply(expr); + + expr = methodMaker.apply("setHttpMethod", getHttpMethodTypeExpr(protoMethod)).apply(expr); + expr = + methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); + expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); + + expr = + MethodInvocationExpr.builder() + .setMethodName("build") + .setExprReferenceExpr(expr) + .setReturnType(methodDescriptorVarExpr.type()) + .build(); + + return ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr( + methodDescriptorVarExpr + .toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .setIsFinal(true) + .build()) + .setValueExpr(expr) + .build()); + } + + @Override + protected Expr createTransportSettingsInitExpr( + Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(HttpJsonCallSettings.class.getSimpleName())) + .setGenerics(transportSettingsVarExpr.type().reference().generics()) + .setMethodName("newBuilder") + .build(); + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setMethodDescriptor") + .setArguments(Arrays.asList(methodDescriptorVarExpr)) + .build(); + + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("build") + .setReturnType(transportSettingsVarExpr.type()) + .build(); + return AssignmentExpr.builder() + .setVariableExpr(transportSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(callSettingsBuilderExpr) + .build(); + } + + @Override + protected List createClassAnnotations(Service service) { + List annotations = super.createClassAnnotations(service); + + annotations.add( + AnnotationNode.builder() + .setType(FIXED_TYPESTORE.get("BetaApi")) + .setDescription( + "A restructuring of stub classes is planned, so this may break in the future") + .build()); + return annotations; + } + + @Override + protected List createGetMethodDescriptorsMethod( + Service service, + TypeStore typeStore, + Map protoMethodNameToDescriptorVarExprs) { + + List bodyExprs = new ArrayList<>(); + + VariableExpr methodDescriptorsVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics( + Arrays.asList( + FIXED_REST_TYPESTORE.get("ApiMethodDescriptor").reference())) + .build())) + .setName("methodDescriptors") + .build()); + + bodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(methodDescriptorsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(FIXED_REST_TYPESTORE.get("ArrayList")) + .setIsGeneric(true) + .build()) + .build()); + + for (VariableExpr methodDescriptorVarExpr : protoMethodNameToDescriptorVarExprs.values()) { + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptorsVarExpr) + .setMethodName("add") + .setArguments(methodDescriptorVarExpr) + .build()); + } + + return Arrays.asList( + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(methodDescriptorsVarExpr.type()) + .setReturnExpr(methodDescriptorsVarExpr) + .setAnnotations( + Arrays.asList(AnnotationNode.withType(FIXED_REST_TYPESTORE.get("InternalApi")))) + .setName("getMethodDescriptors") + .setBody(bodyExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())) + .build()); + } + + private BiFunction, Function> + getMethodMaker() { + return (mName, argExpr) -> + (m) -> + MethodInvocationExpr.builder() + .setMethodName(mName) + .setArguments(argExpr) + .setExprReferenceExpr(m) + .build(); + } + + private List getRequestFormatterExpr(Method protoMethod) { + BiFunction, Function> + methodMaker = getMethodMaker(); + + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(ProtoMessageRequestFormatter.class.getSimpleName())) + .setMethodName("newBuilder") + .setGenerics(Collections.singletonList(protoMethod.inputType().reference())) + .build(); + + TypeNode extractorVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) + .build()); + + expr = + methodMaker + .apply( + "setPath", + Arrays.asList( + ValueExpr.withValue( + StringObjectValue.withValue( + protoMethod.httpBindings().patternLowerCamel())), + createFieldsExtractorClassInstance( + protoMethod, + extractorVarType, + protoMethod.httpBindings().pathParameters(), + "putPathParam"))) + .apply(expr); + + TypeNode fieldsVarGenericType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(TypeNode.STRING.reference()) + .build()); + + extractorVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics(TypeNode.STRING.reference(), fieldsVarGenericType.reference()) + .build()); + + expr = + methodMaker + .apply( + "setQueryParamsExtractor", + Arrays.asList( + createFieldsExtractorClassInstance( + protoMethod, + extractorVarType, + protoMethod.httpBindings().queryParameters(), + "putQueryParam"))) + .apply(expr); + + extractorVarType = TypeNode.STRING; + boolean asteriskBody = protoMethod.httpBindings().isAsteriskBody(); + expr = + methodMaker + .apply( + "setRequestBodyExtractor", + Arrays.asList( + createBodyFieldsExtractorClassInstance( + protoMethod, + extractorVarType, + asteriskBody + ? protoMethod.httpBindings().pathParameters() + : protoMethod.httpBindings().bodyParameters(), + "toBody", + asteriskBody))) + .apply(expr); + expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); + + return Collections.singletonList(expr); + } + + private List setResponseParserExpr(Method protoMethod) { + BiFunction, Function> + methodMaker = getMethodMaker(); + + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(ProtoMessageResponseParser.class.getSimpleName())) + .setMethodName("newBuilder") + .setGenerics(Collections.singletonList(protoMethod.outputType().reference())) + // .setArguments(Arrays.asList(m)) + .build(); + + expr = + methodMaker + .apply( + "setDefaultInstance", + Arrays.asList( + MethodInvocationExpr.builder() + .setStaticReferenceType(protoMethod.outputType()) + .setMethodName("getDefaultInstance") + .setReturnType(protoMethod.outputType()) + .build())) + .apply(expr); + expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); + + return Collections.singletonList(expr); + } + + private Expr createBodyFieldsExtractorClassInstance( + Method method, + TypeNode extractorReturnType, + Set httpBindingFieldNames, + String serializerMethodName, + boolean asteriskBody) { + List bodyStatements = new ArrayList<>(); + + Expr returnExpr = null; + Expr serializerExpr = + MethodInvocationExpr.builder() + .setMethodName("create") + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName())) + .build(); + + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + Expr bodyRequestExpr = requestVarExpr; + String requestMethodPrefix = "get"; + String bodyParamName = null; + + if (asteriskBody) { + bodyRequestExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestVarExpr) + .setMethodName("toBuilder") + .build(); + // In case of `body: "*"` case we send the whole request message as a body, minus the fields + // in the path, therefore the "clear" prefix here. + requestMethodPrefix = "clear"; + } + + Expr prevExpr = bodyRequestExpr; + for (HttpBinding httpBindingFieldName : httpBindingFieldNames) { + // Handle foo.bar cases by descending into the subfields. + MethodInvocationExpr.Builder requestFieldMethodExprBuilder = + MethodInvocationExpr.builder().setExprReferenceExpr(prevExpr); + bodyParamName = JavaStyle.toLowerCamelCase(httpBindingFieldName.name()); + String[] descendantFields = httpBindingFieldName.name().split("\\."); + if (asteriskBody && descendantFields.length > 1) { + // This is the `body: "*"` case, do not clean nested body fields as it a very rare, not + // well-defined case, and it is generally safer to send more than less in such case. + continue; + } + + for (int i = 0; i < descendantFields.length; i++) { + String currFieldName = descendantFields[i]; + String bindingFieldMethodName = + String.format("%s%s", requestMethodPrefix, JavaStyle.toUpperCamelCase(currFieldName)); + requestFieldMethodExprBuilder = + requestFieldMethodExprBuilder.setMethodName(bindingFieldMethodName); + + if (i < descendantFields.length - 1) { + requestFieldMethodExprBuilder = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestFieldMethodExprBuilder.build()); + } + } + prevExpr = requestFieldMethodExprBuilder.build(); + } + + if (httpBindingFieldNames.isEmpty() && !asteriskBody) { + returnExpr = ValueExpr.createNullExpr(); + } else { + ImmutableList.Builder paramsPutArgs = ImmutableList.builder(); + if (asteriskBody) { + prevExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(prevExpr) + .setMethodName("build") + .build(); + bodyParamName = "*"; + } + paramsPutArgs.add(ValueExpr.withValue(StringObjectValue.withValue(bodyParamName))); + paramsPutArgs.add(prevExpr); + + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serializerExpr) + .setMethodName(serializerMethodName) + .setArguments(paramsPutArgs.build()) + .setReturnType(extractorReturnType) + .build(); + } + + // Overrides FieldsExtractor + // (https://github.com/googleapis/gax-java/blob/12b18ee255d3fabe13bb3969df40753b29f830d5/gax-httpjson/src/main/java/com/google/api/gax/httpjson/FieldsExtractor.java). + return LambdaExpr.builder() + .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(bodyStatements) + .setReturnExpr(returnExpr) + .build(); + } + + private Expr createFieldsExtractorClassInstance( + Method method, + TypeNode extractorReturnType, + Set httpBindingFieldNames, + String serializerMethodName) { + List bodyStatements = new ArrayList<>(); + + VariableExpr fieldsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("fields").setType(extractorReturnType).build()); + Expr fieldsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(FIXED_REST_TYPESTORE.get(HashMap.class.getSimpleName())) + .setIsGeneric(true) + .build()) + .build(); + + bodyStatements.add(ExprStatement.withExpr(fieldsAssignExpr)); + + TypeNode serializerVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ProtoRestSerializer.class) + .setGenerics(method.inputType().reference()) + .build()); + + VariableExpr serializerVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("serializer").setType(serializerVarType).build()); + + Expr serializerAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(serializerVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName())) + .setMethodName("create") + .setReturnType(serializerVarType) + .build()) + .build(); + + bodyStatements.add(ExprStatement.withExpr(serializerAssignExpr)); + + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + + for (HttpBinding httpBindingFieldName : httpBindingFieldNames) { + // Handle foo.bar cases by descending into the subfields. + MethodInvocationExpr.Builder requestFieldGetterExprBuilder = + MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); + MethodInvocationExpr.Builder requestFieldHasExprBuilder = + MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); + String[] descendantFields = httpBindingFieldName.name().split("\\."); + for (int i = 0; i < descendantFields.length; i++) { + String currFieldName = descendantFields[i]; + String bindingFieldMethodName = + String.format("get%s", JavaStyle.toUpperCamelCase(currFieldName)); + requestFieldGetterExprBuilder = + requestFieldGetterExprBuilder.setMethodName(bindingFieldMethodName); + + String bindingFieldHasMethodName = + (i < descendantFields.length - 1) + ? bindingFieldMethodName + : String.format("has%s", JavaStyle.toUpperCamelCase(currFieldName)); + requestFieldHasExprBuilder = + requestFieldHasExprBuilder + .setMethodName(bindingFieldHasMethodName) + .setReturnType(TypeNode.BOOLEAN); + + if (i < descendantFields.length - 1) { + requestFieldGetterExprBuilder = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestFieldGetterExprBuilder.build()); + requestFieldHasExprBuilder = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestFieldHasExprBuilder.build()); + } + } + + MethodInvocationExpr requestBuilderExpr = requestFieldGetterExprBuilder.build(); + MethodInvocationExpr requestHasExpr = requestFieldHasExprBuilder.build(); + + ImmutableList.Builder paramsPutArgs = ImmutableList.builder(); + + paramsPutArgs.add(fieldsVarExpr); + + paramsPutArgs.add( + ValueExpr.withValue( + StringObjectValue.withValue( + JavaStyle.toLowerCamelCase(httpBindingFieldName.name())))); + paramsPutArgs.add(requestBuilderExpr); + + Expr paramsPutExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serializerVarExpr) + .setMethodName(serializerMethodName) + .setArguments(paramsPutArgs.build()) + .setReturnType(extractorReturnType) + .build(); + + if (httpBindingFieldName.isOptional()) { + bodyStatements.add( + IfStatement.builder() + .setConditionExpr(requestHasExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(paramsPutExpr))) + .build()); + } else { + bodyStatements.add(ExprStatement.withExpr(paramsPutExpr)); + } + } + + // Overrides FieldsExtractor + // (https://github.com/googleapis/gax-java/blob/12b18ee255d3fabe13bb3969df40753b29f830d5/gax-httpjson/src/main/java/com/google/api/gax/httpjson/FieldsExtractor.java). + return LambdaExpr.builder() + .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(bodyStatements) + .setReturnExpr(fieldsVarExpr) + .build(); + } + + private List getHttpMethodTypeExpr(Method protoMethod) { + EnumRefExpr expr = + EnumRefExpr.builder() + .setName(protoMethod.httpBindings().httpVerb().toString()) + .setType( + TypeNode.withReference( + ConcreteReference.builder().setClazz(HttpMethods.class).build())) + .build(); + return Collections.singletonList(expr); + } + + @Override + protected Optional getCallableCreatorMethodName(TypeNode callableVarExprType) { + final String typeName = callableVarExprType.reference().name(); + String streamName = "Unary"; + + // Special handling for pagination methods. + if (callableVarExprType.reference().generics().size() == 2 + && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) { + streamName = "Paged"; + } else { + if (typeName.startsWith("Client")) { + return Optional.empty(); // not supported in REST transport + } else if (typeName.startsWith("Server")) { + return Optional.empty(); // not supported in REST transport (for now) + } else if (typeName.startsWith("Bidi")) { + return Optional.empty(); // not supported in REST transport + } else if (typeName.startsWith("Operation")) { + streamName = "Operation"; + } + } + return Optional.of(String.format("create%sCallable", streamName)); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java new file mode 100644 index 0000000000..eab59215bf --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java @@ -0,0 +1,76 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.httpjson.ProtoOperationTransformers; +import com.google.api.gax.httpjson.longrunning.OperationsClient; +import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub; +import com.google.api.generator.gapic.composer.common.TransportContext; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Transport; +import com.google.common.collect.ImmutableList; + +public abstract class RestContext extends TransportContext { + private static final TransportContext INSTANCE = + RestContext.builder() + .setClassNames(new ClassNames("HttpJson")) + .setTransport(Transport.REST) + .setTransportName("REST") + // For httpjson.HttpJsonServiceStubClassComposer + .setCallSettingsClass(HttpJsonCallSettings.class) + .setStubCallableFactoryType(classToType(HttpJsonStubCallableFactory.class)) + .setMethodDescriptorClass(ApiMethodDescriptor.class) + .setTransportOperationsStubTypes( + ImmutableList.of(classToType(HttpJsonOperationsStub.class))) + .setTransportOperationsStubNames(ImmutableList.of("httpJsonOperationsStub")) + // For httpjson.ServiceSettingsClassComposer + .setInstantiatingChannelProviderClasses( + ImmutableList.of(InstantiatingHttpJsonChannelProvider.class)) + .setInstantiatingChannelProviderBuilderClasses( + ImmutableList.of(InstantiatingHttpJsonChannelProvider.Builder.class)) + .setDefaultTransportProviderBuilderNames( + ImmutableList.of("defaultHttpJsonTransportProviderBuilder")) + .setTransportApiClientHeaderProviderBuilderNames( + ImmutableList.of("defaultHttpJsonApiClientHeaderProviderBuilder")) + // For httpjson.ServiceStubSettingsClassComposer + .setTransportChannelTypes(ImmutableList.of(classToType(HttpJsonTransportChannel.class))) + .setTransportGetterNames(ImmutableList.of("getHttpJsonTransportName")) + // For httpjson.HttpJsonServiceCallableFactoryClassComposer + .setTransportCallSettingsType(classToType(HttpJsonCallSettings.class)) + .setTransportCallableFactoryType(classToType(HttpJsonCallableFactory.class)) + // TODO: set to com.google.api.gax.httpjson.longrunning.stub.OperationsStub.class + .setOperationsStubTypes(ImmutableList.of(classToType(BackgroundResource.class))) + .setTransportCallSettingsName("httpJsonCallSettings") + // For RetrySettingsComposer + .setOperationResponseTransformerType( + classToType(ProtoOperationTransformers.ResponseTransformer.class)) + .setOperationMetadataTransformerType( + classToType(ProtoOperationTransformers.MetadataTransformer.class)) + // For ServiceClientClassComposer + .setOperationsClientTypes(ImmutableList.of(classToType(OperationsClient.class))) + .setOperationsClientNames(ImmutableList.of("httpJsonOperationsClient")) + .build(); + + public static TransportContext instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java new file mode 100644 index 0000000000..9b5f996db7 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer; + +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer { + private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer(); + + protected ServiceClientClassComposer() { + super(RestContext.instance()); + } + + public static ServiceClientClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java new file mode 100644 index 0000000000..9df088bbd7 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java @@ -0,0 +1,544 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.StatusCode.Code; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.defaultvalue.DefaultValueComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Message; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.MethodArgument; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ServiceClientTestClassComposer extends AbstractServiceClientTestClassComposer { + private static final String MOCK_SERVICE_VAR_NAME = "mockService"; + + private static final ServiceClientTestClassComposer INSTANCE = + new ServiceClientTestClassComposer(); + + private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); + + protected ServiceClientTestClassComposer() { + super(RestContext.instance()); + } + + public static AbstractServiceClientTestClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createStaticTypes() { + return new TypeStore( + Arrays.asList( + ApiClientHeaderProvider.class, + ApiException.class, + ApiExceptionFactory.class, + ApiMethodDescriptor.class, + Code.class, + Exception.class, + FakeStatusCode.class, + GaxHttpJsonProperties.class, + ImmutableList.class, + MockHttpService.class)); + } + + @Override + protected Map createClassMemberVarExprs( + Service service, GapicContext context, TypeStore typeStore) { + BiFunction varExprFn = + (name, type) -> + VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); + Map fields = new LinkedHashMap<>(); + fields.put( + MOCK_SERVICE_VAR_NAME, FIXED_REST_TYPESTORE.get(MockHttpService.class.getSimpleName())); + fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); + return fields.entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); + } + + @Override + protected List createClassMemberFieldDecls( + Map classMemberVarExprs) { + return classMemberVarExprs.values().stream() + .map( + v -> + ExprStatement.withExpr( + v.toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .build())) + .collect(Collectors.toList()); + } + + @Override + protected MethodDefinition createStartStaticServerMethod( + Service service, + GapicContext context, + Map classMemberVarExprs, + TypeStore typeStore, + String newBuilderMethod) { + + VariableExpr mockServiceVarExpr = classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME); + VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); + TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); + TypeNode transportStubType = + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); + + Function> methodBuilderFn = + methodExpr -> + (mName, argExpr) -> + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodExpr) + .setMethodName(mName) + .setArguments(Arrays.asList(argExpr)) + .build(); + + Expr initMockServiceExpr = + AssignmentExpr.builder() + .setVariableExpr(mockServiceVarExpr) + .setValueExpr( + NewObjectExpr.builder() + .setType(mockServiceVarExpr.type()) + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType(transportStubType) + .setMethodName("getMethodDescriptors") + .build(), + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("getDefaultEndpoint") + .build()) + .build()) + .build(); + + VariableExpr localSettingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("settings").setType(settingsType).build()); + + Expr settingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName(newBuilderMethod) + .build(); + + Expr transportChannelProviderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("defaultHttpJsonTransportProviderBuilder") + .build(); + + transportChannelProviderExpr = + methodBuilderFn + .apply(transportChannelProviderExpr) + .apply("setHttpTransport", mockServiceVarExpr); + + transportChannelProviderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportChannelProviderExpr) + .setMethodName("build") + .setReturnType(localSettingsVarExpr.type()) + .build(); + + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply("setTransportChannelProvider", transportChannelProviderExpr); + + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply( + "setCredentialsProvider", + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("NoCredentialsProvider")) + .setMethodName("create") + .build()); + settingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(settingsBuilderExpr) + .setMethodName("build") + .setReturnType(localSettingsVarExpr.type()) + .build(); + + Expr initLocalSettingsExpr = + AssignmentExpr.builder() + .setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(settingsBuilderExpr) + .build(); + + Expr initClientExpr = + AssignmentExpr.builder() + .setVariableExpr(clientVarExpr) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceClientClassName(service))) + .setMethodName("create") + .setArguments(Arrays.asList(localSettingsVarExpr)) + .setReturnType(clientVarExpr.type()) + .build()) + .build(); + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("startStaticServer") + .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) + .setIsStatic(true) + .setBody( + Arrays.asList(initMockServiceExpr, initLocalSettingsExpr, initClientExpr).stream() + .map(e -> ExprStatement.withExpr(e)) + .collect(Collectors.toList())) + .build(); + } + + @Override + protected MethodDefinition createStopServerMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("AfterClass")))) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(TypeNode.VOID) + .setName("stopServer") + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(CLIENT_VAR_NAME)) + .setMethodName("close") + .build()))) + .build(); + } + + @Override + protected MethodDefinition createSetUpMethod( + Service service, Map classMemberVarExprs, TypeStore typeStore) { + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("Before")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("setUp") + .setBody(Arrays.asList()) + .build(); + } + + @Override + protected MethodDefinition createTearDownMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("After")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("tearDown") + .setThrowsExceptions( + Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME)) + .setMethodName("reset") + .build()))) + .build(); + } + + @Override + protected List constructRpcTestCheckerLogic( + Method method, + Service service, + boolean isRequestArg, + Map classMemberVarExprs, + VariableExpr requestVarExpr, + Message requestMessage, + List argExprs) { + + VariableExpr actualRequestsVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(TypeNode.STRING.reference())) + .build())) + .setName("actualRequests") + .build()); + + List methodExprs = new ArrayList<>(); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualRequestsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("getRequestPaths") + .setReturnType(actualRequestsVarExpr.type()) + .build()) + .build()); + + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertEquals") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualRequestsVarExpr) + .setMethodName("size") + .build()) + .build()); + + List methodStatements = new ArrayList<>(); + methodStatements.addAll( + methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); + + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + VariableExpr apiClientHeaderKeyVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(TypeNode.STRING).setName("apiClientHeaderKey").build()); + + AssignmentExpr apiClientHeaderKeyAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(apiClientHeaderKeyVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setMethodName("next") + .setReturnType(apiClientHeaderKeyVarExpr.type()) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("iterator") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("get") + .setArguments( + MethodInvocationExpr.builder() + .setMethodName("getDefaultApiClientHeaderKey") + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get("ApiClientHeaderProvider")) + .build()) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("getRequestHeaders") + .setExprReferenceExpr( + classMemberVarExprs.get( + getMockServiceVarName(service))) + .build()) + .build()) + .build()) + .build()) + .build(); + + methodExprs.add(apiClientHeaderKeyAssignExpr); + + methodExprs.add( + MethodInvocationExpr.builder() + .setMethodName("assertTrue") + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setArguments( + MethodInvocationExpr.builder() + .setMethodName("matches") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("matcher") + .setArguments(apiClientHeaderKeyVarExpr) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("getDefaultApiClientHeaderPattern") + .setStaticReferenceType( + FIXED_REST_TYPESTORE.get("GaxHttpJsonProperties")) + .build()) + .build()) + .build()) + .build()); + + methodStatements.addAll( + methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); + methodExprs.clear(); + + return methodStatements; + } + + @Override + protected MethodDefinition createStreamingRpcTestMethod( + Service service, + Method method, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + // Add some actual statements once implemented + List methodStatements = new ArrayList<>(); + + String testMethodName = String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())); + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(TEST_ANNOTATION)) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName(testMethodName) + .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) + .setBody(methodStatements) + .build(); + } + + @Override + protected MethodDefinition createRpcExceptionTestMethod( + Method method, + Service service, + List methodSignature, + int variantIndex, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + VariableExpr exceptionVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(FIXED_REST_TYPESTORE.get("ApiException")) + .setName("exception") + .build()); + + // First two assignment lines. + Expr exceptionAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setMethodName("createException") + .setStaticReferenceType(FIXED_REST_TYPESTORE.get("ApiExceptionFactory")) + .setArguments( + NewObjectExpr.withType(FIXED_REST_TYPESTORE.get("Exception")), + MethodInvocationExpr.builder() + .setMethodName("of") + .setStaticReferenceType(FIXED_REST_TYPESTORE.get("FakeStatusCode")) + .setArguments( + EnumRefExpr.builder() + .setName("INVALID_ARGUMENT") + .setType(FIXED_REST_TYPESTORE.get("Code")) + .build()) + .build(), + ValueExpr.withValue( + PrimitiveValue.builder() + .setType(TypeNode.BOOLEAN) + .setValue("false") + .build())) + .setReturnType(exceptionVarExpr.type()) + .build()) + .build(); + + Expr addExceptionExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("addException") + .setArguments(exceptionVarExpr) + .build(); + + // Try-catch block. Build the method call. + String exceptionTestMethodName = + String.format( + "%sExceptionTest%s", + JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); + + boolean isStreaming = !method.stream().equals(Method.Stream.NONE); + List methodBody = new ArrayList<>(); + methodBody.add(ExprStatement.withExpr(exceptionAssignExpr)); + methodBody.add(ExprStatement.withExpr(addExceptionExpr)); + if (isStreaming) { + methodBody.addAll( + createStreamingRpcExceptionTestStatements( + method, classMemberVarExprs, resourceNames, messageTypes)); + } else { + methodBody.addAll( + createRpcExceptionTestStatements( + method, methodSignature, classMemberVarExprs, resourceNames, messageTypes)); + } + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(TEST_ANNOTATION)) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName(exceptionTestMethodName) + .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) + .setBody(methodBody) + .build(); + } + + @Override + protected List createStreamingRpcExceptionTestStatements( + Method method, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + return Collections.emptyList(); + } + + @Override + protected Expr createDefaultValue( + MethodArgument methodArg, Map resourceNames) { + return DefaultValueComposer.createDefaultValue(methodArg, resourceNames, true); + } + + @Override + protected List createRpcLroExceptionTestCatchBody( + VariableExpr exceptionExpr, boolean isStreaming) { + return Collections.emptyList(); + } + + @Override + protected String getMockServiceVarName(Service service) { + return String.format(MOCK_SERVICE_VAR_NAME); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposer.java new file mode 100644 index 0000000000..637dea043f --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposer.java @@ -0,0 +1,29 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; + +public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { + private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer(); + + protected ServiceSettingsClassComposer() { + super(RestContext.instance()); + } + + public static ServiceSettingsClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java new file mode 100644 index 0000000000..704fac96b6 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; + +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer { + private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer(); + + protected ServiceStubClassComposer() { + super(RestContext.instance()); + } + + public static ServiceStubClassComposer instance() { + return INSTANCE; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java new file mode 100644 index 0000000000..b12528ec3f --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java @@ -0,0 +1,87 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer { + private static final ServiceStubSettingsClassComposer INSTANCE = + new ServiceStubSettingsClassComposer(); + + private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); + + public static ServiceStubSettingsClassComposer instance() { + return INSTANCE; + } + + protected ServiceStubSettingsClassComposer() { + super(RestContext.instance()); + } + + private static TypeStore createStaticTypes() { + return new TypeStore( + Arrays.asList( + GaxHttpJsonProperties.class, + HttpJsonTransportChannel.class, + InstantiatingHttpJsonChannelProvider.class)); + } + + @Override + protected List createApiClientHeaderProviderBuilderMethods( + Service service, TypeStore typeStore) { + return Collections.singletonList( + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultApiClientHeaderProviderBuilder", + FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName()), + "getHttpJsonTokenName", + "getHttpJsonVersion")); + } + + @Override + public MethodDefinition createDefaultTransportChannelProviderMethod() { + TypeNode returnType = FIXED_TYPESTORE.get("TransportChannelProvider"); + MethodInvocationExpr transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setMethodName("defaultHttpJsonTransportProviderBuilder") + .build(); + transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportProviderBuilderExpr) + .setMethodName("build") + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultTransportChannelProvider") + .setReturnExpr(transportProviderBuilderExpr) + .build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java index a9403b54a3..5572bde8e3 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java @@ -59,6 +59,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -70,6 +71,7 @@ public static String composeClassHeaderMethodSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); // Use the first pure unary RPC method's sample code as showcase, if no such method exists, use // the first method in the service's methods list. Method method = @@ -232,6 +234,7 @@ public static String composeRpcMethodHeaderSampleCode( List arguments, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -278,6 +281,7 @@ public static String composeRpcDefaultMethodHeaderSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -336,6 +340,7 @@ public static String composeLroCallableMethodHeaderSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -448,6 +453,7 @@ public static String composePagedCallableMethodHeaderSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -477,7 +483,7 @@ public static String composePagedCallableMethodHeaderSampleCode( // Find the repeated field. Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -567,6 +573,7 @@ public static String composeRegularCallableMethodHeaderSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -616,6 +623,7 @@ public static String composeStreamCallableMethodHeaderSampleCode( TypeNode clientType, Map resourceNames, Map messageTypes) { + resourceNames = sortAlphabetically(resourceNames); VariableExpr clientVarExpr = VariableExpr.withVariable( Variable.builder() @@ -708,7 +716,7 @@ private static List composeUnaryPagedRpcMethodBodyStatements( "Output message %s not found, keys: ", method.outputType().reference().fullName(), messageTypes.keySet().toString()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -1134,7 +1142,7 @@ private static List composePagedCallableBodyStatements( Map messageTypes) { // Find the repeated field. Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName()); - Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField(); + Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField(); Preconditions.checkNotNull( repeatedPagedResultsField, String.format( @@ -1302,7 +1310,7 @@ private static List createRpcMethodArgumentDefaultValueExprs( .map( arg -> !isStringTypedResourceName(arg, resourceNames) - ? DefaultValueComposer.createDefaultValue(arg, resourceNames) + ? DefaultValueComposer.createDefaultValue(arg, resourceNames, false) : stringResourceNameDefaultValueExpr.apply(arg)) .collect(Collectors.toList()); } @@ -1349,4 +1357,16 @@ private static boolean isProtoEmptyType(TypeNode type) { return type.reference().pakkage().equals("com.google.protobuf") && type.reference().name().equals("Empty"); } + + /** + * Returns the same "resource type name" to "resource name" key-value map as given, but sorted in + * alphabetical order. This prevents resource name flip-flopping between executions on the various + * machines used for client library publication. + */ + private static TreeMap sortAlphabetically( + Map unsorted) { + // This simple wrapper is not redundant because it hides implementation details from the + // callers. + return new TreeMap<>(unsorted); + } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java index 061c42a67c..4113c3446b 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java +++ b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java @@ -28,7 +28,11 @@ public class TypeStore { public TypeStore() {} - public TypeStore(List concreteClasses) { + public TypeStore(List> concreteClasses) { + putConcreteClassses(concreteClasses); + } + + private void putConcreteClassses(List> concreteClasses) { store.putAll( concreteClasses.stream() .collect( @@ -67,6 +71,10 @@ public void put( .build())); } + public void putAll(List> concreteClasses) { + putConcreteClassses(concreteClasses); + } + public void putAll( String pakkage, List typeNames, diff --git a/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java b/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java index f1abb45a4c..c0b717fc0a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java +++ b/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java @@ -15,6 +15,9 @@ package com.google.api.generator.gapic.composer.utils; import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; /** Provides Gapic class names. */ public class ClassNames { @@ -23,6 +26,7 @@ public class ClassNames { private static final String MOCK_SERVICE_IMPL_CLASS_NAME_PATTERN = "Mock%sImpl"; private static final String SERVICE_CLIENT_CLASS_NAME_PATTERN = "%sClient"; private static final String SERVICE_CLIENT_TEST_CLASS_NAME_PATTERN = "%sClientTest"; + private static final String SERVICE_CLIENT_TRANSPORT_TEST_CLASS_NAME_PATTERN = "%sClient%sTest"; private static final String SERVICE_SETTINGS_CLASS_NAME_PATTERN = "%sSettings"; private static final String SERVICE_STUB_SETTINGS_CLASS_NAME_PATTERN = "%sStubSettings"; private static final String SERVICE_STUB_CLASS_NAME_PATTERN = "%sStub"; @@ -30,10 +34,10 @@ public class ClassNames { private static final String TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN = "%s%sCallableFactory"; - private final String transportPrefix; + private final List transportPrefixes; - public ClassNames(String transportPrefix) { - this.transportPrefix = transportPrefix; + public ClassNames(String... transportPrefixes) { + this.transportPrefixes = Arrays.asList(transportPrefixes); } public static String getServiceClientClassName(Service service) { @@ -59,23 +63,50 @@ public static String getServiceStubClassName(Service service) { } public String getTransportServiceCallableFactoryClassName(Service service) { - return String.format( - TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN, - transportPrefix, - monolithBackwardsCompatibleName(service.name())); + return getTransportServiceCallableFactoryClassNames(service).get(0); + } + + public List getTransportServiceCallableFactoryClassNames(Service service) { + return transportPrefixes.stream() + .map( + prefix -> + String.format( + TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN, + prefix, + monolithBackwardsCompatibleName(service.name()))) + .collect(Collectors.toList()); } public String getTransportServiceStubClassName(Service service) { - return String.format( - TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN, - transportPrefix, - monolithBackwardsCompatibleName(service.name())); + return getTransportServiceStubClassNames(service).get(0); + } + + public List getTransportServiceStubClassNames(Service service) { + return transportPrefixes.stream() + .map( + prefix -> + String.format( + TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN, + prefix, + monolithBackwardsCompatibleName(service.name()))) + .collect(Collectors.toList()); } public static String getServiceClientTestClassName(Service service) { return String.format(SERVICE_CLIENT_TEST_CLASS_NAME_PATTERN, service.overriddenName()); } + public List getServiceClientTestClassNames(Service service) { + return transportPrefixes.stream() + .map( + prefix -> + String.format( + SERVICE_CLIENT_TRANSPORT_TEST_CLASS_NAME_PATTERN, + service.overriddenName(), + prefix)) + .collect(Collectors.toList()); + } + public static String getMockServiceClassName(Service service) { return String.format(MOCK_SERVICE_CLASS_NAME_PATTERN, service.name()); } diff --git a/src/main/java/com/google/api/generator/gapic/model/Field.java b/src/main/java/com/google/api/generator/gapic/model/Field.java index e178e417e6..a5ec9caacb 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Field.java +++ b/src/main/java/com/google/api/generator/gapic/model/Field.java @@ -17,12 +17,19 @@ import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; import java.util.Objects; +import java.util.Optional; import javax.annotation.Nullable; @AutoValue public abstract class Field { + // The field's canonical name, potentially post-processed by conflict resolution logic. public abstract String name(); + // The field's name as it appeared in the protobuf. + // Not equal to name() only when there is a field name conflict, as per protoc's conflict + // resolution behavior. For more context, please see the invocation site of the setter method. + public abstract String originalName(); + public abstract TypeNode type(); public abstract boolean isMessage(); @@ -35,12 +42,18 @@ public abstract class Field { public abstract boolean isContainedInOneof(); + public abstract boolean isProto3Optional(); + @Nullable public abstract ResourceReference resourceReference(); @Nullable public abstract String description(); + public boolean hasFieldNameConflict() { + return !name().equals(originalName()); + } + public boolean hasDescription() { return description() != null; } @@ -57,12 +70,14 @@ public boolean equals(Object o) { Field other = (Field) o; return name().equals(other.name()) + && originalName().equals(other.originalName()) && type().equals(other.type()) && isMessage() == other.isMessage() && isEnum() == other.isEnum() && isRepeated() == other.isRepeated() && isMap() == other.isMap() && isContainedInOneof() == other.isContainedInOneof() + && isProto3Optional() == other.isProto3Optional() && Objects.equals(resourceReference(), other.resourceReference()) && Objects.equals(description(), other.description()); } @@ -70,12 +85,14 @@ && isContainedInOneof() == other.isContainedInOneof() @Override public int hashCode() { return 17 * name().hashCode() + + 31 * originalName().hashCode() + 19 * type().hashCode() + (isMessage() ? 1 : 0) * 23 + (isEnum() ? 1 : 0) * 29 + (isRepeated() ? 1 : 0) * 31 + (isMap() ? 1 : 0) * 37 + (isContainedInOneof() ? 1 : 0) * 41 + + (isProto3Optional() ? 1 : 0) * 43 + (resourceReference() == null ? 0 : resourceReference().hashCode()) + (description() == null ? 0 : description().hashCode()); } @@ -88,13 +105,16 @@ public static Builder builder() { .setIsEnum(false) .setIsRepeated(false) .setIsMap(false) - .setIsContainedInOneof(false); + .setIsContainedInOneof(false) + .setIsProto3Optional(false); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setName(String name); + public abstract Builder setOriginalName(String originalName); + public abstract Builder setType(TypeNode type); public abstract Builder setIsMessage(boolean isMessage); @@ -107,10 +127,24 @@ public abstract static class Builder { public abstract Builder setIsContainedInOneof(boolean isContainedInOneof); + public abstract Builder setIsProto3Optional(boolean isProto3Optional); + public abstract Builder setResourceReference(ResourceReference resourceReference); public abstract Builder setDescription(String description); - public abstract Field build(); + // Private accessors. + abstract String name(); + + abstract Optional originalName(); + + abstract Field autoBuild(); + + public Field build() { + if (!originalName().isPresent()) { + setOriginalName(name()); + } + return autoBuild(); + } } } diff --git a/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java new file mode 100644 index 0000000000..171f6b1bf7 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java @@ -0,0 +1,109 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.model; + +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; +import java.util.Set; + +@AutoValue +public abstract class HttpBindings { + public enum HttpVerb { + GET, + PUT, + POST, + DELETE, + PATCH, + } + + @AutoValue + public abstract static class HttpBinding implements Comparable { + public abstract String name(); + + public abstract boolean isOptional(); + + public static HttpBinding create(String name, boolean isOptional) { + return new AutoValue_HttpBindings_HttpBinding(name, isOptional); + } + + // Do not forget to keep it in sync with equals() implementation. + @Override + public int compareTo(HttpBinding o) { + int res = name().compareTo(o.name()); + return res == 0 ? Boolean.compare(isOptional(), o.isOptional()) : res; + } + } + + public abstract HttpVerb httpVerb(); + + public abstract String pattern(); + + public abstract Set pathParameters(); + + public abstract Set queryParameters(); + + public abstract Set bodyParameters(); + + public abstract boolean isAsteriskBody(); + + public static HttpBindings.Builder builder() { + return new AutoValue_HttpBindings.Builder() + .setPathParameters(ImmutableSet.of()) + .setQueryParameters(ImmutableSet.of()) + .setBodyParameters(ImmutableSet.of()); + } + + // Protobuf fields and template patterns follow snake_case style. When translated into actual Java + // class fields and URL respectively, those must be converted to lowerCamelCase. + // For example: + // in .proto file: "/global/instanceTemplates/{instance_template=*}" + // in .java file: "/global/instanceTemplates/{instanceTemplate=*}" + public String patternLowerCamel() { + String lowerCamelPattern = pattern(); + for (HttpBinding pathParam : pathParameters()) { + lowerCamelPattern = + lowerCamelPattern.replaceAll( + "\\{" + pathParam.name(), "{" + JavaStyle.toLowerCamelCase(pathParam.name())); + } + return lowerCamelPattern; + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract HttpBindings.Builder setHttpVerb(HttpVerb httpVerb); + + public abstract HttpBindings.Builder setPattern(String pattern); + + abstract String pattern(); + + public abstract HttpBindings.Builder setPathParameters(Set pathParameters); + + public abstract HttpBindings.Builder setQueryParameters(Set queryParameters); + + public abstract HttpBindings.Builder setBodyParameters(Set bodyParameters); + + public abstract HttpBindings.Builder setIsAsteriskBody(boolean asteriskBody); + + public abstract HttpBindings autoBuild(); + + public HttpBindings build() { + if ("".equals(pattern())) { + throw new IllegalArgumentException("pattern cannot be empty"); + } + return autoBuild(); + } + } +} diff --git a/src/main/java/com/google/api/generator/gapic/model/Message.java b/src/main/java/com/google/api/generator/gapic/model/Message.java index ad1efa285a..c58e62582e 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Message.java +++ b/src/main/java/com/google/api/generator/gapic/model/Message.java @@ -14,11 +14,13 @@ package com.google.api.generator.gapic.model; +import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -71,7 +73,22 @@ public boolean hasResource() { /** Returns the first list repeated field in a message, unwrapped from its list type. */ @Nullable - public Field findAndUnwrapFirstRepeatedField() { + public Field findAndUnwrapPaginatedRepeatedField() { + for (Field field : fields()) { + if (field.isMap()) { + List repeatedGenericMapRefs = field.type().reference().generics(); + + TypeNode paginatedType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.Entry.class) + .setGenerics( + Arrays.asList(repeatedGenericMapRefs.get(0), repeatedGenericMapRefs.get(1))) + .build()); + + return field.toBuilder().setType(paginatedType).build(); + } + } for (Field field : fields()) { if (field.isRepeated() && !field.isMap()) { Reference repeatedGenericRef = field.type().reference().generics().get(0); @@ -123,11 +140,14 @@ public Builder setEnumValues(List names, List numbers) { public Message build() { Message message = autoBuild(); if (!message.fields().isEmpty()) { - message = - message - .toBuilder() - .setFieldMap(fields().stream().collect(Collectors.toMap(f -> f.name(), f -> f))) - .autoBuild(); + Map fieldMap = + fields().stream().collect(Collectors.toMap(f -> f.name(), f -> f)); + // Handles string occurrences of a field's original name in a protobuf, such as + // in the method signature annotaiton. + fields().stream() + .filter(f -> f.hasFieldNameConflict()) + .forEach(f -> fieldMap.put(f.originalName(), f)); + message = message.toBuilder().setFieldMap(fieldMap).autoBuild(); } return message; } diff --git a/src/main/java/com/google/api/generator/gapic/model/Method.java b/src/main/java/com/google/api/generator/gapic/model/Method.java index df5a9aa668..56a1403098 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Method.java +++ b/src/main/java/com/google/api/generator/gapic/model/Method.java @@ -39,7 +39,12 @@ public enum Stream { public abstract boolean isBatching(); - public abstract boolean isPaged(); + public boolean isPaged() { + return pageSizeFieldName() != null; + } + + @Nullable + public abstract String pageSizeFieldName(); public abstract boolean isDeprecated(); @@ -53,9 +58,9 @@ public enum Stream { @Nullable public abstract String mixedInApiName(); - // TODO(miraleung): May need to change this to MethodArgument, Field, or some new struct // HttpBinding pending dotted reference support. - public abstract List httpBindings(); + @Nullable + public abstract HttpBindings httpBindings(); // Example from Expand in echo.proto: Thet TypeNodes that map to // [["content", "error"], ["content", "error", "info"]]. @@ -70,7 +75,7 @@ public boolean hasDescription() { } public boolean hasHttpBindings() { - return !httpBindings().isEmpty(); + return httpBindings() != null && !httpBindings().pathParameters().isEmpty(); } public boolean isMixin() { @@ -83,9 +88,7 @@ public static Builder builder() { return new AutoValue_Method.Builder() .setStream(Stream.NONE) .setMethodSignatures(ImmutableList.of()) - .setHttpBindings(ImmutableList.of()) .setIsBatching(false) - .setIsPaged(false) .setIsDeprecated(false); } @@ -118,13 +121,13 @@ public abstract static class Builder { public abstract Builder setMixedInApiName(String mixedInApiName); - public abstract Builder setHttpBindings(List httpBindings); + public abstract Builder setHttpBindings(HttpBindings httpBindings); public abstract Builder setMethodSignatures(List> methodSignature); public abstract Builder setIsBatching(boolean isBatching); - public abstract Builder setIsPaged(boolean isPaged); + public abstract Builder setPageSizeFieldName(String pagedFieldName); public abstract Builder setIsDeprecated(boolean isDeprecated); diff --git a/src/main/java/com/google/api/generator/gapic/model/Service.java b/src/main/java/com/google/api/generator/gapic/model/Service.java index f21125fb54..2ce5c09d2e 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Service.java +++ b/src/main/java/com/google/api/generator/gapic/model/Service.java @@ -49,6 +49,15 @@ public boolean hasDescription() { return !Strings.isNullOrEmpty(description()); } + public boolean hasLroMethods() { + for (Method method : methods()) { + if (method.hasLro()) { + return true; + } + } + return false; + } + public abstract Builder toBuilder(); public static Builder builder() { diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java index aeb7b9361c..ae7820c8ed 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Transport.java +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -17,8 +17,6 @@ public enum Transport { REST, GRPC, - // Never used in the context as is, must be split into two contexts (REST and GRPC respectively) - // instead. GRPC_REST; /** diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java index 79a1c9817d..f681399342 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java @@ -20,6 +20,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -69,7 +70,9 @@ static Optional> parse(String gapicYamlConfigFilePat String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } @@ -104,7 +107,7 @@ private static Optional> parseFromMap(Map batchingYamlConfig = diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java index 6836b3002a..e1cad0ef97 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java @@ -19,6 +19,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; @@ -48,7 +49,9 @@ static Optional parse(String gapicYamlConfigFilePath) { String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java index ff0cf7e462..b30e93791b 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java @@ -19,6 +19,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -56,7 +57,9 @@ static Optional> parse(String gapicYamlConfigFilePat String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java index 10c9b1b071..36828206d3 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java @@ -18,16 +18,18 @@ import com.google.api.HttpRule; import com.google.api.HttpRule.PatternCase; import com.google.api.generator.gapic.model.Field; +import com.google.api.generator.gapic.model.HttpBindings; +import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; import com.google.api.generator.gapic.model.Message; import com.google.api.pathtemplate.PathTemplate; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Sets; import com.google.protobuf.DescriptorProtos.MethodOptions; import com.google.protobuf.Descriptors.MethodDescriptor; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -36,11 +38,11 @@ public class HttpRuleParser { private static final String ASTERISK = "*"; - public static Optional> parseHttpBindings( + public static HttpBindings parse( MethodDescriptor protoMethod, Message inputMessage, Map messageTypes) { MethodOptions methodOptions = protoMethod.getOptions(); if (!methodOptions.hasExtension(AnnotationsProto.http)) { - return Optional.empty(); + return null; } HttpRule httpRule = methodOptions.getExtension(AnnotationsProto.http); @@ -53,86 +55,126 @@ public static Optional> parseHttpBindings( return parseHttpRuleHelper(httpRule, Optional.of(inputMessage), messageTypes); } - public static Optional> parseHttpRule(HttpRule httpRule) { + public static HttpBindings parseHttpRule(HttpRule httpRule) { return parseHttpRuleHelper(httpRule, Optional.empty(), Collections.emptyMap()); } - private static Optional> parseHttpRuleHelper( + private static HttpBindings parseHttpRuleHelper( HttpRule httpRule, Optional inputMessageOpt, Map messageTypes) { // Get pattern. - Set uniqueBindings = getHttpVerbPattern(httpRule); - if (uniqueBindings.isEmpty()) { - return Optional.empty(); - } - + String pattern = getHttpVerbPattern(httpRule); + ImmutableSet.Builder bindingsBuilder = getPatternBindings(pattern); if (httpRule.getAdditionalBindingsCount() > 0) { for (HttpRule additionalRule : httpRule.getAdditionalBindingsList()) { - uniqueBindings.addAll(getHttpVerbPattern(additionalRule)); + // TODO: save additional bindings path in HttpRuleBindings + bindingsBuilder.addAll(getPatternBindings(getHttpVerbPattern(additionalRule)).build()); } } - List bindings = new ArrayList<>(uniqueBindings); - Collections.sort(bindings); + Set pathParamNames = bindingsBuilder.build(); + + // TODO: support nested message fields bindings + String body = httpRule.getBody(); + Set bodyParamNames; + Set queryParamNames; + if (!inputMessageOpt.isPresent()) { + // Must be a mixin, do not support full HttpRuleBindings for now + bodyParamNames = ImmutableSet.of(); + queryParamNames = ImmutableSet.of(); + } else if (Strings.isNullOrEmpty(body)) { + bodyParamNames = ImmutableSet.of(); + queryParamNames = Sets.difference(inputMessageOpt.get().fieldMap().keySet(), pathParamNames); + } else if (body.equals(ASTERISK)) { + bodyParamNames = Sets.difference(inputMessageOpt.get().fieldMap().keySet(), pathParamNames); + queryParamNames = ImmutableSet.of(); + } else { + bodyParamNames = ImmutableSet.of(body); + Set bodyBinidngsUnion = Sets.union(bodyParamNames, pathParamNames); + queryParamNames = + Sets.difference(inputMessageOpt.get().fieldMap().keySet(), bodyBinidngsUnion); + } - // Binding validation. - for (String binding : bindings) { - // Handle foo.bar cases by descending into the subfields. - String[] descendantBindings = binding.split("\\."); - Optional containingMessageOpt = inputMessageOpt; - for (int i = 0; i < descendantBindings.length; i++) { - String subField = descendantBindings[i]; - if (!containingMessageOpt.isPresent()) { - continue; - } + Message message = inputMessageOpt.orElse(null); + return HttpBindings.builder() + .setHttpVerb(HttpBindings.HttpVerb.valueOf(httpRule.getPatternCase().toString())) + .setPattern(pattern) + .setPathParameters( + validateAndConstructHttpBindings(pathParamNames, message, messageTypes, true)) + .setQueryParameters( + validateAndConstructHttpBindings(queryParamNames, message, messageTypes, false)) + .setBodyParameters( + validateAndConstructHttpBindings(bodyParamNames, message, messageTypes, false)) + .setIsAsteriskBody(body.equals(ASTERISK)) + .build(); + } - if (i < descendantBindings.length - 1) { - Field field = containingMessageOpt.get().fieldMap().get(subField); - containingMessageOpt = Optional.of(messageTypes.get(field.type().reference().fullName())); + private static Set validateAndConstructHttpBindings( + Set paramNames, + Message inputMessage, + Map messageTypes, + boolean isPath) { + ImmutableSortedSet.Builder httpBindings = ImmutableSortedSet.naturalOrder(); + for (String paramName : paramNames) { + // Handle foo.bar cases by descending into the subfields. + String[] subFields = paramName.split("\\."); + if (inputMessage == null) { + httpBindings.add(HttpBinding.create(paramName, false)); + continue; + } + Message nestedMessage = inputMessage; + for (int i = 0; i < subFields.length; i++) { + String subFieldName = subFields[i]; + if (i < subFields.length - 1) { + Field field = nestedMessage.fieldMap().get(subFieldName); + nestedMessage = messageTypes.get(field.type().reference().fullName()); Preconditions.checkNotNull( - containingMessageOpt.get(), + nestedMessage, String.format( "No containing message found for field %s with type %s", field.name(), field.type().reference().simpleName())); + } else { - checkHttpFieldIsValid(subField, containingMessageOpt.get(), false); + if (isPath) { + checkHttpFieldIsValid(subFieldName, nestedMessage, !isPath); + } + Field field = nestedMessage.fieldMap().get(subFieldName); + httpBindings.add(HttpBinding.create(paramName, field.isProto3Optional())); } } } - - return Optional.of(bindings); + return httpBindings.build(); } - private static Set getHttpVerbPattern(HttpRule httpRule) { - String pattern = null; - // Assign a temp variable to prevent the formatter from removing the import. + private static String getHttpVerbPattern(HttpRule httpRule) { PatternCase patternCase = httpRule.getPatternCase(); switch (patternCase) { case GET: - pattern = httpRule.getGet(); - break; + return httpRule.getGet(); case PUT: - pattern = httpRule.getPut(); - break; + return httpRule.getPut(); case POST: - pattern = httpRule.getPost(); - break; + return httpRule.getPost(); case DELETE: - pattern = httpRule.getDelete(); - break; + return httpRule.getDelete(); case PATCH: - pattern = httpRule.getPatch(); - break; + return httpRule.getPatch(); case CUSTOM: // Invalid pattern. // Fall through. default: - return Collections.emptySet(); + return ""; + } + } + + private static ImmutableSortedSet.Builder getPatternBindings(String pattern) { + ImmutableSortedSet.Builder bindings = ImmutableSortedSet.naturalOrder(); + if (pattern.isEmpty()) { + return bindings; } PathTemplate template = PathTemplate.create(pattern); - Set bindings = - new HashSet( - // Filter out any unbound variable like "$0, $1, etc. - template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toList())); + // Filter out any unbound variable like "$0, $1, etc. + bindings.addAll( + template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toSet())); return bindings; } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java index 4d7259790a..9ca9825def 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java @@ -284,15 +284,4 @@ private static Map parseTypeFromArgumentName( argumentFieldPathAcc, outputArgResourceNames); } - - private static Map createPatternResourceNameMap( - Map resourceNames) { - Map patternsToResourceNames = new HashMap<>(); - for (ResourceName resourceName : resourceNames.values()) { - for (String pattern : resourceName.patterns()) { - patternsToResourceNames.put(pattern, resourceName); - } - } - return patternsToResourceNames; - } } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index a088e8ae46..8fd376b7e0 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -26,6 +26,7 @@ import com.google.api.generator.gapic.model.GapicLanguageSettings; import com.google.api.generator.gapic.model.GapicLroRetrySettings; import com.google.api.generator.gapic.model.GapicServiceConfig; +import com.google.api.generator.gapic.model.HttpBindings; import com.google.api.generator.gapic.model.LongrunningOperation; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; @@ -87,6 +88,9 @@ public class Parser { "google.iam.v1.IAMPolicy", "google.longrunning.Operations", "google.cloud.location.Locations"); + // These must be kept in sync with the above protos' java_package options. + private static final Set MIXIN_JAVA_PACKAGE_ALLOWLIST = + ImmutableSet.of("com.google.iam.v1", "com.google.longrunning", "com.google.cloud.location"); // Allow other parsers to access this. protected static final SourceCodeInfoParser SOURCE_CODE_INFO_PARSER = new SourceCodeInfoParser(); @@ -106,12 +110,13 @@ public static GapicContext parse(CodeGeneratorRequest request) { GapicLroRetrySettingsParser.parse(gapicYamlConfigPathOpt); Optional languageSettingsOpt = GapicLanguageSettingsParser.parse(gapicYamlConfigPathOpt); + Optional transportOpt = PluginArgumentParser.parseTransport(request); boolean willGenerateMetadata = PluginArgumentParser.hasMetadataFlag(request); Optional serviceConfigPathOpt = PluginArgumentParser.parseJsonConfigPath(request); - String serviceConfigPath = serviceConfigPathOpt.isPresent() ? serviceConfigPathOpt.get() : null; - Optional serviceConfigOpt = ServiceConfigParser.parse(serviceConfigPath); + Optional serviceConfigOpt = + ServiceConfigParser.parse(serviceConfigPathOpt.orElse(null)); if (serviceConfigOpt.isPresent()) { GapicServiceConfig serviceConfig = serviceConfigOpt.get(); serviceConfig.setLroRetrySettings(lroRetrySettingsOpt); @@ -123,9 +128,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { Optional serviceYamlConfigPathOpt = PluginArgumentParser.parseServiceYamlConfigPath(request); Optional serviceYamlProtoOpt = - serviceYamlConfigPathOpt.isPresent() - ? ServiceYamlParser.parse(serviceYamlConfigPathOpt.get()) - : Optional.empty(); + serviceYamlConfigPathOpt.flatMap(ServiceYamlParser::parse); // Collect the resource references seen in messages. Set outputResourceReferencesSeen = new HashSet<>(); @@ -137,8 +140,15 @@ public static GapicContext parse(CodeGeneratorRequest request) { Map resourceNames = parseResourceNames(request); messages = updateResourceNamesInMessages(messages, resourceNames.values()); + // Contains only resource names that are actually used. Usage refers to the presence of a + // request message's field in an RPC's method_signature annotation. That is, resource name + // definitions + // or references that are simply defined, but not used in such a manner, will not have + // corresponding Java helper + // classes generated. Set outputArgResourceNames = new HashSet<>(); List mixinServices = new ArrayList<>(); + Transport transport = Transport.parse(transportOpt.orElse(Transport.GRPC.toString())); List services = parseServices( request, @@ -147,34 +157,41 @@ public static GapicContext parse(CodeGeneratorRequest request) { outputArgResourceNames, serviceYamlProtoOpt, serviceConfigOpt, - mixinServices); + mixinServices, + transport); Preconditions.checkState(!services.isEmpty(), "No services found to generate"); - Function typeNameFn = - r -> r.resourceTypeString().substring(r.resourceTypeString().indexOf("/") + 1); - Function, Set> typeStringSetFn = - sr -> sr.stream().map(r -> typeNameFn.apply(r)).collect(Collectors.toSet()); - - // Include all resource names present in message types for backwards-compatibility with the - // monolith. In the future, this should be removed on a client library major semver update. - // Resolve type name collisions with the ones present in the method arguments. - final Set typeStringSet = typeStringSetFn.apply(outputArgResourceNames); - outputArgResourceNames.addAll( - resourceNames.values().stream() - .filter(r -> r.hasParentMessageName() && !typeStringSet.contains(typeNameFn.apply(r))) - .collect(Collectors.toSet())); - - String servicePackage = services.get(0).pakkage(); - Map patternsToResourceNames = - ResourceParserHelpers.createPatternResourceNameMap(resourceNames); - for (ResourceReference resourceReference : outputResourceReferencesSeen) { - final Set interimTypeStringSet = typeStringSetFn.apply(outputArgResourceNames); + + // TODO(vam-google): Figure out whether we should keep this allowlist or bring + // back the unused resource names for all APIs. + // Temporary workaround for Ads, who still need these resource names. + if (services.get(0).protoPakkage().startsWith("google.ads.googleads.v")) { + Function typeNameFn = + r -> r.resourceTypeString().substring(r.resourceTypeString().indexOf("/") + 1); + Function, Set> typeStringSetFn = + sr -> sr.stream().map(typeNameFn).collect(Collectors.toSet()); + + // Include all resource names present in message types for backwards-compatibility with the + // monolith. In the future, this should be removed on a client library major semver update. + // Resolve type name collisions with the ones present in the method arguments. + final Set typeStringSet = typeStringSetFn.apply(outputArgResourceNames); outputArgResourceNames.addAll( - ResourceReferenceParser.parseResourceNames( - resourceReference, servicePackage, null, resourceNames, patternsToResourceNames) - .stream() - .filter(r -> !interimTypeStringSet.contains(typeNameFn.apply(r))) + resourceNames.values().stream() + .filter(r -> r.hasParentMessageName() && !typeStringSet.contains(typeNameFn.apply(r))) .collect(Collectors.toSet())); + + String servicePackage = services.get(0).pakkage(); + Map patternsToResourceNames = + ResourceParserHelpers.createPatternResourceNameMap(resourceNames); + for (ResourceReference resourceReference : outputResourceReferencesSeen) { + final Set interimTypeStringSet = typeStringSetFn.apply(outputArgResourceNames); + outputArgResourceNames.addAll( + ResourceReferenceParser.parseResourceNames( + resourceReference, servicePackage, null, resourceNames, patternsToResourceNames) + .stream() + .filter(r -> !interimTypeStringSet.contains(typeNameFn.apply(r))) + .collect(Collectors.toSet())); + } } return GapicContext.builder() @@ -183,10 +200,10 @@ public static GapicContext parse(CodeGeneratorRequest request) { .setMessages(messages) .setResourceNames(resourceNames) .setHelperResourceNames(outputArgResourceNames) - .setServiceConfig(serviceConfigOpt.isPresent() ? serviceConfigOpt.get() : null) + .setServiceConfig(serviceConfigOpt.orElse(null)) .setGapicMetadataEnabled(willGenerateMetadata) - .setServiceYamlProto(serviceYamlProtoOpt.isPresent() ? serviceYamlProtoOpt.get() : null) - .setTransport(Transport.GRPC) + .setServiceYamlProto(serviceYamlProtoOpt.orElse(null)) + .setTransport(transport) .build(); } @@ -197,7 +214,8 @@ public static List parseServices( Set outputArgResourceNames, Optional serviceYamlProtoOpt, Optional serviceConfigOpt, - List outputMixinServices) { + List outputMixinServices, + Transport transport) { Map fileDescriptors = getFilesToGenerate(request); List services = new ArrayList<>(); @@ -215,7 +233,8 @@ public static List parseServices( resourceNames, serviceYamlProtoOpt, serviceConfigOpt, - outputArgResourceNames)); + outputArgResourceNames, + transport)); } // Prevent codegen for mixed-in services if there are other services present, since that is an @@ -247,18 +266,18 @@ public static List parseServices( // Key: proto_package.ServiceName.RpcName. // Value: HTTP rules, which clobber those in the proto. // Assumes that http.rules.selector always specifies RPC names in the above format. - Map> mixedInMethodsToHttpRules = new HashMap<>(); + Map mixedInMethodsToHttpRules = new HashMap<>(); Map mixedInMethodsToDocs = new HashMap<>(); // Parse HTTP rules and documentation, which will override the proto. if (serviceYamlProtoOpt.isPresent()) { for (HttpRule httpRule : serviceYamlProtoOpt.get().getHttp().getRulesList()) { - Optional> httpBindingsOpt = HttpRuleParser.parseHttpRule(httpRule); - if (!httpBindingsOpt.isPresent()) { + HttpBindings httpBindings = HttpRuleParser.parseHttpRule(httpRule); + if (httpBindings == null) { continue; } for (String rpcFullNameRaw : httpRule.getSelector().split(",")) { String rpcFullName = rpcFullNameRaw.trim(); - mixedInMethodsToHttpRules.put(rpcFullName, httpBindingsOpt.get()); + mixedInMethodsToHttpRules.put(rpcFullName, httpBindings); } } for (DocumentationRule docRule : @@ -270,9 +289,15 @@ public static List parseServices( } } + // Sort potential mixin services alphabetically. + List orderedBlockedCodegenMixinApis = + blockedCodegenMixinApis.stream() + .sorted((s1, s2) -> s2.name().compareTo(s1.name())) + .collect(Collectors.toList()); + Set apiDefinedRpcs = new HashSet<>(); for (Service service : services) { - if (blockedCodegenMixinApis.contains(service)) { + if (orderedBlockedCodegenMixinApis.contains(service)) { continue; } apiDefinedRpcs.addAll( @@ -285,7 +310,7 @@ public static List parseServices( Service originalService = services.get(i); List updatedOriginalServiceMethods = new ArrayList<>(originalService.methods()); // If mixin APIs are present, add the methods to all other services. - for (Service mixinService : blockedCodegenMixinApis) { + for (Service mixinService : orderedBlockedCodegenMixinApis) { final String mixinServiceFullName = serviceFullNameFn.apply(mixinService); if (!mixedInApis.contains(mixinServiceFullName)) { continue; @@ -304,7 +329,7 @@ public static List parseServices( // HTTP rules and RPC documentation in the service.yaml file take // precedence. String fullMethodName = methodToFullProtoNameFn.apply(m); - List httpBindings = + HttpBindings httpBindings = mixedInMethodsToHttpRules.containsKey(fullMethodName) ? mixedInMethodsToHttpRules.get(fullMethodName) : m.httpBindings(); @@ -327,6 +352,11 @@ public static List parseServices( m.toBuilder() .setMixedInApiName(serviceFullNameFn.apply(mixinService)) .build())); + // Sort by method name, to ensure a deterministic method ordering (for tests). + updatedMixinMethods = + updatedMixinMethods.stream() + .sorted((m1, m2) -> m2.name().compareTo(m1.name())) + .collect(Collectors.toList()); outputMixinServiceSet.add( mixinService.toBuilder().setMethods(updatedMixinMethods).build()); } @@ -343,7 +373,10 @@ public static List parseServices( } // Use a list to ensure ordering for deterministic tests. - outputMixinServices.addAll(outputMixinServiceSet); + outputMixinServices.addAll( + outputMixinServiceSet.stream() + .sorted((s1, s2) -> s2.name().compareTo(s1.name())) + .collect(Collectors.toList())); return services; } @@ -360,7 +393,8 @@ public static List parseService( resourceNames, serviceYamlProtoOpt, Optional.empty(), - outputArgResourceNames); + outputArgResourceNames, + Transport.GRPC); } public static List parseService( @@ -369,7 +403,8 @@ public static List parseService( Map resourceNames, Optional serviceYamlProtoOpt, Optional serviceConfigOpt, - Set outputArgResourceNames) { + Set outputArgResourceNames, + Transport transport) { return fileDescriptor.getServices().stream() .map( @@ -443,7 +478,8 @@ public static List parseService( messageTypes, resourceNames, serviceConfigOpt, - outputArgResourceNames)) + outputArgResourceNames, + transport)) .build(); }) .collect(Collectors.toList()); @@ -495,7 +531,7 @@ public static Map parseMessages( private static Map parseMessages( Descriptor messageDescriptor, Set outputResourceReferencesSeen) { - return parseMessages(messageDescriptor, outputResourceReferencesSeen, new ArrayList()); + return parseMessages(messageDescriptor, outputResourceReferencesSeen, new ArrayList<>()); } private static Map parseMessages( @@ -542,7 +578,7 @@ private static boolean isMapType(Descriptor messageDescriptor) { * Populates ResourceName objects in Message POJOs. * * @param messageTypes A map of the message type name (as in the protobuf) to Message POJOs. - * @param resourceNames A list of ResourceName POJOs. + * @param resources A list of ResourceName POJOs. * @return The updated messageTypes map. */ public static Map updateResourceNamesInMessages( @@ -560,7 +596,7 @@ public static Map updateResourceNamesInMessages( } public static Map parseResourceNames(CodeGeneratorRequest request) { - @VisibleForTesting String javaPackage = parseServiceJavaPackage(request); + String javaPackage = parseServiceJavaPackage(request); Map fileDescriptors = getFilesToGenerate(request); Map resourceNames = new HashMap<>(); for (String fileToGenerate : request.getFileToGenerateList()) { @@ -591,7 +627,8 @@ static List parseMethods( Map messageTypes, Map resourceNames, Optional serviceConfigOpt, - Set outputArgResourceNames) { + Set outputArgResourceNames, + Transport transport) { List methods = new ArrayList<>(); for (MethodDescriptor protoMethod : serviceDescriptor.getMethods()) { // Parse the method. @@ -614,10 +651,7 @@ static List parseMethods( Message inputMessage = messageTypes.get(inputType.reference().fullName()); Preconditions.checkNotNull( inputMessage, String.format("No message found for %s", inputType.reference().fullName())); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(protoMethod, inputMessage, messageTypes); - List httpBindings = - httpBindingsOpt.isPresent() ? httpBindingsOpt.get() : Collections.emptyList(); + HttpBindings httpBindings = HttpRuleParser.parse(protoMethod, inputMessage, messageTypes); boolean isBatching = !serviceConfigOpt.isPresent() ? false @@ -646,7 +680,7 @@ static List parseMethods( outputArgResourceNames)) .setHttpBindings(httpBindings) .setIsBatching(isBatching) - .setIsPaged(parseIsPaged(protoMethod, messageTypes)) + .setPageSizeFieldName(parsePageSizeFieldName(protoMethod, messageTypes, transport)) .setIsDeprecated(isDeprecated) .build()); @@ -761,8 +795,8 @@ static LongrunningOperation parseLro( } @VisibleForTesting - static boolean parseIsPaged( - MethodDescriptor methodDescriptor, Map messageTypes) { + static String parsePageSizeFieldName( + MethodDescriptor methodDescriptor, Map messageTypes, Transport transport) { TypeNode inputMessageType = TypeParser.parseType(methodDescriptor.getInputType()); TypeNode outputMessageType = TypeParser.parseType(methodDescriptor.getOutputType()); Message inputMessage = messageTypes.get(inputMessageType.reference().fullName()); @@ -771,14 +805,29 @@ static boolean parseIsPaged( // This should technically handle the absence of either of these fields (aip.dev/158), but we // gate on their collective presence to ensure the generated surface is backawrds-compatible // with monolith-gnerated libraries. - return inputMessage.fieldMap().containsKey("page_size") - && inputMessage.fieldMap().containsKey("page_token") - && outputMessage.fieldMap().containsKey("next_page_token"); + String pagedFieldName = null; + + if (inputMessage.fieldMap().containsKey("page_token") + && outputMessage.fieldMap().containsKey("next_page_token")) { + // List of potential field names representing page size. + // page_size gets priority over max_results if both are present + List fieldNames = new ArrayList<>(); + fieldNames.add("page_size"); + if (transport == Transport.REST) { + fieldNames.add("max_results"); + } + for (String fieldName : fieldNames) { + if (pagedFieldName == null && inputMessage.fieldMap().containsKey(fieldName)) { + pagedFieldName = fieldName; + } + } + } + return pagedFieldName; } @VisibleForTesting static String sanitizeDefaultHost(String rawDefaultHost) { - if (rawDefaultHost.indexOf(COLON) >= 0) { + if (rawDefaultHost.contains(COLON)) { // A port is already present, just return the existing string. return rawDefaultHost; } @@ -791,14 +840,47 @@ private static List parseFields( // Sort by ascending field index order. This is important for paged responses, where the first // repeated type is taken. fields.sort((f1, f2) -> f1.getIndex() - f2.getIndex()); + + // Mirror protoc's name conflict resolution behavior for fields. + // If a singular field's name equals that of a repeated field with "Count" or "List" suffixed, + // append the protobuf's field number to both fields' names. + // See: + // https://github.com/protocolbuffers/protobuf/blob/9df42757f97da9f748a464deeda96427a8f7ade0/src/google/protobuf/compiler/java/java_context.cc#L60 + Map repeatedFieldNamesToNumber = + fields.stream() + .filter(f -> f.isRepeated()) + .collect(Collectors.toMap(f -> f.getName(), f -> f.getNumber())); + Set fieldNumbersWithConflicts = new HashSet<>(); + for (FieldDescriptor field : fields) { + Set conflictingRepeatedFieldNames = + repeatedFieldNamesToNumber.keySet().stream() + .filter( + n -> field.getName().equals(n + "_count") || field.getName().equals(n + "_list")) + .collect(Collectors.toSet()); + if (!conflictingRepeatedFieldNames.isEmpty()) { + fieldNumbersWithConflicts.addAll( + conflictingRepeatedFieldNames.stream() + .map(n -> repeatedFieldNamesToNumber.get(n)) + .collect(Collectors.toSet())); + fieldNumbersWithConflicts.add(field.getNumber()); + } + } + return fields.stream() - .map(f -> parseField(f, messageDescriptor, outputResourceReferencesSeen)) + .map( + f -> + parseField( + f, + messageDescriptor, + fieldNumbersWithConflicts.contains(f.getNumber()), + outputResourceReferencesSeen)) .collect(Collectors.toList()); } private static Field parseField( FieldDescriptor fieldDescriptor, Descriptor messageDescriptor, + boolean hasFieldNameConflict, Set outputResourceReferencesSeen) { FieldOptions fieldOptions = fieldDescriptor.getOptions(); MessageOptions messageOptions = messageDescriptor.getOptions(); @@ -843,12 +925,25 @@ private static Field parseField( } } + // Mirror protoc's name conflict resolution behavior for fields. + // For more context, trace hasFieldNameConflict back to where it gets passed in above. + String actualFieldName = + hasFieldNameConflict + ? fieldDescriptor.getName() + fieldDescriptor.getNumber() + : fieldDescriptor.getName(); + return fieldBuilder - .setName(fieldDescriptor.getName()) + .setName(actualFieldName) + .setOriginalName(fieldDescriptor.getName()) .setType(TypeParser.parseType(fieldDescriptor)) .setIsMessage(fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) .setIsEnum(fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) - .setIsContainedInOneof(fieldDescriptor.getContainingOneof() != null) + .setIsContainedInOneof( + fieldDescriptor.getContainingOneof() != null + && !fieldDescriptor.getContainingOneof().isSynthetic()) + .setIsProto3Optional( + fieldDescriptor.getContainingOneof() != null + && fieldDescriptor.getContainingOneof().isSynthetic()) .setIsRepeated(fieldDescriptor.isRepeated()) .setIsMap(fieldDescriptor.isMapField()) .setResourceReference(resourceReference) @@ -903,8 +998,23 @@ private static String parseServiceJavaPackage(CodeGeneratorRequest request) { } } + // Filter out mixin packages. + Map processedJavaPackageCount = + javaPackageCount.entrySet().stream() + .filter(e -> !MIXIN_JAVA_PACKAGE_ALLOWLIST.contains(e.getKey())) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + + // An empty map indicates that only mixin packages were present, which means that we're + // generating a standalone client for a mixin. + if (processedJavaPackageCount.isEmpty()) { + processedJavaPackageCount = javaPackageCount; + } + String finalJavaPackage = - javaPackageCount.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey(); + processedJavaPackageCount.entrySet().stream() + .max(Map.Entry.comparingByValue()) + .get() + .getKey(); Preconditions.checkState( !Strings.isNullOrEmpty(finalJavaPackage), "No service Java package found"); return finalJavaPackage; diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java index 53cd0f32f3..d5a7de1f79 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java @@ -30,6 +30,7 @@ public class PluginArgumentParser { @VisibleForTesting static final String KEY_GAPIC_CONFIG = "gapic-config"; @VisibleForTesting static final String KEY_METADATA = "metadata"; @VisibleForTesting static final String KEY_SERVICE_YAML_CONFIG = "api-service-config"; + @VisibleForTesting static final String KEY_TRANSPORT = "transport"; private static final String JSON_FILE_ENDING = "grpc_service_config.json"; private static final String GAPIC_YAML_FILE_ENDING = "gapic.yaml"; @@ -47,6 +48,10 @@ static Optional parseServiceYamlConfigPath(CodeGeneratorRequest request) return parseServiceYamlConfigPath(request.getParameter()); } + static Optional parseTransport(CodeGeneratorRequest request) { + return parseConfigArgument(request.getParameter(), KEY_TRANSPORT); + } + static boolean hasMetadataFlag(CodeGeneratorRequest request) { return hasMetadataFlag(request.getParameter()); } @@ -54,17 +59,33 @@ static boolean hasMetadataFlag(CodeGeneratorRequest request) { /** Expects a comma-separated list of file paths. */ @VisibleForTesting static Optional parseJsonConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); + return parseFileArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); } @VisibleForTesting static Optional parseGapicYamlConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); + return parseFileArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); } @VisibleForTesting static Optional parseServiceYamlConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); + return parseFileArgument( + pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); + } + + @VisibleForTesting + private static Optional parseConfigArgument(String pluginProtocArgument, String key) { + if (Strings.isNullOrEmpty(pluginProtocArgument)) { + return Optional.empty(); + } + + for (String argComponent : pluginProtocArgument.split(COMMA)) { + String[] args = argComponent.trim().split(EQUALS); + if (args.length == 2 && key.equals(args[0])) { + return Optional.of(args[1]); + } + } + return Optional.empty(); } @VisibleForTesting @@ -72,10 +93,10 @@ static boolean hasMetadataFlag(String pluginProtocArgument) { return Arrays.stream(pluginProtocArgument.split(COMMA)).anyMatch(s -> s.equals(KEY_METADATA)); } - private static Optional parseArgument( + private static Optional parseFileArgument( String pluginProtocArgument, String key, String fileEnding) { if (Strings.isNullOrEmpty(pluginProtocArgument)) { - return Optional.empty(); + return Optional.empty(); } for (String argComponent : pluginProtocArgument.split(COMMA)) { String[] args = argComponent.trim().split(EQUALS); @@ -93,6 +114,6 @@ private static Optional parseArgument( return Optional.of(valueVal); } } - return Optional.empty(); + return Optional.empty(); } } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java index 839903d460..5b136b897f 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java @@ -21,6 +21,7 @@ import com.google.protobuf.util.JsonFormat; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.LinkedHashMap; @@ -37,7 +38,8 @@ public static Optional parse(String serviceYamlFilePath) String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(serviceYamlFilePath))); + fileContents = + new String(Files.readAllBytes(Paths.get(serviceYamlFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java index 7a4542ee25..49b17d25db 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java @@ -37,8 +37,6 @@ import javax.annotation.Nonnull; public class TypeParser { - private static final String DOT = "."; - private static Reference REFERENCE_BYTE_STRING = ConcreteReference.withClazz(ByteString.class); private static TypeNode TYPE_NODE_BYTE_STRING = TypeNode.withReference(REFERENCE_BYTE_STRING); @@ -245,8 +243,6 @@ static Reference parseEnumReference(@Nonnull EnumDescriptor enumDescriptor) { @VisibleForTesting static TypeNode createListType(FieldDescriptor field) { - JavaType protoFieldType = field.getJavaType(); - Reference listReference = ConcreteReference.builder() .setClazz(List.class) @@ -259,7 +255,6 @@ static TypeNode createListType(FieldDescriptor field) { static TypeNode createMapType(FieldDescriptor field) { Preconditions.checkState( field.isMapField(), "createMapType can only be called on map-type fields"); - JavaType protoJavaType = field.getJavaType(); Descriptor type = field.getMessageType(); FieldDescriptor keyField = type.findFieldByName("key"); diff --git a/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java b/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java index 0113776cee..634174acca 100644 --- a/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java +++ b/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java @@ -24,6 +24,7 @@ import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; import com.google.protobuf.util.JsonFormat; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; @@ -61,7 +62,7 @@ public static CodeGeneratorResponse write( JarEntry jarEntry = new JarEntry(String.format("%s/%s.java", path, className)); try { jos.putNextEntry(jarEntry); - jos.write(code.getBytes()); + jos.write(code.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException( String.format( @@ -80,7 +81,7 @@ public static CodeGeneratorResponse write( JarEntry jarEntry = new JarEntry(String.format("%s/package-info.java", path)); try { jos.putNextEntry(jarEntry); - jos.write(code.getBytes()); + jos.write(code.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException("Could not write code for package-info.java"); } @@ -90,7 +91,8 @@ public static CodeGeneratorResponse write( jarEntry = new JarEntry(String.format("%s/gapic_metadata.json", path)); try { jos.putNextEntry(jarEntry); - jos.write(JsonFormat.printer().print(context.gapicMetadata()).getBytes()); + jos.write( + JsonFormat.printer().print(context.gapicMetadata()).getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException("Could not write gapic_metadata.json"); } diff --git a/src/main/java/com/google/api/generator/util/Trie.java b/src/main/java/com/google/api/generator/util/Trie.java index 51a26180bc..4134b3f543 100644 --- a/src/main/java/com/google/api/generator/util/Trie.java +++ b/src/main/java/com/google/api/generator/util/Trie.java @@ -24,17 +24,17 @@ * A common-prefix trie. T represents the type of each "char" in a word (which is a T-typed list). */ public class Trie { - private class Node { - final T chr; + private class Node { + final U chr; // Maintain insertion order to enable deterministic test output. - Map> children = new LinkedHashMap<>(); + Map> children = new LinkedHashMap<>(); boolean isLeaf; Node() { chr = null; } - Node(T chr) { + Node(U chr) { this.chr = chr; } } @@ -42,18 +42,18 @@ private class Node { private Node root; public Trie() { - root = new Node(); + root = new Node<>(); } public void insert(List word) { Map> children = root.children; for (int i = 0; i < word.size(); i++) { T chr = word.get(i); - Node t; + Node t; if (children.containsKey(chr)) { t = children.get(chr); } else { - t = new Node(chr); + t = new Node<>(chr); children.put(chr, t); } children = t.children; @@ -65,7 +65,7 @@ public void insert(List word) { /** Returns true if the word is in the trie. */ public boolean search(List word) { - Node node = searchNode(word); + Node node = searchNode(word); return node != null && node.isLeaf; } @@ -119,11 +119,10 @@ private R dfsTraverseAndReduce( return parentPostprocFn.apply(node.chr, baseValue, leafReducedValue); } - private Node searchNode(List word) { + private Node searchNode(List word) { Map> children = root.children; - Node t = null; - for (int i = 0; i < word.size(); i++) { - T chr = word.get(i); + Node t = null; + for (T chr : word) { if (children.containsKey(chr)) { t = children.get(chr); children = t.children; diff --git a/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java b/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java index 8ed58c13cb..607ccd89f6 100644 --- a/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java +++ b/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java @@ -297,7 +297,7 @@ private VariableExpr createVarPublicDeclExpr(Variable var) { .build(); } - private NewObjectExpr createNewObjectExpr(Class clazz) { + private NewObjectExpr createNewObjectExpr(Class clazz) { return NewObjectExpr.builder() .setType(TypeNode.withReference(ConcreteReference.withClazz(clazz))) .setIsGeneric(true) @@ -460,11 +460,8 @@ private MethodDefinition createOverrideCreateBookMethod( } private MethodDefinition createAddShelfMethod() { - ConcreteReference integerUtilRef = - ConcreteReference.builder().setClazz(Integer.class).setIsStaticImport(true).build(); Variable nameVar = createVarFromType(TypeNode.STRING, "name"); Variable seriesDoubleNumVar = createVarFromType(TypeNode.DOUBLE, "seriesDoubleNum"); - Variable maxValueVar = createVarFromConcreteRef(integerUtilRef, "MAX_VALUE"); CastExpr seriesNumDoubleToIntExpr = CastExpr.builder() .setExpr(VariableExpr.withVariable(seriesDoubleNumVar)) @@ -606,8 +603,8 @@ private MethodDefinition createPrintShelfListToFile() { loopShelfList, ExprStatement.withExpr(writeToFileWriter), ExprStatement.withExpr(closeFileWriter))) - .setCatchVariableExpr(createVarDeclExpr(ioException)) - .setCatchBody(Arrays.asList(ExprStatement.withExpr(printError))) + .addCatch( + createVarDeclExpr(ioException), Arrays.asList(ExprStatement.withExpr(printError))) .build(); return MethodDefinition.builder() diff --git a/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java b/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java index b53fa9e77b..9fab46d98d 100644 --- a/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.common.base.Function; import java.util.Arrays; @@ -103,10 +103,7 @@ public void validAnonymousClass_genericAndVariableExpr() { public void invalidAnonymousClass_primitiveType() { assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(TypeNode.INT).build(); - }); + () -> AnonymousClassExpr.builder().setType(TypeNode.INT).build()); } @Test @@ -126,10 +123,7 @@ public void invalidAnonymousClass_staticMethod() { assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build(); - }); + () -> AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build()); } @Test @@ -145,10 +139,7 @@ public void invalidAnonymousClass_explicitConstructor() { .build(); assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build(); - }); + () -> AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build()); } @Test @@ -162,13 +153,11 @@ public void invalidAnonymousClass_staticVariableExpr() { ExprStatement exprStatement = ExprStatement.withExpr(variableExpr); assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder() - .setType(type) - .setStatements(Arrays.asList(exprStatement)) - .build(); - }); + () -> + AnonymousClassExpr.builder() + .setType(type) + .setStatements(Arrays.asList(exprStatement)) + .build()); } private static AssignmentExpr createAssignmentExpr( diff --git a/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java b/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java index f39bff072a..04bb8a05ca 100644 --- a/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java @@ -32,8 +32,6 @@ public void validCastExpr_basic() { @Test public void validCastExpr_basicNull() { - Variable variable = Variable.builder().setName("x").setType(TypeNode.STRING).build(); - VariableExpr variableExpr = VariableExpr.builder().setVariable(variable).build(); CastExpr.builder() .setType(TypeNode.withReference(ConcreteReference.withClazz(Object.class))) .setExpr(ValueExpr.createNullExpr()) diff --git a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java index d45c9bdc37..6fdc65a937 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java b/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java index 7eb401637f..569eebb3c0 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java @@ -49,14 +49,12 @@ public void invalidForStatement() { MethodInvocationExpr.builder().setMethodName("getSomeStrings").build(); assertThrows( IllegalStateException.class, - () -> { - ForStatement forStatement = - ForStatement.builder() - .setLocalVariableExpr(variableExpr) - .setCollectionExpr(methodExpr) - .setBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .build(); - }); + () -> + ForStatement.builder() + .setLocalVariableExpr(variableExpr) + .setCollectionExpr(methodExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .build()); } private static AssignmentExpr createAssignmentExpr() { diff --git a/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java b/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java index b4a7453337..ead7d8be37 100644 --- a/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.IdentifierNode.InvalidIdentifierException; diff --git a/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java b/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java index 8e969a4f45..0d3550971d 100644 --- a/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.testutils.LineFormatter; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java b/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java index 1bc2c48cd6..2287a75394 100644 --- a/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java b/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java index 22e3434ea3..fa9dfa2669 100644 --- a/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java index 9c2f034d4c..37c3ae9cc4 100644 --- a/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.TypeNode.TypeKind; diff --git a/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java index 4fb0dca02d..b4e4b43496 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.util.Arrays; import java.util.HashMap; diff --git a/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java b/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java index 48202e8552..cc4b38f3df 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java @@ -14,6 +14,7 @@ package com.google.api.generator.engine.ast; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import org.junit.Test; @@ -24,7 +25,24 @@ public void createThrowExpr_basic() { TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); ThrowExpr.builder().setType(npeType).build(); // No exception thrown, we're good. + } + @Test + public void createThrowExpr_basicExpr() { + TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); + VariableExpr throwVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("e") + .setType(TypeNode.withExceptionClazz(RuntimeException.class)) + .build()) + .build(); + ThrowExpr throwExpr = ThrowExpr.builder().setThrowExpr(throwVarExpr).build(); + assertEquals(throwVarExpr.variable().type(), throwExpr.type()); + // Setting the type doesn't matter. + throwExpr = ThrowExpr.builder().setThrowExpr(throwVarExpr).setType(npeType).build(); + assertEquals(throwVarExpr.variable().type(), throwExpr.type()); } @Test @@ -62,4 +80,136 @@ public void createThrowExpr_badMessageExpr() { IllegalStateException.class, () -> ThrowExpr.builder().setType(npeType).setMessageExpr(messageExpr).build()); } + + @Test + public void createThrowExpr_causeExpr() { + TypeNode npeType = + TypeNode.withReference(ConcreteReference.withClazz(NullPointerException.class)); + ThrowExpr.builder() + .setType(npeType) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build()) + .build(); + // Successfully created a ThrowExpr. + } + + @Test + public void createThrowExpr_causeExpr_throwableSubtype() { + TypeNode npeType = + TypeNode.withReference(ConcreteReference.withClazz(NullPointerException.class)); + ThrowExpr.builder() + .setType(npeType) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withExceptionClazz(IllegalStateException.class)) + .build()) + .build(); + // Successfully created a ThrowExpr. + } + + @Test + public void createThrowExpr_causeExpr_onThrowableSubtype() { + TypeNode npeType = + TypeNode.withReference(ConcreteReference.withClazz(NullPointerException.class)); + assertThrows( + IllegalStateException.class, + () -> + ThrowExpr.builder() + .setType(npeType) + .setCauseExpr(NewObjectExpr.builder().setType(TypeNode.STRING).build()) + .build()); + } + + @Test + public void createThrowExpr_messageAndCauseExpr() { + TypeNode npeType = + TypeNode.withReference(ConcreteReference.withClazz(NullPointerException.class)); + Expr messageExpr = + MethodInvocationExpr.builder() + .setMethodName("foobar") + .setReturnType(TypeNode.STRING) + .build(); + ThrowExpr.builder() + .setType(npeType) + .setMessageExpr(messageExpr) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build()) + .build(); + // Successfully created a ThrowExpr. + } + + @Test + public void createThrowExpr_cannotThrowVariableDeclaration() { + VariableExpr throwVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("e") + .setType(TypeNode.withExceptionClazz(RuntimeException.class)) + .build()) + .build(); + assertThrows( + IllegalStateException.class, + () -> + ThrowExpr.builder() + .setThrowExpr(throwVarExpr.toBuilder().setIsDecl(true).build()) + .build()); + } + + @Test + public void createThrowExpr_cannotThrowNonExceptionTypedExpr() { + VariableExpr throwVarExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("str").setType(TypeNode.STRING).build()) + .build(); + assertThrows( + IllegalStateException.class, () -> ThrowExpr.builder().setThrowExpr(throwVarExpr).build()); + } + + @Test + public void createThrowExpr_cannotHaveThrowVariableAndMessageExprPresent() { + Expr messageExpr = + MethodInvocationExpr.builder() + .setMethodName("foobar") + .setReturnType(TypeNode.STRING) + .build(); + VariableExpr throwVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("e") + .setType(TypeNode.withExceptionClazz(RuntimeException.class)) + .build()) + .build(); + assertThrows( + IllegalStateException.class, + () -> ThrowExpr.builder().setThrowExpr(throwVarExpr).setMessageExpr(messageExpr).build()); + } + + @Test + public void createThrowExpr_cannotHaveThrowVariableAndCauseExprPresent() { + VariableExpr throwVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("e") + .setType(TypeNode.withExceptionClazz(RuntimeException.class)) + .build()) + .build(); + assertThrows( + IllegalStateException.class, + () -> + ThrowExpr.builder() + .setThrowExpr(throwVarExpr) + .setCauseExpr( + NewObjectExpr.builder() + .setType( + TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build()) + .build()); + } } diff --git a/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java b/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java index db406aa9eb..9837c192f5 100644 --- a/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java @@ -15,9 +15,11 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; public class TryCatchStatementTest { @@ -32,9 +34,36 @@ public void validTryCatchStatement_simple() { TryCatchStatement tryCatch = TryCatchStatement.builder() .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .setCatchVariableExpr(variableExpr) + .addCatch(variableExpr, Collections.emptyList()) .build(); - assertThat(tryCatch.catchVariableExpr()).isEqualTo(variableExpr); + assertEquals(1, tryCatch.catchVariableExprs().size()); + assertThat(tryCatch.catchVariableExprs().get(0)).isEqualTo(variableExpr); + } + + @Test + public void validTryCatchStatement_simpleMultiBlock() { + VariableExpr firstCatchVarExpr = + VariableExpr.builder() + .setVariable( + createVariable("e", TypeNode.withExceptionClazz(IllegalArgumentException.class))) + .setIsDecl(true) + .build(); + VariableExpr secondCatchVarExpr = + VariableExpr.builder() + .setVariable(createVariable("e", TypeNode.withExceptionClazz(RuntimeException.class))) + .setIsDecl(true) + .build(); + + TryCatchStatement tryCatch = + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(firstCatchVarExpr, Collections.emptyList()) + .addCatch(secondCatchVarExpr, Collections.emptyList()) + .build(); + + assertEquals(2, tryCatch.catchVariableExprs().size()); + assertThat(tryCatch.catchVariableExprs().get(0)).isEqualTo(firstCatchVarExpr); + assertThat(tryCatch.catchVariableExprs().get(1)).isEqualTo(secondCatchVarExpr); } @Test @@ -49,41 +78,30 @@ public void validTryCatchStatement_withResources() { TryCatchStatement.builder() .setTryResourceExpr(assignmentExpr) .setTryBody(Arrays.asList(ExprStatement.withExpr(assignmentExpr))) - .setCatchVariableExpr(variableExpr) + .addCatch(variableExpr, Collections.emptyList()) .build(); - assertThat(tryCatch.catchVariableExpr()).isEqualTo(variableExpr); + assertThat(tryCatch.catchVariableExprs().get(0)).isEqualTo(variableExpr); assertThat(tryCatch.tryResourceExpr()).isEqualTo(assignmentExpr); } @Test public void validTryCatchStatement_sampleCode() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - TryCatchStatement tryCatch = TryCatchStatement.builder() .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) .setIsSampleCode(true) .build(); - assertThat(tryCatch.catchVariableExpr()).isNull(); + assertThat(tryCatch.catchVariableExprs()).isEmpty(); } @Test public void invalidTryCatchStatement_missingCatchVariable() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - assertThrows( - NullPointerException.class, - () -> { - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .build(); - }); + IllegalStateException.class, + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .build()); } @Test @@ -95,13 +113,11 @@ public void invalidTryCatchStatement_catchVariableNotDecl() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .setCatchVariableExpr(variableExpr) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(variableExpr, Collections.emptyList()) + .build()); } @Test @@ -113,13 +129,11 @@ public void invalidTryCatchStatement_nonExceptionReference() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .setCatchVariableExpr(variableExpr) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(variableExpr, Collections.emptyList()) + .build()); } private static AssignmentExpr createAssignmentExpr() { diff --git a/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java b/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java index 77c649e72f..5b80fdedc0 100644 --- a/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java @@ -15,9 +15,9 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode.TypeKind; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java index c8a662fdc9..486bc2efab 100644 --- a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -52,7 +52,6 @@ public void basic_isStaticImport() { public void basic_nested() { String pkg = "com.google.example.examples.library.v1"; String name = "Charles"; - String enclosingClassName = "Babbage"; Reference ref = VaporReference.builder() .setEnclosingClassNames("Babbage", "Ada") diff --git a/src/test/java/com/google/api/generator/engine/ast/VariableTest.java b/src/test/java/com/google/api/generator/engine/ast/VariableTest.java index 4f0b6c4743..b11cfd0662 100644 --- a/src/test/java/com/google/api/generator/engine/ast/VariableTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/VariableTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.TypeNode.TypeKind; diff --git a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java index 47a63ea6ee..07be47a996 100644 --- a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.writer; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AnonymousClassExpr; @@ -58,6 +58,7 @@ import com.google.common.base.Function; import com.google.common.base.Strings; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -448,6 +449,26 @@ public void writeThrowExprImports_basic() { assertEquals("import java.io.IOException;\n\n", writerVisitor.write()); } + @Test + public void writeThrowExprImports_throwExpr() { + Expr exprToThrow = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(Statement.class))) + .setMethodName("createException") + .setReturnType(TypeNode.withExceptionClazz(Exception.class)) + .build(); + + TypeNode ignoredExceptionType = + TypeNode.withReference(ConcreteReference.withClazz(IOException.class)); + ThrowExpr throwExpr = + ThrowExpr.builder().setType(ignoredExceptionType).setThrowExpr(exprToThrow).build(); + throwExpr.accept(writerVisitor); + assertEquals( + LineFormatter.lines("import com.google.api.generator.engine.ast.Statement;\n\n"), + writerVisitor.write()); + } + @Test public void writeThrowExprImports_messageExpr() { TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); @@ -475,6 +496,42 @@ public void writeThrowExprImports_messageExpr() { writerVisitor.write()); } + @Test + public void writeThrowExprImports_messageAndCauseExpr() { + TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); + Expr messageExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(IfStatement.class))) + .setMethodName("conditionExpr") + .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(Expr.class))) + .build(); + + messageExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(messageExpr) + .setMethodName("foobar") + .setReturnType(TypeNode.STRING) + .build(); + ThrowExpr throwExpr = + ThrowExpr.builder() + .setType(npeType) + .setMessageExpr(messageExpr) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withExceptionClazz(FileNotFoundException.class)) + .build()) + .build(); + + throwExpr.accept(writerVisitor); + assertEquals( + LineFormatter.lines( + "import com.google.api.generator.engine.ast.Expr;\n", + "import com.google.api.generator.engine.ast.IfStatement;\n", + "import java.io.FileNotFoundException;\n\n"), + writerVisitor.write()); + } + @Test public void writeInstanceofExprImports_basic() { TypeNode exprType = TypeNode.withReference(ConcreteReference.withClazz(Expr.class)); @@ -837,10 +894,6 @@ public void writeLambdaExprImports() { } /** =============================== HELPERS =============================== */ - private static TypeNode createType(Class clazz) { - return TypeNode.withReference(ConcreteReference.withClazz(clazz)); - } - private static Variable createVariable(String variableName, TypeNode type) { return Variable.builder().setName(variableName).setType(type).build(); } diff --git a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java index ac1f515169..39e448a263 100644 --- a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.writer; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AnonymousClassExpr; @@ -73,6 +73,7 @@ import com.google.common.base.Function; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -333,7 +334,6 @@ public void writeVariableExpr_localFinalDecl() { @Test public void writeVariableExpr_scopedDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.INT).build(); VariableExpr expr = VariableExpr.builder() @@ -348,7 +348,6 @@ public void writeVariableExpr_scopedDecl() { @Test public void writeVariableExpr_scopedStaticFinalDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.BOOLEAN).build(); VariableExpr expr = VariableExpr.builder() @@ -365,7 +364,6 @@ public void writeVariableExpr_scopedStaticFinalDecl() { @Test public void writeVariableExpr_scopedStaticFinalVolatileDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.BOOLEAN).build(); VariableExpr expr = VariableExpr.builder() @@ -643,9 +641,6 @@ public void writeJavaDocComment_specialChar() { @Test public void writeTernaryExpr_basic() { - Variable variable = Variable.builder().setName("x").setType(TypeNode.INT).build(); - VariableExpr variableExpr = VariableExpr.builder().setVariable(variable).build(); - Variable conditionVariable = Variable.builder().setName("condition").setType(TypeNode.BOOLEAN).build(); VariableExpr conditionExpr = VariableExpr.builder().setVariable(conditionVariable).build(); @@ -1031,6 +1026,21 @@ public void writeThrowExpr_basic() { assertEquals("throw new NullPointerException()", writerVisitor.write()); } + @Test + public void writeThrowExpr_basicThrowExpr() { + Expr exprToThrow = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(Statement.class))) + .setMethodName("createException") + .setReturnType(TypeNode.withExceptionClazz(Exception.class)) + .build(); + + ThrowExpr throwExpr = ThrowExpr.builder().setThrowExpr(exprToThrow).build(); + throwExpr.accept(writerVisitor); + assertEquals("throw Statement.createException()", writerVisitor.write()); + } + @Test public void writeThrowExpr_basicWithMessage() { TypeNode npeType = @@ -1041,6 +1051,22 @@ public void writeThrowExpr_basicWithMessage() { assertEquals("throw new NullPointerException(\"Some message asdf\")", writerVisitor.write()); } + @Test + public void writeThrowExpr_basicWithCause() { + TypeNode npeType = + TypeNode.withReference(ConcreteReference.withClazz(NullPointerException.class)); + ThrowExpr throwExpr = + ThrowExpr.builder() + .setType(npeType) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build()) + .build(); + throwExpr.accept(writerVisitor); + assertEquals("throw new NullPointerException(new Throwable())", writerVisitor.write()); + } + @Test public void writeThrowExpr_messageExpr() { TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); @@ -1055,6 +1081,29 @@ public void writeThrowExpr_messageExpr() { assertEquals("throw new NullPointerException(foobar())", writerVisitor.write()); } + @Test + public void writeThrowExpr_messageAndCauseExpr() { + TypeNode npeType = TypeNode.withExceptionClazz(NullPointerException.class); + Expr messageExpr = + MethodInvocationExpr.builder() + .setMethodName("foobar") + .setReturnType(TypeNode.STRING) + .build(); + ThrowExpr throwExpr = + ThrowExpr.builder() + .setType(npeType) + .setMessageExpr(messageExpr) + .setCauseExpr( + NewObjectExpr.builder() + .setType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build()) + .build(); + + throwExpr.accept(writerVisitor); + assertEquals( + "throw new NullPointerException(foobar(), new Throwable())", writerVisitor.write()); + } + @Test public void writeInstanceofExpr() { Variable variable = Variable.builder().setName("x").setType(TypeNode.STRING).build(); @@ -1415,7 +1464,7 @@ public void writeTryCatchStatement_simple() { TryCatchStatement.builder() .setTryBody( Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("x", "3", TypeNode.INT)))) - .setCatchVariableExpr(variableExpr) + .addCatch(variableExpr, Collections.emptyList()) .build(); tryCatch.accept(writerVisitor); @@ -1426,6 +1475,72 @@ public void writeTryCatchStatement_simple() { writerVisitor.write()); } + @Test + public void writeTryCatchStatement_simpleMultiCatch() { + VariableExpr firstCatchVarExpr = + VariableExpr.builder() + .setVariable( + createVariable("e", TypeNode.withExceptionClazz(IllegalArgumentException.class))) + .build(); + VariableExpr secondCatchVarExpr = + VariableExpr.builder() + .setVariable(createVariable("e", TypeNode.withExceptionClazz(RuntimeException.class))) + .build(); + + TryCatchStatement tryCatch = + TryCatchStatement.builder() + .setTryBody( + Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("x", "3", TypeNode.INT)))) + .addCatch( + firstCatchVarExpr.toBuilder().setIsDecl(true).build(), Collections.emptyList()) + .addCatch( + secondCatchVarExpr.toBuilder().setIsDecl(true).build(), Collections.emptyList()) + .build(); + + tryCatch.accept(writerVisitor); + assertEquals( + LineFormatter.lines( + "try {\n", + "int x = 3;\n", + "} catch (IllegalArgumentException e) {\n", + "} catch (RuntimeException e) {\n", + "}\n"), + writerVisitor.write()); + } + + @Test + public void writeTryCatchStatement_simpleMultiCatchOrderMatters() { + VariableExpr firstCatchVarExpr = + VariableExpr.builder() + .setVariable( + createVariable("e", TypeNode.withExceptionClazz(IllegalArgumentException.class))) + .build(); + VariableExpr secondCatchVarExpr = + VariableExpr.builder() + .setVariable(createVariable("e", TypeNode.withExceptionClazz(RuntimeException.class))) + .build(); + + TryCatchStatement tryCatch = + TryCatchStatement.builder() + .setTryBody( + Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("x", "3", TypeNode.INT)))) + .addCatch( + secondCatchVarExpr.toBuilder().setIsDecl(true).build(), Collections.emptyList()) + .addCatch( + firstCatchVarExpr.toBuilder().setIsDecl(true).build(), Collections.emptyList()) + .build(); + + tryCatch.accept(writerVisitor); + assertEquals( + LineFormatter.lines( + "try {\n", + "int x = 3;\n", + "} catch (RuntimeException e) {\n", + "} catch (IllegalArgumentException e) {\n", + "}\n"), + writerVisitor.write()); + } + @Test public void writeTryCatchStatement_withResources() { Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); @@ -1438,8 +1553,8 @@ public void writeTryCatchStatement_withResources() { .setTryResourceExpr(createAssignmentExpr("aBool", "false", TypeNode.BOOLEAN)) .setTryBody( Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("y", "4", TypeNode.INT)))) - .setCatchVariableExpr(variableExpr) - .setCatchBody( + .addCatch( + variableExpr, Arrays.asList( ExprStatement.withExpr(createAssignmentExpr("foobar", "123", TypeNode.INT)))) .build(); @@ -1458,11 +1573,6 @@ public void writeTryCatchStatement_withResources() { @Test public void writeTryCatchStatement_sampleCodeNoCatch() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - TryCatchStatement tryCatch = TryCatchStatement.builder() .setTryBody( @@ -1487,8 +1597,8 @@ public void writeTryCatchStatement_sampleCodeWithCatch() { .setTryResourceExpr(createAssignmentExpr("aBool", "false", TypeNode.BOOLEAN)) .setTryBody( Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("y", "4", TypeNode.INT)))) - .setCatchVariableExpr(variableExpr) - .setCatchBody( + .addCatch( + variableExpr, Arrays.asList( ExprStatement.withExpr(createAssignmentExpr("foobar", "123", TypeNode.INT)))) .build(); diff --git a/src/test/java/com/google/api/generator/gapic/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/BUILD.bazel index 7c614e8093..5c5f8983ad 100644 --- a/src/test/java/com/google/api/generator/gapic/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/BUILD.bazel @@ -4,6 +4,13 @@ filegroup( name = "gapic_files", srcs = [ "//src/test/java/com/google/api/generator/gapic/composer:composer_files", + "//src/test/java/com/google/api/generator/gapic/composer/defaultvalue:defaultvalue_files", + "//src/test/java/com/google/api/generator/gapic/composer/grpc:grpc_files", + # "//src/test/java/com/google/api/generator/gapic/composer/grpcrest:grpcrest_files", + "//src/test/java/com/google/api/generator/gapic/composer/resourcename:resourcename_files", + "//src/test/java/com/google/api/generator/gapic/composer/rest:rest_files", + "//src/test/java/com/google/api/generator/gapic/composer/samplecode:samplecode_files", + "//src/test/java/com/google/api/generator/gapic/composer/utils:utils_files", "//src/test/java/com/google/api/generator/gapic/model:model_files", "//src/test/java/com/google/api/generator/gapic/protoparser:protoparser_files", "//src/test/java/com/google/api/generator/gapic/utils:utils_files", diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel index 1d8c68ad72..28a4bfc8b4 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel @@ -5,8 +5,6 @@ package(default_visibility = ["//visibility:public"]) UPDATE_GOLDENS_TESTS = [ "BatchingDescriptorComposerTest", - "ServiceClientClassComposerTest", - "ServiceStubClassComposerTest", ] TESTS = UPDATE_GOLDENS_TESTS + [ @@ -29,6 +27,7 @@ TEST_DEPS = [ "//src/main/java/com/google/api/generator/gapic/protoparser", "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:bookshop_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", "@com_google_api_api_common//jar", diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java index f2ac7a5da5..50fdf0fac3 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.common; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.writer.JavaWriterVisitor; diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java index 09b1bf5b1c..598f261f8a 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java @@ -15,8 +15,8 @@ package com.google.api.generator.gapic.composer.common; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.gax.rpc.StatusCode; import com.google.api.generator.engine.ast.BlockStatement; @@ -27,6 +27,7 @@ import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.grpc.GrpcContext; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.GapicServiceConfig; @@ -41,7 +42,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; import java.nio.file.Path; import java.nio.file.Paths; @@ -141,7 +141,6 @@ public void paramDefinitionsBlock_basic() { @Test public void codesDefinitionsBlock_noConfigsFound() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -178,7 +177,6 @@ public void codesDefinitionsBlock_noConfigsFound() { @Test public void codesDefinitionsBlock_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -218,7 +216,6 @@ public void codesDefinitionsBlock_basic() { @Test public void simpleBuilderExpr_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -300,7 +297,6 @@ public void simpleBuilderExpr_basic() { @Test public void lroBuilderExpr() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -329,7 +325,9 @@ public void lroBuilderExpr() { waitMethod, builderVarExpr, RETRY_CODES_DEFINITIONS_VAR_EXPR, - RETRY_PARAM_DEFINITIONS_VAR_EXPR); + RETRY_PARAM_DEFINITIONS_VAR_EXPR, + GrpcContext.instance().operationResponseTransformerType(), + GrpcContext.instance().operationMetadataTransformerType()); builderExpr.accept(writerVisitor); String expected = LineFormatter.lines( diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java index 5cd4ade9da..e9eb95721d 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.common; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; @@ -27,6 +27,7 @@ import com.google.api.generator.gapic.protoparser.BatchingSettingsConfigParser; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; +import com.google.bookshop.v1beta1.BookshopProto; import com.google.logging.v2.LogEntryProto; import com.google.logging.v2.LoggingConfigProto; import com.google.logging.v2.LoggingMetricsProto; @@ -51,8 +52,7 @@ public class TestProtoLoader { private static final TestProtoLoader INSTANCE = - new TestProtoLoader( - Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); + new TestProtoLoader(Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); private final String testFilesDirectory; private final Transport transport; @@ -93,6 +93,34 @@ public GapicContext parseDeprecatedService() { .build(); } + public GapicContext parseBookshopService() { + FileDescriptor fileDescriptor = BookshopProto.getDescriptor(); + ServiceDescriptor serviceDescriptor = fileDescriptor.getServices().get(0); + assertEquals(serviceDescriptor.getName(), "Bookshop"); + + Map messageTypes = Parser.parseMessages(fileDescriptor); + Map resourceNames = new HashMap<>(); + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + fileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); + + String jsonFilename = "bookshop_grpc_service_config.json"; + Path jsonPath = Paths.get(testFilesDirectory, jsonFilename); + Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); + assertTrue(configOpt.isPresent()); + GapicServiceConfig config = configOpt.get(); + + return GapicContext.builder() + .setMessages(messageTypes) + .setResourceNames(resourceNames) + .setServices(services) + .setServiceConfig(config) + .setHelperResourceNames(outputResourceNames) + .setTransport(transport) + .build(); + } + public GapicContext parseShowcaseEcho() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); @@ -268,4 +296,8 @@ public GapicContext parseLogging() { public String getTestFilesDirectory() { return testFilesDirectory; } + + public Transport getTransport() { + return transport; + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java index 6a60b91e5d..cf444a270d 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.defaultvalue; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; @@ -24,6 +24,7 @@ import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.protoparser.Parser; +import com.google.api.generator.testutils.LineFormatter; import com.google.protobuf.ByteString; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; @@ -222,8 +223,8 @@ public void defaultValue_wildcardResourceNameWithOnlyDeletedTopic() { } @Test - public void defaultValue_resourceNameWithOnlyWildcards() { - // Edge case that should never happen in practice. + public void defaultValue_resourceNameWithOnlyWildcards_valueOnly() { + // Edge case that occurs in GCS. // Wildcard, but the resource names map has only other names that contain only the deleted-topic // constant. FileDescriptor lockerServiceFileDescriptor = LockerProto.getDescriptor(); @@ -233,13 +234,50 @@ public void defaultValue_resourceNameWithOnlyWildcards() { typeStringsToResourceNames.get("cloudresourcemanager.googleapis.com/Anything"); String fallbackField = "foobar"; Expr expr = - DefaultValueComposer.createDefaultValue( - resourceName, Collections.emptyList(), fallbackField); + DefaultValueComposer.createDefaultValueResourceHelper( + resourceName, + Collections.emptyList(), + fallbackField, + /* allowAnonResourceNameClass = */ false); expr.accept(writerVisitor); assertEquals( String.format("\"%s%s\"", fallbackField, fallbackField.hashCode()), writerVisitor.write()); } + @Test + public void defaultValue_resourceNameWithOnlyWildcards_allowAnonResourceNameClass() { + // Edge case that occurs in GCS. + // Wildcard, but the resource names map has only other names that contain only the deleted-topic + // constant. + FileDescriptor lockerServiceFileDescriptor = LockerProto.getDescriptor(); + Map typeStringsToResourceNames = + Parser.parseResourceNames(lockerServiceFileDescriptor); + ResourceName resourceName = + typeStringsToResourceNames.get("cloudresourcemanager.googleapis.com/Anything"); + String fallbackField = "foobar"; + Expr expr = + DefaultValueComposer.createDefaultValue( + resourceName, Collections.emptyList(), fallbackField); + expr.accept(writerVisitor); + String expected = + LineFormatter.lines( + "new ResourceName() {\n", + "@Override\n", + "public Map getFieldValuesMap() {\n", + "Map fieldValuesMap = new HashMap<>();\n", + "fieldValuesMap.put(\"foobar\", \"foobar-1268878963\");\n", + "return fieldValuesMap;\n", + "}\n", + "\n", + "@Override\n", + "public String getFieldValue(String fieldName) {\n", + "return getFieldValuesMap().get(fieldName);\n", + "}\n", + "\n", + "}"); + assertEquals(expected, writerVisitor.write()); + } + @Test public void createSimpleMessage_basicPrimitivesOnly() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); @@ -307,4 +345,28 @@ public void createSimpleMessage_onlyOneofs() { expr.accept(writerVisitor); assertEquals("WaitRequest.newBuilder().build()", writerVisitor.write()); } + + @Test + public void createAnonymousResourceNameClass() { + Expr expr = DefaultValueComposer.createAnonymousResourceNameClass("resource"); + expr.accept(writerVisitor); + String expected = + LineFormatter.lines( + "new ResourceName() {\n", + "@Override\n", + "public Map getFieldValuesMap() {\n", + "Map fieldValuesMap = new HashMap<>();\n", + "fieldValuesMap.put(\"resource\", \"resource-341064690\");\n", + "return fieldValuesMap;\n", + "}\n", + "\n", + "@Override\n", + "public String getFieldValue(String fieldName) {\n", + "return getFieldValuesMap().get(fieldName);\n", + "}\n", + "\n", + "}"); + + assertEquals(expected, writerVisitor.write()); + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel index 8c0cabe5a1..825635a75e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel @@ -8,8 +8,10 @@ TESTS = [ "GrpcServiceStubClassComposerTest", "MockServiceClassComposerTest", "MockServiceImplClassComposerTest", + "ServiceClientClassComposerTest", "ServiceClientTestClassComposerTest", "ServiceSettingsClassComposerTest", + "ServiceStubClassComposerTest", "ServiceStubSettingsClassComposerTest", ] @@ -33,9 +35,7 @@ TEST_DEPS = [ "//src/main/java/com/google/api/generator/gapic/model", "//src/main/java/com/google/api/generator/gapic/protoparser", "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", - "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", - "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", "@com_google_api_api_common//jar", "@com_google_api_gax_java//gax", "@com_google_api_api_common", @@ -49,17 +49,10 @@ TEST_DEPS = [ ] filegroup( - name = "composer_files", + name = "grpc_files", srcs = glob(["*.java"]), ) -java_proto_library( - name = "pubsub_java_proto", - deps = [ - "@com_google_googleapis//google/pubsub/v1:pubsub_proto", - ], -) - java_proto_library( name = "common_resources_java_proto", deps = [ diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java index 8ccbc442ed..9bdb460f96 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java @@ -62,8 +62,7 @@ public void generateGrpcServiceStubClass_httpBindings() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcTestingStub.golden", visitor.write()); - Path goldenFilePath = - Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcTestingStub.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcTestingStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.java similarity index 71% rename from src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.java index 3510efaf3f..331b94e484 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer.common; +package com.google.api.generator.gapic.composer.grpc; import static com.google.api.generator.test.framework.Assert.assertCodeEquals; @@ -28,7 +28,7 @@ public class ServiceClientClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoader.instance().parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, echoProtoService); @@ -41,7 +41,7 @@ public void generateServiceClasses() { @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoader.instance().parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); @@ -55,15 +55,27 @@ public void generateServiceClasses_deprecated() { @Test public void generateServiceClasses_methodSignatureHasNestedFields() { - GapicContext context = TestProtoLoader.instance().parseShowcaseIdentity(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseIdentity(); Service protoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "IdentityClient.golden", visitor.write()); - Path goldenFilePath = - Paths.get(Utils.getGoldenDir(this.getClass()), "IdentityClient.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "IdentityClient.golden"); + assertCodeEquals(goldenFilePath, visitor.write()); + } + + @Test + public void generateServiceClasses_bookshopNameConflicts() { + GapicContext context = GrpcTestProtoLoader.instance().parseBookshopService(); + Service protoService = context.services().get(0); + GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "BookshopClient.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "BookshopClient.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java index cbb6bae23b..9874286d82 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java @@ -15,10 +15,9 @@ package com.google.api.generator.gapic.composer.grpc; import static com.google.api.generator.test.framework.Assert.assertCodeEquals; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.common.ServiceClientClassComposer; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -38,8 +37,7 @@ public void generateClientTest_echoClient() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoClientTest.golden", visitor.write()); - Path goldenFilePath = - Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClientTest.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java similarity index 94% rename from src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java index b30ce3630c..bb411b9ad3 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer.common; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.common.TestProtoLoader; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java index 3a907c432f..468c2d8219 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.grpc; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; import com.google.api.generator.gapic.model.GapicClass; @@ -67,8 +67,7 @@ public void generateServiceStubSettingsClasses_basic() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoStubSettings.golden", visitor.write()); - Path goldenFilePath = - Paths.get(Utils.getGoldenDir(this.getClass()), "EchoStubSettings.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoStubSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden new file mode 100644 index 0000000000..069bd7a634 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden @@ -0,0 +1,242 @@ +package com.google.bookshop.v1beta1; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.bookshop.v1beta1.stub.BookshopStub; +import com.google.bookshop.v1beta1.stub.BookshopStubSettings; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * This class provides the ability to make remote calls to the backing service through method calls + * that map to API methods. Sample code to get started: + * + *
{@code
+ * try (BookshopClient bookshopClient = BookshopClient.create()) {
+ *   int booksCount = 1618425911;
+ *   List books = new ArrayList<>();
+ *   Book response = bookshopClient.getBook(booksCount, books);
+ * }
+ * }
+ * + *

Note: close() needs to be called on the BookshopClient object to clean up resources such as + * threads. In the example above, try-with-resources is used, which automatically calls close(). + * + *

The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

    + *
  1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
  2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
+ * + *

See the individual methods for example code. + * + *

Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

This class can be customized by passing in a custom instance of BookshopSettings to create(). + * For example: + * + *

To customize credentials: + * + *

{@code
+ * BookshopSettings bookshopSettings =
+ *     BookshopSettings.newBuilder()
+ *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ *         .build();
+ * BookshopClient bookshopClient = BookshopClient.create(bookshopSettings);
+ * }
+ * + *

To customize the endpoint: + * + *

{@code
+ * BookshopSettings bookshopSettings =
+ *     BookshopSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * BookshopClient bookshopClient = BookshopClient.create(bookshopSettings);
+ * }
+ * + *

Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class BookshopClient implements BackgroundResource { + private final BookshopSettings settings; + private final BookshopStub stub; + + /** Constructs an instance of BookshopClient with default settings. */ + public static final BookshopClient create() throws IOException { + return create(BookshopSettings.newBuilder().build()); + } + + /** + * Constructs an instance of BookshopClient, using the given settings. The channels are created + * based on the settings passed in, or defaults for any settings that are not set. + */ + public static final BookshopClient create(BookshopSettings settings) throws IOException { + return new BookshopClient(settings); + } + + /** + * Constructs an instance of BookshopClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(BookshopSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final BookshopClient create(BookshopStub stub) { + return new BookshopClient(stub); + } + + /** + * Constructs an instance of BookshopClient, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected BookshopClient(BookshopSettings settings) throws IOException { + this.settings = settings; + this.stub = ((BookshopStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected BookshopClient(BookshopStub stub) { + this.settings = null; + this.stub = stub; + } + + public final BookshopSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public BookshopStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *

{@code
+   * try (BookshopClient bookshopClient = BookshopClient.create()) {
+   *   int booksCount = 1618425911;
+   *   List books = new ArrayList<>();
+   *   Book response = bookshopClient.getBook(booksCount, books);
+   * }
+   * }
+ * + * @param booksCount + * @param books + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Book getBook(int booksCount, List books) { + GetBookRequest request = + GetBookRequest.newBuilder().setBooksCount(booksCount).addAllBooks(books).build(); + return getBook(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * try (BookshopClient bookshopClient = BookshopClient.create()) {
+   *   String booksList = "booksList2-1119589686";
+   *   List books = new ArrayList<>();
+   *   Book response = bookshopClient.getBook(booksList, books);
+   * }
+   * }
+ * + * @param booksList + * @param books + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Book getBook(String booksList, List books) { + GetBookRequest request = + GetBookRequest.newBuilder().setBooksList(booksList).addAllBooks(books).build(); + return getBook(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * try (BookshopClient bookshopClient = BookshopClient.create()) {
+   *   GetBookRequest request =
+   *       GetBookRequest.newBuilder()
+   *           .setBooksCount1(1618425911)
+   *           .setBooksList2("booksList2-1119589686")
+   *           .addAllBooks3(new ArrayList())
+   *           .build();
+   *   Book response = bookshopClient.getBook(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Book getBook(GetBookRequest request) { + return getBookCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * try (BookshopClient bookshopClient = BookshopClient.create()) {
+   *   GetBookRequest request =
+   *       GetBookRequest.newBuilder()
+   *           .setBooksCount1(1618425911)
+   *           .setBooksList2("booksList2-1119589686")
+   *           .addAllBooks3(new ArrayList())
+   *           .build();
+   *   ApiFuture future = bookshopClient.getBookCallable().futureCall(request);
+   *   // Do something.
+   *   Book response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable getBookCallable() { + return stub.getBookCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClient.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClient.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden index bf7356d98c..5e26ce1290 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden @@ -26,8 +26,8 @@ import org.junit.Test; public class DeprecatedServiceClientTest { private static MockDeprecatedService mockDeprecatedService; private static MockServiceHelper mockServiceHelper; - private DeprecatedServiceClient client; private LocalChannelProvider channelProvider; + private DeprecatedServiceClient client; @BeforeClass public static void startStaticServer() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden index 34d39be82a..5e61122577 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden @@ -155,14 +155,13 @@ public class DeprecatedServiceSettings extends ClientSettingsNote: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden index 6e44ff4bd2..899b03bbce 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden @@ -108,6 +108,11 @@ public class DeprecatedServiceStubSettings extends StubSettings getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -115,7 +120,9 @@ public class DeprecatedServiceStubSettings extends StubSettingsNote: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden similarity index 94% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden index 5791d9086d..3e6735f6bd 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden @@ -1,6 +1,5 @@ package com.google.showcase.v1beta1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -769,6 +768,53 @@ public class EchoClient implements BackgroundResource { return stub.blockCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   Object response = echoClient.collideName(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Object collideName(EchoRequest request) { + return collideNameCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   ApiFuture future = echoClient.collideNameCallable().futureCall(request);
+   *   // Do something.
+   *   Object response = future.get();
+   * }
+   * }
+   */
+  public final UnaryCallable collideNameCallable() {
+    return stub.collideNameCallable();
+  }
+
   @Override
   public final void close() {
     stub.close();
@@ -813,14 +859,7 @@ public class EchoClient implements BackgroundResource {
       ApiFuture futurePage =
           PagedExpandPage.createEmptyPage().createPageAsync(context, futureResponse);
       return ApiFutures.transform(
-          futurePage,
-          new ApiFunction() {
-            @Override
-            public PagedExpandPagedResponse apply(PagedExpandPage input) {
-              return new PagedExpandPagedResponse(input);
-            }
-          },
-          MoreExecutors.directExecutor());
+          futurePage, input -> new PagedExpandPagedResponse(input), MoreExecutors.directExecutor());
     }
 
     private PagedExpandPagedResponse(PagedExpandPage page) {
@@ -894,12 +933,7 @@ public class EchoClient implements BackgroundResource {
           SimplePagedExpandPage.createEmptyPage().createPageAsync(context, futureResponse);
       return ApiFutures.transform(
           futurePage,
-          new ApiFunction() {
-            @Override
-            public SimplePagedExpandPagedResponse apply(SimplePagedExpandPage input) {
-              return new SimplePagedExpandPagedResponse(input);
-            }
-          },
+          input -> new SimplePagedExpandPagedResponse(input),
           MoreExecutors.directExecutor());
     }
 
diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden
index ba815b973f..1372cdd94e 100644
--- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden
+++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden
@@ -42,8 +42,8 @@ import org.junit.Test;
 public class EchoClientTest {
   private static MockEcho mockEcho;
   private static MockServiceHelper mockServiceHelper;
-  private EchoClient client;
   private LocalChannelProvider channelProvider;
+  private EchoClient client;
 
   @BeforeClass
   public static void startStaticServer() {
@@ -838,4 +838,56 @@ public class EchoClientTest {
       // Expected exception.
     }
   }
+
+  @Test
+  public void collideNameTest() throws Exception {
+    Object expectedResponse = Object.newBuilder().setContent("content951530617").build();
+    mockEcho.addResponse(expectedResponse);
+
+    EchoRequest request =
+        EchoRequest.newBuilder()
+            .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setSeverity(Severity.forNumber(0))
+            .setFoobar(Foobar.newBuilder().build())
+            .build();
+
+    Object actualResponse = client.collideName(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(request.getName(), actualRequest.getName());
+    Assert.assertEquals(request.getParent(), actualRequest.getParent());
+    Assert.assertEquals(request.getContent(), actualRequest.getContent());
+    Assert.assertEquals(request.getError(), actualRequest.getError());
+    Assert.assertEquals(request.getSeverity(), actualRequest.getSeverity());
+    Assert.assertEquals(request.getFoobar(), actualRequest.getFoobar());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void collideNameExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      EchoRequest request =
+          EchoRequest.newBuilder()
+              .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setSeverity(Severity.forNumber(0))
+              .setFoobar(Foobar.newBuilder().build())
+              .build();
+      client.collideName(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
 }
diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden
index d94e7838ef..e88ba04676 100644
--- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden
+++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden
@@ -111,6 +111,11 @@ public class EchoSettings extends ClientSettings {
     return ((EchoStubSettings) getStubSettings()).blockSettings();
   }
 
+  /** Returns the object with the settings used for calls to collideName. */
+  public UnaryCallSettings collideNameSettings() {
+    return ((EchoStubSettings) getStubSettings()).collideNameSettings();
+  }
+
   public static final EchoSettings create(EchoStubSettings stub) throws IOException {
     return new EchoSettings.Builder(stub.toBuilder()).build();
   }
@@ -195,14 +200,13 @@ public class EchoSettings extends ClientSettings {
       return ((EchoStubSettings.Builder) getStubSettings());
     }
 
-    // NEXT_MAJOR_VER: remove 'throws Exception'.
     /**
      * Applies the given settings updater function to all of the unary API methods in this service.
      *
      * 

Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; @@ -263,6 +267,11 @@ public class EchoSettings extends ClientSettings { return getStubSettingsBuilder().blockSettings(); } + /** Returns the builder for the settings used for calls to collideName. */ + public UnaryCallSettings.Builder collideNameSettings() { + return getStubSettingsBuilder().collideNameSettings(); + } + @Override public EchoSettings build() throws IOException { return new EchoSettings(this); diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden similarity index 94% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden index 629e9939bb..9270f22851 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden @@ -17,6 +17,7 @@ import com.google.showcase.v1beta1.BlockResponse; import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; +import com.google.showcase.v1beta1.Object; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -87,6 +88,10 @@ public abstract class EchoStub implements BackgroundResource { throw new UnsupportedOperationException("Not implemented: blockCallable()"); } + public UnaryCallable collideNameCallable() { + throw new UnsupportedOperationException("Not implemented: collideNameCallable()"); + } + @Override public abstract void close(); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden index df88bb4b31..2006b2a30d 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden @@ -41,6 +41,7 @@ import com.google.showcase.v1beta1.BlockResponse; import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; +import com.google.showcase.v1beta1.Object; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -103,6 +104,7 @@ public class EchoStubSettings extends StubSettings { private final OperationCallSettings waitOperationSettings; private final UnaryCallSettings blockSettings; + private final UnaryCallSettings collideNameSettings; private static final PagedListDescriptor PAGED_EXPAND_PAGE_STR_DESC = @@ -262,6 +264,11 @@ public class EchoStubSettings extends StubSettings { return blockSettings; } + /** Returns the object with the settings used for calls to collideName. */ + public UnaryCallSettings collideNameSettings() { + return collideNameSettings; + } + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public EchoStub createStub() throws IOException { if (getTransportChannelProvider() @@ -284,6 +291,11 @@ public class EchoStubSettings extends StubSettings { return "localhost:7469"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "localhost:7469"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -291,7 +303,9 @@ public class EchoStubSettings extends StubSettings { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -340,6 +354,7 @@ public class EchoStubSettings extends StubSettings { waitSettings = settingsBuilder.waitSettings().build(); waitOperationSettings = settingsBuilder.waitOperationSettings().build(); blockSettings = settingsBuilder.blockSettings().build(); + collideNameSettings = settingsBuilder.collideNameSettings().build(); } /** Builder for EchoStubSettings. */ @@ -360,6 +375,7 @@ public class EchoStubSettings extends StubSettings { private final OperationCallSettings.Builder waitOperationSettings; private final UnaryCallSettings.Builder blockSettings; + private final UnaryCallSettings.Builder collideNameSettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; @@ -420,6 +436,7 @@ public class EchoStubSettings extends StubSettings { waitSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); waitOperationSettings = OperationCallSettings.newBuilder(); blockSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + collideNameSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -427,7 +444,8 @@ public class EchoStubSettings extends StubSettings { pagedExpandSettings, simplePagedExpandSettings, waitSettings, - blockSettings); + blockSettings, + collideNameSettings); initDefaults(this); } @@ -444,6 +462,7 @@ public class EchoStubSettings extends StubSettings { waitSettings = settings.waitSettings.toBuilder(); waitOperationSettings = settings.waitOperationSettings.toBuilder(); blockSettings = settings.blockSettings.toBuilder(); + collideNameSettings = settings.collideNameSettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -451,7 +470,8 @@ public class EchoStubSettings extends StubSettings { pagedExpandSettings, simplePagedExpandSettings, waitSettings, - blockSettings); + blockSettings, + collideNameSettings); } private static Builder createDefault() { @@ -461,6 +481,8 @@ public class EchoStubSettings extends StubSettings { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -496,6 +518,11 @@ public class EchoStubSettings extends StubSettings { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder + .collideNameSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder .waitOperationSettings() .setInitialCallSettings( @@ -522,14 +549,13 @@ public class EchoStubSettings extends StubSettings { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } @@ -595,6 +621,11 @@ public class EchoStubSettings extends StubSettings { return blockSettings; } + /** Returns the builder for the settings used for calls to collideName. */ + public UnaryCallSettings.Builder collideNameSettings() { + return collideNameSettings; + } + @Override public EchoStubSettings build() throws IOException { return new EchoStubSettings(this); diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden index 431b6688f5..b472790622 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden @@ -125,7 +125,13 @@ public class GrpcDeprecatedServiceStub extends DeprecatedServiceStub { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden index 194849ba09..940ab7d4c4 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden @@ -21,6 +21,7 @@ import com.google.showcase.v1beta1.BlockResponse; import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.EchoResponse; import com.google.showcase.v1beta1.ExpandRequest; +import com.google.showcase.v1beta1.Object; import com.google.showcase.v1beta1.PagedExpandRequest; import com.google.showcase.v1beta1.PagedExpandResponse; import com.google.showcase.v1beta1.WaitMetadata; @@ -117,6 +118,14 @@ public class GrpcEchoStub extends EchoStub { .setResponseMarshaller(ProtoUtils.marshaller(BlockResponse.getDefaultInstance())) .build(); + private static final MethodDescriptor collideNameMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.v1beta1.Echo/CollideName") + .setRequestMarshaller(ProtoUtils.marshaller(EchoRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Object.getDefaultInstance())) + .build(); + private final UnaryCallable echoCallable; private final ServerStreamingCallable expandCallable; private final ClientStreamingCallable collectCallable; @@ -131,6 +140,7 @@ public class GrpcEchoStub extends EchoStub { private final UnaryCallable waitCallable; private final OperationCallable waitOperationCallable; private final UnaryCallable blockCallable; + private final UnaryCallable collideNameCallable; private final BackgroundResource backgroundResources; private final GrpcOperationsStub operationsStub; @@ -206,6 +216,10 @@ public class GrpcEchoStub extends EchoStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(blockMethodDescriptor) .build(); + GrpcCallSettings collideNameTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(collideNameMethodDescriptor) + .build(); this.echoCallable = callableFactory.createUnaryCallable( @@ -247,6 +261,9 @@ public class GrpcEchoStub extends EchoStub { this.blockCallable = callableFactory.createUnaryCallable( blockTransportSettings, settings.blockSettings(), clientContext); + this.collideNameCallable = + callableFactory.createUnaryCallable( + collideNameTransportSettings, settings.collideNameSettings(), clientContext); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); @@ -317,9 +334,20 @@ public class GrpcEchoStub extends EchoStub { return blockCallable; } + @Override + public UnaryCallable collideNameCallable() { + return collideNameCallable; + } + @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden index 9e221ab5a2..b0f6557279 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden @@ -9,7 +9,6 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.longrunning.stub.GrpcOperationsStub; @@ -190,65 +189,50 @@ public class GrpcPublisherStub extends PublisherStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(createTopicMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(Topic request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings updateTopicTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateTopicMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateTopicRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic.name", String.valueOf(request.getTopic().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic.name", String.valueOf(request.getTopic().getName())); + return params.build(); }) .build(); GrpcCallSettings publishTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(publishMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(PublishRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic", String.valueOf(request.getTopic())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); }) .build(); GrpcCallSettings getTopicTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getTopicMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetTopicRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic", String.valueOf(request.getTopic())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); }) .build(); GrpcCallSettings listTopicsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listTopicsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListTopicsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("project", String.valueOf(request.getProject())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("project", String.valueOf(request.getProject())); + return params.build(); }) .build(); GrpcCallSettings @@ -257,13 +241,10 @@ public class GrpcPublisherStub extends PublisherStub { .newBuilder() .setMethodDescriptor(listTopicSubscriptionsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListTopicSubscriptionsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic", String.valueOf(request.getTopic())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); }) .build(); GrpcCallSettings @@ -271,26 +252,20 @@ public class GrpcPublisherStub extends PublisherStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(listTopicSnapshotsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListTopicSnapshotsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic", String.valueOf(request.getTopic())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); }) .build(); GrpcCallSettings deleteTopicTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteTopicMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteTopicRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("topic", String.valueOf(request.getTopic())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); }) .build(); GrpcCallSettings @@ -298,13 +273,10 @@ public class GrpcPublisherStub extends PublisherStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(detachSubscriptionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DetachSubscriptionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("subscription", String.valueOf(request.getSubscription())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("subscription", String.valueOf(request.getSubscription())); + return params.build(); }) .build(); @@ -430,7 +402,13 @@ public class GrpcPublisherStub extends PublisherStub { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden index ed6f22313a..7312b79d37 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden @@ -9,7 +9,6 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.longrunning.stub.GrpcOperationsStub; @@ -186,13 +185,10 @@ public class GrpcTestingStub extends TestingStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(getSessionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetSessionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listSessionsTransportSettings = @@ -203,83 +199,65 @@ public class GrpcTestingStub extends TestingStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteSessionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteSessionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings reportSessionTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(reportSessionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ReportSessionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getTestTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getTestMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetTestRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listTestsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listTestsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListTestsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings deleteTestTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteTestMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteTestRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings verifyTestTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(verifyTestMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(VerifyTestRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("answer", String.valueOf(request.getAnswer())); - params.put("foo", String.valueOf(request.getFoo())); - params.put("name", String.valueOf(request.getName())); - params.put( - "test_to_verify.name", String.valueOf(request.getTestToVerify().getName())); - params.put("type", String.valueOf(request.getType())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("answer", String.valueOf(request.getAnswer())); + params.put("foo", String.valueOf(request.getFoo())); + params.put("name", String.valueOf(request.getName())); + params.put( + "test_to_verify.name", String.valueOf(request.getTestToVerify().getName())); + params.put("type", String.valueOf(request.getType())); + return params.build(); }) .build(); @@ -382,7 +360,13 @@ public class GrpcTestingStub extends TestingStub { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/IdentityClient.golden similarity index 98% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/IdentityClient.golden index 2081b3bd1c..235c0055b6 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/IdentityClient.golden @@ -1,6 +1,5 @@ package com.google.showcase.v1beta1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -644,14 +643,7 @@ public class IdentityClient implements BackgroundResource { ApiFuture futurePage = ListUsersPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListUsersPagedResponse apply(ListUsersPage input) { - return new ListUsersPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListUsersPagedResponse(input), MoreExecutors.directExecutor()); } private ListUsersPagedResponse(ListUsersPage page) { diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden index afa0414c65..ead00722f4 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden @@ -45,8 +45,8 @@ import org.junit.Test; public class LoggingServiceV2ClientTest { private static MockLoggingServiceV2 mockLoggingServiceV2; private static MockServiceHelper mockServiceHelper; - private LoggingServiceV2Client client; private LocalChannelProvider channelProvider; + private LoggingServiceV2Client client; @BeforeClass public static void startStaticServer() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden index 4033943f64..cc308eb5de 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden @@ -428,6 +428,11 @@ public class LoggingServiceV2StubSettings extends StubSettings getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -435,7 +440,9 @@ public class LoggingServiceV2StubSettings extends StubSettingsNote: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden index f400f9aa20..7092d93a9e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden @@ -15,7 +15,7 @@ import javax.annotation.Generated; @Generated("by gapic-generator-java") public class MockDeprecatedServiceImpl extends DeprecatedServiceImplBase { private List requests; - private Queue responses; + private Queue responses; public MockDeprecatedServiceImpl() { requests = new ArrayList<>(); @@ -31,7 +31,7 @@ public class MockDeprecatedServiceImpl extends DeprecatedServiceImplBase { } public void setResponses(List responses) { - this.responses = new LinkedList(responses); + this.responses = new LinkedList(responses); } public void addException(Exception exception) { @@ -45,7 +45,7 @@ public class MockDeprecatedServiceImpl extends DeprecatedServiceImplBase { @Override public void fastFibonacci(FibonacciRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof Empty) { requests.add(request); responseObserver.onNext(((Empty) response)); @@ -65,7 +65,7 @@ public class MockDeprecatedServiceImpl extends DeprecatedServiceImplBase { @Override public void slowFibonacci(FibonacciRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof Empty) { requests.add(request); responseObserver.onNext(((Empty) response)); diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden index 50da1d568c..ae3ff13888 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden @@ -15,7 +15,7 @@ import javax.annotation.Generated; @Generated("by gapic-generator-java") public class MockEchoImpl extends EchoImplBase { private List requests; - private Queue responses; + private Queue responses; public MockEchoImpl() { requests = new ArrayList<>(); @@ -31,7 +31,7 @@ public class MockEchoImpl extends EchoImplBase { } public void setResponses(List responses) { - this.responses = new LinkedList(responses); + this.responses = new LinkedList(responses); } public void addException(Exception exception) { @@ -45,7 +45,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void echo(EchoRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof EchoResponse) { requests.add(request); responseObserver.onNext(((EchoResponse) response)); @@ -65,7 +65,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void expand(ExpandRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof EchoResponse) { requests.add(request); responseObserver.onNext(((EchoResponse) response)); @@ -90,7 +90,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void onNext(EchoRequest value) { requests.add(value); - final Object response = responses.remove(); + final java.lang.Object response = responses.remove(); if (response instanceof EchoResponse) { responseObserver.onNext(((EchoResponse) response)); } else if (response instanceof Exception) { @@ -126,7 +126,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void onNext(EchoRequest value) { requests.add(value); - final Object response = responses.remove(); + final java.lang.Object response = responses.remove(); if (response instanceof EchoResponse) { responseObserver.onNext(((EchoResponse) response)); } else if (response instanceof Exception) { @@ -163,7 +163,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void onNext(EchoRequest value) { requests.add(value); - final Object response = responses.remove(); + final java.lang.Object response = responses.remove(); if (response instanceof EchoResponse) { responseObserver.onNext(((EchoResponse) response)); } else if (response instanceof Exception) { @@ -195,7 +195,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void pagedExpand( PagedExpandRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof PagedExpandResponse) { requests.add(request); responseObserver.onNext(((PagedExpandResponse) response)); @@ -216,7 +216,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void simplePagedExpand( PagedExpandRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof PagedExpandResponse) { requests.add(request); responseObserver.onNext(((PagedExpandResponse) response)); @@ -236,7 +236,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void wait(WaitRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof Operation) { requests.add(request); responseObserver.onNext(((Operation) response)); @@ -256,7 +256,7 @@ public class MockEchoImpl extends EchoImplBase { @Override public void block(BlockRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); + java.lang.Object response = responses.poll(); if (response instanceof BlockResponse) { requests.add(request); responseObserver.onNext(((BlockResponse) response)); @@ -273,4 +273,24 @@ public class MockEchoImpl extends EchoImplBase { Exception.class.getName()))); } } + + @Override + public void collideName(EchoRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof Object) { + requests.add(request); + responseObserver.onNext(((Object) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method CollideName, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + Object.class.getName(), + Exception.class.getName()))); + } + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden index 41585255b2..d050f8a921 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden @@ -437,6 +437,11 @@ public class PublisherStubSettings extends StubSettings { return "pubsub.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "pubsub.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -444,7 +449,9 @@ public class PublisherStubSettings extends StubSettings { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -651,6 +658,8 @@ public class PublisherStubSettings extends StubSettings { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -717,14 +726,13 @@ public class PublisherStubSettings extends StubSettings { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden index 941e4d1ea6..62467289ae 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden @@ -36,10 +36,10 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class SubscriberClientTest { - private static MockSubscriber mockSubscriber; private static MockServiceHelper mockServiceHelper; - private SubscriberClient client; + private static MockSubscriber mockSubscriber; private LocalChannelProvider channelProvider; + private SubscriberClient client; @BeforeClass public static void startStaticServer() { @@ -778,6 +778,84 @@ public class SubscriberClientTest { PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); mockSubscriber.addResponse(expectedResponse); + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); + int maxMessages = 496131527; + + PullResponse actualResponse = client.pull(subscription, maxMessages); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockSubscriber.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + PullRequest actualRequest = ((PullRequest) actualRequests.get(0)); + + Assert.assertEquals(subscription.toString(), actualRequest.getSubscription()); + Assert.assertEquals(maxMessages, actualRequest.getMaxMessages()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void pullExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockSubscriber.addException(exception); + + try { + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); + int maxMessages = 496131527; + client.pull(subscription, maxMessages); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void pullTest2() throws Exception { + PullResponse expectedResponse = + PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); + mockSubscriber.addResponse(expectedResponse); + + String subscription = "subscription341203229"; + int maxMessages = 496131527; + + PullResponse actualResponse = client.pull(subscription, maxMessages); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockSubscriber.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + PullRequest actualRequest = ((PullRequest) actualRequests.get(0)); + + Assert.assertEquals(subscription, actualRequest.getSubscription()); + Assert.assertEquals(maxMessages, actualRequest.getMaxMessages()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void pullExceptionTest2() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockSubscriber.addException(exception); + + try { + String subscription = "subscription341203229"; + int maxMessages = 496131527; + client.pull(subscription, maxMessages); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void pullTest3() throws Exception { + PullResponse expectedResponse = + PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); + mockSubscriber.addResponse(expectedResponse); + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); boolean returnImmediately = true; int maxMessages = 496131527; @@ -799,7 +877,7 @@ public class SubscriberClientTest { } @Test - public void pullExceptionTest() throws Exception { + public void pullExceptionTest3() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockSubscriber.addException(exception); @@ -815,7 +893,7 @@ public class SubscriberClientTest { } @Test - public void pullTest2() throws Exception { + public void pullTest4() throws Exception { PullResponse expectedResponse = PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); mockSubscriber.addResponse(expectedResponse); @@ -841,7 +919,7 @@ public class SubscriberClientTest { } @Test - public void pullExceptionTest2() throws Exception { + public void pullExceptionTest4() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockSubscriber.addException(exception); @@ -861,6 +939,8 @@ public class SubscriberClientTest { StreamingPullResponse expectedResponse = StreamingPullResponse.newBuilder() .addAllReceivedMessages(new ArrayList()) + .setSubscriptionProperties( + StreamingPullResponse.SubscriptionProperties.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); StreamingPullRequest request = diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden index d124cfb5e2..76a18a39b5 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden @@ -31,10 +31,10 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class TestingClientTest { - private static MockTesting mockTesting; private static MockServiceHelper mockServiceHelper; - private TestingClient client; + private static MockTesting mockTesting; private LocalChannelProvider channelProvider; + private TestingClient client; @BeforeClass public static void startStaticServer() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel index a62cd2dad8..c62de44173 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel @@ -23,6 +23,7 @@ TEST_DEPS = [ "//src/main/java/com/google/api/generator/gapic/composer/resourcename", "//src/main/java/com/google/api/generator/gapic/model", "//src/main/java/com/google/api/generator/gapic/protoparser", + "//src/test/java/com/google/api/generator/gapic/composer/common", "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", "//src/test/java/com/google/api/generator/test/framework:asserts", "//src/test/java/com/google/api/generator/test/framework:utils", diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java index 16251dc124..c54218a52e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java @@ -15,13 +15,14 @@ package com.google.api.generator.gapic.composer.resourcename; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.common.TestProtoLoader; import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; -import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.test.framework.Assert; import com.google.api.generator.test.framework.Utils; @@ -94,14 +95,15 @@ public void generateResourceNameClass_echoFoobarMultiplePatterns() { Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); + Parser.parseService( + echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName foobarResname = resourceNames.get("showcase.googleapis.com/Foobar"); assertThat(outputResourceNames).contains(foobarResname); - GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(foobarResname); + GapicClass clazz = + ResourceNameHelperClassComposer.instance() + .generate(foobarResname, TestProtoLoader.instance().parseShowcaseEcho()); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); @@ -136,20 +138,16 @@ public void generateResourceNameClass_loggingOnePatternMultipleVariables() { resourceNames.putAll(Parser.parseResourceNames(commonResourcesFileDescriptor)); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - serviceFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + serviceFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName billingAccountLocationResname = resourceNames.get("logging.googleapis.com/BillingAccountLocation"); assertThat(outputResourceNames).contains(billingAccountLocationResname); GapicClass clazz = - ResourceNameHelperClassComposer.instance().generate(billingAccountLocationResname); + ResourceNameHelperClassComposer.instance() + .generate(billingAccountLocationResname, TestProtoLoader.instance().parseLogging()); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); @@ -168,18 +166,15 @@ public void generateResourceNameClass_testingSessionOnePattern() { Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - testingFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + testingFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName sessionResname = resourceNames.get("showcase.googleapis.com/Session"); assertThat(outputResourceNames).contains(sessionResname); - GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(sessionResname); + GapicClass clazz = + ResourceNameHelperClassComposer.instance() + .generate(sessionResname, TestProtoLoader.instance().parseShowcaseTesting()); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); @@ -197,18 +192,15 @@ public void generateResourceNameClass_testingBlueprintPatternWithNonSlashSeparat Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - testingFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + testingFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName testResname = resourceNames.get("showcase.googleapis.com/Test"); assertThat(outputResourceNames).contains(testResname); - GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(testResname); + GapicClass clazz = + ResourceNameHelperClassComposer.instance() + .generate(testResname, TestProtoLoader.instance().parseShowcaseTesting()); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); @@ -231,7 +223,9 @@ public void generateResourceNameClass_childSingleton() { .setDescription("This is a description") .build(); - GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(agentResname); + GapicContext irrelevantContext = TestProtoLoader.instance().parseShowcaseEcho(); + GapicClass clazz = + ResourceNameHelperClassComposer.instance().generate(agentResname, irrelevantContext); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "AgentName.golden", visitor.write()); diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java index 6e17170841..b49e731db2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java @@ -15,9 +15,8 @@ package com.google.api.generator.gapic.composer.resourcename; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; -import com.google.api.generator.gapic.composer.resourcename.ResourceNameTokenizer; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden index 595151d8c1..76f96eead8 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden @@ -164,7 +164,7 @@ public class AgentName implements ResourceName { } @Override - public boolean equals(Object o) { + public boolean equals(java.lang.Object o) { if (o == this) { return true; } @@ -217,8 +217,8 @@ public class AgentName implements ResourceName { Preconditions.checkArgument( Objects.equals(agentName.pathTemplate, PROJECT_LOCATION), "toBuilder is only supported when AgentName has the pattern of projects/{project}/locations/{location}/agent"); - project = agentName.project; - location = agentName.location; + this.project = agentName.project; + this.location = agentName.location; } public AgentName build() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden index ba8efd9eb6..68c8b4c472 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden @@ -120,7 +120,7 @@ public class BillingAccountLocationName implements ResourceName { } @Override - public boolean equals(Object o) { + public boolean equals(java.lang.Object o) { if (o == this) { return true; } @@ -168,8 +168,8 @@ public class BillingAccountLocationName implements ResourceName { } private Builder(BillingAccountLocationName billingAccountLocationName) { - billingAccount = billingAccountLocationName.billingAccount; - location = billingAccountLocationName.location; + this.billingAccount = billingAccountLocationName.billingAccount; + this.location = billingAccountLocationName.location; } public BillingAccountLocationName build() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden index f9b1fe01e3..4af08e31b7 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden @@ -258,7 +258,7 @@ public class FoobarName implements ResourceName { } @Override - public boolean equals(Object o) { + public boolean equals(java.lang.Object o) { if (o == this) { return true; } @@ -317,8 +317,8 @@ public class FoobarName implements ResourceName { Preconditions.checkArgument( Objects.equals(foobarName.pathTemplate, PROJECT_FOOBAR), "toBuilder is only supported when FoobarName has the pattern of projects/{project}/foobars/{foobar}"); - project = foobarName.project; - foobar = foobarName.foobar; + this.project = foobarName.project; + this.foobar = foobarName.foobar; } public FoobarName build() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden index 82ed52244b..d61bb14c47 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden @@ -142,7 +142,7 @@ public class SessionName implements ResourceName { } private Builder(SessionName sessionName) { - session = sessionName.session; + this.session = sessionName.session; } public SessionName build() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden index 5f99dac9ee..1864a4e7f9 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden @@ -194,9 +194,9 @@ public class TestName implements ResourceName { } private Builder(TestName testName) { - session = testName.session; - shardId = testName.shardId; - testId = testName.testId; + this.session = testName.session; + this.shardId = testName.shardId; + this.testId = testName.testId; } public TestName build() { diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel new file mode 100644 index 0000000000..c4532b3599 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/BUILD.bazel @@ -0,0 +1,92 @@ +load("@rules_java//java:defs.bzl", "java_proto_library", "java_test") +load("//:rules_bazel/java/java_diff_test.bzl", "golden_update") + +package(default_visibility = ["//visibility:public"]) + +TESTS = [ + "HttpJsonServiceCallableFactoryClassComposerTest", + "HttpJsonServiceStubClassComposerTest", + "ServiceClientTestClassComposerTest", + "ServiceSettingsClassComposerTest", + "ServiceStubSettingsClassComposerTest", +] + +COMMON_SRCS = [ + "RestTestProtoLoader.java", +] + +TEST_DEPS = [ + ":common_resources_java_proto", + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic/composer", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/rest", + "//src/test/java/com/google/api/generator/gapic/composer/common", + "//src/test/java/com/google/api/generator/test/framework:asserts", + "//src/test/java/com/google/api/generator/test/framework:utils", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/test/java/com/google/api/generator/testutils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/protoparser", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_api_common", + "@com_google_googleapis//google/logging/v2:logging_java_proto", + "@com_google_googleapis//google/pubsub/v1:pubsub_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + "@com_google_truth_truth//jar", + "@junit_junit//jar", +] + +filegroup( + name = "rest_files", + srcs = glob(["*.java"]), +) + +java_proto_library( + name = "common_resources_java_proto", + deps = [ + "@com_google_googleapis//google/cloud:common_resources_proto", + ], +) + +[java_test( + name = test_name, + size = "medium", + srcs = [ + "{0}.java".format(test_name), + ] + COMMON_SRCS, + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/rest/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.rest.{0}".format(test_name), + deps = TEST_DEPS, +) for test_name in TESTS] + +# Run `bazel run src/test/java/com/google/api/generator/gapic/composer/rest:testTargetName_update` +# to update goldens as expected generated code. +# `ServiceClient*` tests are not supported now since they are still in active development. + +[golden_update( + name = "{0}_update".format(test_name), + srcs = [ + "{0}.java".format(test_name), + ] + COMMON_SRCS, + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/rest/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.rest.{0}".format(test_name), + deps = TEST_DEPS, +) for test_name in TESTS] diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposerTest.java new file mode 100644 index 0000000000..2207e3d7d1 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class HttpJsonServiceCallableFactoryClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile( + this.getClass(), "HttpJsonComplianceCallableFactory.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "HttpJsonComplianceCallableFactory.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java new file mode 100644 index 0000000000..1efb7fd67b --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java @@ -0,0 +1,42 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class HttpJsonServiceStubClassComposerTest { + @Test + public void generateHttpJsonServiceStubClass_simple() { + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + HttpJsonServiceStubClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "HttpJsonComplianceStub.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "HttpJsonComplianceStub.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java new file mode 100644 index 0000000000..13ef1cea69 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java @@ -0,0 +1,78 @@ +// Copyright 2021 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. + +package com.google.api.generator.gapic.composer.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.api.generator.gapic.composer.common.TestProtoLoader; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.GapicServiceConfig; +import com.google.api.generator.gapic.model.Message; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.model.Transport; +import com.google.api.generator.gapic.protoparser.Parser; +import com.google.api.generator.gapic.protoparser.ServiceConfigParser; +import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.ServiceDescriptor; +import com.google.showcase.v1beta1.ComplianceOuterClass; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public class RestTestProtoLoader extends TestProtoLoader { + private static final RestTestProtoLoader INSTANCE = new RestTestProtoLoader(); + + protected RestTestProtoLoader() { + super(Transport.REST, "src/test/java/com/google/api/generator/gapic/testdata/"); + } + + public static RestTestProtoLoader instance() { + return INSTANCE; + } + + public GapicContext parseCompliance() { + FileDescriptor echoFileDescriptor = ComplianceOuterClass.getDescriptor(); + ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); + assertEquals(echoServiceDescriptor.getName(), "Compliance"); + + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); + + String jsonFilename = "showcase_grpc_service_config.json"; + Path jsonPath = Paths.get(getTestFilesDirectory(), jsonFilename); + Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); + assertTrue(configOpt.isPresent()); + GapicServiceConfig config = configOpt.get(); + + return GapicContext.builder() + .setMessages(messageTypes) + .setResourceNames(resourceNames) + .setServices(services) + .setServiceConfig(config) + .setHelperResourceNames(outputResourceNames) + .setTransport(getTransport()) + .build(); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java new file mode 100644 index 0000000000..028f4cca14 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.rest; + +import static com.google.api.generator.test.framework.Assert.assertCodeEquals; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceClientTestClassComposerTest { + @Test + public void generateClientTest_echoClient() { + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + ServiceClientTestClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "ComplianceClientTest.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "ComplianceClientTest.golden"); + assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposerTest.java new file mode 100644 index 0000000000..5631b00607 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceSettingsClassComposerTest.java @@ -0,0 +1,41 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceSettingsClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = ServiceSettingsClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "ComplianceSettings.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "ComplianceSettings.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java new file mode 100644 index 0000000000..53392a549e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java @@ -0,0 +1,42 @@ +// Copyright 2020 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. + +package com.google.api.generator.gapic.composer.rest; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceStubSettingsClassComposerTest { + @Test + public void generateServiceStubSettingsClasses_basic() { + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + ServiceStubSettingsClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "ComplianceStubSettings.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "ComplianceStubSettings.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/BUILD.bazel new file mode 100644 index 0000000000..85ac1a519e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob(["*.golden"]), +) diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceClientTest.golden new file mode 100644 index 0000000000..9bc2d799ce --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceClientTest.golden @@ -0,0 +1,368 @@ +package com.google.showcase.v1beta1; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.showcase.v1beta1.stub.HttpJsonComplianceStub; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class ComplianceClientTest { + private static MockHttpService mockService; + private static ComplianceClient client; + + @BeforeClass + public static void startStaticServer() throws IOException { + mockService = + new MockHttpService( + HttpJsonComplianceStub.getMethodDescriptors(), ComplianceSettings.getDefaultEndpoint()); + ComplianceSettings settings = + ComplianceSettings.newBuilder() + .setTransportChannelProvider( + ComplianceSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(mockService) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = ComplianceClient.create(settings); + } + + @AfterClass + public static void stopServer() { + client.close(); + } + + @Before + public void setUp() {} + + @After + public void tearDown() throws Exception { + mockService.reset(); + } + + @Test + public void repeatDataBodyTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataBody(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataBodyExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataBody(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void repeatDataBodyInfoTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataBodyInfo(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataBodyInfoExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataBodyInfo(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void repeatDataQueryTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataQuery(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataQueryExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataQuery(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void repeatDataSimplePathTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataSimplePath(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataSimplePathExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataSimplePath(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void repeatDataPathResourceTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataPathResource(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataPathResourceExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataPathResource(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void repeatDataPathTrailingResourceTest() throws Exception { + RepeatResponse expectedResponse = + RepeatResponse.newBuilder().setInfo(ComplianceData.newBuilder().build()).build(); + mockService.addResponse(expectedResponse); + + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + + RepeatResponse actualResponse = client.repeatDataPathTrailingResource(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void repeatDataPathTrailingResourceExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + RepeatRequest request = + RepeatRequest.newBuilder() + .setName("name3373707") + .setInfo(ComplianceData.newBuilder().build()) + .setServerVerify(true) + .build(); + client.repeatDataPathTrailingResource(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceSettings.golden new file mode 100644 index 0000000000..11af8d46ae --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceSettings.golden @@ -0,0 +1,218 @@ +package com.google.showcase.v1beta1; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.showcase.v1beta1.stub.ComplianceStubSettings; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link ComplianceClient}. + * + *

The default instance has everything set to sensible defaults: + * + *

    + *
  • The default service address (localhost) and default port (7469) are used. + *
  • Credentials are acquired automatically through Application Default Credentials. + *
  • Retries are configured for idempotent methods but not for non-idempotent methods. + *
+ * + *

The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

For example, to set the total timeout of repeatDataBody to 30 seconds: + * + *

{@code
+ * ComplianceSettings.Builder complianceSettingsBuilder = ComplianceSettings.newBuilder();
+ * complianceSettingsBuilder
+ *     .repeatDataBodySettings()
+ *     .setRetrySettings(
+ *         complianceSettingsBuilder
+ *             .repeatDataBodySettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * ComplianceSettings complianceSettings = complianceSettingsBuilder.build();
+ * }
+ */ +@BetaApi +@Generated("by gapic-generator-java") +public class ComplianceSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to repeatDataBody. */ + public UnaryCallSettings repeatDataBodySettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataBodySettings(); + } + + /** Returns the object with the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings repeatDataBodyInfoSettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataBodyInfoSettings(); + } + + /** Returns the object with the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings repeatDataQuerySettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataQuerySettings(); + } + + /** Returns the object with the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings repeatDataSimplePathSettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataSimplePathSettings(); + } + + /** Returns the object with the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings repeatDataPathResourceSettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataPathResourceSettings(); + } + + /** Returns the object with the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings repeatDataPathTrailingResourceSettings() { + return ((ComplianceStubSettings) getStubSettings()).repeatDataPathTrailingResourceSettings(); + } + + public static final ComplianceSettings create(ComplianceStubSettings stub) throws IOException { + return new ComplianceSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return ComplianceStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return ComplianceStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return ComplianceStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return ComplianceStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return ComplianceStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return ComplianceStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ComplianceStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected ComplianceSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for ComplianceSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(ComplianceStubSettings.newBuilder(clientContext)); + } + + protected Builder(ComplianceSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(ComplianceStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(ComplianceStubSettings.newBuilder()); + } + + public ComplianceStubSettings.Builder getStubSettingsBuilder() { + return ((ComplianceStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to repeatDataBody. */ + public UnaryCallSettings.Builder repeatDataBodySettings() { + return getStubSettingsBuilder().repeatDataBodySettings(); + } + + /** Returns the builder for the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings.Builder repeatDataBodyInfoSettings() { + return getStubSettingsBuilder().repeatDataBodyInfoSettings(); + } + + /** Returns the builder for the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings.Builder repeatDataQuerySettings() { + return getStubSettingsBuilder().repeatDataQuerySettings(); + } + + /** Returns the builder for the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings.Builder repeatDataSimplePathSettings() { + return getStubSettingsBuilder().repeatDataSimplePathSettings(); + } + + /** Returns the builder for the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings.Builder + repeatDataPathResourceSettings() { + return getStubSettingsBuilder().repeatDataPathResourceSettings(); + } + + /** Returns the builder for the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings() { + return getStubSettingsBuilder().repeatDataPathTrailingResourceSettings(); + } + + @Override + public ComplianceSettings build() throws IOException { + return new ComplianceSettings(this); + } + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden new file mode 100644 index 0000000000..a858c0123e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden @@ -0,0 +1,366 @@ +package com.google.showcase.v1beta1.stub; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.showcase.v1beta1.RepeatRequest; +import com.google.showcase.v1beta1.RepeatResponse; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link ComplianceStub}. + * + *

The default instance has everything set to sensible defaults: + * + *

    + *
  • The default service address (localhost) and default port (7469) are used. + *
  • Credentials are acquired automatically through Application Default Credentials. + *
  • Retries are configured for idempotent methods but not for non-idempotent methods. + *
+ * + *

The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

For example, to set the total timeout of repeatDataBody to 30 seconds: + * + *

{@code
+ * ComplianceStubSettings.Builder complianceSettingsBuilder = ComplianceStubSettings.newBuilder();
+ * complianceSettingsBuilder
+ *     .repeatDataBodySettings()
+ *     .setRetrySettings(
+ *         complianceSettingsBuilder
+ *             .repeatDataBodySettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * ComplianceStubSettings complianceSettings = complianceSettingsBuilder.build();
+ * }
+ */ +@BetaApi +@Generated("by gapic-generator-java") +public class ComplianceStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder().build(); + + private final UnaryCallSettings repeatDataBodySettings; + private final UnaryCallSettings repeatDataBodyInfoSettings; + private final UnaryCallSettings repeatDataQuerySettings; + private final UnaryCallSettings repeatDataSimplePathSettings; + private final UnaryCallSettings repeatDataPathResourceSettings; + private final UnaryCallSettings + repeatDataPathTrailingResourceSettings; + + /** Returns the object with the settings used for calls to repeatDataBody. */ + public UnaryCallSettings repeatDataBodySettings() { + return repeatDataBodySettings; + } + + /** Returns the object with the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings repeatDataBodyInfoSettings() { + return repeatDataBodyInfoSettings; + } + + /** Returns the object with the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings repeatDataQuerySettings() { + return repeatDataQuerySettings; + } + + /** Returns the object with the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings repeatDataSimplePathSettings() { + return repeatDataSimplePathSettings; + } + + /** Returns the object with the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings repeatDataPathResourceSettings() { + return repeatDataPathResourceSettings; + } + + /** Returns the object with the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings repeatDataPathTrailingResourceSettings() { + return repeatDataPathTrailingResourceSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public ComplianceStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonComplianceStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "localhost:7469"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "localhost:7469"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultHttpJsonTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(ComplianceStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected ComplianceStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + repeatDataBodySettings = settingsBuilder.repeatDataBodySettings().build(); + repeatDataBodyInfoSettings = settingsBuilder.repeatDataBodyInfoSettings().build(); + repeatDataQuerySettings = settingsBuilder.repeatDataQuerySettings().build(); + repeatDataSimplePathSettings = settingsBuilder.repeatDataSimplePathSettings().build(); + repeatDataPathResourceSettings = settingsBuilder.repeatDataPathResourceSettings().build(); + repeatDataPathTrailingResourceSettings = + settingsBuilder.repeatDataPathTrailingResourceSettings().build(); + } + + /** Builder for ComplianceStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final UnaryCallSettings.Builder repeatDataBodySettings; + private final UnaryCallSettings.Builder + repeatDataBodyInfoSettings; + private final UnaryCallSettings.Builder repeatDataQuerySettings; + private final UnaryCallSettings.Builder + repeatDataSimplePathSettings; + private final UnaryCallSettings.Builder + repeatDataPathResourceSettings; + private final UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = RetrySettings.newBuilder().setRpcTimeoutMultiplier(1.0).build(); + definitions.put("no_retry_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + repeatDataBodySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataBodyInfoSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataQuerySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataSimplePathSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathTrailingResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); + initDefaults(this); + } + + protected Builder(ComplianceStubSettings settings) { + super(settings); + + repeatDataBodySettings = settings.repeatDataBodySettings.toBuilder(); + repeatDataBodyInfoSettings = settings.repeatDataBodyInfoSettings.toBuilder(); + repeatDataQuerySettings = settings.repeatDataQuerySettings.toBuilder(); + repeatDataSimplePathSettings = settings.repeatDataSimplePathSettings.toBuilder(); + repeatDataPathResourceSettings = settings.repeatDataPathResourceSettings.toBuilder(); + repeatDataPathTrailingResourceSettings = + settings.repeatDataPathTrailingResourceSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .repeatDataBodySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + builder + .repeatDataBodyInfoSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + builder + .repeatDataQuerySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + builder + .repeatDataSimplePathSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + builder + .repeatDataPathResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + builder + .repeatDataPathTrailingResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to repeatDataBody. */ + public UnaryCallSettings.Builder repeatDataBodySettings() { + return repeatDataBodySettings; + } + + /** Returns the builder for the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings.Builder repeatDataBodyInfoSettings() { + return repeatDataBodyInfoSettings; + } + + /** Returns the builder for the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings.Builder repeatDataQuerySettings() { + return repeatDataQuerySettings; + } + + /** Returns the builder for the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings.Builder repeatDataSimplePathSettings() { + return repeatDataSimplePathSettings; + } + + /** Returns the builder for the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings.Builder + repeatDataPathResourceSettings() { + return repeatDataPathResourceSettings; + } + + /** Returns the builder for the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings() { + return repeatDataPathTrailingResourceSettings; + } + + @Override + public ComplianceStubSettings build() throws IOException { + return new ComplianceStubSettings(this); + } + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden new file mode 100644 index 0000000000..7d6032778d --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -0,0 +1,68 @@ +package com.google.showcase.v1beta1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the Compliance service API. + * + *

This class is for advanced usage. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class HttpJsonComplianceCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + BackgroundResource operationsStub) { + return null; + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden new file mode 100644 index 0000000000..331e5bf961 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden @@ -0,0 +1,449 @@ +package com.google.showcase.v1beta1.stub; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.showcase.v1beta1.RepeatRequest; +import com.google.showcase.v1beta1.RepeatResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the Compliance service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@BetaApi +@Generated("by gapic-generator-java") +@BetaApi("A restructuring of stub classes is planned, so this may break in the future") +public class HttpJsonComplianceStub extends ComplianceStub { + private static final ApiMethodDescriptor + repeatDataBodyMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataBody") + .setHttpMethod(HttpMethods.POST) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat:body", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + repeatDataBodyInfoMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataBodyInfo") + .setHttpMethod(HttpMethods.POST) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat:bodyinfo", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "name", request.getName()); + serializer.putQueryParam( + fields, "serverVerify", request.getServerVerify()); + return fields; + }) + .setRequestBodyExtractor( + request -> ProtoRestSerializer.create().toBody("info", request.getInfo())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + repeatDataQueryMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataQuery") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat:query", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "info", request.getInfo()); + serializer.putQueryParam(fields, "name", request.getName()); + serializer.putQueryParam( + fields, "serverVerify", request.getServerVerify()); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + repeatDataSimplePathMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataSimplePath") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat/{info.fString}/{info.fInt32}/{info.fDouble}/{info.fBool}/{info.fKingdom}:simplepath", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.getInfo().hasFBool()) { + serializer.putPathParam( + fields, "info.fBool", request.getInfo().getFBool()); + } + serializer.putPathParam( + fields, "info.fDouble", request.getInfo().getFDouble()); + serializer.putPathParam( + fields, "info.fInt32", request.getInfo().getFInt32()); + serializer.putPathParam( + fields, "info.fKingdom", request.getInfo().getFKingdom()); + serializer.putPathParam( + fields, "info.fString", request.getInfo().getFString()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "info", request.getInfo()); + serializer.putQueryParam(fields, "name", request.getName()); + serializer.putQueryParam( + fields, "serverVerify", request.getServerVerify()); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + repeatDataPathResourceMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataPathResource") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat/{info.fString=first/*}/{info.fChild.fString=second/*}/bool/{info.fBool}:pathresource", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.getInfo().hasFBool()) { + serializer.putPathParam( + fields, "info.fBool", request.getInfo().getFBool()); + } + serializer.putPathParam( + fields, + "info.fChild.fString", + request.getInfo().getFChild().getFString()); + serializer.putPathParam( + fields, "info.fString", request.getInfo().getFString()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "info", request.getInfo()); + serializer.putQueryParam(fields, "name", request.getName()); + serializer.putQueryParam( + fields, "serverVerify", request.getServerVerify()); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor + repeatDataPathTrailingResourceMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName( + "google.showcase.v1beta1.Compliance/RepeatDataPathTrailingResource") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/repeat/{info.fString=first/*}/{info.fChild.fString=second/**}:pathtrailingresource", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam( + fields, + "info.fChild.fString", + request.getInfo().getFChild().getFString()); + serializer.putPathParam( + fields, "info.fString", request.getInfo().getFString()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "info", request.getInfo()); + serializer.putQueryParam(fields, "name", request.getName()); + serializer.putQueryParam( + fields, "serverVerify", request.getServerVerify()); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .build()) + .build(); + + private final UnaryCallable repeatDataBodyCallable; + private final UnaryCallable repeatDataBodyInfoCallable; + private final UnaryCallable repeatDataQueryCallable; + private final UnaryCallable repeatDataSimplePathCallable; + private final UnaryCallable repeatDataPathResourceCallable; + private final UnaryCallable repeatDataPathTrailingResourceCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonComplianceStub create(ComplianceStubSettings settings) + throws IOException { + return new HttpJsonComplianceStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonComplianceStub create(ClientContext clientContext) + throws IOException { + return new HttpJsonComplianceStub(ComplianceStubSettings.newBuilder().build(), clientContext); + } + + public static final HttpJsonComplianceStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonComplianceStub( + ComplianceStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonComplianceStub, using the given settings. This is protected + * so that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonComplianceStub(ComplianceStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new HttpJsonComplianceCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonComplianceStub, using the given settings. This is protected + * so that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonComplianceStub( + ComplianceStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings repeatDataBodyTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataBodyMethodDescriptor) + .build(); + HttpJsonCallSettings repeatDataBodyInfoTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataBodyInfoMethodDescriptor) + .build(); + HttpJsonCallSettings repeatDataQueryTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataQueryMethodDescriptor) + .build(); + HttpJsonCallSettings repeatDataSimplePathTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataSimplePathMethodDescriptor) + .build(); + HttpJsonCallSettings repeatDataPathResourceTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataPathResourceMethodDescriptor) + .build(); + HttpJsonCallSettings + repeatDataPathTrailingResourceTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(repeatDataPathTrailingResourceMethodDescriptor) + .build(); + + this.repeatDataBodyCallable = + callableFactory.createUnaryCallable( + repeatDataBodyTransportSettings, settings.repeatDataBodySettings(), clientContext); + this.repeatDataBodyInfoCallable = + callableFactory.createUnaryCallable( + repeatDataBodyInfoTransportSettings, + settings.repeatDataBodyInfoSettings(), + clientContext); + this.repeatDataQueryCallable = + callableFactory.createUnaryCallable( + repeatDataQueryTransportSettings, settings.repeatDataQuerySettings(), clientContext); + this.repeatDataSimplePathCallable = + callableFactory.createUnaryCallable( + repeatDataSimplePathTransportSettings, + settings.repeatDataSimplePathSettings(), + clientContext); + this.repeatDataPathResourceCallable = + callableFactory.createUnaryCallable( + repeatDataPathResourceTransportSettings, + settings.repeatDataPathResourceSettings(), + clientContext); + this.repeatDataPathTrailingResourceCallable = + callableFactory.createUnaryCallable( + repeatDataPathTrailingResourceTransportSettings, + settings.repeatDataPathTrailingResourceSettings(), + clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(repeatDataBodyMethodDescriptor); + methodDescriptors.add(repeatDataBodyInfoMethodDescriptor); + methodDescriptors.add(repeatDataQueryMethodDescriptor); + methodDescriptors.add(repeatDataSimplePathMethodDescriptor); + methodDescriptors.add(repeatDataPathResourceMethodDescriptor); + methodDescriptors.add(repeatDataPathTrailingResourceMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable repeatDataBodyCallable() { + return repeatDataBodyCallable; + } + + @Override + public UnaryCallable repeatDataBodyInfoCallable() { + return repeatDataBodyInfoCallable; + } + + @Override + public UnaryCallable repeatDataQueryCallable() { + return repeatDataQueryCallable; + } + + @Override + public UnaryCallable repeatDataSimplePathCallable() { + return repeatDataSimplePathCallable; + } + + @Override + public UnaryCallable repeatDataPathResourceCallable() { + return repeatDataPathResourceCallable; + } + + @Override + public UnaryCallable repeatDataPathTrailingResourceCallable() { + return repeatDataPathTrailingResourceCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SampleCodeWriterTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SampleCodeWriterTest.java index 4e5be8cd19..d9456c7dcf 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SampleCodeWriterTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SampleCodeWriterTest.java @@ -22,9 +22,9 @@ import com.google.api.generator.engine.ast.ExprStatement; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.PrimitiveValue; -import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.Statement; import com.google.api.generator.engine.ast.TryCatchStatement; +import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; @@ -34,47 +34,49 @@ public class SampleCodeWriterTest { @Test public void writeSampleCode_statements() { - TypeNode settingType = TypeNode.withReference(ConcreteReference.withClazz(ClientSettings.class)); + TypeNode settingType = + TypeNode.withReference(ConcreteReference.withClazz(ClientSettings.class)); Variable aVar = Variable.builder().setName("clientSettings").setType(settingType).build(); VariableExpr aVarExpr = VariableExpr.withVariable(aVar); - MethodInvocationExpr aValueExpr = MethodInvocationExpr.builder() - .setExprReferenceExpr(MethodInvocationExpr.builder() - .setMethodName("newBuilder") - .setStaticReferenceType(settingType) - .build()) - .setReturnType(settingType) - .setMethodName("build") - .build(); - AssignmentExpr assignmentExpr = AssignmentExpr.builder() - .setVariableExpr(aVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(aValueExpr) - .build(); - Statement sampleStatement = TryCatchStatement.builder() - .setTryResourceExpr(createAssignmentExpr("aBool", "false", TypeNode.BOOLEAN)) - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("x", "3", TypeNode.INT)))) - .setIsSampleCode(true) - .build(); - String result = SampleCodeWriter.write( - ExprStatement.withExpr(assignmentExpr), - sampleStatement); - String expected = "ClientSettings clientSettings = ClientSettings.newBuilder().build();\n" - + "try (boolean aBool = false) {\n" - + " int x = 3;\n" - + "}"; + MethodInvocationExpr aValueExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("newBuilder") + .setStaticReferenceType(settingType) + .build()) + .setReturnType(settingType) + .setMethodName("build") + .build(); + AssignmentExpr assignmentExpr = + AssignmentExpr.builder() + .setVariableExpr(aVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(aValueExpr) + .build(); + Statement sampleStatement = + TryCatchStatement.builder() + .setTryResourceExpr(createAssignmentExpr("aBool", "false", TypeNode.BOOLEAN)) + .setTryBody( + Arrays.asList(ExprStatement.withExpr(createAssignmentExpr("x", "3", TypeNode.INT)))) + .setIsSampleCode(true) + .build(); + String result = SampleCodeWriter.write(ExprStatement.withExpr(assignmentExpr), sampleStatement); + String expected = + "ClientSettings clientSettings = ClientSettings.newBuilder().build();\n" + + "try (boolean aBool = false) {\n" + + " int x = 3;\n" + + "}"; assertEquals(expected, result); } private AssignmentExpr createAssignmentExpr(String varName, String varValue, TypeNode type) { Variable variable = Variable.builder().setName(varName).setType(type).build(); VariableExpr variableExpr = - VariableExpr.builder() - .setVariable(variable) - .setIsDecl(true) - .build(); + VariableExpr.builder().setVariable(variable).setIsDecl(true).build(); return AssignmentExpr.builder() .setVariableExpr(variableExpr) - .setValueExpr(ValueExpr.withValue(PrimitiveValue.builder().setType(type).setValue(varValue).build())) + .setValueExpr( + ValueExpr.withValue(PrimitiveValue.builder().setType(type).setValue(varValue).build())) .build(); } - } diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java index e360b1eb3a..59eb3536be 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.samplecode; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.ConcreteReference; @@ -32,7 +32,6 @@ import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.testutils.LineFormatter; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; import java.util.Arrays; import java.util.Collections; @@ -47,6 +46,7 @@ public class ServiceClientSampleCodeComposerTest { private static final String SHOWCASE_PACKAGE_NAME = "com.google.showcase.v1beta1"; private static final String LRO_PACKAGE_NAME = "com.google.longrunning"; private static final String PROTO_PACKAGE_NAME = "com.google.protobuf"; + private static final String PAGINATED_FIELD_NAME = "page_size"; // =============================== Class Header Sample Code ===============================// @Test @@ -54,7 +54,6 @@ public void composeClassHeaderMethodSampleCode_unaryRpc() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Map messageTypes = Parser.parseMessages(echoFileDescriptor); - ServiceDescriptor echoService = echoFileDescriptor.getServices().get(0); Set outputResourceNames = new HashSet<>(); List services = Parser.parseService( @@ -1005,7 +1004,7 @@ public void validComposeRpcMethodHeaderSampleCode_pagedRpcWithMultipleMethodArgu .setMethodSignatures(Arrays.asList(arguments)) .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); Reference repeatedResponseReference = VaporReference.builder().setName("Content").setPakkage(SHOWCASE_PACKAGE_NAME).build(); @@ -1078,7 +1077,7 @@ public void validComposeRpcMethodHeaderSampleCode_pagedRpcWithNoMethodArguments( .setMethodSignatures(Arrays.asList(arguments)) .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); Reference repeatedResponseReference = VaporReference.builder().setName("Content").setPakkage(SHOWCASE_PACKAGE_NAME).build(); @@ -1148,7 +1147,7 @@ public void invalidComposeRpcMethodHeaderSampleCode_noMatchedRepeatedResponseTyp .setMethodSignatures(Arrays.asList(methodArguments)) .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); assertThrows( NullPointerException.class, @@ -1187,7 +1186,7 @@ public void invalidComposeRpcMethodHeaderSampleCode_noRepeatedResponseTypeInPage .setMethodSignatures(Arrays.asList(methodArguments)) .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); Field responseField = Field.builder() @@ -1439,7 +1438,7 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_isPagedMethod() { .setInputType(inputType) .setOutputType(outputType) .setMethodSignatures(Collections.emptyList()) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); String results = ServiceClientSampleCodeComposer.composeRpcDefaultMethodHeaderSampleCode( @@ -1489,7 +1488,7 @@ public void invalidComposeRpcDefaultMethodHeaderSampleCode_isPagedMethod() { .setInputType(inputType) .setOutputType(outputType) .setMethodSignatures(Collections.emptyList()) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); assertThrows( NullPointerException.class, @@ -1835,7 +1834,7 @@ public void validComposePagedCallableMethodHeaderSampleCode() { .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); String results = ServiceClientSampleCodeComposer.composePagedCallableMethodHeaderSampleCode( @@ -1887,7 +1886,7 @@ public void invalidComposePagedCallableMethodHeaderSampleCode_inputTypeNotExistI .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); assertThrows( NullPointerException.class, @@ -1924,7 +1923,7 @@ public void invalidComposePagedCallableMethodHeaderSampleCode_noExistMethodRespo .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); assertThrows( NullPointerException.class, @@ -1961,7 +1960,7 @@ public void invalidComposePagedCallableMethodHeaderSampleCode_noRepeatedResponse .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); Field responseField = Field.builder().setName("response").setType(TypeNode.STRING).build(); Message noRepeatedResponseMessage = @@ -2449,7 +2448,7 @@ public void validComposeRegularCallableMethodHeaderSampleCode_pageRpc() { .setInputType(inputType) .setOutputType(outputType) .setMethodSignatures(Collections.emptyList()) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); String results = ServiceClientSampleCodeComposer.composeRegularCallableMethodHeaderSampleCode( @@ -2539,7 +2538,7 @@ public void invalidComposeRegularCallableMethodHeaderSampleCode_noExistMethodRes .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); assertThrows( NullPointerException.class, @@ -2576,7 +2575,7 @@ public void invalidComposeRegularCallableMethodHeaderSampleCode_noRepeatedRespon .setName("PagedExpand") .setInputType(inputType) .setOutputType(outputType) - .setIsPaged(true) + .setPageSizeFieldName(PAGINATED_FIELD_NAME) .build(); Field responseField = Field.builder().setName("response").setType(TypeNode.STRING).build(); Message noRepeatedResponseMessage = diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java index b7438e4732..a62d57275c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.samplecode; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; @@ -25,56 +25,68 @@ public class SettingsSampleCodeComposerTest { @Test public void composeSettingsSampleCode_noMethods() { - TypeNode classType = TypeNode.withReference(VaporReference.builder() - .setName("EchoSettings") - .setPakkage("com.google.showcase.v1beta1") - .build()); - Optional results = SettingsSampleCodeComposer.composeSampleCode(Optional.empty(), "EchoSettings", classType); + TypeNode classType = + TypeNode.withReference( + VaporReference.builder() + .setName("EchoSettings") + .setPakkage("com.google.showcase.v1beta1") + .build()); + Optional results = + SettingsSampleCodeComposer.composeSampleCode(Optional.empty(), "EchoSettings", classType); assertEquals(results, Optional.empty()); } @Test public void composeSettingsSampleCode_serviceSettingsClass() { - TypeNode classType = TypeNode.withReference(VaporReference.builder() - .setName("EchoSettings") - .setPakkage("com.google.showcase.v1beta1") - .build()); - Optional results = SettingsSampleCodeComposer.composeSampleCode(Optional.of("Echo"), "EchoSettings", classType); - String expected = LineFormatter.lines( - "EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder();\n", - "echoSettingsBuilder\n", - " .echoSettings()\n", - " .setRetrySettings(\n", - " echoSettingsBuilder\n", - " .echoSettings()\n", - " .getRetrySettings()\n", - " .toBuilder()\n", - " .setTotalTimeout(Duration.ofSeconds(30))\n", - " .build());\n", - "EchoSettings echoSettings = echoSettingsBuilder.build();"); + TypeNode classType = + TypeNode.withReference( + VaporReference.builder() + .setName("EchoSettings") + .setPakkage("com.google.showcase.v1beta1") + .build()); + Optional results = + SettingsSampleCodeComposer.composeSampleCode( + Optional.of("Echo"), "EchoSettings", classType); + String expected = + LineFormatter.lines( + "EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder();\n", + "echoSettingsBuilder\n", + " .echoSettings()\n", + " .setRetrySettings(\n", + " echoSettingsBuilder\n", + " .echoSettings()\n", + " .getRetrySettings()\n", + " .toBuilder()\n", + " .setTotalTimeout(Duration.ofSeconds(30))\n", + " .build());\n", + "EchoSettings echoSettings = echoSettingsBuilder.build();"); assertEquals(results.get(), expected); } @Test public void composeSettingsSampleCode_serviceStubClass() { - TypeNode classType = TypeNode.withReference(VaporReference.builder() - .setName("EchoStubSettings") - .setPakkage("com.google.showcase.v1beta1") - .build()); - Optional results = SettingsSampleCodeComposer.composeSampleCode(Optional.of("Echo"), "EchoSettings", classType); - String expected = LineFormatter.lines( - "EchoStubSettings.Builder echoSettingsBuilder = EchoStubSettings.newBuilder();\n", - "echoSettingsBuilder\n", - " .echoSettings()\n", - " .setRetrySettings(\n", - " echoSettingsBuilder\n", - " .echoSettings()\n", - " .getRetrySettings()\n", - " .toBuilder()\n", - " .setTotalTimeout(Duration.ofSeconds(30))\n", - " .build());\n", - "EchoStubSettings echoSettings = echoSettingsBuilder.build();"); + TypeNode classType = + TypeNode.withReference( + VaporReference.builder() + .setName("EchoStubSettings") + .setPakkage("com.google.showcase.v1beta1") + .build()); + Optional results = + SettingsSampleCodeComposer.composeSampleCode( + Optional.of("Echo"), "EchoSettings", classType); + String expected = + LineFormatter.lines( + "EchoStubSettings.Builder echoSettingsBuilder = EchoStubSettings.newBuilder();\n", + "echoSettingsBuilder\n", + " .echoSettings()\n", + " .setRetrySettings(\n", + " echoSettingsBuilder\n", + " .echoSettings()\n", + " .getRetrySettings()\n", + " .toBuilder()\n", + " .setTotalTimeout(Duration.ofSeconds(30))\n", + " .build());\n", + "EchoStubSettings echoSettings = echoSettingsBuilder.build();"); assertEquals(results.get(), expected); } - } diff --git a/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java b/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java index 9cde282e24..c8f220f65e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.utils; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java b/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java index 61f9e45b02..6c5a0846e7 100644 --- a/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java +++ b/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java @@ -15,14 +15,13 @@ package com.google.api.generator.gapic.model; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.protobuf.util.Durations; import com.google.rpc.Code; import com.google.showcase.v1beta1.EchoOuterClass; @@ -45,7 +44,6 @@ public class GapicServiceConfigTest { @Test public void serviceConfig_noConfigsFound() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "retrying_grpc_service_config.json"; @@ -74,7 +72,6 @@ public void serviceConfig_noConfigsFound() { @Test public void serviceConfig_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; @@ -129,7 +126,6 @@ public void serviceConfig_basic() { @Test public void serviceConfig_withBatchingSettings() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; @@ -203,12 +199,10 @@ public void serviceConfig_withBatchingSettings() { @Test public void serviceConfig_withLroRetrySettings() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; Path jsonPath = Paths.get(TESTDATA_DIRECTORY, jsonFilename); - Optional> batchingSettingsOpt = Optional.empty(); // Construct LRO retry settings. GapicLroRetrySettings origLroRetrySetting = diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel index abf6a5e00a..f15a3d1a6e 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel @@ -41,6 +41,7 @@ filegroup( "//src/main/java/com/google/api/generator/gapic/model", "//src/main/java/com/google/api/generator/gapic/protoparser", "//src/main/java/com/google/api/generator/gapic/utils", + "//src/test/java/com/google/api/generator/gapic/testdata:bookshop_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", "@com_google_api_api_common//jar", diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java index 92ba2e5094..3d3c16dc6e 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java @@ -15,9 +15,9 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicBatchingSettings; import java.nio.file.Path; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java index 111abd1a80..1db960c0ab 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicLanguageSettings; import java.nio.file.Path; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java index 262b266f53..664b7d2e69 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import com.google.api.generator.gapic.model.GapicLroRetrySettings; import java.nio.file.Path; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java index 59a0775b69..31fc531555 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java @@ -15,19 +15,19 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import com.google.api.generator.gapic.model.HttpBindings; +import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; import com.google.api.generator.gapic.model.Message; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.TestingOuterClass; -import java.util.List; import java.util.Map; -import java.util.Optional; +import java.util.stream.Collectors; import org.junit.Test; public class HttpRuleParserTest { @@ -42,16 +42,18 @@ public void parseHttpAnnotation_basic() { // CreateSession method. MethodDescriptor rpcMethod = testingService.getMethods().get(0); Message inputMessage = messages.get("com.google.showcase.v1beta1.CreateSessionRequest"); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertFalse(httpBindingsOpt.isPresent()); + HttpBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertTrue(httpBindings.pathParameters().isEmpty()); // GetSession method. rpcMethod = testingService.getMethods().get(1); inputMessage = messages.get("com.google.showcase.v1beta1.GetSessionRequest"); - httpBindingsOpt = HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertTrue(httpBindingsOpt.isPresent()); - assertThat(httpBindingsOpt.get()).containsExactly("name"); + httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertThat( + httpBindings.pathParameters().stream() + .map(HttpBinding::name) + .collect(Collectors.toList())) + .containsExactly("name"); } @Test @@ -66,10 +68,11 @@ public void parseHttpAnnotation_multipleBindings() { MethodDescriptor rpcMethod = testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("com.google.showcase.v1beta1.VerifyTestRequest"); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertTrue(httpBindingsOpt.isPresent()); - assertThat(httpBindingsOpt.get()) + HttpBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertThat( + httpBindings.pathParameters().stream() + .map(HttpBinding::name) + .collect(Collectors.toList())) .containsExactly("answer", "foo", "name", "test_to_verify.name", "type"); } @@ -86,7 +89,6 @@ public void parseHttpAnnotation_missingFieldFromMessage() { testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("com.google.showcase.v1beta1.CreateSessionRequest"); assertThrows( - IllegalStateException.class, - () -> HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages)); + IllegalStateException.class, () -> HttpRuleParser.parse(rpcMethod, inputMessage, messages)); } } diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java index 4f141f6125..68a2bbc66b 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java @@ -14,16 +14,13 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.gapic.model.Field; import com.google.api.generator.gapic.model.MethodArgument; -import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; -import com.google.testgapic.v1beta1.LockerProto; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -31,20 +28,9 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; -import org.junit.Before; import org.junit.Test; public class MethodSignatureParserTest { - private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - - private ServiceDescriptor lockerService; - private FileDescriptor lockerServiceFileDescriptor; - - @Before - public void setUp() { - lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); - } @Test public void flattenMethodSignatures_basic() { diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index b19aa30b92..9026437b6d 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -15,10 +15,10 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Reference; @@ -30,6 +30,8 @@ import com.google.api.generator.gapic.model.MethodArgument; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.ResourceReference; +import com.google.api.generator.gapic.model.Transport; +import com.google.bookshop.v1beta1.BookshopProto; import com.google.common.collect.ImmutableList; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; @@ -96,6 +98,17 @@ public void parseMessages_basic() { echoResponseMessage, messageTypes.get("com.google.showcase.v1beta1." + echoResponseName)); } + @Test + public void parseMessages_fieldNameConflicts() { + FileDescriptor bookshopFileDescriptor = BookshopProto.getDescriptor(); + Map messageTypes = Parser.parseMessages(bookshopFileDescriptor); + Message requestMessage = messageTypes.get("com.google.bookshop.v1beta1.GetBookRequest"); + // Check that field names have been changed. + assertThat(requestMessage.fieldMap()).containsKey("books_count1"); + assertThat(requestMessage.fieldMap()).containsKey("books_list2"); + assertThat(requestMessage.fieldMap()).containsKey("books3"); + } + @Test public void parseMethods_basic() { Map messageTypes = Parser.parseMessages(echoFileDescriptor); @@ -108,9 +121,10 @@ public void parseMethods_basic() { messageTypes, resourceNames, Optional.empty(), - outputResourceNames); + outputResourceNames, + Transport.GRPC); - assertEquals(9, methods.size()); + assertEquals(10, methods.size()); // Methods should appear in the same order as in the protobuf file. Method echoMethod = methods.get(0); @@ -165,9 +179,10 @@ public void parseMethods_basicLro() { messageTypes, resourceNames, Optional.empty(), - outputResourceNames); + outputResourceNames, + Transport.GRPC); - assertEquals(9, methods.size()); + assertEquals(10, methods.size()); // Methods should appear in the same order as in the protobuf file. Method waitMethod = methods.get(7); @@ -209,14 +224,6 @@ public void parseMethodSignatures_empty() { Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List methods = - Parser.parseMethods( - echoService, - ECHO_PACKAGE, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); assertThat( MethodSignatureParser.parseMethodSignatures( methodDescriptor, @@ -238,14 +245,6 @@ public void parseMethodSignatures_validArgstAndEmptyString() { Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List methods = - Parser.parseMethods( - echoService, - ECHO_PACKAGE, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); List> methodArgs = MethodSignatureParser.parseMethodSignatures( methodDescriptor, diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java index f6a55f0602..2dcaa298cf 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.Arrays; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java index 36395ec10b..04b6622b5a 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java @@ -15,10 +15,10 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.TypeNode; @@ -26,7 +26,6 @@ import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.testgapic.v1beta1.BadMessageResnameDefProto; import com.google.testgapic.v1beta1.LockerProto; import java.util.List; @@ -38,13 +37,11 @@ public class ResourceNameParserTest { private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - private ServiceDescriptor lockerService; private FileDescriptor lockerServiceFileDescriptor; @Before public void setUp() { lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); } @Test diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java index 346431d2c5..5056192c1c 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java @@ -14,16 +14,15 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.testgapic.v1beta1.LockerProto; import java.util.Arrays; import java.util.HashMap; @@ -35,13 +34,11 @@ public class ResourceReferenceParserTest { private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - private ServiceDescriptor lockerService; private FileDescriptor lockerServiceFileDescriptor; @Before public void setUp() { lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); } @Test @@ -173,7 +170,6 @@ public void resolvePackages_resourcePackageIsSubpackageOfService() { @Test public void resolvePackages_resourcePackageIsSameAsService() { - String resourcePackage = "com.google.testgapic.v1beta1.common"; assertEquals(MAIN_PACKAGE, ResourceReferenceParser.resolvePackages(MAIN_PACKAGE, MAIN_PACKAGE)); } diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java index d5688d545d..eb69209242 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.protobuf.util.Durations; import com.google.rpc.Code; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java index 615aacc9b0..de432646fa 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java index a33f20c782..4be6c37fe4 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; import com.google.protobuf.DescriptorProtos.FileDescriptorProto; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java index 096302e2c1..a79460e915 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.Reference; import com.google.protobuf.Descriptors.Descriptor; @@ -26,7 +26,6 @@ import org.junit.Test; public class TypeParserTest { - private static final String ECHO_PACKAGE = "com.google.showcase.v1beta1"; // TODO(miraleung): Backfill with more tests (e.g. field, message, methods) for Parser.java. @Test public void parseMessageType_basic() { diff --git a/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel index 3be657ef66..1a5133b74c 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel @@ -33,9 +33,20 @@ genrule( ], ) +proto_library( + name = "bookshop_proto", + srcs = ["bookshop.proto"], + deps = [ + "@com_google_googleapis//google/api:annotations_proto", + "@com_google_googleapis//google/api:client_proto", + "@com_google_googleapis//google/api:field_behavior_proto", + ], +) + proto_library( name = "showcase_proto", srcs = [ + "compliance.proto", "echo.proto", "identity.proto", "testing.proto", @@ -100,6 +111,11 @@ java_proto_library( deps = [":deprecated_service_proto"], ) +java_proto_library( + name = "bookshop_java_proto", + deps = [":bookshop_proto"], +) + java_proto_library( name = "showcase_java_proto", deps = [":showcase_proto"], diff --git a/src/test/java/com/google/api/generator/gapic/testdata/bookshop.proto b/src/test/java/com/google/api/generator/gapic/testdata/bookshop.proto new file mode 100644 index 0000000000..0498b45430 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/testdata/bookshop.proto @@ -0,0 +1,61 @@ +// Copyright 2021 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. + +syntax = "proto3"; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; + +package google.bookshop.v1beta1; + +option go_package = "github.com/googleapis/gapic-showcase/server/genproto"; +option java_package = "com.google.bookshop.v1beta1"; +option java_outer_classname = "BookshopProto"; +option java_multiple_files = true; + +// Exercises name conflict behavior in Java. +service Bookshop { + // This service is meant to only run locally on the port 7469 (keypad digits + // for "book"). + option (google.api.default_host) = "localhost:2665"; + option (google.api.oauth_scopes) = + "https://www.googleapis.com/auth/cloud-platform"; + + // This method simply echos the request. This method is showcases unary rpcs. + rpc GetBook(GetBookRequest) returns (Book) { + option (google.api.http) = { + post: "/v1beta1/echo:echo" + body: "*" + }; + option (google.api.method_signature) = "books_count,books"; + option (google.api.method_signature) = "books_list,books"; + } +} + +message GetBookRequest { + // The number of books. + int32 books_count = 1; + + // The name of the book list. + string books_list = 2; + + // The books. + repeated Book books = 3; +} + +message Book { + // The bookk title. + string title = 1; +} diff --git a/src/test/java/com/google/api/generator/gapic/testdata/bookshop_grpc_service_config.json b/src/test/java/com/google/api/generator/gapic/testdata/bookshop_grpc_service_config.json new file mode 100644 index 0000000000..4604425cb0 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/testdata/bookshop_grpc_service_config.json @@ -0,0 +1,8 @@ +{ + "methodConfig": [ + { + "name": [{"service": "google.bookshop.v1beta1.Bookshop"}], + "timeout": "60s" + } + ] +} diff --git a/src/test/java/com/google/api/generator/gapic/testdata/compliance.proto b/src/test/java/com/google/api/generator/gapic/testdata/compliance.proto new file mode 100644 index 0000000000..c602452b13 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/testdata/compliance.proto @@ -0,0 +1,193 @@ +// Copyright 2021 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. + +syntax = "proto3"; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; + +package google.showcase.v1beta1; + +option go_package = "github.com/googleapis/gapic-showcase/server/genproto"; +option java_package = "com.google.showcase.v1beta1"; +option java_multiple_files = true; + +// This service is used to test that GAPICs can transcode proto3 requests to +// REST format correctly for various types of HTTP annotations. +service Compliance { + // This service is meant to only run locally on the port 7469 (keypad digits + // for "show"). + option (google.api.default_host) = "localhost:7469"; + + // This method echoes the ComplianceData request. This method exercises + // sending the entire request object in the REST body. + rpc RepeatDataBody(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + post: "/v1beta1/repeat:body" + body: "*" + }; + } + + // This method echoes the ComplianceData request. This method exercises + // sending the a message-type field in the REST body. Per AIP-127, only + // top-level, non-repeated fields can be sent this way. + rpc RepeatDataBodyInfo(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + post: "/v1beta1/repeat:bodyinfo" + body: "info" + }; + } + + // This method echoes the ComplianceData request. This method exercises + // sending all request fields as query parameters. + rpc RepeatDataQuery(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + get: "/v1beta1/repeat:query" + }; + } + + // This method echoes the ComplianceData request. This method exercises + // sending some parameters as "simple" path variables (i.e., of the form + // "/bar/{foo}" rather than "/{foo=bar/*}"), and the rest as query parameters. + rpc RepeatDataSimplePath(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + get: "/v1beta1/repeat/{info.f_string}/{info.f_int32}/{info.f_double}/{info.f_bool}/{info.f_kingdom}:simplepath" + }; + } + + // Same as RepeatDataSimplePath, but with a path resource. + rpc RepeatDataPathResource(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + get: "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource" + }; + } + + // Same as RepeatDataSimplePath, but with a trailing resource. + rpc RepeatDataPathTrailingResource(RepeatRequest) returns (RepeatResponse) { + option (google.api.http) = { + get: "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/**}:pathtrailingresource" + }; + } +} + +message RepeatRequest { + string name = 1; + ComplianceData info = 2; + + // If true, the server will verify that the received request matches + // the request with the same name in the compliance test suite. + bool server_verify = 3; +} + +message RepeatResponse { + ComplianceData info = 1; +} + +// ComplianceSuite contains a set of requests that microgenerators should issue +// over REST to the Compliance service to test their gRPC-to-REST transcoding +// implementation. +message ComplianceSuite { + repeated ComplianceGroup group = 1; +} + +// ComplianceGroups encapsulates a group of RPC requests to the Compliance +// server: one request for each combination of elements of `rpcs` and of +// `requests`. +message ComplianceGroup { + string name = 1; + repeated string rpcs = 2; + repeated RepeatRequest requests = 3; +} + +// ComplianceData is a message used for testing REST transcoding of +// different data types. +message ComplianceData { + enum LifeKingdom { + LIFE_KINGDOM_UNSPECIFIED = 0; + ARCHAEBACTERIA = 1; + EUBACTERIA = 2; + PROTISTA = 3; + FUNGI = 4; + PLANTAE = 5; + ANIMALIA = 6; +} + // scalar types + + string f_string = 1; + + int32 f_int32 = 2; + sint32 f_sint32 = 3; + sfixed32 f_sfixed32 = 4; + + uint32 f_uint32 = 5; + fixed32 f_fixed32 = 6; + + int64 f_int64 = 7; + sint64 f_sint64 = 8; + sfixed64 f_sfixed64 = 9; + + uint64 f_uint64 = 10; + fixed64 f_fixed64 = 11; + + double f_double = 12; + float f_float = 13; + + optional bool f_bool = 14; + + bytes f_bytes = 15; + + LifeKingdom f_kingdom = 22; + + ComplianceDataChild f_child = 16; + + // optional fields + + optional string p_string = 17; + optional int32 p_int32 = 18; + optional double p_double = 19; + optional bool p_bool = 20; + optional LifeKingdom p_kingdom = 23; + optional ComplianceDataChild p_child = 21; +} + +message ComplianceDataChild { + string f_string = 1; + float f_float = 2; + double f_double = 3; + bool f_bool = 4; + Continent f_continent = 11; + ComplianceDataGrandchild f_child = 5; + + optional string p_string = 6; + optional float p_float = 7; + optional double p_double = 8; + optional bool p_bool = 9; + Continent p_continent = 12; + optional ComplianceDataGrandchild p_child = 10; +} + +message ComplianceDataGrandchild { + string f_string = 1; + double f_double = 2; + bool f_bool = 3; +} + +enum Continent { + CONTINENT_UNSPECIFIED = 0; + AFRICA = 1; + AMERICA = 2; + ANTARTICA = 3; + AUSTRALIA = 4; + EUROPE = 5; +} \ No newline at end of file diff --git a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto index 136ee598f8..ea262faf32 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto +++ b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto @@ -130,6 +130,15 @@ service Echo { body: "*" }; }; + + // This method primarily tests Java name collisions by using the Object + // message. + rpc CollideName(EchoRequest) returns (Object) { + option (google.api.http) = { + post: "/v1beta1/echo:foo" + body: "*" + }; + } } // A severity enum used to test enum capabilities in GAPIC surfaces @@ -193,6 +202,12 @@ message EchoResponse { Severity severity = 2; } +// Tests name collisions with java.lang.Object. +message Object { + // The content specified in the request. + string content = 1; +} + // The request message for the Expand method. message ExpandRequest { // The content that will be split into words and returned on the stream. diff --git a/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java b/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java index 10b65c9b9c..3cf7d647cc 100644 --- a/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java +++ b/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.utils; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java b/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java index a11ad6437a..eda4ae7f8c 100644 --- a/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java +++ b/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java @@ -28,7 +28,7 @@ public static void main(String... args) { throw new MissingRequiredArgException("Missing the JUnit class name argument."); } String className = args[0]; - Class clazz = null; + Class clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { diff --git a/src/test/java/com/google/api/generator/test/framework/Utils.java b/src/test/java/com/google/api/generator/test/framework/Utils.java index 728be5f5b5..d38142a582 100644 --- a/src/test/java/com/google/api/generator/test/framework/Utils.java +++ b/src/test/java/com/google/api/generator/test/framework/Utils.java @@ -33,7 +33,7 @@ public class Utils { * @param fileName the name of saved file, usually it is test method name with suffix `.golden`. * @param codegen the generated code from JUnit test. */ - public static void saveCodegenToFile(Class clazz, String fileName, String codegen) { + public static void saveCodegenToFile(Class clazz, String fileName, String codegen) { // This system environment variable `TEST_OUTPUT_HOME` is used to specify a folder // which contains generated output from JUnit test. // It will be set when running `bazel run testTarget_update` command. @@ -51,15 +51,15 @@ public static void saveCodegenToFile(Class clazz, String fileName, String codege } } - private static String getTestoutGoldenDir(Class clazz) { + private static String getTestoutGoldenDir(Class clazz) { return clazz.getPackage().getName().replace(".", "/") + "/goldens/"; } - public static String getGoldenDir(Class clazz) { + public static String getGoldenDir(Class clazz) { return "src/test/java/" + clazz.getPackage().getName().replace(".", "/") + "/goldens/"; } - public static String getClassName(Class clazz) { + public static String getClassName(Class clazz) { return clazz.getSimpleName(); } diff --git a/src/test/java/com/google/api/generator/util/TrieTest.java b/src/test/java/com/google/api/generator/util/TrieTest.java index 8854ff7a2f..8769e522cb 100644 --- a/src/test/java/com/google/api/generator/util/TrieTest.java +++ b/src/test/java/com/google/api/generator/util/TrieTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.util; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.testutils.LineFormatter; import java.util.Arrays; @@ -69,7 +69,6 @@ public void insertAndSearch_multiStringTrie() { @Test public void dfsTraverseAndReduce_emptyTrie() { // Add up points in the tree, where each parent gets (num child node points) * 2 + 1. - int baseValue = 0; Function parentPreprocFn = nodeVal -> new Integer(0); BiFunction leafReduceFn = (nodeVal, accVal) -> new Integer(accVal + 1); @@ -84,7 +83,6 @@ public void dfsTraverseAndReduce_emptyTrie() { @Test public void dfsTraverseAndReduce_singleNodeTrie() { // Add up points in the tree, where each parent gets (num child node points) * 2 + 1. - int baseValue = 0; Function parentPreprocFn = nodeVal -> new Integer(0); BiFunction leafReduceFn = (nodeVal, accVal) -> new Integer(accVal + 1); diff --git a/test/integration/BUILD.bazel b/test/integration/BUILD.bazel index 23360e672b..addd91b3e8 100644 --- a/test/integration/BUILD.bazel +++ b/test/integration/BUILD.bazel @@ -1,12 +1,14 @@ load( - "@com_google_googleapis_imports//:imports.bzl", - "java_gapic_assembly_gradle_pkg", + "@gapic_generator_java//rules_java_gapic:java_gapic.bzl", "java_gapic_library", "java_gapic_test", - "java_grpc_library", - "java_proto_library", - "proto_library_with_info", ) +load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library") +load( + "@gapic_generator_java//rules_java_gapic:java_gapic_pkg.bzl", + "java_gapic_assembly_gradle_pkg", +) +load("@rules_gapic//:gapic.bzl", "proto_library_with_info") load( "//:rules_bazel/java/integration_test.bzl", "golden_update", @@ -28,7 +30,9 @@ INTEGRATION_TEST_LIBRARIES = [ "pubsub", # Special=case handling for "_deleted-topic_" resource name patterns. "logging", # Java package remapping in gapic.yaml. "redis", # Has a gapic.yaml. + "storage", # Exercises storage-specific edge cases. "library", # No gRPC service config. + "compute", # REGAPIC test. ] # Keys must match the values in INTEGRATION_TEST_LIBRARIES above. @@ -40,7 +44,9 @@ API_GAPIC_TARGETS = { "pubsub": ":pubsub_java_gapic", "logging": "@com_google_googleapis//google/logging/v2:logging_java_gapic", "redis": "@com_google_googleapis//google/cloud/redis/v1beta1:redis_java_gapic", + "storage": "@com_google_googleapis//google/storage/v2:storage_java_gapic", "library": "@com_google_googleapis//google/example/library/v1:library_java_gapic", + "compute": "@com_google_googleapis_discovery//google/cloud/compute/v1:compute_small_java_gapic", } [integration_test( @@ -58,9 +64,6 @@ API_GAPIC_TARGETS = { #################################################### # API Library Rules #################################################### -# These will eventually go away once more APIs in googleapis have been migrated to the -# microgenerator. - # Asset API. java_gapic_test( name = "asset_java_gapic_test_suite", @@ -99,6 +102,25 @@ java_gapic_assembly_gradle_pkg( ], ) +# Storage API. +java_gapic_test( + name = "storage_java_gapic_test_suite", + test_classes = [ + "com.google.storage.v2.StorageClientTest", + ], + runtime_deps = ["@com_google_googleapis//google/storage/v2:storage_java_gapic_test"], +) + +java_gapic_assembly_gradle_pkg( + name = "google-cloud-storage-v2-java", + deps = [ + "@com_google_googleapis//google/storage/v2:storage_java_gapic", + "@com_google_googleapis//google/storage/v2:storage_java_grpc", + "@com_google_googleapis//google/storage/v2:storage_java_proto", + "@com_google_googleapis//google/storage/v2:storage_proto", + ], +) + # Logging API java_gapic_test( name = "logging_java_gapic_test_suite", @@ -278,7 +300,6 @@ java_gapic_assembly_gradle_pkg( ) # PubSub -# TODO: Remove some of these targets when PubSub has been migrated in googleapis. java_gapic_library( name = "pubsub_java_gapic", srcs = ["@com_google_googleapis//google/pubsub/v1:pubsub_proto_with_info"], diff --git a/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml b/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml index 2828ca13f0..7ce51316c7 100644 --- a/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml +++ b/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml @@ -16,12 +16,14 @@ documentation: Manages keys and performs cryptographic operations in a central cloud service, for direct use by other cloud resources and applications. rules: + # This RPC shouldn't appear in the proto, since it's been clobered by KMS's definition in the proto. - selector: google.iam.v1.IAMPolicy.GetIamPolicy description: |- Gets the access control policy for a resource. Returns an empty policy if the resource exists and does not have a policy set. - # This RPC shouldn't appear in the proto even though the documentation field is set. + # This RPC shouldn't appear in the proto, since it's not in the HTTP rules list below, + # even though the documentation field is set. - selector: google.iam.v1.IAMPolicy.SetIamPolicy description: |- Sets the access control policy on the specified resource. Replaces diff --git a/test/integration/goldens/asset/BUILD.bazel b/test/integration/goldens/asset/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/asset/BUILD.bazel +++ b/test/integration/goldens/asset/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java index f1bbf06c9f..1860b0cca4 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java @@ -16,7 +16,6 @@ package com.google.cloud.asset.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -28,6 +27,7 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PageContext; import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.resourcenames.ResourceName; import com.google.cloud.asset.v1.stub.AssetServiceStub; import com.google.cloud.asset.v1.stub.AssetServiceStubSettings; import com.google.common.util.concurrent.MoreExecutors; @@ -271,6 +271,154 @@ public final UnaryCallable exportAssetsCallable( return stub.exportAssetsCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists assets with time and resource types and returns paged results in response. + * + *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   ResourceName parent = FeedName.ofProjectFeedName("[PROJECT]", "[FEED]");
+   *   for (Asset element : assetServiceClient.listAssets(parent).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param parent Required. Name of the organization or project the assets belong to. Format: + * "organizations/[organization-number]" (such as "organizations/123"), + * "projects/[project-id]" (such as "projects/my-project-id"), or "projects/[project-number]" + * (such as "projects/12345"). + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListAssetsPagedResponse listAssets(ResourceName parent) { + ListAssetsRequest request = + ListAssetsRequest.newBuilder().setParent(parent == null ? null : parent.toString()).build(); + return listAssets(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists assets with time and resource types and returns paged results in response. + * + *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   String parent = FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString();
+   *   for (Asset element : assetServiceClient.listAssets(parent).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param parent Required. Name of the organization or project the assets belong to. Format: + * "organizations/[organization-number]" (such as "organizations/123"), + * "projects/[project-id]" (such as "projects/my-project-id"), or "projects/[project-number]" + * (such as "projects/12345"). + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListAssetsPagedResponse listAssets(String parent) { + ListAssetsRequest request = ListAssetsRequest.newBuilder().setParent(parent).build(); + return listAssets(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists assets with time and resource types and returns paged results in response. + * + *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   ListAssetsRequest request =
+   *       ListAssetsRequest.newBuilder()
+   *           .setParent(FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString())
+   *           .setReadTime(Timestamp.newBuilder().build())
+   *           .addAllAssetTypes(new ArrayList())
+   *           .setContentType(ContentType.forNumber(0))
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   for (Asset element : assetServiceClient.listAssets(request).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListAssetsPagedResponse listAssets(ListAssetsRequest request) { + return listAssetsPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists assets with time and resource types and returns paged results in response. + * + *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   ListAssetsRequest request =
+   *       ListAssetsRequest.newBuilder()
+   *           .setParent(FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString())
+   *           .setReadTime(Timestamp.newBuilder().build())
+   *           .addAllAssetTypes(new ArrayList())
+   *           .setContentType(ContentType.forNumber(0))
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   ApiFuture future = assetServiceClient.listAssetsPagedCallable().futureCall(request);
+   *   // Do something.
+   *   for (Asset element : future.get().iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable listAssetsPagedCallable() { + return stub.listAssetsPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Lists assets with time and resource types and returns paged results in response. + * + *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   ListAssetsRequest request =
+   *       ListAssetsRequest.newBuilder()
+   *           .setParent(FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString())
+   *           .setReadTime(Timestamp.newBuilder().build())
+   *           .addAllAssetTypes(new ArrayList())
+   *           .setContentType(ContentType.forNumber(0))
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   while (true) {
+   *     ListAssetsResponse response = assetServiceClient.listAssetsCallable().call(request);
+   *     for (Asset element : response.getResponsesList()) {
+   *       // doThingsWith(element);
+   *     }
+   *     String nextPageToken = response.getNextPageToken();
+   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
+   *       request = request.toBuilder().setPageToken(nextPageToken).build();
+   *     } else {
+   *       break;
+   *     }
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable listAssetsCallable() { + return stub.listAssetsCallable(); + } + // AUTO-GENERATED DOCUMENTATION AND METHOD. /** * Batch gets the update history of assets that overlap a time window. For IAM_POLICY content, @@ -747,7 +895,7 @@ public final UnaryCallable deleteFeedCallable() { * * @param scope Required. A scope can be a project, a folder, or an organization. The search is * limited to the resources within the `scope`. The caller must be granted the - * [`cloudasset.assets.searchAllResources`](http://cloud.google.com/asset-inventory/docs/access-control#required_permissions) + * [`cloudasset.assets.searchAllResources`](https://cloud.google.com/asset-inventory/docs/access-control#required_permissions) * permission on the desired scope. *

The allowed values are: *

    @@ -758,32 +906,36 @@ public final UnaryCallable deleteFeedCallable() { *
* * @param query Optional. The query statement. See [how to construct a - * query](http://cloud.google.com/asset-inventory/docs/searching-resources#how_to_construct_a_query) + * query](https://cloud.google.com/asset-inventory/docs/searching-resources#how_to_construct_a_query) * for more information. If not specified or empty, it will search all the resources within - * the specified `scope`. Note that the query string is compared against each Cloud IAM policy - * binding, including its members, roles, and Cloud IAM conditions. The returned Cloud IAM - * policies will only contain the bindings that match your query. To learn more about the IAM - * policy structure, see [IAM policy - * doc](https://cloud.google.com/iam/docs/policies#structure). + * the specified `scope`. *

Examples: *

    *
  • `name:Important` to find Cloud resources whose name contains "Important" as a word. + *
  • `name=Important` to find the Cloud resource whose name is exactly "Important". *
  • `displayName:Impor*` to find Cloud resources whose display name contains "Impor" - * as a prefix. - *
  • `description:*por*` to find Cloud resources whose description contains "por" - * as a substring. - *
  • `location:us-west*` to find Cloud resources whose location is prefixed with - * "us-west". + * as a prefix of any word in the field. + *
  • `location:us-west*` to find Cloud resources whose location contains both "us" and + * "west" as prefixes. *
  • `labels:prod` to find Cloud resources whose labels contain "prod" as a key or value. *
  • `labels.env:prod` to find Cloud resources that have a label "env" and its value is * "prod". *
  • `labels.env:*` to find Cloud resources that have a label "env". + *
  • `kmsKey:key` to find Cloud resources encrypted with a customer-managed encryption key + * whose name contains the word "key". + *
  • `state:ACTIVE` to find Cloud resources whose state contains "ACTIVE" as a word. + *
  • `NOT state:ACTIVE` to find {{gcp_name}} resources whose state doesn't contain + * "ACTIVE" as a word. + *
  • `createTime<1609459200` to find Cloud resources that were created before + * "2021-01-01 00:00:00 UTC". 1609459200 is the epoch timestamp of "2021-01-01 00:00:00 + * UTC" in seconds. + *
  • `updateTime>1609459200` to find Cloud resources that were updated after + * "2021-01-01 00:00:00 UTC". 1609459200 is the epoch timestamp of "2021-01-01 00:00:00 + * UTC" in seconds. *
  • `Important` to find Cloud resources that contain "Important" as a word in any of the * searchable fields. - *
  • `Impor*` to find Cloud resources that contain "Impor" as a prefix in any of the - * searchable fields. - *
  • `*por*` to find Cloud resources that contain "por" as a substring in any of - * the searchable fields. + *
  • `Impor*` to find Cloud resources that contain "Impor" as a prefix of any word in + * any of the searchable fields. *
  • `Important location:(us-west1 OR global)` to find Cloud resources that contain * "Important" as a word in any of the searchable fields and are also located in the * "us-west1" region or the "global" location. @@ -792,6 +944,16 @@ public final UnaryCallable deleteFeedCallable() { * @param assetTypes Optional. A list of asset types that this request searches for. If empty, it * will search all the [searchable asset * types](https://cloud.google.com/asset-inventory/docs/supported-asset-types#searchable_asset_types). + *

    Regular expressions are also supported. For example: + *

      + *
    • "compute.googleapis.com.*" snapshots resources whose asset type starts with + * "compute.googleapis.com". + *
    • ".*Instance" snapshots resources whose asset type ends with "Instance". + *
    • ".*Instance.*" snapshots resources whose asset type contains "Instance". + *
    + *

    See [RE2](https://github.com/google/re2/wiki/Syntax) for all supported regular + * expression syntax. If the regular expression does not match any supported asset type, an + * INVALID_ARGUMENT error will be returned. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final SearchAllResourcesPagedResponse searchAllResources( @@ -933,7 +1095,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * * @param scope Required. A scope can be a project, a folder, or an organization. The search is * limited to the IAM policies within the `scope`. The caller must be granted the - * [`cloudasset.assets.searchAllIamPolicies`](http://cloud.google.com/asset-inventory/docs/access-control#required_permissions) + * [`cloudasset.assets.searchAllIamPolicies`](https://cloud.google.com/asset-inventory/docs/access-control#required_permissions) * permission on the desired scope. *

    The allowed values are: *

      @@ -946,25 +1108,38 @@ public final SearchAllResourcesPagedResponse searchAllResources( * @param query Optional. The query statement. See [how to construct a * query](https://cloud.google.com/asset-inventory/docs/searching-iam-policies#how_to_construct_a_query) * for more information. If not specified or empty, it will search all the IAM policies within - * the specified `scope`. + * the specified `scope`. Note that the query string is compared against each Cloud IAM policy + * binding, including its members, roles, and Cloud IAM conditions. The returned Cloud IAM + * policies will only contain the bindings that match your query. To learn more about the IAM + * policy structure, see [IAM policy + * doc](https://cloud.google.com/iam/docs/policies#structure). *

      Examples: *

        *
      • `policy:amy{@literal @}gmail.com` to find IAM policy bindings that specify user * "amy{@literal @}gmail.com". *
      • `policy:roles/compute.admin` to find IAM policy bindings that specify the Compute * Admin role. + *
      • `policy:comp*` to find IAM policy bindings that contain "comp" as a prefix of any + * word in the binding. *
      • `policy.role.permissions:storage.buckets.update` to find IAM policy bindings that * specify a role containing "storage.buckets.update" permission. Note that if callers * don't have `iam.roles.get` access to a role's included permissions, policy bindings * that specify this role will be dropped from the search results. + *
      • `policy.role.permissions:upd*` to find IAM policy bindings that specify a role + * containing "upd" as a prefix of any word in the role permission. Note that if callers + * don't have `iam.roles.get` access to a role's included permissions, policy bindings + * that specify this role will be dropped from the search results. *
      • `resource:organizations/123456` to find IAM policy bindings that are set on * "organizations/123456". + *
      • `resource=//cloudresourcemanager.googleapis.com/projects/myproject` to find IAM + * policy bindings that are set on the project named "myproject". *
      • `Important` to find IAM policy bindings that contain "Important" as a word in any of * the searchable fields (except for the included permissions). - *
      • `*por*` to find IAM policy bindings that contain "por" as a substring in any - * of the searchable fields (except for the included permissions). *
      • `resource:(instance1 OR instance2) policy:amy` to find IAM policy bindings that are * set on resources "instance1" or "instance2" and also specify user "amy". + *
      • `roles:roles/compute.admin` to find IAM policy bindings that specify the Compute + * Admin role. + *
      • `memberTypes:user` to find IAM policy bindings that contain the "user" member type. *
      * * @throws com.google.api.gax.rpc.ApiException if the remote call fails @@ -991,6 +1166,8 @@ public final SearchAllIamPoliciesPagedResponse searchAllIamPolicies(String scope * .setQuery("query107944136") * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllAssetTypes(new ArrayList()) + * .setOrderBy("orderBy-1207110587") * .build(); * for (IamPolicySearchResult element : * assetServiceClient.searchAllIamPolicies(request).iterateAll()) { @@ -1023,6 +1200,8 @@ public final SearchAllIamPoliciesPagedResponse searchAllIamPolicies( * .setQuery("query107944136") * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllAssetTypes(new ArrayList()) + * .setOrderBy("orderBy-1207110587") * .build(); * ApiFuture future = * assetServiceClient.searchAllIamPoliciesPagedCallable().futureCall(request); @@ -1054,6 +1233,8 @@ public final SearchAllIamPoliciesPagedResponse searchAllIamPolicies( * .setQuery("query107944136") * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllAssetTypes(new ArrayList()) + * .setOrderBy("orderBy-1207110587") * .build(); * while (true) { * SearchAllIamPoliciesResponse response = @@ -1257,6 +1438,79 @@ public boolean awaitTermination(long duration, TimeUnit unit) throws Interrupted return stub.awaitTermination(duration, unit); } + public static class ListAssetsPagedResponse + extends AbstractPagedListResponse< + ListAssetsRequest, + ListAssetsResponse, + Asset, + ListAssetsPage, + ListAssetsFixedSizeCollection> { + + public static ApiFuture createAsync( + PageContext context, + ApiFuture futureResponse) { + ApiFuture futurePage = + ListAssetsPage.createEmptyPage().createPageAsync(context, futureResponse); + return ApiFutures.transform( + futurePage, input -> new ListAssetsPagedResponse(input), MoreExecutors.directExecutor()); + } + + private ListAssetsPagedResponse(ListAssetsPage page) { + super(page, ListAssetsFixedSizeCollection.createEmptyCollection()); + } + } + + public static class ListAssetsPage + extends AbstractPage { + + private ListAssetsPage( + PageContext context, + ListAssetsResponse response) { + super(context, response); + } + + private static ListAssetsPage createEmptyPage() { + return new ListAssetsPage(null, null); + } + + @Override + protected ListAssetsPage createPage( + PageContext context, + ListAssetsResponse response) { + return new ListAssetsPage(context, response); + } + + @Override + public ApiFuture createPageAsync( + PageContext context, + ApiFuture futureResponse) { + return super.createPageAsync(context, futureResponse); + } + } + + public static class ListAssetsFixedSizeCollection + extends AbstractFixedSizeCollection< + ListAssetsRequest, + ListAssetsResponse, + Asset, + ListAssetsPage, + ListAssetsFixedSizeCollection> { + + private ListAssetsFixedSizeCollection(List pages, int collectionSize) { + super(pages, collectionSize); + } + + private static ListAssetsFixedSizeCollection createEmptyCollection() { + return new ListAssetsFixedSizeCollection(null, 0); + } + + @Override + protected ListAssetsFixedSizeCollection createCollection( + List pages, int collectionSize) { + return new ListAssetsFixedSizeCollection(pages, collectionSize); + } + } + public static class SearchAllResourcesPagedResponse extends AbstractPagedListResponse< SearchAllResourcesRequest, @@ -1273,12 +1527,7 @@ public static ApiFuture createAsync( SearchAllResourcesPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public SearchAllResourcesPagedResponse apply(SearchAllResourcesPage input) { - return new SearchAllResourcesPagedResponse(input); - } - }, + input -> new SearchAllResourcesPagedResponse(input), MoreExecutors.directExecutor()); } @@ -1363,12 +1612,7 @@ public static ApiFuture createAsync( SearchAllIamPoliciesPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public SearchAllIamPoliciesPagedResponse apply(SearchAllIamPoliciesPage input) { - return new SearchAllIamPoliciesPagedResponse(input); - } - }, + input -> new SearchAllIamPoliciesPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java index e419696424..de8ca67414 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java @@ -16,6 +16,7 @@ package com.google.cloud.asset.v1; +import static com.google.cloud.asset.v1.AssetServiceClient.ListAssetsPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllIamPoliciesPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllResourcesPagedResponse; @@ -27,6 +28,7 @@ import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.InvalidArgumentException; import com.google.api.gax.rpc.StatusCode; +import com.google.api.resourcenames.ResourceName; import com.google.common.collect.Lists; import com.google.longrunning.Operation; import com.google.protobuf.AbstractMessage; @@ -52,10 +54,10 @@ @Generated("by gapic-generator-java") public class AssetServiceClientTest { + private static MockAssetService mockAssetService; private static MockServiceHelper mockServiceHelper; - private AssetServiceClient client; private LocalChannelProvider channelProvider; - private static MockAssetService mockAssetService; + private AssetServiceClient client; @BeforeClass public static void startStaticServer() { @@ -154,6 +156,94 @@ public void exportAssetsExceptionTest() throws Exception { } } + @Test + public void listAssetsTest() throws Exception { + Asset responsesElement = Asset.newBuilder().build(); + ListAssetsResponse expectedResponse = + ListAssetsResponse.newBuilder() + .setNextPageToken("") + .addAllAssets(Arrays.asList(responsesElement)) + .build(); + mockAssetService.addResponse(expectedResponse); + + ResourceName parent = FeedName.ofProjectFeedName("[PROJECT]", "[FEED]"); + + ListAssetsPagedResponse pagedListResponse = client.listAssets(parent); + + List resources = Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals(expectedResponse.getAssetsList().get(0), resources.get(0)); + + List actualRequests = mockAssetService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + ListAssetsRequest actualRequest = ((ListAssetsRequest) actualRequests.get(0)); + + Assert.assertEquals(parent.toString(), actualRequest.getParent()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void listAssetsExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockAssetService.addException(exception); + + try { + ResourceName parent = FeedName.ofProjectFeedName("[PROJECT]", "[FEED]"); + client.listAssets(parent); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void listAssetsTest2() throws Exception { + Asset responsesElement = Asset.newBuilder().build(); + ListAssetsResponse expectedResponse = + ListAssetsResponse.newBuilder() + .setNextPageToken("") + .addAllAssets(Arrays.asList(responsesElement)) + .build(); + mockAssetService.addResponse(expectedResponse); + + String parent = "parent-995424086"; + + ListAssetsPagedResponse pagedListResponse = client.listAssets(parent); + + List resources = Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals(expectedResponse.getAssetsList().get(0), resources.get(0)); + + List actualRequests = mockAssetService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + ListAssetsRequest actualRequest = ((ListAssetsRequest) actualRequests.get(0)); + + Assert.assertEquals(parent, actualRequest.getParent()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void listAssetsExceptionTest2() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockAssetService.addException(exception); + + try { + String parent = "parent-995424086"; + client.listAssets(parent); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + @Test public void batchGetAssetsHistoryTest() throws Exception { BatchGetAssetsHistoryResponse expectedResponse = diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java index 50c5dca652..df338c00a9 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java @@ -16,6 +16,7 @@ package com.google.cloud.asset.v1; +import static com.google.cloud.asset.v1.AssetServiceClient.ListAssetsPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllIamPoliciesPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllResourcesPagedResponse; @@ -84,6 +85,12 @@ public UnaryCallSettings exportAssetsSettings() return ((AssetServiceStubSettings) getStubSettings()).exportAssetsOperationSettings(); } + /** Returns the object with the settings used for calls to listAssets. */ + public PagedCallSettings + listAssetsSettings() { + return ((AssetServiceStubSettings) getStubSettings()).listAssetsSettings(); + } + /** Returns the object with the settings used for calls to batchGetAssetsHistory. */ public UnaryCallSettings batchGetAssetsHistorySettings() { @@ -238,14 +245,13 @@ public AssetServiceStubSettings.Builder getStubSettingsBuilder() { return ((AssetServiceStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; @@ -263,6 +269,12 @@ public UnaryCallSettings.Builder exportAssetsSet return getStubSettingsBuilder().exportAssetsOperationSettings(); } + /** Returns the builder for the settings used for calls to listAssets. */ + public PagedCallSettings.Builder + listAssetsSettings() { + return getStubSettingsBuilder().listAssetsSettings(); + } + /** Returns the builder for the settings used for calls to batchGetAssetsHistory. */ public UnaryCallSettings.Builder batchGetAssetsHistorySettings() { diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/FeedName.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/FeedName.java index d8c9ee9593..8c19eaba01 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/FeedName.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/FeedName.java @@ -295,8 +295,8 @@ private Builder(FeedName feedName) { Preconditions.checkArgument( Objects.equals(feedName.pathTemplate, PROJECT_FEED), "toBuilder is only supported when FeedName has the pattern of projects/{project}/feeds/{feed}"); - project = feedName.project; - feed = feedName.feed; + this.project = feedName.project; + this.feed = feedName.feed; } public FeedName build() { diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java index 27b5f4021b..643691d8d4 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java @@ -81,6 +81,27 @@ public void exportAssets( } } + @Override + public void listAssets( + ListAssetsRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof ListAssetsResponse) { + requests.add(request); + responseObserver.onNext(((ListAssetsResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method ListAssets, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + ListAssetsResponse.class.getName(), + Exception.class.getName()))); + } + } + @Override public void batchGetAssetsHistory( BatchGetAssetsHistoryRequest request, diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json b/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json index d2c1608bb4..ea1187e7ac 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json @@ -31,6 +31,9 @@ "GetFeed": { "methods": ["getFeed", "getFeed", "getFeed", "getFeedCallable"] }, + "ListAssets": { + "methods": ["listAssets", "listAssets", "listAssets", "listAssetsPagedCallable", "listAssetsCallable"] + }, "ListFeeds": { "methods": ["listFeeds", "listFeeds", "listFeedsCallable"] }, diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java index e4032e3df0..27db247ed3 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java @@ -27,7 +27,7 @@ * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) { * BatchGetAssetsHistoryRequest request = * BatchGetAssetsHistoryRequest.newBuilder() - * .setParent(ProjectName.of("[PROJECT]").toString()) + * .setParent(FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString()) * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java index b97b1874bb..462d7e2922 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java @@ -16,6 +16,7 @@ package com.google.cloud.asset.v1.stub; +import static com.google.cloud.asset.v1.AssetServiceClient.ListAssetsPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllIamPoliciesPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllResourcesPagedResponse; @@ -34,6 +35,8 @@ import com.google.cloud.asset.v1.ExportAssetsResponse; import com.google.cloud.asset.v1.Feed; import com.google.cloud.asset.v1.GetFeedRequest; +import com.google.cloud.asset.v1.ListAssetsRequest; +import com.google.cloud.asset.v1.ListAssetsResponse; import com.google.cloud.asset.v1.ListFeedsRequest; import com.google.cloud.asset.v1.ListFeedsResponse; import com.google.cloud.asset.v1.SearchAllIamPoliciesRequest; @@ -68,6 +71,14 @@ public UnaryCallable exportAssetsCallable() { throw new UnsupportedOperationException("Not implemented: exportAssetsCallable()"); } + public UnaryCallable listAssetsPagedCallable() { + throw new UnsupportedOperationException("Not implemented: listAssetsPagedCallable()"); + } + + public UnaryCallable listAssetsCallable() { + throw new UnsupportedOperationException("Not implemented: listAssetsCallable()"); + } + public UnaryCallable batchGetAssetsHistoryCallable() { throw new UnsupportedOperationException("Not implemented: batchGetAssetsHistoryCallable()"); diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java index cceca0029a..24b8b894a1 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java @@ -16,6 +16,7 @@ package com.google.cloud.asset.v1.stub; +import static com.google.cloud.asset.v1.AssetServiceClient.ListAssetsPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllIamPoliciesPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllResourcesPagedResponse; @@ -49,6 +50,7 @@ import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningResponse; import com.google.cloud.asset.v1.AnalyzeIamPolicyRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyResponse; +import com.google.cloud.asset.v1.Asset; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; import com.google.cloud.asset.v1.CreateFeedRequest; @@ -58,6 +60,8 @@ import com.google.cloud.asset.v1.Feed; import com.google.cloud.asset.v1.GetFeedRequest; import com.google.cloud.asset.v1.IamPolicySearchResult; +import com.google.cloud.asset.v1.ListAssetsRequest; +import com.google.cloud.asset.v1.ListAssetsResponse; import com.google.cloud.asset.v1.ListFeedsRequest; import com.google.cloud.asset.v1.ListFeedsResponse; import com.google.cloud.asset.v1.ResourceSearchResult; @@ -119,6 +123,8 @@ public class AssetServiceStubSettings extends StubSettings exportAssetsOperationSettings; + private final PagedCallSettings + listAssetsSettings; private final UnaryCallSettings batchGetAssetsHistorySettings; private final UnaryCallSettings createFeedSettings; @@ -144,6 +150,42 @@ public class AssetServiceStubSettings extends StubSettings analyzeIamPolicyLongrunningOperationSettings; + private static final PagedListDescriptor + LIST_ASSETS_PAGE_STR_DESC = + new PagedListDescriptor() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public ListAssetsRequest injectToken(ListAssetsRequest payload, String token) { + return ListAssetsRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public ListAssetsRequest injectPageSize(ListAssetsRequest payload, int pageSize) { + return ListAssetsRequest.newBuilder(payload).setPageSize(pageSize).build(); + } + + @Override + public Integer extractPageSize(ListAssetsRequest payload) { + return payload.getPageSize(); + } + + @Override + public String extractNextToken(ListAssetsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListAssetsResponse payload) { + return payload.getAssetsList() == null + ? ImmutableList.of() + : payload.getAssetsList(); + } + }; + private static final PagedListDescriptor< SearchAllResourcesRequest, SearchAllResourcesResponse, ResourceSearchResult> SEARCH_ALL_RESOURCES_PAGE_STR_DESC = @@ -226,6 +268,23 @@ public Iterable extractResources( } }; + private static final PagedListResponseFactory< + ListAssetsRequest, ListAssetsResponse, ListAssetsPagedResponse> + LIST_ASSETS_PAGE_STR_FACT = + new PagedListResponseFactory< + ListAssetsRequest, ListAssetsResponse, ListAssetsPagedResponse>() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + ListAssetsRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext pageContext = + PageContext.create(callable, LIST_ASSETS_PAGE_STR_DESC, request, context); + return ListAssetsPagedResponse.createAsync(pageContext, futureResponse); + } + }; + private static final PagedListResponseFactory< SearchAllResourcesRequest, SearchAllResourcesResponse, SearchAllResourcesPagedResponse> SEARCH_ALL_RESOURCES_PAGE_STR_FACT = @@ -285,6 +344,12 @@ public UnaryCallSettings exportAssetsSettings() return exportAssetsOperationSettings; } + /** Returns the object with the settings used for calls to listAssets. */ + public PagedCallSettings + listAssetsSettings() { + return listAssetsSettings; + } + /** Returns the object with the settings used for calls to batchGetAssetsHistory. */ public UnaryCallSettings batchGetAssetsHistorySettings() { @@ -375,6 +440,11 @@ public static String getDefaultEndpoint() { return "cloudasset.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "cloudasset.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -382,7 +452,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -424,6 +496,7 @@ protected AssetServiceStubSettings(Builder settingsBuilder) throws IOException { exportAssetsSettings = settingsBuilder.exportAssetsSettings().build(); exportAssetsOperationSettings = settingsBuilder.exportAssetsOperationSettings().build(); + listAssetsSettings = settingsBuilder.listAssetsSettings().build(); batchGetAssetsHistorySettings = settingsBuilder.batchGetAssetsHistorySettings().build(); createFeedSettings = settingsBuilder.createFeedSettings().build(); getFeedSettings = settingsBuilder.getFeedSettings().build(); @@ -446,6 +519,9 @@ public static class Builder extends StubSettings.Builder exportAssetsOperationSettings; + private final PagedCallSettings.Builder< + ListAssetsRequest, ListAssetsResponse, ListAssetsPagedResponse> + listAssetsSettings; private final UnaryCallSettings.Builder< BatchGetAssetsHistoryRequest, BatchGetAssetsHistoryResponse> batchGetAssetsHistorySettings; @@ -486,9 +562,7 @@ public static class Builder extends StubSettings.BuildernewArrayList( - StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); + ImmutableSet.copyOf(Lists.newArrayList(StatusCode.Code.UNAVAILABLE))); definitions.put( "retry_policy_3_codes", ImmutableSet.copyOf(Lists.newArrayList(StatusCode.Code.UNAVAILABLE))); @@ -524,10 +598,10 @@ public static class Builder extends StubSettings.Builder>of( exportAssetsSettings, + listAssetsSettings, batchGetAssetsHistorySettings, createFeedSettings, getFeedSettings, @@ -587,6 +663,7 @@ protected Builder(AssetServiceStubSettings settings) { exportAssetsSettings = settings.exportAssetsSettings.toBuilder(); exportAssetsOperationSettings = settings.exportAssetsOperationSettings.toBuilder(); + listAssetsSettings = settings.listAssetsSettings.toBuilder(); batchGetAssetsHistorySettings = settings.batchGetAssetsHistorySettings.toBuilder(); createFeedSettings = settings.createFeedSettings.toBuilder(); getFeedSettings = settings.getFeedSettings.toBuilder(); @@ -604,6 +681,7 @@ protected Builder(AssetServiceStubSettings settings) { unaryMethodSettingsBuilders = ImmutableList.>of( exportAssetsSettings, + listAssetsSettings, batchGetAssetsHistorySettings, createFeedSettings, getFeedSettings, @@ -623,6 +701,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -633,6 +713,11 @@ private static Builder initDefaults(Builder builder) { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder + .listAssetsSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + builder .batchGetAssetsHistorySettings() .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) @@ -737,14 +822,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } @@ -767,6 +851,12 @@ public UnaryCallSettings.Builder exportAssetsSet return exportAssetsOperationSettings; } + /** Returns the builder for the settings used for calls to listAssets. */ + public PagedCallSettings.Builder + listAssetsSettings() { + return listAssetsSettings; + } + /** Returns the builder for the settings used for calls to batchGetAssetsHistory. */ public UnaryCallSettings.Builder batchGetAssetsHistorySettings() { diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java index 7fb9b4ba50..d884f02bf9 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java @@ -16,6 +16,7 @@ package com.google.cloud.asset.v1.stub; +import static com.google.cloud.asset.v1.AssetServiceClient.ListAssetsPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllIamPoliciesPagedResponse; import static com.google.cloud.asset.v1.AssetServiceClient.SearchAllResourcesPagedResponse; @@ -25,7 +26,6 @@ import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallable; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningResponse; @@ -39,6 +39,8 @@ import com.google.cloud.asset.v1.ExportAssetsResponse; import com.google.cloud.asset.v1.Feed; import com.google.cloud.asset.v1.GetFeedRequest; +import com.google.cloud.asset.v1.ListAssetsRequest; +import com.google.cloud.asset.v1.ListAssetsResponse; import com.google.cloud.asset.v1.ListFeedsRequest; import com.google.cloud.asset.v1.ListFeedsResponse; import com.google.cloud.asset.v1.SearchAllIamPoliciesRequest; @@ -74,6 +76,15 @@ public class GrpcAssetServiceStub extends AssetServiceStub { .setResponseMarshaller(ProtoUtils.marshaller(Operation.getDefaultInstance())) .build(); + private static final MethodDescriptor + listAssetsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.cloud.asset.v1.AssetService/ListAssets") + .setRequestMarshaller(ProtoUtils.marshaller(ListAssetsRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(ListAssetsResponse.getDefaultInstance())) + .build(); + private static final MethodDescriptor batchGetAssetsHistoryMethodDescriptor = MethodDescriptor.newBuilder() @@ -172,6 +183,8 @@ public class GrpcAssetServiceStub extends AssetServiceStub { private final UnaryCallable exportAssetsCallable; private final OperationCallable exportAssetsOperationCallable; + private final UnaryCallable listAssetsCallable; + private final UnaryCallable listAssetsPagedCallable; private final UnaryCallable batchGetAssetsHistoryCallable; private final UnaryCallable createFeedCallable; @@ -243,13 +256,20 @@ protected GrpcAssetServiceStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(exportAssetsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ExportAssetsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); + }) + .build(); + GrpcCallSettings listAssetsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(listAssetsMethodDescriptor) + .setParamsExtractor( + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -258,78 +278,60 @@ public Map extract(ExportAssetsRequest request) { .newBuilder() .setMethodDescriptor(batchGetAssetsHistoryMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(BatchGetAssetsHistoryRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings createFeedTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createFeedMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateFeedRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getFeedTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getFeedMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetFeedRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listFeedsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listFeedsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListFeedsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateFeedTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateFeedMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateFeedRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("feed.name", String.valueOf(request.getFeed().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("feed.name", String.valueOf(request.getFeed().getName())); + return params.build(); }) .build(); GrpcCallSettings deleteFeedTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteFeedMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteFeedRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -337,13 +339,10 @@ public Map extract(DeleteFeedRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(searchAllResourcesMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SearchAllResourcesRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("scope", String.valueOf(request.getScope())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("scope", String.valueOf(request.getScope())); + return params.build(); }) .build(); GrpcCallSettings @@ -351,13 +350,10 @@ public Map extract(SearchAllResourcesRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(searchAllIamPoliciesMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SearchAllIamPoliciesRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("scope", String.valueOf(request.getScope())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("scope", String.valueOf(request.getScope())); + return params.build(); }) .build(); GrpcCallSettings @@ -365,15 +361,12 @@ public Map extract(SearchAllIamPoliciesRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(analyzeIamPolicyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(AnalyzeIamPolicyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put( - "analysis_query.scope", - String.valueOf(request.getAnalysisQuery().getScope())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put( + "analysis_query.scope", + String.valueOf(request.getAnalysisQuery().getScope())); + return params.build(); }) .build(); GrpcCallSettings @@ -381,16 +374,12 @@ public Map extract(AnalyzeIamPolicyRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(analyzeIamPolicyLongrunningMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract( - AnalyzeIamPolicyLongrunningRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put( - "analysis_query.scope", - String.valueOf(request.getAnalysisQuery().getScope())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put( + "analysis_query.scope", + String.valueOf(request.getAnalysisQuery().getScope())); + return params.build(); }) .build(); @@ -403,6 +392,12 @@ public Map extract( settings.exportAssetsOperationSettings(), clientContext, operationsStub); + this.listAssetsCallable = + callableFactory.createUnaryCallable( + listAssetsTransportSettings, settings.listAssetsSettings(), clientContext); + this.listAssetsPagedCallable = + callableFactory.createPagedCallable( + listAssetsTransportSettings, settings.listAssetsSettings(), clientContext); this.batchGetAssetsHistoryCallable = callableFactory.createUnaryCallable( batchGetAssetsHistoryTransportSettings, @@ -477,6 +472,16 @@ public UnaryCallable exportAssetsCallable() { return exportAssetsOperationCallable; } + @Override + public UnaryCallable listAssetsCallable() { + return listAssetsCallable; + } + + @Override + public UnaryCallable listAssetsPagedCallable() { + return listAssetsPagedCallable; + } + @Override public UnaryCallable batchGetAssetsHistoryCallable() { @@ -555,7 +560,13 @@ public UnaryCallable deleteFeedCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/compute/BUILD.bazel b/test/integration/goldens/compute/BUILD.bazel new file mode 100644 index 0000000000..2822013159 --- /dev/null +++ b/test/integration/goldens/compute/BUILD.bazel @@ -0,0 +1,12 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), +) diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java new file mode 100644 index 0000000000..eb9db7ce24 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java @@ -0,0 +1,757 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.paging.AbstractFixedSizeCollection; +import com.google.api.gax.paging.AbstractPage; +import com.google.api.gax.paging.AbstractPagedListResponse; +import com.google.api.gax.rpc.PageContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.stub.AddressesStub; +import com.google.cloud.compute.v1.stub.AddressesStubSettings; +import com.google.common.util.concurrent.MoreExecutors; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: Services + * + *

      The Addresses API. + * + *

      This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

      {@code
      + * try (AddressesClient addressesClient = AddressesClient.create()) {
      + *   String project = "project-309310695";
      + *   String region = "region-934795532";
      + *   String address = "address-1147692044";
      + *   Operation response = addressesClient.delete(project, region, address);
      + * }
      + * }
      + * + *

      Note: close() needs to be called on the AddressesClient object to clean up resources such as + * threads. In the example above, try-with-resources is used, which automatically calls close(). + * + *

      The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

        + *
      1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
      2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
      3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
      + * + *

      See the individual methods for example code. + * + *

      Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

      This class can be customized by passing in a custom instance of AddressesSettings to create(). + * For example: + * + *

      To customize credentials: + * + *

      {@code
      + * AddressesSettings addressesSettings =
      + *     AddressesSettings.newBuilder()
      + *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
      + *         .build();
      + * AddressesClient addressesClient = AddressesClient.create(addressesSettings);
      + * }
      + * + *

      To customize the endpoint: + * + *

      {@code
      + * AddressesSettings addressesSettings =
      + *     AddressesSettings.newBuilder().setEndpoint(myEndpoint).build();
      + * AddressesClient addressesClient = AddressesClient.create(addressesSettings);
      + * }
      + * + *

      Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +public class AddressesClient implements BackgroundResource { + private final AddressesSettings settings; + private final AddressesStub stub; + + /** Constructs an instance of AddressesClient with default settings. */ + public static final AddressesClient create() throws IOException { + return create(AddressesSettings.newBuilder().build()); + } + + /** + * Constructs an instance of AddressesClient, using the given settings. The channels are created + * based on the settings passed in, or defaults for any settings that are not set. + */ + public static final AddressesClient create(AddressesSettings settings) throws IOException { + return new AddressesClient(settings); + } + + /** + * Constructs an instance of AddressesClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(AddressesSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final AddressesClient create(AddressesStub stub) { + return new AddressesClient(stub); + } + + /** + * Constructs an instance of AddressesClient, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected AddressesClient(AddressesSettings settings) throws IOException { + this.settings = settings; + this.stub = ((AddressesStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected AddressesClient(AddressesStub stub) { + this.settings = null; + this.stub = stub; + } + + public final AddressesSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public AddressesStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves an aggregated list of addresses. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   String project = "project-309310695";
      +   *   for (Map.Entry element :
      +   *       addressesClient.aggregatedList(project).iterateAll()) {
      +   *     // doThingsWith(element);
      +   *   }
      +   * }
      +   * }
      + * + * @param project Project ID for this request. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final AggregatedListPagedResponse aggregatedList(String project) { + AggregatedListAddressesRequest request = + AggregatedListAddressesRequest.newBuilder().setProject(project).build(); + return aggregatedList(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves an aggregated list of addresses. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   AggregatedListAddressesRequest request =
      +   *       AggregatedListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setIncludeAllScopes(true)
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .build();
      +   *   for (Map.Entry element :
      +   *       addressesClient.aggregatedList(request).iterateAll()) {
      +   *     // doThingsWith(element);
      +   *   }
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final AggregatedListPagedResponse aggregatedList(AggregatedListAddressesRequest request) { + return aggregatedListPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves an aggregated list of addresses. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   AggregatedListAddressesRequest request =
      +   *       AggregatedListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setIncludeAllScopes(true)
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .build();
      +   *   ApiFuture> future =
      +   *       addressesClient.aggregatedListPagedCallable().futureCall(request);
      +   *   // Do something.
      +   *   for (Map.Entry element : future.get().iterateAll()) {
      +   *     // doThingsWith(element);
      +   *   }
      +   * }
      +   * }
      + */ + public final UnaryCallable + aggregatedListPagedCallable() { + return stub.aggregatedListPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves an aggregated list of addresses. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   AggregatedListAddressesRequest request =
      +   *       AggregatedListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setIncludeAllScopes(true)
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .build();
      +   *   while (true) {
      +   *     AddressAggregatedList response = addressesClient.aggregatedListCallable().call(request);
      +   *     for (Map.Entry element : response.getResponsesList()) {
      +   *       // doThingsWith(element);
      +   *     }
      +   *     String nextPageToken = response.getNextPageToken();
      +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
      +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
      +   *     } else {
      +   *       break;
      +   *     }
      +   *   }
      +   * }
      +   * }
      + */ + public final UnaryCallable + aggregatedListCallable() { + return stub.aggregatedListCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes the specified address resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   String project = "project-309310695";
      +   *   String region = "region-934795532";
      +   *   String address = "address-1147692044";
      +   *   Operation response = addressesClient.delete(project, region, address);
      +   * }
      +   * }
      + * + * @param project Project ID for this request. + * @param region Name of the region for this request. + * @param address Name of the address resource to delete. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation delete(String project, String region, String address) { + DeleteAddressRequest request = + DeleteAddressRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setAddress(address) + .build(); + return delete(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes the specified address resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   DeleteAddressRequest request =
      +   *       DeleteAddressRequest.newBuilder()
      +   *           .setAddress("address-1147692044")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .setRequestId("requestId693933066")
      +   *           .build();
      +   *   Operation response = addressesClient.delete(request);
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation delete(DeleteAddressRequest request) { + return deleteCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes the specified address resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   DeleteAddressRequest request =
      +   *       DeleteAddressRequest.newBuilder()
      +   *           .setAddress("address-1147692044")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .setRequestId("requestId693933066")
      +   *           .build();
      +   *   ApiFuture future = addressesClient.deleteCallable().futureCall(request);
      +   *   // Do something.
      +   *   Operation response = future.get();
      +   * }
      +   * }
      + */ + public final UnaryCallable deleteCallable() { + return stub.deleteCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Creates an address resource in the specified project by using the data included in the request. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   String project = "project-309310695";
      +   *   String region = "region-934795532";
      +   *   Address addressResource = Address.newBuilder().build();
      +   *   Operation response = addressesClient.insert(project, region, addressResource);
      +   * }
      +   * }
      + * + * @param project Project ID for this request. + * @param region Name of the region for this request. + * @param addressResource The body resource for this request + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation insert(String project, String region, Address addressResource) { + InsertAddressRequest request = + InsertAddressRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setAddressResource(addressResource) + .build(); + return insert(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Creates an address resource in the specified project by using the data included in the request. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   InsertAddressRequest request =
      +   *       InsertAddressRequest.newBuilder()
      +   *           .setAddressResource(Address.newBuilder().build())
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .setRequestId("requestId693933066")
      +   *           .build();
      +   *   Operation response = addressesClient.insert(request);
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation insert(InsertAddressRequest request) { + return insertCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Creates an address resource in the specified project by using the data included in the request. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   InsertAddressRequest request =
      +   *       InsertAddressRequest.newBuilder()
      +   *           .setAddressResource(Address.newBuilder().build())
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .setRequestId("requestId693933066")
      +   *           .build();
      +   *   ApiFuture future = addressesClient.insertCallable().futureCall(request);
      +   *   // Do something.
      +   *   Operation response = future.get();
      +   * }
      +   * }
      + */ + public final UnaryCallable insertCallable() { + return stub.insertCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves a list of addresses contained within the specified region. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   String project = "project-309310695";
      +   *   String region = "region-934795532";
      +   *   String orderBy = "orderBy-1207110587";
      +   *   for (Address element : addressesClient.list(project, region, orderBy).iterateAll()) {
      +   *     // doThingsWith(element);
      +   *   }
      +   * }
      +   * }
      + * + * @param project Project ID for this request. + * @param region Name of the region for this request. + * @param orderBy Sorts list results by a certain order. By default, results are returned in + * alphanumerical order based on the resource name. + *

      You can also sort results in descending order based on the creation timestamp using + * orderBy="creationTimestamp desc". This sorts results based on the creationTimestamp field + * in reverse chronological order (newest result first). Use this to sort resources like + * operations so that the newest operation is returned first. + *

      Currently, only sorting by name or creationTimestamp desc is supported. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListPagedResponse list(String project, String region, String orderBy) { + ListAddressesRequest request = + ListAddressesRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setOrderBy(orderBy) + .build(); + return list(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves a list of addresses contained within the specified region. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   ListAddressesRequest request =
      +   *       ListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .build();
      +   *   for (Address element : addressesClient.list(request).iterateAll()) {
      +   *     // doThingsWith(element);
      +   *   }
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final ListPagedResponse list(ListAddressesRequest request) { + return listPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves a list of addresses contained within the specified region. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   ListAddressesRequest request =
      +   *       ListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .build();
      +   *   ApiFuture
      future = addressesClient.listPagedCallable().futureCall(request); + * // Do something. + * for (Address element : future.get().iterateAll()) { + * // doThingsWith(element); + * } + * } + * }
      + */ + public final UnaryCallable listPagedCallable() { + return stub.listPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves a list of addresses contained within the specified region. + * + *

      Sample code: + * + *

      {@code
      +   * try (AddressesClient addressesClient = AddressesClient.create()) {
      +   *   ListAddressesRequest request =
      +   *       ListAddressesRequest.newBuilder()
      +   *           .setFilter("filter-1274492040")
      +   *           .setMaxResults(1128457243)
      +   *           .setOrderBy("orderBy-1207110587")
      +   *           .setPageToken("pageToken873572522")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .build();
      +   *   while (true) {
      +   *     AddressList response = addressesClient.listCallable().call(request);
      +   *     for (Address element : response.getResponsesList()) {
      +   *       // doThingsWith(element);
      +   *     }
      +   *     String nextPageToken = response.getNextPageToken();
      +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
      +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
      +   *     } else {
      +   *       break;
      +   *     }
      +   *   }
      +   * }
      +   * }
      + */ + public final UnaryCallable listCallable() { + return stub.listCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } + + public static class AggregatedListPagedResponse + extends AbstractPagedListResponse< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry, + AggregatedListPage, + AggregatedListFixedSizeCollection> { + + public static ApiFuture createAsync( + PageContext< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + context, + ApiFuture futureResponse) { + ApiFuture futurePage = + AggregatedListPage.createEmptyPage().createPageAsync(context, futureResponse); + return ApiFutures.transform( + futurePage, + input -> new AggregatedListPagedResponse(input), + MoreExecutors.directExecutor()); + } + + private AggregatedListPagedResponse(AggregatedListPage page) { + super(page, AggregatedListFixedSizeCollection.createEmptyCollection()); + } + } + + public static class AggregatedListPage + extends AbstractPage< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry, + AggregatedListPage> { + + private AggregatedListPage( + PageContext< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + context, + AddressAggregatedList response) { + super(context, response); + } + + private static AggregatedListPage createEmptyPage() { + return new AggregatedListPage(null, null); + } + + @Override + protected AggregatedListPage createPage( + PageContext< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + context, + AddressAggregatedList response) { + return new AggregatedListPage(context, response); + } + + @Override + public ApiFuture createPageAsync( + PageContext< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + context, + ApiFuture futureResponse) { + return super.createPageAsync(context, futureResponse); + } + } + + public static class AggregatedListFixedSizeCollection + extends AbstractFixedSizeCollection< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry, + AggregatedListPage, + AggregatedListFixedSizeCollection> { + + private AggregatedListFixedSizeCollection(List pages, int collectionSize) { + super(pages, collectionSize); + } + + private static AggregatedListFixedSizeCollection createEmptyCollection() { + return new AggregatedListFixedSizeCollection(null, 0); + } + + @Override + protected AggregatedListFixedSizeCollection createCollection( + List pages, int collectionSize) { + return new AggregatedListFixedSizeCollection(pages, collectionSize); + } + } + + public static class ListPagedResponse + extends AbstractPagedListResponse< + ListAddressesRequest, AddressList, Address, ListPage, ListFixedSizeCollection> { + + public static ApiFuture createAsync( + PageContext context, + ApiFuture futureResponse) { + ApiFuture futurePage = + ListPage.createEmptyPage().createPageAsync(context, futureResponse); + return ApiFutures.transform( + futurePage, input -> new ListPagedResponse(input), MoreExecutors.directExecutor()); + } + + private ListPagedResponse(ListPage page) { + super(page, ListFixedSizeCollection.createEmptyCollection()); + } + } + + public static class ListPage + extends AbstractPage { + + private ListPage( + PageContext context, AddressList response) { + super(context, response); + } + + private static ListPage createEmptyPage() { + return new ListPage(null, null); + } + + @Override + protected ListPage createPage( + PageContext context, AddressList response) { + return new ListPage(context, response); + } + + @Override + public ApiFuture createPageAsync( + PageContext context, + ApiFuture futureResponse) { + return super.createPageAsync(context, futureResponse); + } + } + + public static class ListFixedSizeCollection + extends AbstractFixedSizeCollection< + ListAddressesRequest, AddressList, Address, ListPage, ListFixedSizeCollection> { + + private ListFixedSizeCollection(List pages, int collectionSize) { + super(pages, collectionSize); + } + + private static ListFixedSizeCollection createEmptyCollection() { + return new ListFixedSizeCollection(null, 0); + } + + @Override + protected ListFixedSizeCollection createCollection(List pages, int collectionSize) { + return new ListFixedSizeCollection(pages, collectionSize); + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java new file mode 100644 index 0000000000..bc7d9c2a16 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java @@ -0,0 +1,324 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import static com.google.cloud.compute.v1.AddressesClient.AggregatedListPagedResponse; +import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.compute.v1.stub.HttpJsonAddressesStub; +import com.google.common.collect.Lists; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class AddressesClientTest { + private static MockHttpService mockService; + private static AddressesClient client; + + @BeforeClass + public static void startStaticServer() throws IOException { + mockService = + new MockHttpService( + HttpJsonAddressesStub.getMethodDescriptors(), AddressesSettings.getDefaultEndpoint()); + AddressesSettings settings = + AddressesSettings.newBuilder() + .setTransportChannelProvider( + AddressesSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(mockService) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = AddressesClient.create(settings); + } + + @AfterClass + public static void stopServer() { + client.close(); + } + + @Before + public void setUp() {} + + @After + public void tearDown() throws Exception { + mockService.reset(); + } + + @Test + public void aggregatedListTest() throws Exception { + AddressesScopedList responsesElement = AddressesScopedList.newBuilder().build(); + AddressAggregatedList expectedResponse = + AddressAggregatedList.newBuilder() + .setNextPageToken("") + .putAllItems(Collections.singletonMap("items", responsesElement)) + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + + AggregatedListPagedResponse pagedListResponse = client.aggregatedList(project); + + List> resources = + Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals( + expectedResponse.getItemsMap().entrySet().iterator().next(), resources.get(0)); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void aggregatedListExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + client.aggregatedList(project); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void deleteTest() throws Exception { + Operation expectedResponse = + Operation.newBuilder() + .setClientOperationId("clientOperationId-1230366697") + .setCreationTimestamp("creationTimestamp-370203401") + .setDescription("description-1724546052") + .setEndTime("endTime-1607243192") + .setError(Error.newBuilder().build()) + .setHttpErrorMessage("httpErrorMessage1577303431") + .setHttpErrorStatusCode(1386087020) + .setId("id3355") + .setInsertTime("insertTime966165798") + .setKind("kind3292052") + .setName("name3373707") + .setOperationType("operationType91999553") + .setProgress(-1001078227) + .setRegion("region-934795532") + .setSelfLink("selfLink1191800166") + .setStartTime("startTime-2129294769") + .setStatusMessage("statusMessage-958704715") + .setTargetId("targetId-441951604") + .setTargetLink("targetLink486368555") + .setUser("user3599307") + .addAllWarnings(new ArrayList()) + .setZone("zone3744684") + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + String region = "region-934795532"; + String address = "address-1147692044"; + + Operation actualResponse = client.delete(project, region, address); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void deleteExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + String region = "region-934795532"; + String address = "address-1147692044"; + client.delete(project, region, address); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void insertTest() throws Exception { + Operation expectedResponse = + Operation.newBuilder() + .setClientOperationId("clientOperationId-1230366697") + .setCreationTimestamp("creationTimestamp-370203401") + .setDescription("description-1724546052") + .setEndTime("endTime-1607243192") + .setError(Error.newBuilder().build()) + .setHttpErrorMessage("httpErrorMessage1577303431") + .setHttpErrorStatusCode(1386087020) + .setId("id3355") + .setInsertTime("insertTime966165798") + .setKind("kind3292052") + .setName("name3373707") + .setOperationType("operationType91999553") + .setProgress(-1001078227) + .setRegion("region-934795532") + .setSelfLink("selfLink1191800166") + .setStartTime("startTime-2129294769") + .setStatusMessage("statusMessage-958704715") + .setTargetId("targetId-441951604") + .setTargetLink("targetLink486368555") + .setUser("user3599307") + .addAllWarnings(new ArrayList()) + .setZone("zone3744684") + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + String region = "region-934795532"; + Address addressResource = Address.newBuilder().build(); + + Operation actualResponse = client.insert(project, region, addressResource); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void insertExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + String region = "region-934795532"; + Address addressResource = Address.newBuilder().build(); + client.insert(project, region, addressResource); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void listTest() throws Exception { + Address responsesElement = Address.newBuilder().build(); + AddressList expectedResponse = + AddressList.newBuilder() + .setNextPageToken("") + .addAllItems(Arrays.asList(responsesElement)) + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + String region = "region-934795532"; + String orderBy = "orderBy-1207110587"; + + ListPagedResponse pagedListResponse = client.list(project, region, orderBy); + + List
      resources = Lists.newArrayList(pagedListResponse.iterateAll()); + + Assert.assertEquals(1, resources.size()); + Assert.assertEquals(expectedResponse.getItemsList().get(0), resources.get(0)); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void listExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + String region = "region-934795532"; + String orderBy = "orderBy-1207110587"; + client.list(project, region, orderBy); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java new file mode 100644 index 0000000000..d2dc359f73 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java @@ -0,0 +1,220 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import static com.google.cloud.compute.v1.AddressesClient.AggregatedListPagedResponse; +import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.compute.v1.stub.AddressesStubSettings; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link AddressesClient}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (compute.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of delete to 30 seconds: + * + *

      {@code
      + * AddressesSettings.Builder addressesSettingsBuilder = AddressesSettings.newBuilder();
      + * addressesSettingsBuilder
      + *     .deleteSettings()
      + *     .setRetrySettings(
      + *         addressesSettingsBuilder
      + *             .deleteSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * AddressesSettings addressesSettings = addressesSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class AddressesSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to aggregatedList. */ + public PagedCallSettings< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings() { + return ((AddressesStubSettings) getStubSettings()).aggregatedListSettings(); + } + + /** Returns the object with the settings used for calls to delete. */ + public UnaryCallSettings deleteSettings() { + return ((AddressesStubSettings) getStubSettings()).deleteSettings(); + } + + /** Returns the object with the settings used for calls to insert. */ + public UnaryCallSettings insertSettings() { + return ((AddressesStubSettings) getStubSettings()).insertSettings(); + } + + /** Returns the object with the settings used for calls to list. */ + public PagedCallSettings listSettings() { + return ((AddressesStubSettings) getStubSettings()).listSettings(); + } + + public static final AddressesSettings create(AddressesStubSettings stub) throws IOException { + return new AddressesSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return AddressesStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return AddressesStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return AddressesStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return AddressesStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return AddressesStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return AddressesStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return AddressesStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected AddressesSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for AddressesSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(AddressesStubSettings.newBuilder(clientContext)); + } + + protected Builder(AddressesSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(AddressesStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(AddressesStubSettings.newBuilder()); + } + + public AddressesStubSettings.Builder getStubSettingsBuilder() { + return ((AddressesStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to aggregatedList. */ + public PagedCallSettings.Builder< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings() { + return getStubSettingsBuilder().aggregatedListSettings(); + } + + /** Returns the builder for the settings used for calls to delete. */ + public UnaryCallSettings.Builder deleteSettings() { + return getStubSettingsBuilder().deleteSettings(); + } + + /** Returns the builder for the settings used for calls to insert. */ + public UnaryCallSettings.Builder insertSettings() { + return getStubSettingsBuilder().insertSettings(); + } + + /** Returns the builder for the settings used for calls to list. */ + public PagedCallSettings.Builder + listSettings() { + return getStubSettingsBuilder().listSettings(); + } + + @Override + public AddressesSettings build() throws IOException { + return new AddressesSettings(this); + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java new file mode 100644 index 0000000000..fb6a5e296d --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java @@ -0,0 +1,254 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.stub.RegionOperationsStub; +import com.google.cloud.compute.v1.stub.RegionOperationsStubSettings; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: The RegionOperations API. + * + *

      This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

      {@code
      + * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
      + *   String project = "project-309310695";
      + *   String region = "region-934795532";
      + *   String operation = "operation1662702951";
      + *   Operation response = regionOperationsClient.get(project, region, operation);
      + * }
      + * }
      + * + *

      Note: close() needs to be called on the RegionOperationsClient object to clean up resources + * such as threads. In the example above, try-with-resources is used, which automatically calls + * close(). + * + *

      The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

        + *
      1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
      2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
      3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
      + * + *

      See the individual methods for example code. + * + *

      Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

      This class can be customized by passing in a custom instance of RegionOperationsSettings to + * create(). For example: + * + *

      To customize credentials: + * + *

      {@code
      + * RegionOperationsSettings regionOperationsSettings =
      + *     RegionOperationsSettings.newBuilder()
      + *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
      + *         .build();
      + * RegionOperationsClient regionOperationsClient =
      + *     RegionOperationsClient.create(regionOperationsSettings);
      + * }
      + * + *

      To customize the endpoint: + * + *

      {@code
      + * RegionOperationsSettings regionOperationsSettings =
      + *     RegionOperationsSettings.newBuilder().setEndpoint(myEndpoint).build();
      + * RegionOperationsClient regionOperationsClient =
      + *     RegionOperationsClient.create(regionOperationsSettings);
      + * }
      + * + *

      Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +public class RegionOperationsClient implements BackgroundResource { + private final RegionOperationsSettings settings; + private final RegionOperationsStub stub; + + /** Constructs an instance of RegionOperationsClient with default settings. */ + public static final RegionOperationsClient create() throws IOException { + return create(RegionOperationsSettings.newBuilder().build()); + } + + /** + * Constructs an instance of RegionOperationsClient, using the given settings. The channels are + * created based on the settings passed in, or defaults for any settings that are not set. + */ + public static final RegionOperationsClient create(RegionOperationsSettings settings) + throws IOException { + return new RegionOperationsClient(settings); + } + + /** + * Constructs an instance of RegionOperationsClient, using the given stub for making calls. This + * is for advanced usage - prefer using create(RegionOperationsSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final RegionOperationsClient create(RegionOperationsStub stub) { + return new RegionOperationsClient(stub); + } + + /** + * Constructs an instance of RegionOperationsClient, using the given settings. This is protected + * so that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected RegionOperationsClient(RegionOperationsSettings settings) throws IOException { + this.settings = settings; + this.stub = ((RegionOperationsStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected RegionOperationsClient(RegionOperationsStub stub) { + this.settings = null; + this.stub = stub; + } + + public final RegionOperationsSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public RegionOperationsStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves the specified region-specific Operations resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
      +   *   String project = "project-309310695";
      +   *   String region = "region-934795532";
      +   *   String operation = "operation1662702951";
      +   *   Operation response = regionOperationsClient.get(project, region, operation);
      +   * }
      +   * }
      + * + * @param project Project ID for this request. + * @param region Name of the region for this request. + * @param operation Name of the Operations resource to return. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation get(String project, String region, String operation) { + GetRegionOperationRequest request = + GetRegionOperationRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setOperation(operation) + .build(); + return get(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves the specified region-specific Operations resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
      +   *   GetRegionOperationRequest request =
      +   *       GetRegionOperationRequest.newBuilder()
      +   *           .setOperation("operation1662702951")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .build();
      +   *   Operation response = regionOperationsClient.get(request);
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation get(GetRegionOperationRequest request) { + return getCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Retrieves the specified region-specific Operations resource. + * + *

      Sample code: + * + *

      {@code
      +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
      +   *   GetRegionOperationRequest request =
      +   *       GetRegionOperationRequest.newBuilder()
      +   *           .setOperation("operation1662702951")
      +   *           .setProject("project-309310695")
      +   *           .setRegion("region-934795532")
      +   *           .build();
      +   *   ApiFuture future = regionOperationsClient.getCallable().futureCall(request);
      +   *   // Do something.
      +   *   Operation response = future.get();
      +   * }
      +   * }
      + */ + public final UnaryCallable getCallable() { + return stub.getCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java new file mode 100644 index 0000000000..7f6b78232a --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.compute.v1.stub.HttpJsonRegionOperationsStub; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class RegionOperationsClientTest { + private static MockHttpService mockService; + private static RegionOperationsClient client; + + @BeforeClass + public static void startStaticServer() throws IOException { + mockService = + new MockHttpService( + HttpJsonRegionOperationsStub.getMethodDescriptors(), + RegionOperationsSettings.getDefaultEndpoint()); + RegionOperationsSettings settings = + RegionOperationsSettings.newBuilder() + .setTransportChannelProvider( + RegionOperationsSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(mockService) + .build()) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = RegionOperationsClient.create(settings); + } + + @AfterClass + public static void stopServer() { + client.close(); + } + + @Before + public void setUp() {} + + @After + public void tearDown() throws Exception { + mockService.reset(); + } + + @Test + public void getTest() throws Exception { + Operation expectedResponse = + Operation.newBuilder() + .setClientOperationId("clientOperationId-1230366697") + .setCreationTimestamp("creationTimestamp-370203401") + .setDescription("description-1724546052") + .setEndTime("endTime-1607243192") + .setError(Error.newBuilder().build()) + .setHttpErrorMessage("httpErrorMessage1577303431") + .setHttpErrorStatusCode(1386087020) + .setId("id3355") + .setInsertTime("insertTime966165798") + .setKind("kind3292052") + .setName("name3373707") + .setOperationType("operationType91999553") + .setProgress(-1001078227) + .setRegion("region-934795532") + .setSelfLink("selfLink1191800166") + .setStartTime("startTime-2129294769") + .setStatusMessage("statusMessage-958704715") + .setTargetId("targetId-441951604") + .setTargetLink("targetLink486368555") + .setUser("user3599307") + .addAllWarnings(new ArrayList()) + .setZone("zone3744684") + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + String region = "region-934795532"; + String operation = "operation1662702951"; + + Operation actualResponse = client.get(project, region, operation); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void getExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + String region = "region-934795532"; + String operation = "operation1662702951"; + client.get(project, region, operation); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java new file mode 100644 index 0000000000..4e0ffca9d4 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java @@ -0,0 +1,183 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.compute.v1.stub.RegionOperationsStubSettings; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link RegionOperationsClient}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (compute.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of get to 30 seconds: + * + *

      {@code
      + * RegionOperationsSettings.Builder regionOperationsSettingsBuilder =
      + *     RegionOperationsSettings.newBuilder();
      + * regionOperationsSettingsBuilder
      + *     .getSettings()
      + *     .setRetrySettings(
      + *         regionOperationsSettingsBuilder
      + *             .getSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * RegionOperationsSettings regionOperationsSettings = regionOperationsSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class RegionOperationsSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to get. */ + public UnaryCallSettings getSettings() { + return ((RegionOperationsStubSettings) getStubSettings()).getSettings(); + } + + public static final RegionOperationsSettings create(RegionOperationsStubSettings stub) + throws IOException { + return new RegionOperationsSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return RegionOperationsStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return RegionOperationsStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return RegionOperationsStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return RegionOperationsStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return RegionOperationsStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return RegionOperationsStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return RegionOperationsStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected RegionOperationsSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for RegionOperationsSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(RegionOperationsStubSettings.newBuilder(clientContext)); + } + + protected Builder(RegionOperationsSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(RegionOperationsStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(RegionOperationsStubSettings.newBuilder()); + } + + public RegionOperationsStubSettings.Builder getStubSettingsBuilder() { + return ((RegionOperationsStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to get. */ + public UnaryCallSettings.Builder getSettings() { + return getStubSettingsBuilder().getSettings(); + } + + @Override + public RegionOperationsSettings build() throws IOException { + return new RegionOperationsSettings(this); + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json new file mode 100644 index 0000000000..14eb0320fd --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json @@ -0,0 +1,42 @@ +{ + "schema": "1.0", + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "java", + "protoPackage": "google.cloud.compute.v1", + "libraryPackage": "com.google.cloud.compute.v1", + "services": { + "Addresses": { + "clients": { + "grpc": { + "libraryClient": "AddressesClient", + "rpcs": { + "AggregatedList": { + "methods": ["aggregatedList", "aggregatedList", "aggregatedListPagedCallable", "aggregatedListCallable"] + }, + "Delete": { + "methods": ["delete", "delete", "deleteCallable"] + }, + "Insert": { + "methods": ["insert", "insert", "insertCallable"] + }, + "List": { + "methods": ["list", "list", "listPagedCallable", "listCallable"] + } + } + } + } + }, + "RegionOperations": { + "clients": { + "grpc": { + "libraryClient": "RegionOperationsClient", + "rpcs": { + "Get": { + "methods": ["get", "get", "getCallable"] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java new file mode 100644 index 0000000000..941f3ab751 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java @@ -0,0 +1,55 @@ +/* + * Copyright 2021 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. + */ + +/** + * The interfaces provided are listed below, along with usage samples. + * + *

      ======================= AddressesClient ======================= + * + *

      Service Description: Services + * + *

      The Addresses API. + * + *

      Sample for AddressesClient: + * + *

      {@code
      + * try (AddressesClient addressesClient = AddressesClient.create()) {
      + *   String project = "project-309310695";
      + *   String region = "region-934795532";
      + *   String address = "address-1147692044";
      + *   Operation response = addressesClient.delete(project, region, address);
      + * }
      + * }
      + * + *

      ======================= RegionOperationsClient ======================= + * + *

      Service Description: The RegionOperations API. + * + *

      Sample for RegionOperationsClient: + * + *

      {@code
      + * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
      + *   String project = "project-309310695";
      + *   String region = "region-934795532";
      + *   String operation = "operation1662702951";
      + *   Operation response = regionOperationsClient.get(project, region, operation);
      + * }
      + * }
      + */ +@Generated("by gapic-generator-java") +package com.google.cloud.compute.v1; + +import javax.annotation.Generated; diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java new file mode 100644 index 0000000000..b7d7f6e590 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java @@ -0,0 +1,70 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import static com.google.cloud.compute.v1.AddressesClient.AggregatedListPagedResponse; +import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.AddressAggregatedList; +import com.google.cloud.compute.v1.AddressList; +import com.google.cloud.compute.v1.AggregatedListAddressesRequest; +import com.google.cloud.compute.v1.DeleteAddressRequest; +import com.google.cloud.compute.v1.InsertAddressRequest; +import com.google.cloud.compute.v1.ListAddressesRequest; +import com.google.cloud.compute.v1.Operation; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the Addresses service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public abstract class AddressesStub implements BackgroundResource { + + public UnaryCallable + aggregatedListPagedCallable() { + throw new UnsupportedOperationException("Not implemented: aggregatedListPagedCallable()"); + } + + public UnaryCallable + aggregatedListCallable() { + throw new UnsupportedOperationException("Not implemented: aggregatedListCallable()"); + } + + public UnaryCallable deleteCallable() { + throw new UnsupportedOperationException("Not implemented: deleteCallable()"); + } + + public UnaryCallable insertCallable() { + throw new UnsupportedOperationException("Not implemented: insertCallable()"); + } + + public UnaryCallable listPagedCallable() { + throw new UnsupportedOperationException("Not implemented: listPagedCallable()"); + } + + public UnaryCallable listCallable() { + throw new UnsupportedOperationException("Not implemented: listCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java new file mode 100644 index 0000000000..69e3c4d6c0 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java @@ -0,0 +1,500 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import static com.google.cloud.compute.v1.AddressesClient.AggregatedListPagedResponse; +import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; + +import com.google.api.core.ApiFunction; +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.PageContext; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.PagedListDescriptor; +import com.google.api.gax.rpc.PagedListResponseFactory; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.Address; +import com.google.cloud.compute.v1.AddressAggregatedList; +import com.google.cloud.compute.v1.AddressList; +import com.google.cloud.compute.v1.AddressesScopedList; +import com.google.cloud.compute.v1.AggregatedListAddressesRequest; +import com.google.cloud.compute.v1.DeleteAddressRequest; +import com.google.cloud.compute.v1.InsertAddressRequest; +import com.google.cloud.compute.v1.ListAddressesRequest; +import com.google.cloud.compute.v1.Operation; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import org.threeten.bp.Duration; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link AddressesStub}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (compute.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of delete to 30 seconds: + * + *

      {@code
      + * AddressesStubSettings.Builder addressesSettingsBuilder = AddressesStubSettings.newBuilder();
      + * addressesSettingsBuilder
      + *     .deleteSettings()
      + *     .setRetrySettings(
      + *         addressesSettingsBuilder
      + *             .deleteSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * AddressesStubSettings addressesSettings = addressesSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class AddressesStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/compute") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private final PagedCallSettings< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings; + private final UnaryCallSettings deleteSettings; + private final UnaryCallSettings insertSettings; + private final PagedCallSettings + listSettings; + + private static final PagedListDescriptor< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + AGGREGATED_LIST_PAGE_STR_DESC = + new PagedListDescriptor< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry>() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public AggregatedListAddressesRequest injectToken( + AggregatedListAddressesRequest payload, String token) { + return AggregatedListAddressesRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public AggregatedListAddressesRequest injectPageSize( + AggregatedListAddressesRequest payload, int pageSize) { + return AggregatedListAddressesRequest.newBuilder(payload) + .setMaxResults(pageSize) + .build(); + } + + @Override + public Integer extractPageSize(AggregatedListAddressesRequest payload) { + return payload.getMaxResults(); + } + + @Override + public String extractNextToken(AddressAggregatedList payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable> extractResources( + AddressAggregatedList payload) { + return payload.getItemsMap() == null + ? Collections.>emptySet() + : payload.getItemsMap().entrySet(); + } + }; + + private static final PagedListDescriptor + LIST_PAGE_STR_DESC = + new PagedListDescriptor() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public ListAddressesRequest injectToken(ListAddressesRequest payload, String token) { + return ListAddressesRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public ListAddressesRequest injectPageSize(ListAddressesRequest payload, int pageSize) { + return ListAddressesRequest.newBuilder(payload).setMaxResults(pageSize).build(); + } + + @Override + public Integer extractPageSize(ListAddressesRequest payload) { + return payload.getMaxResults(); + } + + @Override + public String extractNextToken(AddressList payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable
      extractResources(AddressList payload) { + return payload.getItemsList() == null + ? ImmutableList.
      of() + : payload.getItemsList(); + } + }; + + private static final PagedListResponseFactory< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + AGGREGATED_LIST_PAGE_STR_FACT = + new PagedListResponseFactory< + AggregatedListAddressesRequest, + AddressAggregatedList, + AggregatedListPagedResponse>() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + AggregatedListAddressesRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext< + AggregatedListAddressesRequest, + AddressAggregatedList, + Map.Entry> + pageContext = + PageContext.create(callable, AGGREGATED_LIST_PAGE_STR_DESC, request, context); + return AggregatedListPagedResponse.createAsync(pageContext, futureResponse); + } + }; + + private static final PagedListResponseFactory< + ListAddressesRequest, AddressList, ListPagedResponse> + LIST_PAGE_STR_FACT = + new PagedListResponseFactory() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + ListAddressesRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext pageContext = + PageContext.create(callable, LIST_PAGE_STR_DESC, request, context); + return ListPagedResponse.createAsync(pageContext, futureResponse); + } + }; + + /** Returns the object with the settings used for calls to aggregatedList. */ + public PagedCallSettings< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings() { + return aggregatedListSettings; + } + + /** Returns the object with the settings used for calls to delete. */ + public UnaryCallSettings deleteSettings() { + return deleteSettings; + } + + /** Returns the object with the settings used for calls to insert. */ + public UnaryCallSettings insertSettings() { + return insertSettings; + } + + /** Returns the object with the settings used for calls to list. */ + public PagedCallSettings listSettings() { + return listSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public AddressesStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonAddressesStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "compute.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "compute.mtls.googleapis.com:443"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultHttpJsonTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(AddressesStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected AddressesStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + aggregatedListSettings = settingsBuilder.aggregatedListSettings().build(); + deleteSettings = settingsBuilder.deleteSettings().build(); + insertSettings = settingsBuilder.insertSettings().build(); + listSettings = settingsBuilder.listSettings().build(); + } + + /** Builder for AddressesStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final PagedCallSettings.Builder< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings; + private final UnaryCallSettings.Builder deleteSettings; + private final UnaryCallSettings.Builder insertSettings; + private final PagedCallSettings.Builder + listSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf( + Lists.newArrayList( + StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); + definitions.put( + "no_retry_1_codes", ImmutableSet.copyOf(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(100L)) + .setRetryDelayMultiplier(1.3) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(600000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(600000L)) + .setTotalTimeout(Duration.ofMillis(600000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + settings = + RetrySettings.newBuilder() + .setInitialRpcTimeout(Duration.ofMillis(600000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(600000L)) + .setTotalTimeout(Duration.ofMillis(600000L)) + .build(); + definitions.put("no_retry_1_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + aggregatedListSettings = PagedCallSettings.newBuilder(AGGREGATED_LIST_PAGE_STR_FACT); + deleteSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + insertSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + listSettings = PagedCallSettings.newBuilder(LIST_PAGE_STR_FACT); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + aggregatedListSettings, deleteSettings, insertSettings, listSettings); + initDefaults(this); + } + + protected Builder(AddressesStubSettings settings) { + super(settings); + + aggregatedListSettings = settings.aggregatedListSettings.toBuilder(); + deleteSettings = settings.deleteSettings.toBuilder(); + insertSettings = settings.insertSettings.toBuilder(); + listSettings = settings.listSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + aggregatedListSettings, deleteSettings, insertSettings, listSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .aggregatedListSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .deleteSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .insertSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params")); + + builder + .listSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to aggregatedList. */ + public PagedCallSettings.Builder< + AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse> + aggregatedListSettings() { + return aggregatedListSettings; + } + + /** Returns the builder for the settings used for calls to delete. */ + public UnaryCallSettings.Builder deleteSettings() { + return deleteSettings; + } + + /** Returns the builder for the settings used for calls to insert. */ + public UnaryCallSettings.Builder insertSettings() { + return insertSettings; + } + + /** Returns the builder for the settings used for calls to list. */ + public PagedCallSettings.Builder + listSettings() { + return listSettings; + } + + @Override + public AddressesStubSettings build() throws IOException { + return new AddressesStubSettings(this); + } + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java new file mode 100644 index 0000000000..afa275a6f5 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java @@ -0,0 +1,84 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the Addresses service API. + * + *

      This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonAddressesCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + BackgroundResource operationsStub) { + return null; + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java new file mode 100644 index 0000000000..d8d960d342 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -0,0 +1,387 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import static com.google.cloud.compute.v1.AddressesClient.AggregatedListPagedResponse; +import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.AddressAggregatedList; +import com.google.cloud.compute.v1.AddressList; +import com.google.cloud.compute.v1.AggregatedListAddressesRequest; +import com.google.cloud.compute.v1.DeleteAddressRequest; +import com.google.cloud.compute.v1.InsertAddressRequest; +import com.google.cloud.compute.v1.ListAddressesRequest; +import com.google.cloud.compute.v1.Operation; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the Addresses service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi("A restructuring of stub classes is planned, so this may break in the future") +public class HttpJsonAddressesStub extends AddressesStub { + private static final ApiMethodDescriptor + aggregatedListMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.Addresses/AggregatedList") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/{project}/aggregated/addresses", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "project", request.getProject()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.hasFilter()) { + serializer.putQueryParam(fields, "filter", request.getFilter()); + } + if (request.hasIncludeAllScopes()) { + serializer.putQueryParam( + fields, "includeAllScopes", request.getIncludeAllScopes()); + } + if (request.hasMaxResults()) { + serializer.putQueryParam( + fields, "maxResults", request.getMaxResults()); + } + if (request.hasOrderBy()) { + serializer.putQueryParam(fields, "orderBy", request.getOrderBy()); + } + if (request.hasPageToken()) { + serializer.putQueryParam(fields, "pageToken", request.getPageToken()); + } + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(AddressAggregatedList.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor deleteMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.Addresses/Delete") + .setHttpMethod(HttpMethods.DELETE) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/{project}/regions/{region}/addresses/{address}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "address", request.getAddress()); + serializer.putPathParam(fields, "project", request.getProject()); + serializer.putPathParam(fields, "region", request.getRegion()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.hasRequestId()) { + serializer.putQueryParam(fields, "requestId", request.getRequestId()); + } + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor insertMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.Addresses/Insert") + .setHttpMethod(HttpMethods.POST) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/{project}/regions/{region}/addresses", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "project", request.getProject()); + serializer.putPathParam(fields, "region", request.getRegion()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.hasRequestId()) { + serializer.putQueryParam(fields, "requestId", request.getRequestId()); + } + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("addressResource", request.getAddressResource())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .build()) + .build(); + + private static final ApiMethodDescriptor listMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.Addresses/List") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/{project}/regions/{region}/addresses", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "project", request.getProject()); + serializer.putPathParam(fields, "region", request.getRegion()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + if (request.hasFilter()) { + serializer.putQueryParam(fields, "filter", request.getFilter()); + } + if (request.hasMaxResults()) { + serializer.putQueryParam(fields, "maxResults", request.getMaxResults()); + } + serializer.putQueryParam(fields, "orderBy", request.getOrderBy()); + if (request.hasPageToken()) { + serializer.putQueryParam(fields, "pageToken", request.getPageToken()); + } + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(AddressList.getDefaultInstance()) + .build()) + .build(); + + private final UnaryCallable + aggregatedListCallable; + private final UnaryCallable + aggregatedListPagedCallable; + private final UnaryCallable deleteCallable; + private final UnaryCallable insertCallable; + private final UnaryCallable listCallable; + private final UnaryCallable listPagedCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonAddressesStub create(AddressesStubSettings settings) + throws IOException { + return new HttpJsonAddressesStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonAddressesStub create(ClientContext clientContext) throws IOException { + return new HttpJsonAddressesStub(AddressesStubSettings.newBuilder().build(), clientContext); + } + + public static final HttpJsonAddressesStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonAddressesStub( + AddressesStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonAddressesStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonAddressesStub(AddressesStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new HttpJsonAddressesCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonAddressesStub, using the given settings. This is protected so + * that it is easy to make a subclass, but otherwise, the static factory methods should be + * preferred. + */ + protected HttpJsonAddressesStub( + AddressesStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings + aggregatedListTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(aggregatedListMethodDescriptor) + .build(); + HttpJsonCallSettings deleteTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(deleteMethodDescriptor) + .build(); + HttpJsonCallSettings insertTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(insertMethodDescriptor) + .build(); + HttpJsonCallSettings listTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(listMethodDescriptor) + .build(); + + this.aggregatedListCallable = + callableFactory.createUnaryCallable( + aggregatedListTransportSettings, settings.aggregatedListSettings(), clientContext); + this.aggregatedListPagedCallable = + callableFactory.createPagedCallable( + aggregatedListTransportSettings, settings.aggregatedListSettings(), clientContext); + this.deleteCallable = + callableFactory.createUnaryCallable( + deleteTransportSettings, settings.deleteSettings(), clientContext); + this.insertCallable = + callableFactory.createUnaryCallable( + insertTransportSettings, settings.insertSettings(), clientContext); + this.listCallable = + callableFactory.createUnaryCallable( + listTransportSettings, settings.listSettings(), clientContext); + this.listPagedCallable = + callableFactory.createPagedCallable( + listTransportSettings, settings.listSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(aggregatedListMethodDescriptor); + methodDescriptors.add(deleteMethodDescriptor); + methodDescriptors.add(insertMethodDescriptor); + methodDescriptors.add(listMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable + aggregatedListCallable() { + return aggregatedListCallable; + } + + @Override + public UnaryCallable + aggregatedListPagedCallable() { + return aggregatedListPagedCallable; + } + + @Override + public UnaryCallable deleteCallable() { + return deleteCallable; + } + + @Override + public UnaryCallable insertCallable() { + return insertCallable; + } + + @Override + public UnaryCallable listCallable() { + return listCallable; + } + + @Override + public UnaryCallable listPagedCallable() { + return listPagedCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java new file mode 100644 index 0000000000..6dac14a84e --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -0,0 +1,84 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the RegionOperations service API. + * + *

      This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +@BetaApi +public class HttpJsonRegionOperationsCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + BackgroundResource operationsStub) { + return null; + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java new file mode 100644 index 0000000000..9d90915792 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -0,0 +1,188 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.GetRegionOperationRequest; +import com.google.cloud.compute.v1.Operation; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the RegionOperations service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +@BetaApi("A restructuring of stub classes is planned, so this may break in the future") +public class HttpJsonRegionOperationsStub extends RegionOperationsStub { + private static final ApiMethodDescriptor + getMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.RegionOperations/Get") + .setHttpMethod(HttpMethods.GET) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/{project}/regions/{region}/operations/{operation}", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "operation", request.getOperation()); + serializer.putPathParam(fields, "project", request.getProject()); + serializer.putPathParam(fields, "region", request.getRegion()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .build()) + .build(); + + private final UnaryCallable getCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonRegionOperationsStub create(RegionOperationsStubSettings settings) + throws IOException { + return new HttpJsonRegionOperationsStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonRegionOperationsStub create(ClientContext clientContext) + throws IOException { + return new HttpJsonRegionOperationsStub( + RegionOperationsStubSettings.newBuilder().build(), clientContext); + } + + public static final HttpJsonRegionOperationsStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonRegionOperationsStub( + RegionOperationsStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonRegionOperationsStub, using the given settings. This is + * protected so that it is easy to make a subclass, but otherwise, the static factory methods + * should be preferred. + */ + protected HttpJsonRegionOperationsStub( + RegionOperationsStubSettings settings, ClientContext clientContext) throws IOException { + this(settings, clientContext, new HttpJsonRegionOperationsCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonRegionOperationsStub, using the given settings. This is + * protected so that it is easy to make a subclass, but otherwise, the static factory methods + * should be preferred. + */ + protected HttpJsonRegionOperationsStub( + RegionOperationsStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + + HttpJsonCallSettings getTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(getMethodDescriptor) + .build(); + + this.getCallable = + callableFactory.createUnaryCallable( + getTransportSettings, settings.getSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(getMethodDescriptor); + return methodDescriptors; + } + + @Override + public UnaryCallable getCallable() { + return getCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java new file mode 100644 index 0000000000..c3019038cb --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.GetRegionOperationRequest; +import com.google.cloud.compute.v1.Operation; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the RegionOperations service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public abstract class RegionOperationsStub implements BackgroundResource { + + public UnaryCallable getCallable() { + throw new UnsupportedOperationException("Not implemented: getCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java new file mode 100644 index 0000000000..ebcf98e4f7 --- /dev/null +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java @@ -0,0 +1,277 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.compute.v1.stub; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.cloud.compute.v1.GetRegionOperationRequest; +import com.google.cloud.compute.v1.Operation; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; +import org.threeten.bp.Duration; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link RegionOperationsStub}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (compute.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of get to 30 seconds: + * + *

      {@code
      + * RegionOperationsStubSettings.Builder regionOperationsSettingsBuilder =
      + *     RegionOperationsStubSettings.newBuilder();
      + * regionOperationsSettingsBuilder
      + *     .getSettings()
      + *     .setRetrySettings(
      + *         regionOperationsSettingsBuilder
      + *             .getSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * RegionOperationsStubSettings regionOperationsSettings = regionOperationsSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class RegionOperationsStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/compute.readonly") + .add("https://www.googleapis.com/auth/compute") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private final UnaryCallSettings getSettings; + + /** Returns the object with the settings used for calls to get. */ + public UnaryCallSettings getSettings() { + return getSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public RegionOperationsStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { + return HttpJsonRegionOperationsStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "compute.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "compute.mtls.googleapis.com:443"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return InstantiatingHttpJsonChannelProvider.newBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultHttpJsonTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(RegionOperationsStubSettings.class)) + .setTransportToken( + GaxHttpJsonProperties.getHttpJsonTokenName(), + GaxHttpJsonProperties.getHttpJsonVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected RegionOperationsStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + getSettings = settingsBuilder.getSettings().build(); + } + + /** Builder for RegionOperationsStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final UnaryCallSettings.Builder getSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf( + Lists.newArrayList( + StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(100L)) + .setRetryDelayMultiplier(1.3) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(600000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(600000L)) + .setTotalTimeout(Duration.ofMillis(600000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + getSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = ImmutableList.>of(getSettings); + initDefaults(this); + } + + protected Builder(RegionOperationsStubSettings settings) { + super(settings); + + getSettings = settings.getSettings.toBuilder(); + + unaryMethodSettingsBuilders = ImmutableList.>of(getSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .getSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to get. */ + public UnaryCallSettings.Builder getSettings() { + return getSettings; + } + + @Override + public RegionOperationsStubSettings build() throws IOException { + return new RegionOperationsStubSettings(this); + } + } +} diff --git a/test/integration/goldens/credentials/BUILD.bazel b/test/integration/goldens/credentials/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/credentials/BUILD.bazel +++ b/test/integration/goldens/credentials/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IAMCredentialsClientTest.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IAMCredentialsClientTest.java index ad8fb75d32..e386fdec3c 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IAMCredentialsClientTest.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IAMCredentialsClientTest.java @@ -43,10 +43,10 @@ @Generated("by gapic-generator-java") public class IAMCredentialsClientTest { - private static MockServiceHelper mockServiceHelper; private static MockIAMCredentials mockIAMCredentials; - private IamCredentialsClient client; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private IamCredentialsClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IamCredentialsSettings.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IamCredentialsSettings.java index 9018bc6ffd..7395ce677d 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IamCredentialsSettings.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/IamCredentialsSettings.java @@ -175,14 +175,13 @@ public IamCredentialsStubSettings.Builder getStubSettingsBuilder() { return ((IamCredentialsStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/ServiceAccountName.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/ServiceAccountName.java index dfca251fb1..148cbe58cb 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/ServiceAccountName.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/ServiceAccountName.java @@ -182,8 +182,8 @@ public Builder setServiceAccount(String serviceAccount) { } private Builder(ServiceAccountName serviceAccountName) { - project = serviceAccountName.project; - serviceAccount = serviceAccountName.serviceAccount; + this.project = serviceAccountName.project; + this.serviceAccount = serviceAccountName.serviceAccount; } public ServiceAccountName build() { diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/GrpcIamCredentialsStub.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/GrpcIamCredentialsStub.java index 48731cd53d..8d57d52a19 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/GrpcIamCredentialsStub.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/GrpcIamCredentialsStub.java @@ -21,7 +21,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.iam.credentials.v1.GenerateAccessTokenRequest; import com.google.cloud.iam.credentials.v1.GenerateAccessTokenResponse; @@ -143,13 +142,10 @@ protected GrpcIamCredentialsStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(generateAccessTokenMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GenerateAccessTokenRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -157,39 +153,30 @@ public Map extract(GenerateAccessTokenRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(generateIdTokenMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GenerateIdTokenRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings signBlobTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(signBlobMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SignBlobRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings signJwtTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(signJwtMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SignJwtRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); @@ -239,7 +226,13 @@ public UnaryCallable signJwtCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java index 0cec2d9668..26792da200 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java @@ -138,6 +138,11 @@ public static String getDefaultEndpoint() { return "iamcredentials.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "iamcredentials.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -145,7 +150,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -277,6 +284,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -305,14 +314,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/iam/BUILD.bazel b/test/integration/goldens/iam/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/iam/BUILD.bazel +++ b/test/integration/goldens/iam/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/iam/com/google/iam/v1/IAMPolicyClientTest.java b/test/integration/goldens/iam/com/google/iam/v1/IAMPolicyClientTest.java index a055a7a204..fd1836ff9f 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/IAMPolicyClientTest.java +++ b/test/integration/goldens/iam/com/google/iam/v1/IAMPolicyClientTest.java @@ -41,10 +41,10 @@ @Generated("by gapic-generator-java") public class IAMPolicyClientTest { - private static MockServiceHelper mockServiceHelper; - private IAMPolicyClient client; private static MockIAMPolicy mockIAMPolicy; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private IAMPolicyClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/iam/com/google/iam/v1/IAMPolicySettings.java b/test/integration/goldens/iam/com/google/iam/v1/IAMPolicySettings.java index a1c55c5782..26eb385562 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/IAMPolicySettings.java +++ b/test/integration/goldens/iam/com/google/iam/v1/IAMPolicySettings.java @@ -166,14 +166,13 @@ public IAMPolicyStubSettings.Builder getStubSettingsBuilder() { return ((IAMPolicyStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/iam/com/google/iam/v1/package-info.java b/test/integration/goldens/iam/com/google/iam/v1/package-info.java index 136353c3e3..8f87748c4b 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/package-info.java +++ b/test/integration/goldens/iam/com/google/iam/v1/package-info.java @@ -48,7 +48,7 @@ * try (IAMPolicyClient iAMPolicyClient = IAMPolicyClient.create()) { * SetIamPolicyRequest request = * SetIamPolicyRequest.newBuilder() - * .setResource("SetIamPolicyRequest1223629066".toString()) + * .setResource("resource-341064690") * .setPolicy(Policy.newBuilder().build()) * .build(); * Policy response = iAMPolicyClient.setIamPolicy(request); diff --git a/test/integration/goldens/iam/com/google/iam/v1/stub/GrpcIAMPolicyStub.java b/test/integration/goldens/iam/com/google/iam/v1/stub/GrpcIAMPolicyStub.java index f40c2bfffe..1e19326973 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/stub/GrpcIAMPolicyStub.java +++ b/test/integration/goldens/iam/com/google/iam/v1/stub/GrpcIAMPolicyStub.java @@ -21,7 +21,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.iam.v1.GetIamPolicyRequest; @@ -122,26 +121,20 @@ protected GrpcIAMPolicyStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(setIamPolicyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SetIamPolicyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); }) .build(); GrpcCallSettings getIamPolicyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getIamPolicyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetIamPolicyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); }) .build(); GrpcCallSettings @@ -149,13 +142,10 @@ public Map extract(GetIamPolicyRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(testIamPermissionsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(TestIamPermissionsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); }) .build(); @@ -197,7 +187,13 @@ public UnaryCallable getIamPolicyCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java b/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java index 5959e94a06..03c10fcb73 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java +++ b/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java @@ -125,6 +125,11 @@ public static String getDefaultEndpoint() { return "iam-meta-api.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "iam-meta-api.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -132,7 +137,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -250,6 +257,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -273,14 +282,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/kms/BUILD.bazel b/test/integration/goldens/kms/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/kms/BUILD.bazel +++ b/test/integration/goldens/kms/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyName.java index ebad53ab26..3e782de33a 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyName.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyName.java @@ -248,10 +248,10 @@ public Builder setCryptoKey(String cryptoKey) { } private Builder(CryptoKeyName cryptoKeyName) { - project = cryptoKeyName.project; - location = cryptoKeyName.location; - keyRing = cryptoKeyName.keyRing; - cryptoKey = cryptoKeyName.cryptoKey; + this.project = cryptoKeyName.project; + this.location = cryptoKeyName.location; + this.keyRing = cryptoKeyName.keyRing; + this.cryptoKey = cryptoKeyName.cryptoKey; } public CryptoKeyName build() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyVersionName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyVersionName.java index c9317320c2..f60ef735fc 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyVersionName.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/CryptoKeyVersionName.java @@ -284,11 +284,11 @@ public Builder setCryptoKeyVersion(String cryptoKeyVersion) { } private Builder(CryptoKeyVersionName cryptoKeyVersionName) { - project = cryptoKeyVersionName.project; - location = cryptoKeyVersionName.location; - keyRing = cryptoKeyVersionName.keyRing; - cryptoKey = cryptoKeyVersionName.cryptoKey; - cryptoKeyVersion = cryptoKeyVersionName.cryptoKeyVersion; + this.project = cryptoKeyVersionName.project; + this.location = cryptoKeyVersionName.location; + this.keyRing = cryptoKeyVersionName.keyRing; + this.cryptoKey = cryptoKeyVersionName.cryptoKey; + this.cryptoKeyVersion = cryptoKeyVersionName.cryptoKeyVersion; } public CryptoKeyVersionName build() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/ImportJobName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/ImportJobName.java index 23b29da21a..8b966623be 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/ImportJobName.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/ImportJobName.java @@ -248,10 +248,10 @@ public Builder setImportJob(String importJob) { } private Builder(ImportJobName importJobName) { - project = importJobName.project; - location = importJobName.location; - keyRing = importJobName.keyRing; - importJob = importJobName.importJob; + this.project = importJobName.project; + this.location = importJobName.location; + this.keyRing = importJobName.keyRing; + this.importJob = importJobName.importJob; } public ImportJobName build() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java index cc3e563cff..e4d0dcc548 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java @@ -16,7 +16,6 @@ package com.google.cloud.kms.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -2148,7 +2147,7 @@ public final CryptoKeyVersion updateCryptoKeyVersion(UpdateCryptoKeyVersionReque *

      {@code
          * try (KeyManagementServiceClient keyManagementServiceClient =
          *     KeyManagementServiceClient.create()) {
      -   *   ResourceName name = KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]");
      +   *   ResourceName name = CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]");
          *   ByteString plaintext = ByteString.EMPTY;
          *   EncryptResponse response = keyManagementServiceClient.encrypt(name, plaintext);
          * }
      @@ -2188,7 +2187,8 @@ public final EncryptResponse encrypt(ResourceName name, ByteString plaintext) {
          * 
      {@code
          * try (KeyManagementServiceClient keyManagementServiceClient =
          *     KeyManagementServiceClient.create()) {
      -   *   String name = KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString();
      +   *   String name =
      +   *       CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]").toString();
          *   ByteString plaintext = ByteString.EMPTY;
          *   EncryptResponse response = keyManagementServiceClient.encrypt(name, plaintext);
          * }
      @@ -2227,7 +2227,9 @@ public final EncryptResponse encrypt(String name, ByteString plaintext) {
          *     KeyManagementServiceClient.create()) {
          *   EncryptRequest request =
          *       EncryptRequest.newBuilder()
      -   *           .setName(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setName(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .setPlaintext(ByteString.EMPTY)
          *           .setAdditionalAuthenticatedData(ByteString.EMPTY)
          *           .setPlaintextCrc32C(Int64Value.newBuilder().build())
      @@ -2258,7 +2260,9 @@ public final EncryptResponse encrypt(EncryptRequest request) {
          *     KeyManagementServiceClient.create()) {
          *   EncryptRequest request =
          *       EncryptRequest.newBuilder()
      -   *           .setName(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setName(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .setPlaintext(ByteString.EMPTY)
          *           .setAdditionalAuthenticatedData(ByteString.EMPTY)
          *           .setPlaintextCrc32C(Int64Value.newBuilder().build())
      @@ -3154,7 +3158,9 @@ public final CryptoKeyVersion restoreCryptoKeyVersion(RestoreCryptoKeyVersionReq
          *     KeyManagementServiceClient.create()) {
          *   GetIamPolicyRequest request =
          *       GetIamPolicyRequest.newBuilder()
      -   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setResource(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .setOptions(GetPolicyOptions.newBuilder().build())
          *           .build();
          *   Policy response = keyManagementServiceClient.getIamPolicy(request);
      @@ -3180,7 +3186,9 @@ public final Policy getIamPolicy(GetIamPolicyRequest request) {
          *     KeyManagementServiceClient.create()) {
          *   GetIamPolicyRequest request =
          *       GetIamPolicyRequest.newBuilder()
      -   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setResource(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .setOptions(GetPolicyOptions.newBuilder().build())
          *           .build();
          *   ApiFuture future =
      @@ -3343,7 +3351,9 @@ public final UnaryCallable getLocationCallable() {
          *     KeyManagementServiceClient.create()) {
          *   TestIamPermissionsRequest request =
          *       TestIamPermissionsRequest.newBuilder()
      -   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setResource(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .addAllPermissions(new ArrayList())
          *           .build();
          *   TestIamPermissionsResponse response = keyManagementServiceClient.testIamPermissions(request);
      @@ -3369,7 +3379,9 @@ public final TestIamPermissionsResponse testIamPermissions(TestIamPermissionsReq
          *     KeyManagementServiceClient.create()) {
          *   TestIamPermissionsRequest request =
          *       TestIamPermissionsRequest.newBuilder()
      -   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
      +   *           .setResource(
      +   *               CryptoKeyName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]")
      +   *                   .toString())
          *           .addAllPermissions(new ArrayList())
          *           .build();
          *   ApiFuture future =
      @@ -3429,12 +3441,7 @@ public static ApiFuture createAsync(
                 ListKeyRingsPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
                 futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListKeyRingsPagedResponse apply(ListKeyRingsPage input) {
      -              return new ListKeyRingsPagedResponse(input);
      -            }
      -          },
      +          input -> new ListKeyRingsPagedResponse(input),
                 MoreExecutors.directExecutor());
           }
       
      @@ -3509,12 +3516,7 @@ public static ApiFuture createAsync(
                 ListCryptoKeysPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
                 futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListCryptoKeysPagedResponse apply(ListCryptoKeysPage input) {
      -              return new ListCryptoKeysPagedResponse(input);
      -            }
      -          },
      +          input -> new ListCryptoKeysPagedResponse(input),
                 MoreExecutors.directExecutor());
           }
       
      @@ -3591,12 +3593,7 @@ public static ApiFuture createAsync(
                 ListCryptoKeyVersionsPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
                 futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListCryptoKeyVersionsPagedResponse apply(ListCryptoKeyVersionsPage input) {
      -              return new ListCryptoKeyVersionsPagedResponse(input);
      -            }
      -          },
      +          input -> new ListCryptoKeyVersionsPagedResponse(input),
                 MoreExecutors.directExecutor());
           }
       
      @@ -3679,12 +3676,7 @@ public static ApiFuture createAsync(
                 ListImportJobsPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
                 futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListImportJobsPagedResponse apply(ListImportJobsPage input) {
      -              return new ListImportJobsPagedResponse(input);
      -            }
      -          },
      +          input -> new ListImportJobsPagedResponse(input),
                 MoreExecutors.directExecutor());
           }
       
      @@ -3760,12 +3752,7 @@ public static ApiFuture createAsync(
                 ListLocationsPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
                 futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListLocationsPagedResponse apply(ListLocationsPage input) {
      -              return new ListLocationsPagedResponse(input);
      -            }
      -          },
      +          input -> new ListLocationsPagedResponse(input),
                 MoreExecutors.directExecutor());
           }
       
      diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java
      index b1952fc8e3..29a0c79b67 100644
      --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java
      +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java
      @@ -66,22 +66,22 @@
       
       @Generated("by gapic-generator-java")
       public class KeyManagementServiceClientTest {
      -  private static MockKeyManagementService mockKeyManagementService;
      -  private static MockServiceHelper mockServiceHelper;
      -  private KeyManagementServiceClient client;
         private static MockIAMPolicy mockIAMPolicy;
      +  private static MockKeyManagementService mockKeyManagementService;
         private static MockLocations mockLocations;
      +  private static MockServiceHelper mockServiceHelper;
         private LocalChannelProvider channelProvider;
      +  private KeyManagementServiceClient client;
       
         @BeforeClass
         public static void startStaticServer() {
           mockKeyManagementService = new MockKeyManagementService();
      -    mockIAMPolicy = new MockIAMPolicy();
           mockLocations = new MockLocations();
      +    mockIAMPolicy = new MockIAMPolicy();
           mockServiceHelper =
               new MockServiceHelper(
                   UUID.randomUUID().toString(),
      -            Arrays.asList(mockKeyManagementService, mockIAMPolicy, mockLocations));
      +            Arrays.asList(mockKeyManagementService, mockLocations, mockIAMPolicy));
           mockServiceHelper.start();
         }
       
      @@ -752,14 +752,7 @@ public void getPublicKeyTest() throws Exception {
               PublicKey.newBuilder()
                   .setPem("pem110872")
                   .setPemCrc32C(Int64Value.newBuilder().build())
      -            .setName(
      -                PublicKeyName.of(
      -                        "[PROJECT]",
      -                        "[LOCATION]",
      -                        "[KEY_RING]",
      -                        "[CRYPTO_KEY]",
      -                        "[CRYPTO_KEY_VERSION]")
      -                    .toString())
      +            .setName("name3373707")
                   .build();
           mockKeyManagementService.addResponse(expectedResponse);
       
      @@ -803,14 +796,7 @@ public void getPublicKeyTest2() throws Exception {
               PublicKey.newBuilder()
                   .setPem("pem110872")
                   .setPemCrc32C(Int64Value.newBuilder().build())
      -            .setName(
      -                PublicKeyName.of(
      -                        "[PROJECT]",
      -                        "[LOCATION]",
      -                        "[KEY_RING]",
      -                        "[CRYPTO_KEY]",
      -                        "[CRYPTO_KEY_VERSION]")
      -                    .toString())
      +            .setName("name3373707")
                   .build();
           mockKeyManagementService.addResponse(expectedResponse);
       
      diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java
      index d749c91145..fb53484f12 100644
      --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java
      +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java
      @@ -324,14 +324,13 @@ public KeyManagementServiceStubSettings.Builder getStubSettingsBuilder() {
             return ((KeyManagementServiceStubSettings.Builder) getStubSettings());
           }
       
      -    // NEXT_MAJOR_VER: remove 'throws Exception'.
           /**
            * Applies the given settings updater function to all of the unary API methods in this service.
            *
            * 

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyRingName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyRingName.java index 1deea50c8e..7938c9a34a 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyRingName.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyRingName.java @@ -211,9 +211,9 @@ public Builder setKeyRing(String keyRing) { } private Builder(KeyRingName keyRingName) { - project = keyRingName.project; - location = keyRingName.location; - keyRing = keyRingName.keyRing; + this.project = keyRingName.project; + this.location = keyRingName.location; + this.keyRing = keyRingName.keyRing; } public KeyRingName build() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/LocationName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/LocationName.java index bd6776a8cc..143d06cd6e 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/LocationName.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/LocationName.java @@ -181,8 +181,8 @@ public Builder setLocation(String location) { } private Builder(LocationName locationName) { - project = locationName.project; - location = locationName.location; + this.project = locationName.project; + this.location = locationName.location; } public LocationName build() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/PublicKeyName.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/PublicKeyName.java deleted file mode 100644 index 048fc3f413..0000000000 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/PublicKeyName.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.kms.v1; - -import com.google.api.pathtemplate.PathTemplate; -import com.google.api.resourcenames.ResourceName; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import javax.annotation.Generated; - -// AUTO-GENERATED DOCUMENTATION AND CLASS. -@Generated("by gapic-generator-java") -public class PublicKeyName implements ResourceName { - private static final PathTemplate PROJECT_LOCATION_KEY_RING_CRYPTO_KEY_CRYPTO_KEY_VERSION = - PathTemplate.createWithoutUrlEncoding( - "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}/publicKey"); - private volatile Map fieldValuesMap; - private final String project; - private final String location; - private final String keyRing; - private final String cryptoKey; - private final String cryptoKeyVersion; - - @Deprecated - protected PublicKeyName() { - project = null; - location = null; - keyRing = null; - cryptoKey = null; - cryptoKeyVersion = null; - } - - private PublicKeyName(Builder builder) { - project = Preconditions.checkNotNull(builder.getProject()); - location = Preconditions.checkNotNull(builder.getLocation()); - keyRing = Preconditions.checkNotNull(builder.getKeyRing()); - cryptoKey = Preconditions.checkNotNull(builder.getCryptoKey()); - cryptoKeyVersion = Preconditions.checkNotNull(builder.getCryptoKeyVersion()); - } - - public String getProject() { - return project; - } - - public String getLocation() { - return location; - } - - public String getKeyRing() { - return keyRing; - } - - public String getCryptoKey() { - return cryptoKey; - } - - public String getCryptoKeyVersion() { - return cryptoKeyVersion; - } - - public static Builder newBuilder() { - return new Builder(); - } - - public Builder toBuilder() { - return new Builder(this); - } - - public static PublicKeyName of( - String project, String location, String keyRing, String cryptoKey, String cryptoKeyVersion) { - return newBuilder() - .setProject(project) - .setLocation(location) - .setKeyRing(keyRing) - .setCryptoKey(cryptoKey) - .setCryptoKeyVersion(cryptoKeyVersion) - .build(); - } - - public static String format( - String project, String location, String keyRing, String cryptoKey, String cryptoKeyVersion) { - return newBuilder() - .setProject(project) - .setLocation(location) - .setKeyRing(keyRing) - .setCryptoKey(cryptoKey) - .setCryptoKeyVersion(cryptoKeyVersion) - .build() - .toString(); - } - - public static PublicKeyName parse(String formattedString) { - if (formattedString.isEmpty()) { - return null; - } - Map matchMap = - PROJECT_LOCATION_KEY_RING_CRYPTO_KEY_CRYPTO_KEY_VERSION.validatedMatch( - formattedString, "PublicKeyName.parse: formattedString not in valid format"); - return of( - matchMap.get("project"), - matchMap.get("location"), - matchMap.get("key_ring"), - matchMap.get("crypto_key"), - matchMap.get("crypto_key_version")); - } - - public static List parseList(List formattedStrings) { - List list = new ArrayList<>(formattedStrings.size()); - for (String formattedString : formattedStrings) { - list.add(parse(formattedString)); - } - return list; - } - - public static List toStringList(List values) { - List list = new ArrayList<>(values.size()); - for (PublicKeyName value : values) { - if (value == null) { - list.add(""); - } else { - list.add(value.toString()); - } - } - return list; - } - - public static boolean isParsableFrom(String formattedString) { - return PROJECT_LOCATION_KEY_RING_CRYPTO_KEY_CRYPTO_KEY_VERSION.matches(formattedString); - } - - @Override - public Map getFieldValuesMap() { - if (fieldValuesMap == null) { - synchronized (this) { - if (fieldValuesMap == null) { - ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); - if (project != null) { - fieldMapBuilder.put("project", project); - } - if (location != null) { - fieldMapBuilder.put("location", location); - } - if (keyRing != null) { - fieldMapBuilder.put("key_ring", keyRing); - } - if (cryptoKey != null) { - fieldMapBuilder.put("crypto_key", cryptoKey); - } - if (cryptoKeyVersion != null) { - fieldMapBuilder.put("crypto_key_version", cryptoKeyVersion); - } - fieldValuesMap = fieldMapBuilder.build(); - } - } - } - return fieldValuesMap; - } - - public String getFieldValue(String fieldName) { - return getFieldValuesMap().get(fieldName); - } - - @Override - public String toString() { - return PROJECT_LOCATION_KEY_RING_CRYPTO_KEY_CRYPTO_KEY_VERSION.instantiate( - "project", - project, - "location", - location, - "key_ring", - keyRing, - "crypto_key", - cryptoKey, - "crypto_key_version", - cryptoKeyVersion); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o != null || getClass() == o.getClass()) { - PublicKeyName that = ((PublicKeyName) o); - return Objects.equals(this.project, that.project) - && Objects.equals(this.location, that.location) - && Objects.equals(this.keyRing, that.keyRing) - && Objects.equals(this.cryptoKey, that.cryptoKey) - && Objects.equals(this.cryptoKeyVersion, that.cryptoKeyVersion); - } - return false; - } - - @Override - public int hashCode() { - int h = 1; - h *= 1000003; - h ^= Objects.hashCode(project); - h *= 1000003; - h ^= Objects.hashCode(location); - h *= 1000003; - h ^= Objects.hashCode(keyRing); - h *= 1000003; - h ^= Objects.hashCode(cryptoKey); - h *= 1000003; - h ^= Objects.hashCode(cryptoKeyVersion); - return h; - } - - /** - * Builder for - * projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}/publicKey. - */ - public static class Builder { - private String project; - private String location; - private String keyRing; - private String cryptoKey; - private String cryptoKeyVersion; - - protected Builder() {} - - public String getProject() { - return project; - } - - public String getLocation() { - return location; - } - - public String getKeyRing() { - return keyRing; - } - - public String getCryptoKey() { - return cryptoKey; - } - - public String getCryptoKeyVersion() { - return cryptoKeyVersion; - } - - public Builder setProject(String project) { - this.project = project; - return this; - } - - public Builder setLocation(String location) { - this.location = location; - return this; - } - - public Builder setKeyRing(String keyRing) { - this.keyRing = keyRing; - return this; - } - - public Builder setCryptoKey(String cryptoKey) { - this.cryptoKey = cryptoKey; - return this; - } - - public Builder setCryptoKeyVersion(String cryptoKeyVersion) { - this.cryptoKeyVersion = cryptoKeyVersion; - return this; - } - - private Builder(PublicKeyName publicKeyName) { - project = publicKeyName.project; - location = publicKeyName.location; - keyRing = publicKeyName.keyRing; - cryptoKey = publicKeyName.cryptoKey; - cryptoKeyVersion = publicKeyName.cryptoKeyVersion; - } - - public PublicKeyName build() { - return new PublicKeyName(this); - } - } -} diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java index 19065361ed..b1566ca46c 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java @@ -27,7 +27,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.kms.v1.AsymmetricDecryptRequest; import com.google.cloud.kms.v1.AsymmetricDecryptResponse; @@ -451,13 +450,10 @@ protected GrpcKeyManagementServiceStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(listKeyRingsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListKeyRingsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -465,13 +461,10 @@ public Map extract(ListKeyRingsRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(listCryptoKeysMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListCryptoKeysRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -480,13 +473,10 @@ public Map extract(ListCryptoKeysRequest request) { .newBuilder() .setMethodDescriptor(listCryptoKeyVersionsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListCryptoKeyVersionsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -494,39 +484,30 @@ public Map extract(ListCryptoKeyVersionsRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(listImportJobsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListImportJobsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getKeyRingTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getKeyRingMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetKeyRingRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getCryptoKeyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getCryptoKeyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetCryptoKeyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -534,65 +515,50 @@ public Map extract(GetCryptoKeyRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(getCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getPublicKeyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getPublicKeyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetPublicKeyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getImportJobTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getImportJobMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetImportJobRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createKeyRingTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createKeyRingMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateKeyRingRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings createCryptoKeyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createCryptoKeyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateCryptoKeyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -600,13 +566,10 @@ public Map extract(CreateCryptoKeyRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(createCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -614,39 +577,30 @@ public Map extract(CreateCryptoKeyVersionRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(importCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ImportCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings createImportJobTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createImportJobMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateImportJobRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateCryptoKeyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateCryptoKeyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateCryptoKeyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("crypto_key.name", String.valueOf(request.getCryptoKey().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("crypto_key.name", String.valueOf(request.getCryptoKey().getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -654,41 +608,32 @@ public Map extract(UpdateCryptoKeyRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(updateCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put( - "crypto_key_version.name", - String.valueOf(request.getCryptoKeyVersion().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put( + "crypto_key_version.name", + String.valueOf(request.getCryptoKeyVersion().getName())); + return params.build(); }) .build(); GrpcCallSettings encryptTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(encryptMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(EncryptRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings decryptTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(decryptMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DecryptRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -696,13 +641,10 @@ public Map extract(DecryptRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(asymmetricSignMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(AsymmetricSignRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -710,13 +652,10 @@ public Map extract(AsymmetricSignRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(asymmetricDecryptMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(AsymmetricDecryptRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -724,14 +663,10 @@ public Map extract(AsymmetricDecryptRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(updateCryptoKeyPrimaryVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract( - UpdateCryptoKeyPrimaryVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -739,13 +674,10 @@ public Map extract( GrpcCallSettings.newBuilder() .setMethodDescriptor(destroyCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DestroyCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -753,53 +685,41 @@ public Map extract(DestroyCryptoKeyVersionRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(restoreCryptoKeyVersionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(RestoreCryptoKeyVersionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getIamPolicyTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getIamPolicyMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetIamPolicyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); }) .build(); GrpcCallSettings listLocationsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listLocationsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListLocationsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("filter", String.valueOf(request.getFilter())); - params.put("page_size", String.valueOf(request.getPageSize())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("filter", String.valueOf(request.getFilter())); + params.put("page_size", String.valueOf(request.getPageSize())); + return params.build(); }) .build(); GrpcCallSettings getLocationTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getLocationMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetLocationRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings @@ -807,13 +727,10 @@ public Map extract(GetLocationRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(testIamPermissionsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(TestIamPermissionsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); }) .build(); @@ -1119,7 +1036,13 @@ public UnaryCallable getLocationCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java index 5ebc43167f..e3faa10060 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java @@ -645,6 +645,11 @@ public static String getDefaultEndpoint() { return "cloudkms.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "cloudkms.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -652,7 +657,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -962,6 +969,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -1105,14 +1114,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java b/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java index 6245f271c9..d1c753da0d 100644 --- a/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java +++ b/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java @@ -59,11 +59,13 @@ public void reset() { } @Override - public void getIamPolicy(GetIamPolicyRequest request, StreamObserver responseObserver) { + public void testIamPermissions( + TestIamPermissionsRequest request, + StreamObserver responseObserver) { Object response = responses.poll(); - if (response instanceof Policy) { + if (response instanceof TestIamPermissionsResponse) { requests.add(request); - responseObserver.onNext(((Policy) response)); + responseObserver.onNext(((TestIamPermissionsResponse) response)); responseObserver.onCompleted(); } else if (response instanceof Exception) { responseObserver.onError(((Exception) response)); @@ -71,21 +73,19 @@ public void getIamPolicy(GetIamPolicyRequest request, StreamObserver res responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method GetIamPolicy, expected %s or %s", + "Unrecognized response type %s for method TestIamPermissions, expected %s or %s", response == null ? "null" : response.getClass().getName(), - Policy.class.getName(), + TestIamPermissionsResponse.class.getName(), Exception.class.getName()))); } } @Override - public void testIamPermissions( - TestIamPermissionsRequest request, - StreamObserver responseObserver) { + public void getIamPolicy(GetIamPolicyRequest request, StreamObserver responseObserver) { Object response = responses.poll(); - if (response instanceof TestIamPermissionsResponse) { + if (response instanceof Policy) { requests.add(request); - responseObserver.onNext(((TestIamPermissionsResponse) response)); + responseObserver.onNext(((Policy) response)); responseObserver.onCompleted(); } else if (response instanceof Exception) { responseObserver.onError(((Exception) response)); @@ -93,9 +93,9 @@ public void testIamPermissions( responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method TestIamPermissions, expected %s or %s", + "Unrecognized response type %s for method GetIamPolicy, expected %s or %s", response == null ? "null" : response.getClass().getName(), - TestIamPermissionsResponse.class.getName(), + Policy.class.getName(), Exception.class.getName()))); } } diff --git a/test/integration/goldens/library/BUILD.bazel b/test/integration/goldens/library/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/library/BUILD.bazel +++ b/test/integration/goldens/library/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClient.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClient.java index a1dad2c9c7..3a758ad3f9 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClient.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClient.java @@ -16,7 +16,6 @@ package com.google.cloud.example.library.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -47,6 +46,7 @@ import com.google.example.library.v1.ShelfName; import com.google.example.library.v1.UpdateBookRequest; import com.google.protobuf.Empty; +import com.google.protobuf.FieldMask; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; @@ -264,7 +264,7 @@ public final Shelf getShelf(ShelfName name) { * *

      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      +   *   String name = ShelfName.of("[SHELF_ID]").toString();
          *   Shelf response = libraryServiceClient.getShelf(name);
          * }
          * }
      @@ -285,7 +285,8 @@ public final Shelf getShelf(String name) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   GetShelfRequest request = GetShelfRequest.newBuilder().setName("name3373707").build();
      +   *   GetShelfRequest request =
      +   *       GetShelfRequest.newBuilder().setName(ShelfName.of("[SHELF_ID]").toString()).build();
          *   Shelf response = libraryServiceClient.getShelf(request);
          * }
          * }
      @@ -305,7 +306,8 @@ public final Shelf getShelf(GetShelfRequest request) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   GetShelfRequest request = GetShelfRequest.newBuilder().setName("name3373707").build();
      +   *   GetShelfRequest request =
      +   *       GetShelfRequest.newBuilder().setName(ShelfName.of("[SHELF_ID]").toString()).build();
          *   ApiFuture future = libraryServiceClient.getShelfCallable().futureCall(request);
          *   // Do something.
          *   Shelf response = future.get();
      @@ -433,7 +435,7 @@ public final void deleteShelf(ShelfName name) {
          *
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      +   *   String name = ShelfName.of("[SHELF_ID]").toString();
          *   libraryServiceClient.deleteShelf(name);
          * }
          * }
      @@ -454,7 +456,8 @@ public final void deleteShelf(String name) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   DeleteShelfRequest request = DeleteShelfRequest.newBuilder().setName("name3373707").build();
      +   *   DeleteShelfRequest request =
      +   *       DeleteShelfRequest.newBuilder().setName(ShelfName.of("[SHELF_ID]").toString()).build();
          *   libraryServiceClient.deleteShelf(request);
          * }
          * }
      @@ -474,7 +477,8 @@ public final void deleteShelf(DeleteShelfRequest request) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   DeleteShelfRequest request = DeleteShelfRequest.newBuilder().setName("name3373707").build();
      +   *   DeleteShelfRequest request =
      +   *       DeleteShelfRequest.newBuilder().setName(ShelfName.of("[SHELF_ID]").toString()).build();
          *   ApiFuture future = libraryServiceClient.deleteShelfCallable().futureCall(request);
          *   // Do something.
          *   future.get();
      @@ -499,20 +503,20 @@ public final UnaryCallable deleteShelfCallable() {
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
          *   ShelfName name = ShelfName.of("[SHELF_ID]");
      -   *   ShelfName otherShelfName = ShelfName.of("[SHELF_ID]");
      -   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelfName);
      +   *   ShelfName otherShelf = ShelfName.of("[SHELF_ID]");
      +   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelf);
          * }
          * }
      * * @param name The name of the shelf we're adding books to. - * @param otherShelfName The name of the shelf we're removing books from and deleting. + * @param otherShelf The name of the shelf we're removing books from and deleting. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Shelf mergeShelves(ShelfName name, ShelfName otherShelfName) { + public final Shelf mergeShelves(ShelfName name, ShelfName otherShelf) { MergeShelvesRequest request = MergeShelvesRequest.newBuilder() .setName(name == null ? null : name.toString()) - .setOtherShelfName(otherShelfName == null ? null : otherShelfName.toString()) + .setOtherShelf(otherShelf == null ? null : otherShelf.toString()) .build(); return mergeShelves(request); } @@ -531,20 +535,20 @@ public final Shelf mergeShelves(ShelfName name, ShelfName otherShelfName) { *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
          *   ShelfName name = ShelfName.of("[SHELF_ID]");
      -   *   String otherShelfName = "otherShelfName-1942963547";
      -   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelfName);
      +   *   String otherShelf = ShelfName.of("[SHELF_ID]").toString();
      +   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelf);
          * }
          * }
      * * @param name The name of the shelf we're adding books to. - * @param otherShelfName The name of the shelf we're removing books from and deleting. + * @param otherShelf The name of the shelf we're removing books from and deleting. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Shelf mergeShelves(ShelfName name, String otherShelfName) { + public final Shelf mergeShelves(ShelfName name, String otherShelf) { MergeShelvesRequest request = MergeShelvesRequest.newBuilder() .setName(name == null ? null : name.toString()) - .setOtherShelfName(otherShelfName) + .setOtherShelf(otherShelf) .build(); return mergeShelves(request); } @@ -562,21 +566,21 @@ public final Shelf mergeShelves(ShelfName name, String otherShelfName) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      -   *   ShelfName otherShelfName = ShelfName.of("[SHELF_ID]");
      -   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelfName);
      +   *   String name = ShelfName.of("[SHELF_ID]").toString();
      +   *   ShelfName otherShelf = ShelfName.of("[SHELF_ID]");
      +   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelf);
          * }
          * }
      * * @param name The name of the shelf we're adding books to. - * @param otherShelfName The name of the shelf we're removing books from and deleting. + * @param otherShelf The name of the shelf we're removing books from and deleting. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Shelf mergeShelves(String name, ShelfName otherShelfName) { + public final Shelf mergeShelves(String name, ShelfName otherShelf) { MergeShelvesRequest request = MergeShelvesRequest.newBuilder() .setName(name) - .setOtherShelfName(otherShelfName == null ? null : otherShelfName.toString()) + .setOtherShelf(otherShelf == null ? null : otherShelf.toString()) .build(); return mergeShelves(request); } @@ -594,19 +598,19 @@ public final Shelf mergeShelves(String name, ShelfName otherShelfName) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      -   *   String otherShelfName = "otherShelfName-1942963547";
      -   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelfName);
      +   *   String name = ShelfName.of("[SHELF_ID]").toString();
      +   *   String otherShelf = ShelfName.of("[SHELF_ID]").toString();
      +   *   Shelf response = libraryServiceClient.mergeShelves(name, otherShelf);
          * }
          * }
      * * @param name The name of the shelf we're adding books to. - * @param otherShelfName The name of the shelf we're removing books from and deleting. + * @param otherShelf The name of the shelf we're removing books from and deleting. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Shelf mergeShelves(String name, String otherShelfName) { + public final Shelf mergeShelves(String name, String otherShelf) { MergeShelvesRequest request = - MergeShelvesRequest.newBuilder().setName(name).setOtherShelfName(otherShelfName).build(); + MergeShelvesRequest.newBuilder().setName(name).setOtherShelf(otherShelf).build(); return mergeShelves(request); } @@ -625,8 +629,8 @@ public final Shelf mergeShelves(String name, String otherShelfName) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * MergeShelvesRequest request = * MergeShelvesRequest.newBuilder() - * .setName("name3373707") - * .setOtherShelfName("otherShelfName-1942963547") + * .setName(ShelfName.of("[SHELF_ID]").toString()) + * .setOtherShelf(ShelfName.of("[SHELF_ID]").toString()) * .build(); * Shelf response = libraryServiceClient.mergeShelves(request); * } @@ -654,8 +658,8 @@ public final Shelf mergeShelves(MergeShelvesRequest request) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * MergeShelvesRequest request = * MergeShelvesRequest.newBuilder() - * .setName("name3373707") - * .setOtherShelfName("otherShelfName-1942963547") + * .setName(ShelfName.of("[SHELF_ID]").toString()) + * .setOtherShelf(ShelfName.of("[SHELF_ID]").toString()) * .build(); * ApiFuture future = libraryServiceClient.mergeShelvesCallable().futureCall(request); * // Do something. @@ -675,20 +679,20 @@ public final UnaryCallable mergeShelvesCallable() { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   ShelfName name = ShelfName.of("[SHELF_ID]");
      +   *   ShelfName parent = ShelfName.of("[SHELF_ID]");
          *   Book book = Book.newBuilder().build();
      -   *   Book response = libraryServiceClient.createBook(name, book);
      +   *   Book response = libraryServiceClient.createBook(parent, book);
          * }
          * }
      * - * @param name The name of the shelf in which the book is created. + * @param parent The name of the shelf in which the book is created. * @param book The book to create. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Book createBook(ShelfName name, Book book) { + public final Book createBook(ShelfName parent, Book book) { CreateBookRequest request = CreateBookRequest.newBuilder() - .setName(name == null ? null : name.toString()) + .setParent(parent == null ? null : parent.toString()) .setBook(book) .build(); return createBook(request); @@ -702,18 +706,19 @@ public final Book createBook(ShelfName name, Book book) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      +   *   String parent = ShelfName.of("[SHELF_ID]").toString();
          *   Book book = Book.newBuilder().build();
      -   *   Book response = libraryServiceClient.createBook(name, book);
      +   *   Book response = libraryServiceClient.createBook(parent, book);
          * }
          * }
      * - * @param name The name of the shelf in which the book is created. + * @param parent The name of the shelf in which the book is created. * @param book The book to create. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Book createBook(String name, Book book) { - CreateBookRequest request = CreateBookRequest.newBuilder().setName(name).setBook(book).build(); + public final Book createBook(String parent, Book book) { + CreateBookRequest request = + CreateBookRequest.newBuilder().setParent(parent).setBook(book).build(); return createBook(request); } @@ -727,7 +732,7 @@ public final Book createBook(String name, Book book) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * CreateBookRequest request = * CreateBookRequest.newBuilder() - * .setName("name3373707") + * .setParent(ShelfName.of("[SHELF_ID]").toString()) * .setBook(Book.newBuilder().build()) * .build(); * Book response = libraryServiceClient.createBook(request); @@ -751,7 +756,7 @@ public final Book createBook(CreateBookRequest request) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * CreateBookRequest request = * CreateBookRequest.newBuilder() - * .setName("name3373707") + * .setParent(ShelfName.of("[SHELF_ID]").toString()) * .setBook(Book.newBuilder().build()) * .build(); * ApiFuture future = libraryServiceClient.createBookCallable().futureCall(request); @@ -772,7 +777,7 @@ public final UnaryCallable createBookCallable() { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]");
      +   *   BookName name = BookName.of("[SHELF]", "[BOOK]");
          *   Book response = libraryServiceClient.getBook(name);
          * }
          * }
      @@ -794,7 +799,7 @@ public final Book getBook(BookName name) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      +   *   String name = BookName.of("[SHELF]", "[BOOK]").toString();
          *   Book response = libraryServiceClient.getBook(name);
          * }
          * }
      @@ -815,7 +820,8 @@ public final Book getBook(String name) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   GetBookRequest request = GetBookRequest.newBuilder().setName("name3373707").build();
      +   *   GetBookRequest request =
      +   *       GetBookRequest.newBuilder().setName(BookName.of("[SHELF]", "[BOOK]").toString()).build();
          *   Book response = libraryServiceClient.getBook(request);
          * }
          * }
      @@ -835,7 +841,8 @@ public final Book getBook(GetBookRequest request) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   GetBookRequest request = GetBookRequest.newBuilder().setName("name3373707").build();
      +   *   GetBookRequest request =
      +   *       GetBookRequest.newBuilder().setName(BookName.of("[SHELF]", "[BOOK]").toString()).build();
          *   ApiFuture future = libraryServiceClient.getBookCallable().futureCall(request);
          *   // Do something.
          *   Book response = future.get();
      @@ -856,19 +863,19 @@ public final UnaryCallable getBookCallable() {
          *
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   ShelfName name = ShelfName.of("[SHELF_ID]");
      -   *   for (Book element : libraryServiceClient.listBooks(name).iterateAll()) {
      +   *   ShelfName parent = ShelfName.of("[SHELF_ID]");
      +   *   for (Book element : libraryServiceClient.listBooks(parent).iterateAll()) {
          *     // doThingsWith(element);
          *   }
          * }
          * }
      * - * @param name The name of the shelf whose books we'd like to list. + * @param parent The name of the shelf whose books we'd like to list. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final ListBooksPagedResponse listBooks(ShelfName name) { + public final ListBooksPagedResponse listBooks(ShelfName parent) { ListBooksRequest request = - ListBooksRequest.newBuilder().setName(name == null ? null : name.toString()).build(); + ListBooksRequest.newBuilder().setParent(parent == null ? null : parent.toString()).build(); return listBooks(request); } @@ -882,18 +889,18 @@ public final ListBooksPagedResponse listBooks(ShelfName name) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      -   *   for (Book element : libraryServiceClient.listBooks(name).iterateAll()) {
      +   *   String parent = ShelfName.of("[SHELF_ID]").toString();
      +   *   for (Book element : libraryServiceClient.listBooks(parent).iterateAll()) {
          *     // doThingsWith(element);
          *   }
          * }
          * }
      * - * @param name The name of the shelf whose books we'd like to list. + * @param parent The name of the shelf whose books we'd like to list. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final ListBooksPagedResponse listBooks(String name) { - ListBooksRequest request = ListBooksRequest.newBuilder().setName(name).build(); + public final ListBooksPagedResponse listBooks(String parent) { + ListBooksRequest request = ListBooksRequest.newBuilder().setParent(parent).build(); return listBooks(request); } @@ -909,7 +916,7 @@ public final ListBooksPagedResponse listBooks(String name) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * ListBooksRequest request = * ListBooksRequest.newBuilder() - * .setName("name3373707") + * .setParent(ShelfName.of("[SHELF_ID]").toString()) * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .build(); @@ -938,7 +945,7 @@ public final ListBooksPagedResponse listBooks(ListBooksRequest request) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * ListBooksRequest request = * ListBooksRequest.newBuilder() - * .setName("name3373707") + * .setParent(ShelfName.of("[SHELF_ID]").toString()) * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .build(); @@ -966,7 +973,7 @@ public final UnaryCallable listBooksPa * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * ListBooksRequest request = * ListBooksRequest.newBuilder() - * .setName("name3373707") + * .setParent(ShelfName.of("[SHELF_ID]").toString()) * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .build(); @@ -997,7 +1004,53 @@ public final UnaryCallable listBooksCallabl * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   DeleteBookRequest request = DeleteBookRequest.newBuilder().setName("name3373707").build();
      +   *   BookName name = BookName.of("[SHELF]", "[BOOK]");
      +   *   libraryServiceClient.deleteBook(name);
      +   * }
      +   * }
      + * + * @param name The name of the book to delete. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final void deleteBook(BookName name) { + DeleteBookRequest request = + DeleteBookRequest.newBuilder().setName(name == null ? null : name.toString()).build(); + deleteBook(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes a book. Returns NOT_FOUND if the book does not exist. + * + *

      Sample code: + * + *

      {@code
      +   * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      +   *   String name = BookName.of("[SHELF]", "[BOOK]").toString();
      +   *   libraryServiceClient.deleteBook(name);
      +   * }
      +   * }
      + * + * @param name The name of the book to delete. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final void deleteBook(String name) { + DeleteBookRequest request = DeleteBookRequest.newBuilder().setName(name).build(); + deleteBook(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes a book. Returns NOT_FOUND if the book does not exist. + * + *

      Sample code: + * + *

      {@code
      +   * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      +   *   DeleteBookRequest request =
      +   *       DeleteBookRequest.newBuilder()
      +   *           .setName(BookName.of("[SHELF]", "[BOOK]").toString())
      +   *           .build();
          *   libraryServiceClient.deleteBook(request);
          * }
          * }
      @@ -1017,7 +1070,10 @@ public final void deleteBook(DeleteBookRequest request) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   DeleteBookRequest request = DeleteBookRequest.newBuilder().setName("name3373707").build();
      +   *   DeleteBookRequest request =
      +   *       DeleteBookRequest.newBuilder()
      +   *           .setName(BookName.of("[SHELF]", "[BOOK]").toString())
      +   *           .build();
          *   ApiFuture future = libraryServiceClient.deleteBookCallable().futureCall(request);
          *   // Do something.
          *   future.get();
      @@ -1038,15 +1094,18 @@ public final UnaryCallable deleteBookCallable() {
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
          *   Book book = Book.newBuilder().build();
      -   *   Book response = libraryServiceClient.updateBook(book);
      +   *   FieldMask updateMask = FieldMask.newBuilder().build();
      +   *   Book response = libraryServiceClient.updateBook(book, updateMask);
          * }
          * }
      * - * @param book The book to update with. The name must match or be empty. + * @param book The name of the book to update. + * @param updateMask Required. Mask of fields to update. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Book updateBook(Book book) { - UpdateBookRequest request = UpdateBookRequest.newBuilder().setBook(book).build(); + public final Book updateBook(Book book, FieldMask updateMask) { + UpdateBookRequest request = + UpdateBookRequest.newBuilder().setBook(book).setUpdateMask(updateMask).build(); return updateBook(request); } @@ -1061,8 +1120,8 @@ public final Book updateBook(Book book) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * UpdateBookRequest request = * UpdateBookRequest.newBuilder() - * .setName("name3373707") * .setBook(Book.newBuilder().build()) + * .setUpdateMask(FieldMask.newBuilder().build()) * .build(); * Book response = libraryServiceClient.updateBook(request); * } @@ -1086,8 +1145,8 @@ public final Book updateBook(UpdateBookRequest request) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * UpdateBookRequest request = * UpdateBookRequest.newBuilder() - * .setName("name3373707") * .setBook(Book.newBuilder().build()) + * .setUpdateMask(FieldMask.newBuilder().build()) * .build(); * ApiFuture future = libraryServiceClient.updateBookCallable().futureCall(request); * // Do something. @@ -1108,7 +1167,7 @@ public final UnaryCallable updateBookCallable() { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]");
      +   *   BookName name = BookName.of("[SHELF]", "[BOOK]");
          *   ShelfName otherShelfName = ShelfName.of("[SHELF_ID]");
          *   Book response = libraryServiceClient.moveBook(name, otherShelfName);
          * }
      @@ -1136,8 +1195,8 @@ public final Book moveBook(BookName name, ShelfName otherShelfName) {
          *
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]");
      -   *   String otherShelfName = "otherShelfName-1942963547";
      +   *   BookName name = BookName.of("[SHELF]", "[BOOK]");
      +   *   String otherShelfName = ShelfName.of("[SHELF_ID]").toString();
          *   Book response = libraryServiceClient.moveBook(name, otherShelfName);
          * }
          * }
      @@ -1164,7 +1223,7 @@ public final Book moveBook(BookName name, String otherShelfName) { * *
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      +   *   String name = BookName.of("[SHELF]", "[BOOK]").toString();
          *   ShelfName otherShelfName = ShelfName.of("[SHELF_ID]");
          *   Book response = libraryServiceClient.moveBook(name, otherShelfName);
          * }
      @@ -1192,8 +1251,8 @@ public final Book moveBook(String name, ShelfName otherShelfName) {
          *
          * 
      {@code
          * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) {
      -   *   String name = "name3373707";
      -   *   String otherShelfName = "otherShelfName-1942963547";
      +   *   String name = BookName.of("[SHELF]", "[BOOK]").toString();
      +   *   String otherShelfName = ShelfName.of("[SHELF_ID]").toString();
          *   Book response = libraryServiceClient.moveBook(name, otherShelfName);
          * }
          * }
      @@ -1219,8 +1278,8 @@ public final Book moveBook(String name, String otherShelfName) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * MoveBookRequest request = * MoveBookRequest.newBuilder() - * .setName("name3373707") - * .setOtherShelfName("otherShelfName-1942963547") + * .setName(BookName.of("[SHELF]", "[BOOK]").toString()) + * .setOtherShelfName(ShelfName.of("[SHELF_ID]").toString()) * .build(); * Book response = libraryServiceClient.moveBook(request); * } @@ -1244,8 +1303,8 @@ public final Book moveBook(MoveBookRequest request) { * try (LibraryServiceClient libraryServiceClient = LibraryServiceClient.create()) { * MoveBookRequest request = * MoveBookRequest.newBuilder() - * .setName("name3373707") - * .setOtherShelfName("otherShelfName-1942963547") + * .setName(BookName.of("[SHELF]", "[BOOK]").toString()) + * .setOtherShelfName(ShelfName.of("[SHELF_ID]").toString()) * .build(); * ApiFuture future = libraryServiceClient.moveBookCallable().futureCall(request); * // Do something. @@ -1301,14 +1360,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListShelvesPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListShelvesPagedResponse apply(ListShelvesPage input) { - return new ListShelvesPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListShelvesPagedResponse(input), MoreExecutors.directExecutor()); } private ListShelvesPagedResponse(ListShelvesPage page) { @@ -1377,14 +1429,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListBooksPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListBooksPagedResponse apply(ListBooksPage input) { - return new ListBooksPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListBooksPagedResponse(input), MoreExecutors.directExecutor()); } private ListBooksPagedResponse(ListBooksPage page) { diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClientTest.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClientTest.java index 82edc829d0..5cc5819105 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClientTest.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceClientTest.java @@ -46,6 +46,7 @@ import com.google.example.library.v1.UpdateBookRequest; import com.google.protobuf.AbstractMessage; import com.google.protobuf.Empty; +import com.google.protobuf.FieldMask; import io.grpc.StatusRuntimeException; import java.io.IOException; import java.util.Arrays; @@ -61,10 +62,10 @@ @Generated("by gapic-generator-java") public class LibraryServiceClientTest { - private static MockServiceHelper mockServiceHelper; - private LibraryServiceClient client; private static MockLibraryService mockLibraryService; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private LibraryServiceClient client; @BeforeClass public static void startStaticServer() { @@ -345,9 +346,9 @@ public void mergeShelvesTest() throws Exception { mockLibraryService.addResponse(expectedResponse); ShelfName name = ShelfName.of("[SHELF_ID]"); - ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); + ShelfName otherShelf = ShelfName.of("[SHELF_ID]"); - Shelf actualResponse = client.mergeShelves(name, otherShelfName); + Shelf actualResponse = client.mergeShelves(name, otherShelf); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); @@ -355,7 +356,7 @@ public void mergeShelvesTest() throws Exception { MergeShelvesRequest actualRequest = ((MergeShelvesRequest) actualRequests.get(0)); Assert.assertEquals(name.toString(), actualRequest.getName()); - Assert.assertEquals(otherShelfName.toString(), actualRequest.getOtherShelfName()); + Assert.assertEquals(otherShelf.toString(), actualRequest.getOtherShelf()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -369,8 +370,8 @@ public void mergeShelvesExceptionTest() throws Exception { try { ShelfName name = ShelfName.of("[SHELF_ID]"); - ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); - client.mergeShelves(name, otherShelfName); + ShelfName otherShelf = ShelfName.of("[SHELF_ID]"); + client.mergeShelves(name, otherShelf); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -387,9 +388,9 @@ public void mergeShelvesTest2() throws Exception { mockLibraryService.addResponse(expectedResponse); ShelfName name = ShelfName.of("[SHELF_ID]"); - String otherShelfName = "otherShelfName-1942963547"; + String otherShelf = "otherShelf-193668870"; - Shelf actualResponse = client.mergeShelves(name, otherShelfName); + Shelf actualResponse = client.mergeShelves(name, otherShelf); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); @@ -397,7 +398,7 @@ public void mergeShelvesTest2() throws Exception { MergeShelvesRequest actualRequest = ((MergeShelvesRequest) actualRequests.get(0)); Assert.assertEquals(name.toString(), actualRequest.getName()); - Assert.assertEquals(otherShelfName, actualRequest.getOtherShelfName()); + Assert.assertEquals(otherShelf, actualRequest.getOtherShelf()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -411,8 +412,8 @@ public void mergeShelvesExceptionTest2() throws Exception { try { ShelfName name = ShelfName.of("[SHELF_ID]"); - String otherShelfName = "otherShelfName-1942963547"; - client.mergeShelves(name, otherShelfName); + String otherShelf = "otherShelf-193668870"; + client.mergeShelves(name, otherShelf); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -429,9 +430,9 @@ public void mergeShelvesTest3() throws Exception { mockLibraryService.addResponse(expectedResponse); String name = "name3373707"; - ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); + ShelfName otherShelf = ShelfName.of("[SHELF_ID]"); - Shelf actualResponse = client.mergeShelves(name, otherShelfName); + Shelf actualResponse = client.mergeShelves(name, otherShelf); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); @@ -439,7 +440,7 @@ public void mergeShelvesTest3() throws Exception { MergeShelvesRequest actualRequest = ((MergeShelvesRequest) actualRequests.get(0)); Assert.assertEquals(name, actualRequest.getName()); - Assert.assertEquals(otherShelfName.toString(), actualRequest.getOtherShelfName()); + Assert.assertEquals(otherShelf.toString(), actualRequest.getOtherShelf()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -453,8 +454,8 @@ public void mergeShelvesExceptionTest3() throws Exception { try { String name = "name3373707"; - ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); - client.mergeShelves(name, otherShelfName); + ShelfName otherShelf = ShelfName.of("[SHELF_ID]"); + client.mergeShelves(name, otherShelf); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -471,9 +472,9 @@ public void mergeShelvesTest4() throws Exception { mockLibraryService.addResponse(expectedResponse); String name = "name3373707"; - String otherShelfName = "otherShelfName-1942963547"; + String otherShelf = "otherShelf-193668870"; - Shelf actualResponse = client.mergeShelves(name, otherShelfName); + Shelf actualResponse = client.mergeShelves(name, otherShelf); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); @@ -481,7 +482,7 @@ public void mergeShelvesTest4() throws Exception { MergeShelvesRequest actualRequest = ((MergeShelvesRequest) actualRequests.get(0)); Assert.assertEquals(name, actualRequest.getName()); - Assert.assertEquals(otherShelfName, actualRequest.getOtherShelfName()); + Assert.assertEquals(otherShelf, actualRequest.getOtherShelf()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -495,8 +496,8 @@ public void mergeShelvesExceptionTest4() throws Exception { try { String name = "name3373707"; - String otherShelfName = "otherShelfName-1942963547"; - client.mergeShelves(name, otherShelfName); + String otherShelf = "otherShelf-193668870"; + client.mergeShelves(name, otherShelf); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -507,24 +508,24 @@ public void mergeShelvesExceptionTest4() throws Exception { public void createBookTest() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) .build(); mockLibraryService.addResponse(expectedResponse); - ShelfName name = ShelfName.of("[SHELF_ID]"); + ShelfName parent = ShelfName.of("[SHELF_ID]"); Book book = Book.newBuilder().build(); - Book actualResponse = client.createBook(name, book); + Book actualResponse = client.createBook(parent, book); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); Assert.assertEquals(1, actualRequests.size()); CreateBookRequest actualRequest = ((CreateBookRequest) actualRequests.get(0)); - Assert.assertEquals(name.toString(), actualRequest.getName()); + Assert.assertEquals(parent.toString(), actualRequest.getParent()); Assert.assertEquals(book, actualRequest.getBook()); Assert.assertTrue( channelProvider.isHeaderSent( @@ -538,9 +539,9 @@ public void createBookExceptionTest() throws Exception { mockLibraryService.addException(exception); try { - ShelfName name = ShelfName.of("[SHELF_ID]"); + ShelfName parent = ShelfName.of("[SHELF_ID]"); Book book = Book.newBuilder().build(); - client.createBook(name, book); + client.createBook(parent, book); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -551,24 +552,24 @@ public void createBookExceptionTest() throws Exception { public void createBookTest2() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) .build(); mockLibraryService.addResponse(expectedResponse); - String name = "name3373707"; + String parent = "parent-995424086"; Book book = Book.newBuilder().build(); - Book actualResponse = client.createBook(name, book); + Book actualResponse = client.createBook(parent, book); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); Assert.assertEquals(1, actualRequests.size()); CreateBookRequest actualRequest = ((CreateBookRequest) actualRequests.get(0)); - Assert.assertEquals(name, actualRequest.getName()); + Assert.assertEquals(parent, actualRequest.getParent()); Assert.assertEquals(book, actualRequest.getBook()); Assert.assertTrue( channelProvider.isHeaderSent( @@ -582,9 +583,9 @@ public void createBookExceptionTest2() throws Exception { mockLibraryService.addException(exception); try { - String name = "name3373707"; + String parent = "parent-995424086"; Book book = Book.newBuilder().build(); - client.createBook(name, book); + client.createBook(parent, book); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -595,14 +596,14 @@ public void createBookExceptionTest2() throws Exception { public void getBookTest() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) .build(); mockLibraryService.addResponse(expectedResponse); - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); Book actualResponse = client.getBook(name); Assert.assertEquals(expectedResponse, actualResponse); @@ -624,7 +625,7 @@ public void getBookExceptionTest() throws Exception { mockLibraryService.addException(exception); try { - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); client.getBook(name); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { @@ -636,7 +637,7 @@ public void getBookExceptionTest() throws Exception { public void getBookTest2() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) @@ -683,9 +684,9 @@ public void listBooksTest() throws Exception { .build(); mockLibraryService.addResponse(expectedResponse); - ShelfName name = ShelfName.of("[SHELF_ID]"); + ShelfName parent = ShelfName.of("[SHELF_ID]"); - ListBooksPagedResponse pagedListResponse = client.listBooks(name); + ListBooksPagedResponse pagedListResponse = client.listBooks(parent); List resources = Lists.newArrayList(pagedListResponse.iterateAll()); @@ -696,7 +697,7 @@ public void listBooksTest() throws Exception { Assert.assertEquals(1, actualRequests.size()); ListBooksRequest actualRequest = ((ListBooksRequest) actualRequests.get(0)); - Assert.assertEquals(name.toString(), actualRequest.getName()); + Assert.assertEquals(parent.toString(), actualRequest.getParent()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -709,8 +710,8 @@ public void listBooksExceptionTest() throws Exception { mockLibraryService.addException(exception); try { - ShelfName name = ShelfName.of("[SHELF_ID]"); - client.listBooks(name); + ShelfName parent = ShelfName.of("[SHELF_ID]"); + client.listBooks(parent); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -727,9 +728,9 @@ public void listBooksTest2() throws Exception { .build(); mockLibraryService.addResponse(expectedResponse); - String name = "name3373707"; + String parent = "parent-995424086"; - ListBooksPagedResponse pagedListResponse = client.listBooks(name); + ListBooksPagedResponse pagedListResponse = client.listBooks(parent); List resources = Lists.newArrayList(pagedListResponse.iterateAll()); @@ -740,7 +741,7 @@ public void listBooksTest2() throws Exception { Assert.assertEquals(1, actualRequests.size()); ListBooksRequest actualRequest = ((ListBooksRequest) actualRequests.get(0)); - Assert.assertEquals(name, actualRequest.getName()); + Assert.assertEquals(parent, actualRequest.getParent()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -753,8 +754,8 @@ public void listBooksExceptionTest2() throws Exception { mockLibraryService.addException(exception); try { - String name = "name3373707"; - client.listBooks(name); + String parent = "parent-995424086"; + client.listBooks(parent); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -766,15 +767,15 @@ public void deleteBookTest() throws Exception { Empty expectedResponse = Empty.newBuilder().build(); mockLibraryService.addResponse(expectedResponse); - DeleteBookRequest request = DeleteBookRequest.newBuilder().setName("name3373707").build(); + BookName name = BookName.of("[SHELF]", "[BOOK]"); - client.deleteBook(request); + client.deleteBook(name); List actualRequests = mockLibraryService.getRequests(); Assert.assertEquals(1, actualRequests.size()); DeleteBookRequest actualRequest = ((DeleteBookRequest) actualRequests.get(0)); - Assert.assertEquals(request.getName(), actualRequest.getName()); + Assert.assertEquals(name.toString(), actualRequest.getName()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -787,8 +788,42 @@ public void deleteBookExceptionTest() throws Exception { mockLibraryService.addException(exception); try { - DeleteBookRequest request = DeleteBookRequest.newBuilder().setName("name3373707").build(); - client.deleteBook(request); + BookName name = BookName.of("[SHELF]", "[BOOK]"); + client.deleteBook(name); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void deleteBookTest2() throws Exception { + Empty expectedResponse = Empty.newBuilder().build(); + mockLibraryService.addResponse(expectedResponse); + + String name = "name3373707"; + + client.deleteBook(name); + + List actualRequests = mockLibraryService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + DeleteBookRequest actualRequest = ((DeleteBookRequest) actualRequests.get(0)); + + Assert.assertEquals(name, actualRequest.getName()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void deleteBookExceptionTest2() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockLibraryService.addException(exception); + + try { + String name = "name3373707"; + client.deleteBook(name); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -799,7 +834,7 @@ public void deleteBookExceptionTest() throws Exception { public void updateBookTest() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) @@ -807,8 +842,9 @@ public void updateBookTest() throws Exception { mockLibraryService.addResponse(expectedResponse); Book book = Book.newBuilder().build(); + FieldMask updateMask = FieldMask.newBuilder().build(); - Book actualResponse = client.updateBook(book); + Book actualResponse = client.updateBook(book, updateMask); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockLibraryService.getRequests(); @@ -816,6 +852,7 @@ public void updateBookTest() throws Exception { UpdateBookRequest actualRequest = ((UpdateBookRequest) actualRequests.get(0)); Assert.assertEquals(book, actualRequest.getBook()); + Assert.assertEquals(updateMask, actualRequest.getUpdateMask()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -829,7 +866,8 @@ public void updateBookExceptionTest() throws Exception { try { Book book = Book.newBuilder().build(); - client.updateBook(book); + FieldMask updateMask = FieldMask.newBuilder().build(); + client.updateBook(book, updateMask); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { // Expected exception. @@ -840,14 +878,14 @@ public void updateBookExceptionTest() throws Exception { public void moveBookTest() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) .build(); mockLibraryService.addResponse(expectedResponse); - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); Book actualResponse = client.moveBook(name, otherShelfName); @@ -871,7 +909,7 @@ public void moveBookExceptionTest() throws Exception { mockLibraryService.addException(exception); try { - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); ShelfName otherShelfName = ShelfName.of("[SHELF_ID]"); client.moveBook(name, otherShelfName); Assert.fail("No exception raised"); @@ -884,14 +922,14 @@ public void moveBookExceptionTest() throws Exception { public void moveBookTest2() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) .build(); mockLibraryService.addResponse(expectedResponse); - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); String otherShelfName = "otherShelfName-1942963547"; Book actualResponse = client.moveBook(name, otherShelfName); @@ -915,7 +953,7 @@ public void moveBookExceptionTest2() throws Exception { mockLibraryService.addException(exception); try { - BookName name = BookName.of("[SHELF_ID]", "[BOOK_ID]"); + BookName name = BookName.of("[SHELF]", "[BOOK]"); String otherShelfName = "otherShelfName-1942963547"; client.moveBook(name, otherShelfName); Assert.fail("No exception raised"); @@ -928,7 +966,7 @@ public void moveBookExceptionTest2() throws Exception { public void moveBookTest3() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) @@ -972,7 +1010,7 @@ public void moveBookExceptionTest3() throws Exception { public void moveBookTest4() throws Exception { Book expectedResponse = Book.newBuilder() - .setName(BookName.of("[SHELF_ID]", "[BOOK_ID]").toString()) + .setName(BookName.of("[SHELF]", "[BOOK]").toString()) .setAuthor("author-1406328437") .setTitle("title110371416") .setRead(true) diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceSettings.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceSettings.java index 81c0fb537b..b4d1a7f314 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceSettings.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/LibraryServiceSettings.java @@ -230,14 +230,13 @@ public LibraryServiceStubSettings.Builder getStubSettingsBuilder() { return ((LibraryServiceStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/gapic_metadata.json b/test/integration/goldens/library/com/google/cloud/example/library/v1/gapic_metadata.json index 412c5f19c7..b2812fef26 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/gapic_metadata.json +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/gapic_metadata.json @@ -17,7 +17,7 @@ "methods": ["createShelf", "createShelf", "createShelfCallable"] }, "DeleteBook": { - "methods": ["deleteBook", "deleteBookCallable"] + "methods": ["deleteBook", "deleteBook", "deleteBook", "deleteBookCallable"] }, "DeleteShelf": { "methods": ["deleteShelf", "deleteShelf", "deleteShelf", "deleteShelfCallable"] diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/GrpcLibraryServiceStub.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/GrpcLibraryServiceStub.java index 3e09a011a6..d1ff40a058 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/GrpcLibraryServiceStub.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/GrpcLibraryServiceStub.java @@ -24,7 +24,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.example.library.v1.Book; @@ -217,13 +216,10 @@ protected GrpcLibraryServiceStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(getShelfMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetShelfRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listShelvesTransportSettings = @@ -234,104 +230,80 @@ public Map extract(GetShelfRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteShelfMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteShelfRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings mergeShelvesTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(mergeShelvesMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(MergeShelvesRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createBookTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createBookMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateBookRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getBookTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getBookMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetBookRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listBooksTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listBooksMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListBooksRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings deleteBookTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteBookMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteBookRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings updateBookTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateBookMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateBookRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("book.name", String.valueOf(request.getBook().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("book.name", String.valueOf(request.getBook().getName())); + return params.build(); }) .build(); GrpcCallSettings moveBookTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(moveBookMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(MoveBookRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); @@ -450,7 +422,13 @@ public UnaryCallable moveBookCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java index 0f7a252975..159cd561a6 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java @@ -64,6 +64,7 @@ import java.io.IOException; import java.util.List; import javax.annotation.Generated; +import org.threeten.bp.Duration; // AUTO-GENERATED DOCUMENTATION AND CLASS. /** @@ -303,6 +304,11 @@ public static String getDefaultEndpoint() { return "library-example.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "library-example.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -310,7 +316,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -387,7 +395,13 @@ public static class Builder extends StubSettings.Builder> definitions = ImmutableMap.builder(); - definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); + definitions.put( + "retry_policy_1_codes", ImmutableSet.copyOf(Lists.newArrayList())); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf( + Lists.newArrayList( + StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -396,8 +410,28 @@ public static class Builder extends StubSettings.Builder definitions = ImmutableMap.builder(); RetrySettings settings = null; - settings = RetrySettings.newBuilder().setRpcTimeoutMultiplier(1.0).build(); - definitions.put("no_retry_params", settings); + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(100L)) + .setRetryDelayMultiplier(1.3) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("retry_policy_1_params", settings); + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(100L)) + .setRetryDelayMultiplier(1.3) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("retry_policy_0_params", settings); RETRY_PARAM_DEFINITIONS = definitions.build(); } @@ -473,6 +507,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -480,70 +516,69 @@ private static Builder createDefault() { private static Builder initDefaults(Builder builder) { builder .createShelfSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); builder .getShelfSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .listShelvesSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .deleteShelfSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .mergeShelvesSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); builder .createBookSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); builder .getBookSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .listBooksSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .deleteBookSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .updateBookSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); builder .moveBookSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/library/com/google/example/library/v1/BookName.java b/test/integration/goldens/library/com/google/example/library/v1/BookName.java index a79c744949..1352d23cc9 100644 --- a/test/integration/goldens/library/com/google/example/library/v1/BookName.java +++ b/test/integration/goldens/library/com/google/example/library/v1/BookName.java @@ -29,29 +29,29 @@ // AUTO-GENERATED DOCUMENTATION AND CLASS. @Generated("by gapic-generator-java") public class BookName implements ResourceName { - private static final PathTemplate SHELF_ID_BOOK_ID = - PathTemplate.createWithoutUrlEncoding("shelves/{shelf_id}/books/{book_id}"); + private static final PathTemplate SHELF_BOOK = + PathTemplate.createWithoutUrlEncoding("shelves/{shelf}/books/{book}"); private volatile Map fieldValuesMap; - private final String shelfId; - private final String bookId; + private final String shelf; + private final String book; @Deprecated protected BookName() { - shelfId = null; - bookId = null; + shelf = null; + book = null; } private BookName(Builder builder) { - shelfId = Preconditions.checkNotNull(builder.getShelfId()); - bookId = Preconditions.checkNotNull(builder.getBookId()); + shelf = Preconditions.checkNotNull(builder.getShelf()); + book = Preconditions.checkNotNull(builder.getBook()); } - public String getShelfId() { - return shelfId; + public String getShelf() { + return shelf; } - public String getBookId() { - return bookId; + public String getBook() { + return book; } public static Builder newBuilder() { @@ -62,12 +62,12 @@ public Builder toBuilder() { return new Builder(this); } - public static BookName of(String shelfId, String bookId) { - return newBuilder().setShelfId(shelfId).setBookId(bookId).build(); + public static BookName of(String shelf, String book) { + return newBuilder().setShelf(shelf).setBook(book).build(); } - public static String format(String shelfId, String bookId) { - return newBuilder().setShelfId(shelfId).setBookId(bookId).build().toString(); + public static String format(String shelf, String book) { + return newBuilder().setShelf(shelf).setBook(book).build().toString(); } public static BookName parse(String formattedString) { @@ -75,9 +75,9 @@ public static BookName parse(String formattedString) { return null; } Map matchMap = - SHELF_ID_BOOK_ID.validatedMatch( + SHELF_BOOK.validatedMatch( formattedString, "BookName.parse: formattedString not in valid format"); - return of(matchMap.get("shelf_id"), matchMap.get("book_id")); + return of(matchMap.get("shelf"), matchMap.get("book")); } public static List parseList(List formattedStrings) { @@ -101,7 +101,7 @@ public static List toStringList(List values) { } public static boolean isParsableFrom(String formattedString) { - return SHELF_ID_BOOK_ID.matches(formattedString); + return SHELF_BOOK.matches(formattedString); } @Override @@ -110,11 +110,11 @@ public Map getFieldValuesMap() { synchronized (this) { if (fieldValuesMap == null) { ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); - if (shelfId != null) { - fieldMapBuilder.put("shelf_id", shelfId); + if (shelf != null) { + fieldMapBuilder.put("shelf", shelf); } - if (bookId != null) { - fieldMapBuilder.put("book_id", bookId); + if (book != null) { + fieldMapBuilder.put("book", book); } fieldValuesMap = fieldMapBuilder.build(); } @@ -129,7 +129,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return SHELF_ID_BOOK_ID.instantiate("shelf_id", shelfId, "book_id", bookId); + return SHELF_BOOK.instantiate("shelf", shelf, "book", book); } @Override @@ -139,7 +139,7 @@ public boolean equals(Object o) { } if (o != null || getClass() == o.getClass()) { BookName that = ((BookName) o); - return Objects.equals(this.shelfId, that.shelfId) && Objects.equals(this.bookId, that.bookId); + return Objects.equals(this.shelf, that.shelf) && Objects.equals(this.book, that.book); } return false; } @@ -148,40 +148,40 @@ public boolean equals(Object o) { public int hashCode() { int h = 1; h *= 1000003; - h ^= Objects.hashCode(shelfId); + h ^= Objects.hashCode(shelf); h *= 1000003; - h ^= Objects.hashCode(bookId); + h ^= Objects.hashCode(book); return h; } - /** Builder for shelves/{shelf_id}/books/{book_id}. */ + /** Builder for shelves/{shelf}/books/{book}. */ public static class Builder { - private String shelfId; - private String bookId; + private String shelf; + private String book; protected Builder() {} - public String getShelfId() { - return shelfId; + public String getShelf() { + return shelf; } - public String getBookId() { - return bookId; + public String getBook() { + return book; } - public Builder setShelfId(String shelfId) { - this.shelfId = shelfId; + public Builder setShelf(String shelf) { + this.shelf = shelf; return this; } - public Builder setBookId(String bookId) { - this.bookId = bookId; + public Builder setBook(String book) { + this.book = book; return this; } private Builder(BookName bookName) { - shelfId = bookName.shelfId; - bookId = bookName.bookId; + this.shelf = bookName.shelf; + this.book = bookName.book; } public BookName build() { diff --git a/test/integration/goldens/library/com/google/example/library/v1/ShelfName.java b/test/integration/goldens/library/com/google/example/library/v1/ShelfName.java index 594e83f032..f4d226c9e0 100644 --- a/test/integration/goldens/library/com/google/example/library/v1/ShelfName.java +++ b/test/integration/goldens/library/com/google/example/library/v1/ShelfName.java @@ -158,7 +158,7 @@ public Builder setShelfId(String shelfId) { } private Builder(ShelfName shelfName) { - shelfId = shelfName.shelfId; + this.shelfId = shelfName.shelfId; } public ShelfName build() { diff --git a/test/integration/goldens/logging/BUILD.bazel b/test/integration/goldens/logging/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/logging/BUILD.bazel +++ b/test/integration/goldens/logging/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClient.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClient.java index 2ac4343fd8..2bce0705f4 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClient.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClient.java @@ -16,7 +16,6 @@ package com.google.cloud.logging.v2; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -2855,14 +2854,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListBucketsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListBucketsPagedResponse apply(ListBucketsPage input) { - return new ListBucketsPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListBucketsPagedResponse(input), MoreExecutors.directExecutor()); } private ListBucketsPagedResponse(ListBucketsPage page) { @@ -2935,14 +2927,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListViewsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListViewsPagedResponse apply(ListViewsPage input) { - return new ListViewsPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListViewsPagedResponse(input), MoreExecutors.directExecutor()); } private ListViewsPagedResponse(ListViewsPage page) { @@ -3015,14 +3000,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListSinksPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListSinksPagedResponse apply(ListSinksPage input) { - return new ListSinksPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListSinksPagedResponse(input), MoreExecutors.directExecutor()); } private ListSinksPagedResponse(ListSinksPage page) { @@ -3096,12 +3074,7 @@ public static ApiFuture createAsync( ListExclusionsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListExclusionsPagedResponse apply(ListExclusionsPage input) { - return new ListExclusionsPagedResponse(input); - } - }, + input -> new ListExclusionsPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClientTest.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClientTest.java index 442b83c86b..f38bbc6eb5 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClientTest.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigClientTest.java @@ -95,10 +95,10 @@ @Generated("by gapic-generator-java") public class ConfigClientTest { + private static MockConfigServiceV2 mockConfigServiceV2; private static MockServiceHelper mockServiceHelper; - private ConfigClient client; private LocalChannelProvider channelProvider; - private static MockConfigServiceV2 mockConfigServiceV2; + private ConfigClient client; @BeforeClass public static void startStaticServer() { @@ -1107,7 +1107,7 @@ public void getSinkTest() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1154,7 +1154,7 @@ public void getSinkTest2() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1201,7 +1201,7 @@ public void createSinkTest() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1251,7 +1251,7 @@ public void createSinkTest2() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1301,7 +1301,7 @@ public void createSinkTest3() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1351,7 +1351,7 @@ public void createSinkTest4() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1401,7 +1401,7 @@ public void createSinkTest5() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1451,7 +1451,7 @@ public void updateSinkTest() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1501,7 +1501,7 @@ public void updateSinkTest2() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1551,7 +1551,7 @@ public void updateSinkTest3() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) @@ -1604,7 +1604,7 @@ public void updateSinkTest4() throws Exception { LogSink expectedResponse = LogSink.newBuilder() .setName(LogSinkName.ofProjectSinkName("[PROJECT]", "[SINK]").toString()) - .setDestination(FolderLocationName.of("[FOLDER]", "[LOCATION]").toString()) + .setDestination("destination-1429847026") .setFilter("filter-1274492040") .setDescription("description-1724546052") .setDisabled(true) diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigSettings.java index 8cf51ceae7..1c57850ec1 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/ConfigSettings.java @@ -309,14 +309,13 @@ public ConfigServiceV2StubSettings.Builder getStubSettingsBuilder() { return ((ConfigServiceV2StubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClient.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClient.java index 66f7afcda2..759c5d2c86 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClient.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClient.java @@ -18,7 +18,6 @@ import com.google.api.MonitoredResource; import com.google.api.MonitoredResourceDescriptor; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -1032,12 +1031,7 @@ public static ApiFuture createAsync( ListLogEntriesPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListLogEntriesPagedResponse apply(ListLogEntriesPage input) { - return new ListLogEntriesPagedResponse(input); - } - }, + input -> new ListLogEntriesPagedResponse(input), MoreExecutors.directExecutor()); } @@ -1118,15 +1112,7 @@ public static ApiFuture createAsy .createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction< - ListMonitoredResourceDescriptorsPage, - ListMonitoredResourceDescriptorsPagedResponse>() { - @Override - public ListMonitoredResourceDescriptorsPagedResponse apply( - ListMonitoredResourceDescriptorsPage input) { - return new ListMonitoredResourceDescriptorsPagedResponse(input); - } - }, + input -> new ListMonitoredResourceDescriptorsPagedResponse(input), MoreExecutors.directExecutor()); } @@ -1214,14 +1200,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListLogsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListLogsPagedResponse apply(ListLogsPage input) { - return new ListLogsPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListLogsPagedResponse(input), MoreExecutors.directExecutor()); } private ListLogsPagedResponse(ListLogsPage page) { diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClientTest.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClientTest.java index a6395714c6..34c69dc87b 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClientTest.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingClientTest.java @@ -73,10 +73,10 @@ @Generated("by gapic-generator-java") public class LoggingClientTest { - private static MockServiceHelper mockServiceHelper; private static MockLoggingServiceV2 mockLoggingServiceV2; - private LoggingClient client; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private LoggingClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingSettings.java index c27146d88f..f7bba757b0 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/LoggingSettings.java @@ -209,14 +209,13 @@ public LoggingServiceV2StubSettings.Builder getStubSettingsBuilder() { return ((LoggingServiceV2StubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClient.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClient.java index 987083a264..e1fdf43653 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClient.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClient.java @@ -16,7 +16,6 @@ package com.google.cloud.logging.v2; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -734,12 +733,7 @@ public static ApiFuture createAsync( ListLogMetricsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListLogMetricsPagedResponse apply(ListLogMetricsPage input) { - return new ListLogMetricsPagedResponse(input); - } - }, + input -> new ListLogMetricsPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClientTest.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClientTest.java index e26c9980fb..a81e0368a8 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClientTest.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsClientTest.java @@ -56,10 +56,10 @@ @Generated("by gapic-generator-java") public class MetricsClientTest { - private static MockServiceHelper mockServiceHelper; - private MetricsClient client; private static MockMetricsServiceV2 mockMetricsServiceV2; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private MetricsClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsSettings.java index 4a4800e90a..1b7765bda7 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/MetricsSettings.java @@ -188,14 +188,13 @@ public MetricsServiceV2StubSettings.Builder getStubSettingsBuilder() { return ((MetricsServiceV2StubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java index bfeba9f0a4..faf8137eea 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java @@ -514,6 +514,11 @@ public static String getDefaultEndpoint() { return "logging.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "logging.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -521,7 +526,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -792,6 +799,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -915,14 +924,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcConfigServiceV2Stub.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcConfigServiceV2Stub.java index 91ddb14f6a..34a747bca2 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcConfigServiceV2Stub.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcConfigServiceV2Stub.java @@ -26,7 +26,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.logging.v2.CmekSettings; @@ -362,208 +361,160 @@ protected GrpcConfigServiceV2Stub( GrpcCallSettings.newBuilder() .setMethodDescriptor(listBucketsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListBucketsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getBucketTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getBucketMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetBucketRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createBucketTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createBucketMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateBucketRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateBucketTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateBucketMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateBucketRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings deleteBucketTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteBucketMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteBucketRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings undeleteBucketTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(undeleteBucketMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UndeleteBucketRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listViewsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listViewsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListViewsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getViewTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getViewMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetViewRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createViewTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createViewMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateViewRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateViewTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateViewMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateViewRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings deleteViewTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteViewMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteViewRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings listSinksTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(listSinksMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListSinksRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getSinkTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getSinkMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetSinkRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("sink_name", String.valueOf(request.getSinkName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("sink_name", String.valueOf(request.getSinkName())); + return params.build(); }) .build(); GrpcCallSettings createSinkTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createSinkMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateSinkRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateSinkTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateSinkMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateSinkRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("sink_name", String.valueOf(request.getSinkName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("sink_name", String.valueOf(request.getSinkName())); + return params.build(); }) .build(); GrpcCallSettings deleteSinkTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteSinkMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteSinkRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("sink_name", String.valueOf(request.getSinkName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("sink_name", String.valueOf(request.getSinkName())); + return params.build(); }) .build(); GrpcCallSettings @@ -571,91 +522,70 @@ public Map extract(DeleteSinkRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(listExclusionsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListExclusionsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getExclusionTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getExclusionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetExclusionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createExclusionTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createExclusionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateExclusionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateExclusionTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateExclusionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateExclusionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings deleteExclusionTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteExclusionMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteExclusionRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings getCmekSettingsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getCmekSettingsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetCmekSettingsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings updateCmekSettingsTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateCmekSettingsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateCmekSettingsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); @@ -889,7 +819,13 @@ public UnaryCallable updateCmekSettings @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcLoggingServiceV2Stub.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcLoggingServiceV2Stub.java index feb0ed3086..c7ce0b40f2 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcLoggingServiceV2Stub.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcLoggingServiceV2Stub.java @@ -26,7 +26,6 @@ import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.logging.v2.DeleteLogRequest; @@ -189,13 +188,10 @@ protected GrpcLoggingServiceV2Stub( GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteLogMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteLogRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("log_name", String.valueOf(request.getLogName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("log_name", String.valueOf(request.getLogName())); + return params.build(); }) .build(); GrpcCallSettings @@ -220,13 +216,10 @@ public Map extract(DeleteLogRequest request) { GrpcCallSettings.newBuilder() .setMethodDescriptor(listLogsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListLogsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings @@ -328,7 +321,13 @@ public UnaryCallable listLogsPagedCallab @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcMetricsServiceV2Stub.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcMetricsServiceV2Stub.java index fe15cf6052..0fda0bb3db 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcMetricsServiceV2Stub.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/GrpcMetricsServiceV2Stub.java @@ -23,7 +23,6 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableMap; import com.google.logging.v2.CreateLogMetricRequest; @@ -157,65 +156,50 @@ protected GrpcMetricsServiceV2Stub( GrpcCallSettings.newBuilder() .setMethodDescriptor(listLogMetricsMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListLogMetricsRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getLogMetricTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getLogMetricMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetLogMetricRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("metric_name", String.valueOf(request.getMetricName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("metric_name", String.valueOf(request.getMetricName())); + return params.build(); }) .build(); GrpcCallSettings createLogMetricTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createLogMetricMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateLogMetricRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateLogMetricTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateLogMetricMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateLogMetricRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("metric_name", String.valueOf(request.getMetricName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("metric_name", String.valueOf(request.getMetricName())); + return params.build(); }) .build(); GrpcCallSettings deleteLogMetricTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteLogMetricMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteLogMetricRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("metric_name", String.valueOf(request.getMetricName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("metric_name", String.valueOf(request.getMetricName())); + return params.build(); }) .build(); @@ -279,7 +263,13 @@ public UnaryCallable deleteLogMetricCallable() { @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java index d1fa3db875..3f3b507702 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java @@ -444,6 +444,11 @@ public static String getDefaultEndpoint() { return "logging.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "logging.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -451,7 +456,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -626,6 +633,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -675,14 +684,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java index 3fd951caa0..3cf4be8d73 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java @@ -212,6 +212,11 @@ public static String getDefaultEndpoint() { return "logging.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "logging.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -219,7 +224,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -371,6 +378,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -404,14 +413,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/logging/com/google/logging/v2/BillingAccountLocationName.java b/test/integration/goldens/logging/com/google/logging/v2/BillingAccountLocationName.java index 0201fe9765..d2b9e2c050 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/BillingAccountLocationName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/BillingAccountLocationName.java @@ -184,8 +184,8 @@ public Builder setLocation(String location) { } private Builder(BillingAccountLocationName billingAccountLocationName) { - billingAccount = billingAccountLocationName.billingAccount; - location = billingAccountLocationName.location; + this.billingAccount = billingAccountLocationName.billingAccount; + this.location = billingAccountLocationName.location; } public BillingAccountLocationName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/BillingAccountName.java b/test/integration/goldens/logging/com/google/logging/v2/BillingAccountName.java index 42f46677c4..b6d13b3b2e 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/BillingAccountName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/BillingAccountName.java @@ -158,7 +158,7 @@ public Builder setBillingAccount(String billingAccount) { } private Builder(BillingAccountName billingAccountName) { - billingAccount = billingAccountName.billingAccount; + this.billingAccount = billingAccountName.billingAccount; } public BillingAccountName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/CmekSettingsName.java b/test/integration/goldens/logging/com/google/logging/v2/CmekSettingsName.java index 60f7b73860..8992813529 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/CmekSettingsName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/CmekSettingsName.java @@ -310,7 +310,7 @@ private Builder(CmekSettingsName cmekSettingsName) { Preconditions.checkArgument( Objects.equals(cmekSettingsName.pathTemplate, PROJECT), "toBuilder is only supported when CmekSettingsName has the pattern of projects/{project}/cmekSettings"); - project = cmekSettingsName.project; + this.project = cmekSettingsName.project; } public CmekSettingsName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/FolderLocationName.java b/test/integration/goldens/logging/com/google/logging/v2/FolderLocationName.java index c380821f0e..08cca56bc8 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/FolderLocationName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/FolderLocationName.java @@ -181,8 +181,8 @@ public Builder setLocation(String location) { } private Builder(FolderLocationName folderLocationName) { - folder = folderLocationName.folder; - location = folderLocationName.location; + this.folder = folderLocationName.folder; + this.location = folderLocationName.location; } public FolderLocationName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/FolderName.java b/test/integration/goldens/logging/com/google/logging/v2/FolderName.java index 4da442ed84..8b76cb8fcb 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/FolderName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/FolderName.java @@ -158,7 +158,7 @@ public Builder setFolder(String folder) { } private Builder(FolderName folderName) { - folder = folderName.folder; + this.folder = folderName.folder; } public FolderName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LocationName.java b/test/integration/goldens/logging/com/google/logging/v2/LocationName.java index 18069bd08d..6fce45d9d7 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LocationName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LocationName.java @@ -181,8 +181,8 @@ public Builder setLocation(String location) { } private Builder(LocationName locationName) { - project = locationName.project; - location = locationName.location; + this.project = locationName.project; + this.location = locationName.location; } public LocationName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogBucketName.java b/test/integration/goldens/logging/com/google/logging/v2/LogBucketName.java index c373feeea0..7dcdc6bc2f 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogBucketName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogBucketName.java @@ -415,9 +415,9 @@ private Builder(LogBucketName logBucketName) { Preconditions.checkArgument( Objects.equals(logBucketName.pathTemplate, PROJECT_LOCATION_BUCKET), "toBuilder is only supported when LogBucketName has the pattern of projects/{project}/locations/{location}/buckets/{bucket}"); - project = logBucketName.project; - location = logBucketName.location; - bucket = logBucketName.bucket; + this.project = logBucketName.project; + this.location = logBucketName.location; + this.bucket = logBucketName.bucket; } public LogBucketName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogExclusionName.java b/test/integration/goldens/logging/com/google/logging/v2/LogExclusionName.java index 04bf413562..71b6aca5a7 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogExclusionName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogExclusionName.java @@ -354,8 +354,8 @@ private Builder(LogExclusionName logExclusionName) { Preconditions.checkArgument( Objects.equals(logExclusionName.pathTemplate, PROJECT_EXCLUSION), "toBuilder is only supported when LogExclusionName has the pattern of projects/{project}/exclusions/{exclusion}"); - project = logExclusionName.project; - exclusion = logExclusionName.exclusion; + this.project = logExclusionName.project; + this.exclusion = logExclusionName.exclusion; } public LogExclusionName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogMetricName.java b/test/integration/goldens/logging/com/google/logging/v2/LogMetricName.java index cbeb10b808..f271ecf0c8 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogMetricName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogMetricName.java @@ -180,8 +180,8 @@ public Builder setMetric(String metric) { } private Builder(LogMetricName logMetricName) { - project = logMetricName.project; - metric = logMetricName.metric; + this.project = logMetricName.project; + this.metric = logMetricName.metric; } public LogMetricName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogName.java b/test/integration/goldens/logging/com/google/logging/v2/LogName.java index af30905c73..056e80cc85 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogName.java @@ -340,8 +340,8 @@ private Builder(LogName logName) { Preconditions.checkArgument( Objects.equals(logName.pathTemplate, PROJECT_LOG), "toBuilder is only supported when LogName has the pattern of projects/{project}/logs/{log}"); - project = logName.project; - log = logName.log; + this.project = logName.project; + this.log = logName.log; } public LogName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogSinkName.java b/test/integration/goldens/logging/com/google/logging/v2/LogSinkName.java index efef17874b..6fcfb8a2f3 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogSinkName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogSinkName.java @@ -344,8 +344,8 @@ private Builder(LogSinkName logSinkName) { Preconditions.checkArgument( Objects.equals(logSinkName.pathTemplate, PROJECT_SINK), "toBuilder is only supported when LogSinkName has the pattern of projects/{project}/sinks/{sink}"); - project = logSinkName.project; - sink = logSinkName.sink; + this.project = logSinkName.project; + this.sink = logSinkName.sink; } public LogSinkName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/LogViewName.java b/test/integration/goldens/logging/com/google/logging/v2/LogViewName.java index 3875d5c5c4..85788f7444 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/LogViewName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/LogViewName.java @@ -472,10 +472,10 @@ private Builder(LogViewName logViewName) { Preconditions.checkArgument( Objects.equals(logViewName.pathTemplate, PROJECT_LOCATION_BUCKET_VIEW), "toBuilder is only supported when LogViewName has the pattern of projects/{project}/locations/{location}/buckets/{bucket}/views/{view}"); - project = logViewName.project; - location = logViewName.location; - bucket = logViewName.bucket; - view = logViewName.view; + this.project = logViewName.project; + this.location = logViewName.location; + this.bucket = logViewName.bucket; + this.view = logViewName.view; } public LogViewName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/OrganizationLocationName.java b/test/integration/goldens/logging/com/google/logging/v2/OrganizationLocationName.java index 6f358bef84..316fdec7e9 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/OrganizationLocationName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/OrganizationLocationName.java @@ -181,8 +181,8 @@ public Builder setLocation(String location) { } private Builder(OrganizationLocationName organizationLocationName) { - organization = organizationLocationName.organization; - location = organizationLocationName.location; + this.organization = organizationLocationName.organization; + this.location = organizationLocationName.location; } public OrganizationLocationName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/OrganizationName.java b/test/integration/goldens/logging/com/google/logging/v2/OrganizationName.java index a4bb999c2e..b04b9c43d6 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/OrganizationName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/OrganizationName.java @@ -158,7 +158,7 @@ public Builder setOrganization(String organization) { } private Builder(OrganizationName organizationName) { - organization = organizationName.organization; + this.organization = organizationName.organization; } public OrganizationName build() { diff --git a/test/integration/goldens/logging/com/google/logging/v2/ProjectName.java b/test/integration/goldens/logging/com/google/logging/v2/ProjectName.java index 2e4f451909..4975232f60 100644 --- a/test/integration/goldens/logging/com/google/logging/v2/ProjectName.java +++ b/test/integration/goldens/logging/com/google/logging/v2/ProjectName.java @@ -158,7 +158,7 @@ public Builder setProject(String project) { } private Builder(ProjectName projectName) { - project = projectName.project; + this.project = projectName.project; } public ProjectName build() { diff --git a/test/integration/goldens/pubsub/BUILD.bazel b/test/integration/goldens/pubsub/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/pubsub/BUILD.bazel +++ b/test/integration/goldens/pubsub/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/MockIAMPolicyImpl.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/MockIAMPolicyImpl.java index 836144b7ee..e4528ae534 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/MockIAMPolicyImpl.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/MockIAMPolicyImpl.java @@ -64,11 +64,13 @@ public void reset() { } @Override - public void setIamPolicy(SetIamPolicyRequest request, StreamObserver responseObserver) { + public void testIamPermissions( + TestIamPermissionsRequest request, + StreamObserver responseObserver) { Object response = responses.poll(); - if (response instanceof Policy) { + if (response instanceof TestIamPermissionsResponse) { requests.add(request); - responseObserver.onNext(((Policy) response)); + responseObserver.onNext(((TestIamPermissionsResponse) response)); responseObserver.onCompleted(); } else if (response instanceof Exception) { responseObserver.onError(((Exception) response)); @@ -76,15 +78,15 @@ public void setIamPolicy(SetIamPolicyRequest request, StreamObserver res responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method SetIamPolicy, expected %s or %s", + "Unrecognized response type %s for method TestIamPermissions, expected %s or %s", response == null ? "null" : response.getClass().getName(), - Policy.class.getName(), + TestIamPermissionsResponse.class.getName(), Exception.class.getName()))); } } @Override - public void getIamPolicy(GetIamPolicyRequest request, StreamObserver responseObserver) { + public void setIamPolicy(SetIamPolicyRequest request, StreamObserver responseObserver) { Object response = responses.poll(); if (response instanceof Policy) { requests.add(request); @@ -96,7 +98,7 @@ public void getIamPolicy(GetIamPolicyRequest request, StreamObserver res responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method GetIamPolicy, expected %s or %s", + "Unrecognized response type %s for method SetIamPolicy, expected %s or %s", response == null ? "null" : response.getClass().getName(), Policy.class.getName(), Exception.class.getName()))); @@ -104,13 +106,11 @@ public void getIamPolicy(GetIamPolicyRequest request, StreamObserver res } @Override - public void testIamPermissions( - TestIamPermissionsRequest request, - StreamObserver responseObserver) { + public void getIamPolicy(GetIamPolicyRequest request, StreamObserver responseObserver) { Object response = responses.poll(); - if (response instanceof TestIamPermissionsResponse) { + if (response instanceof Policy) { requests.add(request); - responseObserver.onNext(((TestIamPermissionsResponse) response)); + responseObserver.onNext(((Policy) response)); responseObserver.onCompleted(); } else if (response instanceof Exception) { responseObserver.onError(((Exception) response)); @@ -118,9 +118,9 @@ public void testIamPermissions( responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method TestIamPermissions, expected %s or %s", + "Unrecognized response type %s for method GetIamPolicy, expected %s or %s", response == null ? "null" : response.getClass().getName(), - TestIamPermissionsResponse.class.getName(), + Policy.class.getName(), Exception.class.getName()))); } } diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClient.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClient.java index 13acfd990c..fa217f1637 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClient.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClient.java @@ -16,7 +16,6 @@ package com.google.cloud.pubsub.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -31,7 +30,6 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.ProjectName; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; @@ -41,6 +39,7 @@ import com.google.pubsub.v1.GetSchemaRequest; import com.google.pubsub.v1.ListSchemasRequest; import com.google.pubsub.v1.ListSchemasResponse; +import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.Schema; import com.google.pubsub.v1.SchemaName; import com.google.pubsub.v1.ValidateMessageRequest; @@ -54,8 +53,10 @@ // AUTO-GENERATED DOCUMENTATION AND CLASS. /** - * This class provides the ability to make remote calls to the backing service through method calls - * that map to API methods. Sample code to get started: + * Service Description: Service for doing schema-related operations. + * + *

      This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: * *

      {@code
        * try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) {
      @@ -965,14 +966,7 @@ public static ApiFuture createAsync(
             ApiFuture futurePage =
                 ListSchemasPage.createEmptyPage().createPageAsync(context, futureResponse);
             return ApiFutures.transform(
      -          futurePage,
      -          new ApiFunction() {
      -            @Override
      -            public ListSchemasPagedResponse apply(ListSchemasPage input) {
      -              return new ListSchemasPagedResponse(input);
      -            }
      -          },
      -          MoreExecutors.directExecutor());
      +          futurePage, input -> new ListSchemasPagedResponse(input), MoreExecutors.directExecutor());
           }
       
           private ListSchemasPagedResponse(ListSchemasPage page) {
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClientTest.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClientTest.java
      index 9a2ce5e16b..ace5e7d42b 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClientTest.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceClientTest.java
      @@ -30,7 +30,6 @@
       import com.google.iam.v1.GetIamPolicyRequest;
       import com.google.iam.v1.GetPolicyOptions;
       import com.google.iam.v1.Policy;
      -import com.google.iam.v1.ProjectName;
       import com.google.iam.v1.SetIamPolicyRequest;
       import com.google.iam.v1.TestIamPermissionsRequest;
       import com.google.iam.v1.TestIamPermissionsResponse;
      @@ -43,6 +42,7 @@
       import com.google.pubsub.v1.GetSchemaRequest;
       import com.google.pubsub.v1.ListSchemasRequest;
       import com.google.pubsub.v1.ListSchemasResponse;
      +import com.google.pubsub.v1.ProjectName;
       import com.google.pubsub.v1.Schema;
       import com.google.pubsub.v1.SchemaName;
       import com.google.pubsub.v1.ValidateMessageRequest;
      @@ -65,11 +65,11 @@
       
       @Generated("by gapic-generator-java")
       public class SchemaServiceClientTest {
      -  private static MockServiceHelper mockServiceHelper;
      -  private static MockSchemaService mockSchemaService;
      -  private SchemaServiceClient client;
         private static MockIAMPolicy mockIAMPolicy;
      +  private static MockSchemaService mockSchemaService;
      +  private static MockServiceHelper mockServiceHelper;
         private LocalChannelProvider channelProvider;
      +  private SchemaServiceClient client;
       
         @BeforeClass
         public static void startStaticServer() {
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceSettings.java
      index da29b9f2de..4f7dfdda43 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceSettings.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SchemaServiceSettings.java
      @@ -218,14 +218,13 @@ public SchemaServiceStubSettings.Builder getStubSettingsBuilder() {
             return ((SchemaServiceStubSettings.Builder) getStubSettings());
           }
       
      -    // NEXT_MAJOR_VER: remove 'throws Exception'.
           /**
            * Applies the given settings updater function to all of the unary API methods in this service.
            *
            * 

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java index c7d77041cb..a6adbe6945 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java @@ -16,7 +16,6 @@ package com.google.cloud.pubsub.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -32,7 +31,6 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.ProjectName; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; @@ -49,6 +47,7 @@ import com.google.pubsub.v1.ListSubscriptionsResponse; import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.PullRequest; import com.google.pubsub.v1.PullResponse; import com.google.pubsub.v1.PushConfig; @@ -1190,6 +1189,63 @@ public final UnaryCallable acknowledgeCallable() { return stub.acknowledgeCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Pulls messages from the server. The server may return `UNAVAILABLE` if there are too many + * concurrent pull requests pending for the given subscription. + * + *

      Sample code: + * + *

      {@code
      +   * try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
      +   *   SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]");
      +   *   int maxMessages = 496131527;
      +   *   PullResponse response = subscriptionAdminClient.pull(subscription, maxMessages);
      +   * }
      +   * }
      + * + * @param subscription Required. The subscription from which messages should be pulled. Format is + * `projects/{project}/subscriptions/{sub}`. + * @param maxMessages Required. The maximum number of messages to return for this request. Must be + * a positive integer. The Pub/Sub system may return fewer than the number specified. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final PullResponse pull(SubscriptionName subscription, int maxMessages) { + PullRequest request = + PullRequest.newBuilder() + .setSubscription(subscription == null ? null : subscription.toString()) + .setMaxMessages(maxMessages) + .build(); + return pull(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Pulls messages from the server. The server may return `UNAVAILABLE` if there are too many + * concurrent pull requests pending for the given subscription. + * + *

      Sample code: + * + *

      {@code
      +   * try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
      +   *   String subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]").toString();
      +   *   int maxMessages = 496131527;
      +   *   PullResponse response = subscriptionAdminClient.pull(subscription, maxMessages);
      +   * }
      +   * }
      + * + * @param subscription Required. The subscription from which messages should be pulled. Format is + * `projects/{project}/subscriptions/{sub}`. + * @param maxMessages Required. The maximum number of messages to return for this request. Must be + * a positive integer. The Pub/Sub system may return fewer than the number specified. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final PullResponse pull(String subscription, int maxMessages) { + PullRequest request = + PullRequest.newBuilder().setSubscription(subscription).setMaxMessages(maxMessages).build(); + return pull(request); + } + // AUTO-GENERATED DOCUMENTATION AND METHOD. /** * Pulls messages from the server. The server may return `UNAVAILABLE` if there are too many @@ -2440,12 +2496,7 @@ public static ApiFuture createAsync( ListSubscriptionsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListSubscriptionsPagedResponse apply(ListSubscriptionsPage input) { - return new ListSubscriptionsPagedResponse(input); - } - }, + input -> new ListSubscriptionsPagedResponse(input), MoreExecutors.directExecutor()); } @@ -2525,12 +2576,7 @@ public static ApiFuture createAsync( ListSnapshotsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListSnapshotsPagedResponse apply(ListSnapshotsPage input) { - return new ListSnapshotsPagedResponse(input); - } - }, + input -> new ListSnapshotsPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java index 2686f5316f..dd1bd27dac 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java @@ -35,7 +35,6 @@ import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.GetPolicyOptions; import com.google.iam.v1.Policy; -import com.google.iam.v1.ProjectName; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; @@ -59,6 +58,7 @@ import com.google.pubsub.v1.ListSubscriptionsResponse; import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.PullRequest; import com.google.pubsub.v1.PullResponse; import com.google.pubsub.v1.PushConfig; @@ -93,11 +93,11 @@ @Generated("by gapic-generator-java") public class SubscriptionAdminClientTest { + private static MockIAMPolicy mockIAMPolicy; private static MockServiceHelper mockServiceHelper; private static MockSubscriber mockSubscriber; - private SubscriptionAdminClient client; - private static MockIAMPolicy mockIAMPolicy; private LocalChannelProvider channelProvider; + private SubscriptionAdminClient client; @BeforeClass public static void startStaticServer() { @@ -847,6 +847,84 @@ public void pullTest() throws Exception { PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); mockSubscriber.addResponse(expectedResponse); + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); + int maxMessages = 496131527; + + PullResponse actualResponse = client.pull(subscription, maxMessages); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockSubscriber.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + PullRequest actualRequest = ((PullRequest) actualRequests.get(0)); + + Assert.assertEquals(subscription.toString(), actualRequest.getSubscription()); + Assert.assertEquals(maxMessages, actualRequest.getMaxMessages()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void pullExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockSubscriber.addException(exception); + + try { + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); + int maxMessages = 496131527; + client.pull(subscription, maxMessages); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void pullTest2() throws Exception { + PullResponse expectedResponse = + PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); + mockSubscriber.addResponse(expectedResponse); + + String subscription = "subscription341203229"; + int maxMessages = 496131527; + + PullResponse actualResponse = client.pull(subscription, maxMessages); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockSubscriber.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + PullRequest actualRequest = ((PullRequest) actualRequests.get(0)); + + Assert.assertEquals(subscription, actualRequest.getSubscription()); + Assert.assertEquals(maxMessages, actualRequest.getMaxMessages()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void pullExceptionTest2() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockSubscriber.addException(exception); + + try { + String subscription = "subscription341203229"; + int maxMessages = 496131527; + client.pull(subscription, maxMessages); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void pullTest3() throws Exception { + PullResponse expectedResponse = + PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); + mockSubscriber.addResponse(expectedResponse); + SubscriptionName subscription = SubscriptionName.of("[PROJECT]", "[SUBSCRIPTION]"); boolean returnImmediately = true; int maxMessages = 496131527; @@ -868,7 +946,7 @@ public void pullTest() throws Exception { } @Test - public void pullExceptionTest() throws Exception { + public void pullExceptionTest3() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockSubscriber.addException(exception); @@ -884,7 +962,7 @@ public void pullExceptionTest() throws Exception { } @Test - public void pullTest2() throws Exception { + public void pullTest4() throws Exception { PullResponse expectedResponse = PullResponse.newBuilder().addAllReceivedMessages(new ArrayList()).build(); mockSubscriber.addResponse(expectedResponse); @@ -910,7 +988,7 @@ public void pullTest2() throws Exception { } @Test - public void pullExceptionTest2() throws Exception { + public void pullExceptionTest4() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockSubscriber.addException(exception); @@ -930,6 +1008,8 @@ public void streamingPullTest() throws Exception { StreamingPullResponse expectedResponse = StreamingPullResponse.newBuilder() .addAllReceivedMessages(new ArrayList()) + .setSubscriptionProperties( + StreamingPullResponse.SubscriptionProperties.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); StreamingPullRequest request = diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminSettings.java index e41dc3b133..d9680d778a 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminSettings.java @@ -285,14 +285,13 @@ public SubscriberStubSettings.Builder getStubSettingsBuilder() { return ((SubscriberStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java index 21cafd6f67..802fe3e940 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java @@ -16,7 +16,6 @@ package com.google.cloud.pubsub.v1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -31,7 +30,6 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.ProjectName; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; @@ -46,6 +44,7 @@ import com.google.pubsub.v1.ListTopicSubscriptionsResponse; import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; import com.google.pubsub.v1.PubsubMessage; @@ -1309,14 +1308,7 @@ public static ApiFuture createAsync( ApiFuture futurePage = ListTopicsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( - futurePage, - new ApiFunction() { - @Override - public ListTopicsPagedResponse apply(ListTopicsPage input) { - return new ListTopicsPagedResponse(input); - } - }, - MoreExecutors.directExecutor()); + futurePage, input -> new ListTopicsPagedResponse(input), MoreExecutors.directExecutor()); } private ListTopicsPagedResponse(ListTopicsPage page) { @@ -1390,12 +1382,7 @@ public static ApiFuture createAsync( ListTopicSubscriptionsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListTopicSubscriptionsPagedResponse apply(ListTopicSubscriptionsPage input) { - return new ListTopicSubscriptionsPagedResponse(input); - } - }, + input -> new ListTopicSubscriptionsPagedResponse(input), MoreExecutors.directExecutor()); } @@ -1475,12 +1462,7 @@ public static ApiFuture createAsync( ListTopicSnapshotsPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListTopicSnapshotsPagedResponse apply(ListTopicSnapshotsPage input) { - return new ListTopicSnapshotsPagedResponse(input); - } - }, + input -> new ListTopicSnapshotsPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java index 94b7162fba..09b8de0f90 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java @@ -32,7 +32,6 @@ import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.GetPolicyOptions; import com.google.iam.v1.Policy; -import com.google.iam.v1.ProjectName; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; @@ -51,6 +50,7 @@ import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; import com.google.pubsub.v1.MessageStoragePolicy; +import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; import com.google.pubsub.v1.PubsubMessage; @@ -76,11 +76,11 @@ @Generated("by gapic-generator-java") public class TopicAdminClientTest { - private static MockServiceHelper mockServiceHelper; - private static MockPublisher mockPublisher; - private TopicAdminClient client; private static MockIAMPolicy mockIAMPolicy; + private static MockPublisher mockPublisher; + private static MockServiceHelper mockServiceHelper; private LocalChannelProvider channelProvider; + private TopicAdminClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminSettings.java index a402b3333d..e17e7237eb 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminSettings.java @@ -245,14 +245,13 @@ public PublisherStubSettings.Builder getStubSettingsBuilder() { return ((PublisherStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/gapic_metadata.json b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/gapic_metadata.json index ec835fc74c..8efac12d01 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/gapic_metadata.json +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/gapic_metadata.json @@ -92,7 +92,7 @@ "methods": ["modifyPushConfig", "modifyPushConfig", "modifyPushConfig", "modifyPushConfigCallable"] }, "Pull": { - "methods": ["pull", "pull", "pull", "pullCallable"] + "methods": ["pull", "pull", "pull", "pull", "pull", "pullCallable"] }, "Seek": { "methods": ["seek", "seekCallable"] diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/package-info.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/package-info.java index 776d93208b..128d542475 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/package-info.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/package-info.java @@ -54,6 +54,8 @@ * *

      ======================= SchemaServiceClient ======================= * + *

      Service Description: Service for doing schema-related operations. + * *

      Sample for SchemaServiceClient: * *

      {@code
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcPublisherStub.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcPublisherStub.java
      index 2b5ce28a06..3b4330559f 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcPublisherStub.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcPublisherStub.java
      @@ -25,7 +25,6 @@
       import com.google.api.gax.grpc.GrpcCallSettings;
       import com.google.api.gax.grpc.GrpcStubCallableFactory;
       import com.google.api.gax.rpc.ClientContext;
      -import com.google.api.gax.rpc.RequestParamsExtractor;
       import com.google.api.gax.rpc.UnaryCallable;
       import com.google.common.collect.ImmutableMap;
       import com.google.iam.v1.GetIamPolicyRequest;
      @@ -242,65 +241,50 @@ protected GrpcPublisherStub(
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(createTopicMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(Topic request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("name", String.valueOf(request.getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("name", String.valueOf(request.getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings updateTopicTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(updateTopicMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(UpdateTopicRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("topic.name", String.valueOf(request.getTopic().getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("topic.name", String.valueOf(request.getTopic().getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings publishTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(publishMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(PublishRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("topic", String.valueOf(request.getTopic()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("topic", String.valueOf(request.getTopic()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getTopicTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getTopicMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetTopicRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("topic", String.valueOf(request.getTopic()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("topic", String.valueOf(request.getTopic()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings listTopicsTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(listTopicsMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(ListTopicsRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("project", String.valueOf(request.getProject()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("project", String.valueOf(request.getProject()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -309,13 +293,10 @@ public Map extract(ListTopicsRequest request) {
                       .newBuilder()
                       .setMethodDescriptor(listTopicSubscriptionsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(ListTopicSubscriptionsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("topic", String.valueOf(request.getTopic()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("topic", String.valueOf(request.getTopic()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings
      @@ -323,26 +304,20 @@ public Map extract(ListTopicSubscriptionsRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(listTopicSnapshotsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(ListTopicSnapshotsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("topic", String.valueOf(request.getTopic()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("topic", String.valueOf(request.getTopic()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings deleteTopicTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(deleteTopicMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(DeleteTopicRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("topic", String.valueOf(request.getTopic()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("topic", String.valueOf(request.getTopic()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -350,39 +325,30 @@ public Map extract(DeleteTopicRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(detachSubscriptionMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(DetachSubscriptionRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("subscription", String.valueOf(request.getSubscription()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("subscription", String.valueOf(request.getSubscription()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings setIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(setIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(SetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -390,13 +356,10 @@ public Map extract(GetIamPolicyRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(testIamPermissionsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(TestIamPermissionsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("resource", String.valueOf(request.getResource()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("resource", String.valueOf(request.getResource()));
      +                      return params.build();
                           })
                       .build();
       
      @@ -549,7 +512,13 @@ public UnaryCallable getIamPolicyCallable() {
       
         @Override
         public final void close() {
      -    shutdown();
      +    try {
      +      backgroundResources.close();
      +    } catch (RuntimeException e) {
      +      throw e;
      +    } catch (Exception e) {
      +      throw new IllegalStateException("Failed to close resource", e);
      +    }
         }
       
         @Override
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSchemaServiceStub.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSchemaServiceStub.java
      index 11bac90c7d..2ec4a27314 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSchemaServiceStub.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSchemaServiceStub.java
      @@ -23,7 +23,6 @@
       import com.google.api.gax.grpc.GrpcCallSettings;
       import com.google.api.gax.grpc.GrpcStubCallableFactory;
       import com.google.api.gax.rpc.ClientContext;
      -import com.google.api.gax.rpc.RequestParamsExtractor;
       import com.google.api.gax.rpc.UnaryCallable;
       import com.google.common.collect.ImmutableMap;
       import com.google.iam.v1.GetIamPolicyRequest;
      @@ -201,52 +200,40 @@ protected GrpcSchemaServiceStub(
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(createSchemaMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(CreateSchemaRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("parent", String.valueOf(request.getParent()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("parent", String.valueOf(request.getParent()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getSchemaTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getSchemaMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetSchemaRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("name", String.valueOf(request.getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("name", String.valueOf(request.getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings listSchemasTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(listSchemasMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(ListSchemasRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("parent", String.valueOf(request.getParent()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("parent", String.valueOf(request.getParent()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings deleteSchemaTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(deleteSchemaMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(DeleteSchemaRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("name", String.valueOf(request.getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("name", String.valueOf(request.getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -254,13 +241,10 @@ public Map extract(DeleteSchemaRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(validateSchemaMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(ValidateSchemaRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("parent", String.valueOf(request.getParent()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("parent", String.valueOf(request.getParent()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings
      @@ -268,39 +252,30 @@ public Map extract(ValidateSchemaRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(validateMessageMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(ValidateMessageRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("parent", String.valueOf(request.getParent()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("parent", String.valueOf(request.getParent()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings setIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(setIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(SetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -308,13 +283,10 @@ public Map extract(GetIamPolicyRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(testIamPermissionsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(TestIamPermissionsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("resource", String.valueOf(request.getResource()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("resource", String.valueOf(request.getResource()));
      +                      return params.build();
                           })
                       .build();
       
      @@ -412,7 +384,13 @@ public UnaryCallable getIamPolicyCallable() {
       
         @Override
         public final void close() {
      -    shutdown();
      +    try {
      +      backgroundResources.close();
      +    } catch (RuntimeException e) {
      +      throw e;
      +    } catch (Exception e) {
      +      throw new IllegalStateException("Failed to close resource", e);
      +    }
         }
       
         @Override
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSubscriberStub.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSubscriberStub.java
      index 8580e626f8..f4da747061 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSubscriberStub.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/GrpcSubscriberStub.java
      @@ -25,7 +25,6 @@
       import com.google.api.gax.grpc.GrpcStubCallableFactory;
       import com.google.api.gax.rpc.BidiStreamingCallable;
       import com.google.api.gax.rpc.ClientContext;
      -import com.google.api.gax.rpc.RequestParamsExtractor;
       import com.google.api.gax.rpc.UnaryCallable;
       import com.google.common.collect.ImmutableMap;
       import com.google.iam.v1.GetIamPolicyRequest;
      @@ -326,40 +325,31 @@ protected GrpcSubscriberStub(
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(createSubscriptionMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(Subscription request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("name", String.valueOf(request.getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("name", String.valueOf(request.getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getSubscriptionTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getSubscriptionMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetSubscriptionRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings updateSubscriptionTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(updateSubscriptionMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(UpdateSubscriptionRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put(
      -                        "subscription.name", String.valueOf(request.getSubscription().getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put(
      +                      "subscription.name", String.valueOf(request.getSubscription().getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -367,65 +357,50 @@ public Map extract(UpdateSubscriptionRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(listSubscriptionsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(ListSubscriptionsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("project", String.valueOf(request.getProject()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("project", String.valueOf(request.getProject()));
      +                      return params.build();
                           })
                       .build();
           GrpcCallSettings deleteSubscriptionTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(deleteSubscriptionMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(DeleteSubscriptionRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings modifyAckDeadlineTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(modifyAckDeadlineMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(ModifyAckDeadlineRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings acknowledgeTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(acknowledgeMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(AcknowledgeRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings pullTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(pullMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(PullRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings streamingPullTransportSettings =
      @@ -436,117 +411,90 @@ public Map extract(PullRequest request) {
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(modifyPushConfigMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(ModifyPushConfigRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getSnapshotTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getSnapshotMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetSnapshotRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("snapshot", String.valueOf(request.getSnapshot()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("snapshot", String.valueOf(request.getSnapshot()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings listSnapshotsTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(listSnapshotsMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(ListSnapshotsRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("project", String.valueOf(request.getProject()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("project", String.valueOf(request.getProject()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings createSnapshotTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(createSnapshotMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(CreateSnapshotRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("name", String.valueOf(request.getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("name", String.valueOf(request.getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings updateSnapshotTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(updateSnapshotMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(UpdateSnapshotRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("snapshot.name", String.valueOf(request.getSnapshot().getName()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("snapshot.name", String.valueOf(request.getSnapshot().getName()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings deleteSnapshotTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(deleteSnapshotMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(DeleteSnapshotRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("snapshot", String.valueOf(request.getSnapshot()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("snapshot", String.valueOf(request.getSnapshot()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings seekTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(seekMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(SeekRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("subscription", String.valueOf(request.getSubscription()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("subscription", String.valueOf(request.getSubscription()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings setIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(setIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(SetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings getIamPolicyTransportSettings =
               GrpcCallSettings.newBuilder()
                   .setMethodDescriptor(getIamPolicyMethodDescriptor)
                   .setParamsExtractor(
      -                new RequestParamsExtractor() {
      -                  @Override
      -                  public Map extract(GetIamPolicyRequest request) {
      -                    ImmutableMap.Builder params = ImmutableMap.builder();
      -                    params.put("resource", String.valueOf(request.getResource()));
      -                    return params.build();
      -                  }
      +                request -> {
      +                  ImmutableMap.Builder params = ImmutableMap.builder();
      +                  params.put("resource", String.valueOf(request.getResource()));
      +                  return params.build();
                       })
                   .build();
           GrpcCallSettings
      @@ -554,13 +502,10 @@ public Map extract(GetIamPolicyRequest request) {
                   GrpcCallSettings.newBuilder()
                       .setMethodDescriptor(testIamPermissionsMethodDescriptor)
                       .setParamsExtractor(
      -                    new RequestParamsExtractor() {
      -                      @Override
      -                      public Map extract(TestIamPermissionsRequest request) {
      -                        ImmutableMap.Builder params = ImmutableMap.builder();
      -                        params.put("resource", String.valueOf(request.getResource()));
      -                        return params.build();
      -                      }
      +                    request -> {
      +                      ImmutableMap.Builder params = ImmutableMap.builder();
      +                      params.put("resource", String.valueOf(request.getResource()));
      +                      return params.build();
                           })
                       .build();
       
      @@ -762,7 +707,13 @@ public UnaryCallable getIamPolicyCallable() {
       
         @Override
         public final void close() {
      -    shutdown();
      +    try {
      +      backgroundResources.close();
      +    } catch (RuntimeException e) {
      +      throw e;
      +    } catch (Exception e) {
      +      throw new IllegalStateException("Failed to close resource", e);
      +    }
         }
       
         @Override
      diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java
      index 5909b0850c..166775ec3c 100644
      --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java
      +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java
      @@ -478,6 +478,11 @@ public static String getDefaultEndpoint() {
           return "pubsub.googleapis.com:443";
         }
       
      +  /** Returns the default mTLS service endpoint. */
      +  public static String getDefaultMtlsEndpoint() {
      +    return "pubsub.mtls.googleapis.com:443";
      +  }
      +
         /** Returns the default service scopes. */
         public static List getDefaultServiceScopes() {
           return DEFAULT_SERVICE_SCOPES;
      @@ -485,7 +490,9 @@ public static List getDefaultServiceScopes() {
       
         /** Returns a builder for the default credentials for this service. */
         public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() {
      -    return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES);
      +    return GoogleCredentialsProvider.newBuilder()
      +        .setScopesToApply(DEFAULT_SERVICE_SCOPES)
      +        .setUseJwtAccessWithScope(true);
         }
       
         /** Returns a builder for the default ChannelProvider for this service. */
      @@ -711,6 +718,8 @@ private static Builder createDefault() {
             builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build());
             builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build());
             builder.setEndpoint(getDefaultEndpoint());
      +      builder.setMtlsEndpoint(getDefaultMtlsEndpoint());
      +      builder.setSwitchToMtlsEndpointAllowed(true);
       
             return initDefaults(builder);
           }
      @@ -792,14 +801,13 @@ private static Builder initDefaults(Builder builder) {
             return builder;
           }
       
      -    // NEXT_MAJOR_VER: remove 'throws Exception'.
           /**
            * Applies the given settings updater function to all of the unary API methods in this service.
            *
            * 

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java index 6f8f9b182e..fb8a87653d 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java @@ -242,6 +242,11 @@ public static String getDefaultEndpoint() { return "pubsub.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "pubsub.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -249,7 +254,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -401,6 +408,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -454,14 +463,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java index 55101f5595..567da1624b 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java @@ -383,6 +383,11 @@ public static String getDefaultEndpoint() { return "pubsub.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "pubsub.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -390,7 +395,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -653,6 +660,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -751,14 +760,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/pubsub/com/google/iam/v1/ProjectName.java b/test/integration/goldens/pubsub/com/google/pubsub/v1/ProjectName.java similarity index 98% rename from test/integration/goldens/pubsub/com/google/iam/v1/ProjectName.java rename to test/integration/goldens/pubsub/com/google/pubsub/v1/ProjectName.java index 21108a2658..4050e3e1aa 100644 --- a/test/integration/goldens/pubsub/com/google/iam/v1/ProjectName.java +++ b/test/integration/goldens/pubsub/com/google/pubsub/v1/ProjectName.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.iam.v1; +package com.google.pubsub.v1; import com.google.api.pathtemplate.PathTemplate; import com.google.api.resourcenames.ResourceName; @@ -158,7 +158,7 @@ public Builder setProject(String project) { } private Builder(ProjectName projectName) { - project = projectName.project; + this.project = projectName.project; } public ProjectName build() { diff --git a/test/integration/goldens/pubsub/com/google/pubsub/v1/SchemaName.java b/test/integration/goldens/pubsub/com/google/pubsub/v1/SchemaName.java index 275fce55e7..af7c5feab1 100644 --- a/test/integration/goldens/pubsub/com/google/pubsub/v1/SchemaName.java +++ b/test/integration/goldens/pubsub/com/google/pubsub/v1/SchemaName.java @@ -180,8 +180,8 @@ public Builder setSchema(String schema) { } private Builder(SchemaName schemaName) { - project = schemaName.project; - schema = schemaName.schema; + this.project = schemaName.project; + this.schema = schemaName.schema; } public SchemaName build() { diff --git a/test/integration/goldens/pubsub/com/google/pubsub/v1/SnapshotName.java b/test/integration/goldens/pubsub/com/google/pubsub/v1/SnapshotName.java index 67cb2458e2..fe26eefe0f 100644 --- a/test/integration/goldens/pubsub/com/google/pubsub/v1/SnapshotName.java +++ b/test/integration/goldens/pubsub/com/google/pubsub/v1/SnapshotName.java @@ -181,8 +181,8 @@ public Builder setSnapshot(String snapshot) { } private Builder(SnapshotName snapshotName) { - project = snapshotName.project; - snapshot = snapshotName.snapshot; + this.project = snapshotName.project; + this.snapshot = snapshotName.snapshot; } public SnapshotName build() { diff --git a/test/integration/goldens/pubsub/com/google/pubsub/v1/SubscriptionName.java b/test/integration/goldens/pubsub/com/google/pubsub/v1/SubscriptionName.java index 50131e8b35..0eed7889aa 100644 --- a/test/integration/goldens/pubsub/com/google/pubsub/v1/SubscriptionName.java +++ b/test/integration/goldens/pubsub/com/google/pubsub/v1/SubscriptionName.java @@ -181,8 +181,8 @@ public Builder setSubscription(String subscription) { } private Builder(SubscriptionName subscriptionName) { - project = subscriptionName.project; - subscription = subscriptionName.subscription; + this.project = subscriptionName.project; + this.subscription = subscriptionName.subscription; } public SubscriptionName build() { diff --git a/test/integration/goldens/pubsub/com/google/pubsub/v1/TopicName.java b/test/integration/goldens/pubsub/com/google/pubsub/v1/TopicName.java index 36d4289b67..dcb2fa83b1 100644 --- a/test/integration/goldens/pubsub/com/google/pubsub/v1/TopicName.java +++ b/test/integration/goldens/pubsub/com/google/pubsub/v1/TopicName.java @@ -224,8 +224,8 @@ private Builder(TopicName topicName) { Preconditions.checkArgument( Objects.equals(topicName.pathTemplate, PROJECT_TOPIC), "toBuilder is only supported when TopicName has the pattern of projects/{project}/topics/{topic}"); - project = topicName.project; - topic = topicName.topic; + this.project = topicName.project; + this.topic = topicName.topic; } public TopicName build() { diff --git a/test/integration/goldens/redis/BUILD.bazel b/test/integration/goldens/redis/BUILD.bazel index 667772f01b..2822013159 100644 --- a/test/integration/goldens/redis/BUILD.bazel +++ b/test/integration/goldens/redis/BUILD.bazel @@ -2,8 +2,11 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "goldens_files", - srcs = glob([ - "*.java", - "gapic_metadata.json", - ]), + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), ) diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClient.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClient.java index f62dcd329d..fe918026ed 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClient.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClient.java @@ -16,7 +16,6 @@ package com.google.cloud.redis.v1beta1; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; @@ -1463,12 +1462,7 @@ public static ApiFuture createAsync( ListInstancesPage.createEmptyPage().createPageAsync(context, futureResponse); return ApiFutures.transform( futurePage, - new ApiFunction() { - @Override - public ListInstancesPagedResponse apply(ListInstancesPage input) { - return new ListInstancesPagedResponse(input); - } - }, + input -> new ListInstancesPagedResponse(input), MoreExecutors.directExecutor()); } diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClientTest.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClientTest.java index 41caaafeb1..63665485a3 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClientTest.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisClientTest.java @@ -52,8 +52,8 @@ public class CloudRedisClientTest { private static MockCloudRedis mockCloudRedis; private static MockServiceHelper mockServiceHelper; - private CloudRedisClient client; private LocalChannelProvider channelProvider; + private CloudRedisClient client; @BeforeClass public static void startStaticServer() { diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisSettings.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisSettings.java index 250349fb1b..08436a1bd7 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisSettings.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/CloudRedisSettings.java @@ -246,14 +246,13 @@ public CloudRedisStubSettings.Builder getStubSettingsBuilder() { return ((CloudRedisStubSettings.Builder) getStubSettings()); } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods( getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); return this; diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/InstanceName.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/InstanceName.java index b58cf0d5e9..c63c2c1f75 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/InstanceName.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/InstanceName.java @@ -211,9 +211,9 @@ public Builder setInstance(String instance) { } private Builder(InstanceName instanceName) { - project = instanceName.project; - location = instanceName.location; - instance = instanceName.instance; + this.project = instanceName.project; + this.location = instanceName.location; + this.instance = instanceName.instance; } public InstanceName build() { diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/LocationName.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/LocationName.java index ab2b214c7b..fdd464ceba 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/LocationName.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/LocationName.java @@ -181,8 +181,8 @@ public Builder setLocation(String location) { } private Builder(LocationName locationName) { - project = locationName.project; - location = locationName.location; + this.project = locationName.project; + this.location = locationName.location; } public LocationName build() { diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java index fcb157ea43..b92734fabc 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java @@ -294,6 +294,11 @@ public static String getDefaultEndpoint() { return "redis.googleapis.com:443"; } + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "redis.mtls.googleapis.com:443"; + } + /** Returns the default service scopes. */ public static List getDefaultServiceScopes() { return DEFAULT_SERVICE_SCOPES; @@ -301,7 +306,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -499,6 +506,8 @@ private static Builder createDefault() { builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); return initDefaults(builder); } @@ -713,14 +722,13 @@ private static Builder initDefaults(Builder builder) { return builder; } - // NEXT_MAJOR_VER: remove 'throws Exception'. /** * Applies the given settings updater function to all of the unary API methods in this service. * *

      Note: This method does not support applying settings to streaming methods. */ public Builder applyToAllUnaryMethods( - ApiFunction, Void> settingsUpdater) throws Exception { + ApiFunction, Void> settingsUpdater) { super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); return this; } diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/GrpcCloudRedisStub.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/GrpcCloudRedisStub.java index 24c34f9b6e..51347bcfd7 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/GrpcCloudRedisStub.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/GrpcCloudRedisStub.java @@ -25,7 +25,6 @@ import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallable; -import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.redis.v1beta1.CreateInstanceRequest; import com.google.cloud.redis.v1beta1.DeleteInstanceRequest; @@ -220,117 +219,90 @@ protected GrpcCloudRedisStub( GrpcCallSettings.newBuilder() .setMethodDescriptor(listInstancesMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ListInstancesRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings getInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(getInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(GetInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings createInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(createInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(CreateInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("parent", String.valueOf(request.getParent())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("parent", String.valueOf(request.getParent())); + return params.build(); }) .build(); GrpcCallSettings updateInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(updateInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpdateInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("instance.name", String.valueOf(request.getInstance().getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("instance.name", String.valueOf(request.getInstance().getName())); + return params.build(); }) .build(); GrpcCallSettings upgradeInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(upgradeInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(UpgradeInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings importInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(importInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ImportInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings exportInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(exportInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(ExportInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings failoverInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(failoverInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(FailoverInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); GrpcCallSettings deleteInstanceTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(deleteInstanceMethodDescriptor) .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(DeleteInstanceRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); - return params.build(); - } + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); }) .build(); @@ -505,7 +477,13 @@ public OperationCallable deleteInstanceOperat @Override public final void close() { - shutdown(); + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } } @Override diff --git a/test/integration/goldens/storage/BUILD.bazel b/test/integration/goldens/storage/BUILD.bazel new file mode 100644 index 0000000000..2822013159 --- /dev/null +++ b/test/integration/goldens/storage/BUILD.bazel @@ -0,0 +1,12 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob( + ["**/*"], + exclude = [ + "BUILD.bazel", + ".*.sw*", + ], + ), +) diff --git a/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java b/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java new file mode 100644 index 0000000000..dbaae70d75 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/MockStorage.java @@ -0,0 +1,59 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.protobuf.AbstractMessage; +import io.grpc.ServerServiceDefinition; +import java.util.List; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockStorage implements MockGrpcService { + private final MockStorageImpl serviceImpl; + + public MockStorage() { + serviceImpl = new MockStorageImpl(); + } + + @Override + public List getRequests() { + return serviceImpl.getRequests(); + } + + @Override + public void addResponse(AbstractMessage response) { + serviceImpl.addResponse(response); + } + + @Override + public void addException(Exception exception) { + serviceImpl.addException(exception); + } + + @Override + public ServerServiceDefinition getServiceDefinition() { + return serviceImpl.bindService(); + } + + @Override + public void reset() { + serviceImpl.reset(); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java b/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java new file mode 100644 index 0000000000..a2787a85bd --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/MockStorageImpl.java @@ -0,0 +1,161 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.protobuf.AbstractMessage; +import com.google.storage.v2.StorageGrpc.StorageImplBase; +import io.grpc.stub.StreamObserver; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import javax.annotation.Generated; + +@BetaApi +@Generated("by gapic-generator-java") +public class MockStorageImpl extends StorageImplBase { + private List requests; + private Queue responses; + + public MockStorageImpl() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + public List getRequests() { + return requests; + } + + public void addResponse(AbstractMessage response) { + responses.add(response); + } + + public void setResponses(List responses) { + this.responses = new LinkedList(responses); + } + + public void addException(Exception exception) { + responses.add(exception); + } + + public void reset() { + requests = new ArrayList<>(); + responses = new LinkedList<>(); + } + + @Override + public void readObject( + ReadObjectRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof ReadObjectResponse) { + requests.add(request); + responseObserver.onNext(((ReadObjectResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method ReadObject, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + ReadObjectResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public StreamObserver writeObject( + final StreamObserver responseObserver) { + StreamObserver requestObserver = + new StreamObserver() { + @Override + public void onNext(WriteObjectRequest value) { + requests.add(value); + final java.lang.Object response = responses.remove(); + if (response instanceof WriteObjectResponse) { + responseObserver.onNext(((WriteObjectResponse) response)); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method WriteObject, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + WriteObjectResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void onError(Throwable t) { + responseObserver.onError(t); + } + + @Override + public void onCompleted() { + responseObserver.onCompleted(); + } + }; + return requestObserver; + } + + @Override + public void startResumableWrite( + StartResumableWriteRequest request, + StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof StartResumableWriteResponse) { + requests.add(request); + responseObserver.onNext(((StartResumableWriteResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method StartResumableWrite, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + StartResumableWriteResponse.class.getName(), + Exception.class.getName()))); + } + } + + @Override + public void queryWriteStatus( + QueryWriteStatusRequest request, StreamObserver responseObserver) { + java.lang.Object response = responses.poll(); + if (response instanceof QueryWriteStatusResponse) { + requests.add(request); + responseObserver.onNext(((QueryWriteStatusResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method QueryWriteStatus, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + QueryWriteStatusResponse.class.getName(), + Exception.class.getName()))); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java b/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java new file mode 100644 index 0000000000..78b7fd7e08 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageClient.java @@ -0,0 +1,428 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.storage.v2.stub.StorageStub; +import com.google.storage.v2.stub.StorageStubSettings; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Service Description: Manages Google Cloud Storage resources. + * + *

      This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

      {@code
      + * try (StorageClient storageClient = StorageClient.create()) {
      + *   StartResumableWriteRequest request =
      + *       StartResumableWriteRequest.newBuilder()
      + *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
      + *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      + *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      + *           .build();
      + *   StartResumableWriteResponse response = storageClient.startResumableWrite(request);
      + * }
      + * }
      + * + *

      Note: close() needs to be called on the StorageClient object to clean up resources such as + * threads. In the example above, try-with-resources is used, which automatically calls close(). + * + *

      The surface of this class includes several types of Java methods for each of the API's + * methods: + * + *

        + *
      1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available as + * parameters, and not every API method will have a flattened method entry point. + *
      2. A "request object" method. This type of method only takes one parameter, a request object, + * which must be constructed before the call. Not every API method will have a request object + * method. + *
      3. A "callable" method. This type of method takes no parameters and returns an immutable API + * callable object, which can be used to initiate calls to the service. + *
      + * + *

      See the individual methods for example code. + * + *

      Many parameters require resource names to be formatted in a particular way. To assist with + * these names, this class includes a format method for each type of name, and additionally a parse + * method to extract the individual identifiers contained within names that are returned. + * + *

      This class can be customized by passing in a custom instance of StorageSettings to create(). + * For example: + * + *

      To customize credentials: + * + *

      {@code
      + * StorageSettings storageSettings =
      + *     StorageSettings.newBuilder()
      + *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
      + *         .build();
      + * StorageClient storageClient = StorageClient.create(storageSettings);
      + * }
      + * + *

      To customize the endpoint: + * + *

      {@code
      + * StorageSettings storageSettings = StorageSettings.newBuilder().setEndpoint(myEndpoint).build();
      + * StorageClient storageClient = StorageClient.create(storageSettings);
      + * }
      + * + *

      Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@Generated("by gapic-generator-java") +public class StorageClient implements BackgroundResource { + private final StorageSettings settings; + private final StorageStub stub; + + /** Constructs an instance of StorageClient with default settings. */ + public static final StorageClient create() throws IOException { + return create(StorageSettings.newBuilder().build()); + } + + /** + * Constructs an instance of StorageClient, using the given settings. The channels are created + * based on the settings passed in, or defaults for any settings that are not set. + */ + public static final StorageClient create(StorageSettings settings) throws IOException { + return new StorageClient(settings); + } + + /** + * Constructs an instance of StorageClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(StorageSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final StorageClient create(StorageStub stub) { + return new StorageClient(stub); + } + + /** + * Constructs an instance of StorageClient, using the given settings. This is protected so that it + * is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected StorageClient(StorageSettings settings) throws IOException { + this.settings = settings; + this.stub = ((StorageStubSettings) settings.getStubSettings()).createStub(); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected StorageClient(StorageStub stub) { + this.settings = null; + this.stub = stub; + } + + public final StorageSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public StorageStub getStub() { + return stub; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Reads an object's data. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   ReadObjectRequest request =
      +   *       ReadObjectRequest.newBuilder()
      +   *           .setBucket("bucket-1378203158")
      +   *           .setObject("object-1023368385")
      +   *           .setGeneration(305703192)
      +   *           .setReadOffset(-715377828)
      +   *           .setReadLimit(-164298798)
      +   *           .setIfGenerationMatch(-1086241088)
      +   *           .setIfGenerationNotMatch(1475720404)
      +   *           .setIfMetagenerationMatch(1043427781)
      +   *           .setIfMetagenerationNotMatch(1025430873)
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .setReadMask(FieldMask.newBuilder().build())
      +   *           .build();
      +   *   ServerStream stream = storageClient.readObjectCallable().call(request);
      +   *   for (ReadObjectResponse response : stream) {
      +   *     // Do something when a response is received.
      +   *   }
      +   * }
      +   * }
      + */ + public final ServerStreamingCallable readObjectCallable() { + return stub.readObjectCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Stores a new object and metadata. + * + *

      An object can be written either in a single message stream or in a resumable sequence of + * message streams. To write using a single stream, the client should include in the first message + * of the stream an `WriteObjectSpec` describing the destination bucket, object, and any + * preconditions. Additionally, the final message must set 'finish_write' to true, or else it is + * an error. + * + *

      For a resumable write, the client should instead call `StartResumableWrite()` and provide + * that method an `WriteObjectSpec.` They should then attach the returned `upload_id` to the first + * message of each following call to `Create`. If there is an error or the connection is broken + * during the resumable `Create()`, the client should check the status of the `Create()` by + * calling `QueryWriteStatus()` and continue writing from the returned `committed_size`. This may + * be less than the amount of data the client previously sent. + * + *

      The service will not view the object as complete until the client has sent a + * `WriteObjectRequest` with `finish_write` set to `true`. Sending any requests on a stream after + * sending a request with `finish_write` set to `true` will cause an error. The client + * **should** check the response it receives to determine how much data the + * service was able to commit and whether the service views the object as complete. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   ApiStreamObserver responseObserver =
      +   *       new ApiStreamObserver() {
      +   *         {@literal @}Override
      +   *         public void onNext(WriteObjectResponse response) {
      +   *           // Do something when a response is received.
      +   *         }
      +   *
      +   *         {@literal @}Override
      +   *         public void onError(Throwable t) {
      +   *           // Add error-handling
      +   *         }
      +   *
      +   *         {@literal @}Override
      +   *         public void onCompleted() {
      +   *           // Do something when complete.
      +   *         }
      +   *       };
      +   *   ApiStreamObserver requestObserver =
      +   *       storageClient.writeObject().clientStreamingCall(responseObserver);
      +   *   WriteObjectRequest request =
      +   *       WriteObjectRequest.newBuilder()
      +   *           .setWriteOffset(-1559543565)
      +   *           .setObjectChecksums(ObjectChecksums.newBuilder().build())
      +   *           .setFinishWrite(true)
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .build();
      +   *   requestObserver.onNext(request);
      +   * }
      +   * }
      + */ + public final ClientStreamingCallable + writeObjectCallable() { + return stub.writeObjectCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts a resumable write. How long the write operation remains valid, and what happens when the + * write operation becomes invalid, are service-dependent. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   StartResumableWriteRequest request =
      +   *       StartResumableWriteRequest.newBuilder()
      +   *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .build();
      +   *   StartResumableWriteResponse response = storageClient.startResumableWrite(request);
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final StartResumableWriteResponse startResumableWrite(StartResumableWriteRequest request) { + return startResumableWriteCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Starts a resumable write. How long the write operation remains valid, and what happens when the + * write operation becomes invalid, are service-dependent. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   StartResumableWriteRequest request =
      +   *       StartResumableWriteRequest.newBuilder()
      +   *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .build();
      +   *   ApiFuture future =
      +   *       storageClient.startResumableWriteCallable().futureCall(request);
      +   *   // Do something.
      +   *   StartResumableWriteResponse response = future.get();
      +   * }
      +   * }
      + */ + public final UnaryCallable + startResumableWriteCallable() { + return stub.startResumableWriteCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

      If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

      The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   String uploadId = "uploadId1563990780";
      +   *   QueryWriteStatusResponse response = storageClient.queryWriteStatus(uploadId);
      +   * }
      +   * }
      + * + * @param uploadId Required. The name of the resume token for the object whose write status is + * being requested. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final QueryWriteStatusResponse queryWriteStatus(String uploadId) { + QueryWriteStatusRequest request = + QueryWriteStatusRequest.newBuilder().setUploadId(uploadId).build(); + return queryWriteStatus(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

      If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

      The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   QueryWriteStatusRequest request =
      +   *       QueryWriteStatusRequest.newBuilder()
      +   *           .setUploadId("uploadId1563990780")
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .build();
      +   *   QueryWriteStatusResponse response = storageClient.queryWriteStatus(request);
      +   * }
      +   * }
      + * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final QueryWriteStatusResponse queryWriteStatus(QueryWriteStatusRequest request) { + return queryWriteStatusCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Determines the `committed_size` for an object that is being written, which can then be used as + * the `write_offset` for the next `Write()` call. + * + *

      If the object does not exist (i.e., the object has been deleted, or the first `Write()` has + * not yet reached the service), this method returns the error `NOT_FOUND`. + * + *

      The client **may** call `QueryWriteStatus()` at any time to determine how + * much data has been processed for this object. This is useful if the client is buffering data + * and needs to know which data can be safely evicted. For any sequence of `QueryWriteStatus()` + * calls for a given object name, the sequence of returned `committed_size` values will be + * non-decreasing. + * + *

      Sample code: + * + *

      {@code
      +   * try (StorageClient storageClient = StorageClient.create()) {
      +   *   QueryWriteStatusRequest request =
      +   *       QueryWriteStatusRequest.newBuilder()
      +   *           .setUploadId("uploadId1563990780")
      +   *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      +   *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      +   *           .build();
      +   *   ApiFuture future =
      +   *       storageClient.queryWriteStatusCallable().futureCall(request);
      +   *   // Do something.
      +   *   QueryWriteStatusResponse response = future.get();
      +   * }
      +   * }
      + */ + public final UnaryCallable + queryWriteStatusCallable() { + return stub.queryWriteStatusCallable(); + } + + @Override + public final void close() { + stub.close(); + } + + @Override + public void shutdown() { + stub.shutdown(); + } + + @Override + public boolean isShutdown() { + return stub.isShutdown(); + } + + @Override + public boolean isTerminated() { + return stub.isTerminated(); + } + + @Override + public void shutdownNow() { + stub.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return stub.awaitTermination(duration, unit); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java b/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java new file mode 100644 index 0000000000..6374e98e7a --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageClientTest.java @@ -0,0 +1,301 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.testing.LocalChannelProvider; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.api.gax.grpc.testing.MockServiceHelper; +import com.google.api.gax.grpc.testing.MockStreamObserver; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiStreamObserver; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StatusCode; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.FieldMask; +import io.grpc.StatusRuntimeException; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +@Generated("by gapic-generator-java") +public class StorageClientTest { + private static MockServiceHelper mockServiceHelper; + private static MockStorage mockStorage; + private LocalChannelProvider channelProvider; + private StorageClient client; + + @BeforeClass + public static void startStaticServer() { + mockStorage = new MockStorage(); + mockServiceHelper = + new MockServiceHelper( + UUID.randomUUID().toString(), Arrays.asList(mockStorage)); + mockServiceHelper.start(); + } + + @AfterClass + public static void stopServer() { + mockServiceHelper.stop(); + } + + @Before + public void setUp() throws IOException { + mockServiceHelper.reset(); + channelProvider = mockServiceHelper.createChannelProvider(); + StorageSettings settings = + StorageSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = StorageClient.create(settings); + } + + @After + public void tearDown() throws Exception { + client.close(); + } + + @Test + public void readObjectTest() throws Exception { + ReadObjectResponse expectedResponse = + ReadObjectResponse.newBuilder() + .setChecksummedData(ChecksummedData.newBuilder().build()) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setContentRange(ContentRange.newBuilder().build()) + .setMetadata(Object.newBuilder().build()) + .build(); + mockStorage.addResponse(expectedResponse); + ReadObjectRequest request = + ReadObjectRequest.newBuilder() + .setBucket("bucket-1378203158") + .setObject("object-1023368385") + .setGeneration(305703192) + .setReadOffset(-715377828) + .setReadLimit(-164298798) + .setIfGenerationMatch(-1086241088) + .setIfGenerationNotMatch(1475720404) + .setIfMetagenerationMatch(1043427781) + .setIfMetagenerationNotMatch(1025430873) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .setReadMask(FieldMask.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.readObjectCallable(); + callable.serverStreamingCall(request, responseObserver); + + List actualResponses = responseObserver.future().get(); + Assert.assertEquals(1, actualResponses.size()); + Assert.assertEquals(expectedResponse, actualResponses.get(0)); + } + + @Test + public void readObjectExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + ReadObjectRequest request = + ReadObjectRequest.newBuilder() + .setBucket("bucket-1378203158") + .setObject("object-1023368385") + .setGeneration(305703192) + .setReadOffset(-715377828) + .setReadLimit(-164298798) + .setIfGenerationMatch(-1086241088) + .setIfGenerationNotMatch(1475720404) + .setIfMetagenerationMatch(1043427781) + .setIfMetagenerationNotMatch(1025430873) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .setReadMask(FieldMask.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.readObjectCallable(); + callable.serverStreamingCall(request, responseObserver); + + try { + List actualResponses = responseObserver.future().get(); + Assert.fail("No exception thrown"); + } catch (ExecutionException e) { + Assert.assertTrue(e.getCause() instanceof InvalidArgumentException); + InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause()); + Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); + } + } + + @Test + public void writeObjectTest() throws Exception { + WriteObjectResponse expectedResponse = WriteObjectResponse.newBuilder().build(); + mockStorage.addResponse(expectedResponse); + WriteObjectRequest request = + WriteObjectRequest.newBuilder() + .setWriteOffset(-1559543565) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setFinishWrite(true) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ClientStreamingCallable callable = + client.writeObjectCallable(); + ApiStreamObserver requestObserver = + callable.clientStreamingCall(responseObserver); + + requestObserver.onNext(request); + requestObserver.onCompleted(); + + List actualResponses = responseObserver.future().get(); + Assert.assertEquals(1, actualResponses.size()); + Assert.assertEquals(expectedResponse, actualResponses.get(0)); + } + + @Test + public void writeObjectExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + WriteObjectRequest request = + WriteObjectRequest.newBuilder() + .setWriteOffset(-1559543565) + .setObjectChecksums(ObjectChecksums.newBuilder().build()) + .setFinishWrite(true) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ClientStreamingCallable callable = + client.writeObjectCallable(); + ApiStreamObserver requestObserver = + callable.clientStreamingCall(responseObserver); + + requestObserver.onNext(request); + + try { + List actualResponses = responseObserver.future().get(); + Assert.fail("No exception thrown"); + } catch (ExecutionException e) { + Assert.assertTrue(e.getCause() instanceof InvalidArgumentException); + InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause()); + Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); + } + } + + @Test + public void startResumableWriteTest() throws Exception { + StartResumableWriteResponse expectedResponse = + StartResumableWriteResponse.newBuilder().setUploadId("uploadId1563990780").build(); + mockStorage.addResponse(expectedResponse); + + StartResumableWriteRequest request = + StartResumableWriteRequest.newBuilder() + .setWriteObjectSpec(WriteObjectSpec.newBuilder().build()) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + + StartResumableWriteResponse actualResponse = client.startResumableWrite(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockStorage.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + StartResumableWriteRequest actualRequest = ((StartResumableWriteRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getWriteObjectSpec(), actualRequest.getWriteObjectSpec()); + Assert.assertEquals( + request.getCommonObjectRequestParams(), actualRequest.getCommonObjectRequestParams()); + Assert.assertEquals(request.getCommonRequestParams(), actualRequest.getCommonRequestParams()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void startResumableWriteExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + + try { + StartResumableWriteRequest request = + StartResumableWriteRequest.newBuilder() + .setWriteObjectSpec(WriteObjectSpec.newBuilder().build()) + .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build()) + .setCommonRequestParams(CommonRequestParams.newBuilder().build()) + .build(); + client.startResumableWrite(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + + @Test + public void queryWriteStatusTest() throws Exception { + QueryWriteStatusResponse expectedResponse = QueryWriteStatusResponse.newBuilder().build(); + mockStorage.addResponse(expectedResponse); + + String uploadId = "uploadId1563990780"; + + QueryWriteStatusResponse actualResponse = client.queryWriteStatus(uploadId); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockStorage.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + QueryWriteStatusRequest actualRequest = ((QueryWriteStatusRequest) actualRequests.get(0)); + + Assert.assertEquals(uploadId, actualRequest.getUploadId()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void queryWriteStatusExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockStorage.addException(exception); + + try { + String uploadId = "uploadId1563990780"; + client.queryWriteStatus(uploadId); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java b/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java new file mode 100644 index 0000000000..8cbe00e72f --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/StorageSettings.java @@ -0,0 +1,218 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.storage.v2.stub.StorageStubSettings; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link StorageClient}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (storage.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of startResumableWrite to 30 seconds: + * + *

      {@code
      + * StorageSettings.Builder storageSettingsBuilder = StorageSettings.newBuilder();
      + * storageSettingsBuilder
      + *     .startResumableWriteSettings()
      + *     .setRetrySettings(
      + *         storageSettingsBuilder
      + *             .startResumableWriteSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * StorageSettings storageSettings = storageSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class StorageSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to readObject. */ + public ServerStreamingCallSettings readObjectSettings() { + return ((StorageStubSettings) getStubSettings()).readObjectSettings(); + } + + /** Returns the object with the settings used for calls to writeObject. */ + public StreamingCallSettings writeObjectSettings() { + return ((StorageStubSettings) getStubSettings()).writeObjectSettings(); + } + + /** Returns the object with the settings used for calls to startResumableWrite. */ + public UnaryCallSettings + startResumableWriteSettings() { + return ((StorageStubSettings) getStubSettings()).startResumableWriteSettings(); + } + + /** Returns the object with the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings + queryWriteStatusSettings() { + return ((StorageStubSettings) getStubSettings()).queryWriteStatusSettings(); + } + + public static final StorageSettings create(StorageStubSettings stub) throws IOException { + return new StorageSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return StorageStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return StorageStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return StorageStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return StorageStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return StorageStubSettings.defaultGrpcTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return StorageStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return StorageStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected StorageSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for StorageSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(StorageStubSettings.newBuilder(clientContext)); + } + + protected Builder(StorageSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(StorageStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(StorageStubSettings.newBuilder()); + } + + public StorageStubSettings.Builder getStubSettingsBuilder() { + return ((StorageStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to readObject. */ + public ServerStreamingCallSettings.Builder + readObjectSettings() { + return getStubSettingsBuilder().readObjectSettings(); + } + + /** Returns the builder for the settings used for calls to writeObject. */ + public StreamingCallSettings.Builder + writeObjectSettings() { + return getStubSettingsBuilder().writeObjectSettings(); + } + + /** Returns the builder for the settings used for calls to startResumableWrite. */ + public UnaryCallSettings.Builder + startResumableWriteSettings() { + return getStubSettingsBuilder().startResumableWriteSettings(); + } + + /** Returns the builder for the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings.Builder + queryWriteStatusSettings() { + return getStubSettingsBuilder().queryWriteStatusSettings(); + } + + @Override + public StorageSettings build() throws IOException { + return new StorageSettings(this); + } + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json b/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json new file mode 100644 index 0000000000..a9899e16f9 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/gapic_metadata.json @@ -0,0 +1,30 @@ +{ + "schema": "1.0", + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "java", + "protoPackage": "google.storage.v2", + "libraryPackage": "com.google.storage.v2", + "services": { + "Storage": { + "clients": { + "grpc": { + "libraryClient": "StorageClient", + "rpcs": { + "QueryWriteStatus": { + "methods": ["queryWriteStatus", "queryWriteStatus", "queryWriteStatusCallable"] + }, + "ReadObject": { + "methods": ["readObjectCallable"] + }, + "StartResumableWrite": { + "methods": ["startResumableWrite", "startResumableWriteCallable"] + }, + "WriteObject": { + "methods": ["writeObjectCallable"] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/test/integration/goldens/storage/com/google/storage/v2/package-info.java b/test/integration/goldens/storage/com/google/storage/v2/package-info.java new file mode 100644 index 0000000000..bfb389cc80 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/package-info.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ + +/** + * The interfaces provided are listed below, along with usage samples. + * + *

      ======================= StorageClient ======================= + * + *

      Service Description: Manages Google Cloud Storage resources. + * + *

      Sample for StorageClient: + * + *

      {@code
      + * try (StorageClient storageClient = StorageClient.create()) {
      + *   StartResumableWriteRequest request =
      + *       StartResumableWriteRequest.newBuilder()
      + *           .setWriteObjectSpec(WriteObjectSpec.newBuilder().build())
      + *           .setCommonObjectRequestParams(CommonObjectRequestParams.newBuilder().build())
      + *           .setCommonRequestParams(CommonRequestParams.newBuilder().build())
      + *           .build();
      + *   StartResumableWriteResponse response = storageClient.startResumableWrite(request);
      + * }
      + * }
      + */ +@Generated("by gapic-generator-java") +package com.google.storage.v2; + +import javax.annotation.Generated; diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java new file mode 100644 index 0000000000..47ef05368a --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageCallableFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcCallableFactory; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.OperationsStub; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC callable factory implementation for the Storage service API. + * + *

      This class is for advanced usage. + */ +@Generated("by gapic-generator-java") +public class GrpcStorageCallableFactory implements GrpcStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + GrpcCallSettings grpcCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createUnaryCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + GrpcCallSettings grpcCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createPagedCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + GrpcCallSettings grpcCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBatchingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + OperationCallable createOperationCallable( + GrpcCallSettings grpcCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + return GrpcCallableFactory.createOperationCallable( + grpcCallSettings, callSettings, clientContext, operationsStub); + } + + @Override + public + BidiStreamingCallable createBidiStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBidiStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + GrpcCallSettings grpcCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createServerStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ClientStreamingCallable createClientStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createClientStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java new file mode 100644 index 0000000000..3097e32c82 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/GrpcStorageStub.java @@ -0,0 +1,237 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the Storage service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public class GrpcStorageStub extends StorageStub { + private static final MethodDescriptor + readObjectMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName("google.storage.v2.Storage/ReadObject") + .setRequestMarshaller(ProtoUtils.marshaller(ReadObjectRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(ReadObjectResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + writeObjectMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName("google.storage.v2.Storage/WriteObject") + .setRequestMarshaller(ProtoUtils.marshaller(WriteObjectRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(WriteObjectResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + startResumableWriteMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.storage.v2.Storage/StartResumableWrite") + .setRequestMarshaller( + ProtoUtils.marshaller(StartResumableWriteRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(StartResumableWriteResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + queryWriteStatusMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.storage.v2.Storage/QueryWriteStatus") + .setRequestMarshaller( + ProtoUtils.marshaller(QueryWriteStatusRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(QueryWriteStatusResponse.getDefaultInstance())) + .build(); + + private final ServerStreamingCallable readObjectCallable; + private final ClientStreamingCallable + writeObjectCallable; + private final UnaryCallable + startResumableWriteCallable; + private final UnaryCallable + queryWriteStatusCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + public static final GrpcStorageStub create(StorageStubSettings settings) throws IOException { + return new GrpcStorageStub(settings, ClientContext.create(settings)); + } + + public static final GrpcStorageStub create(ClientContext clientContext) throws IOException { + return new GrpcStorageStub(StorageStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcStorageStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcStorageStub( + StorageStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of GrpcStorageStub, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected GrpcStorageStub(StorageStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcStorageCallableFactory()); + } + + /** + * Constructs an instance of GrpcStorageStub, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected GrpcStorageStub( + StorageStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings readObjectTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(readObjectMethodDescriptor) + .build(); + GrpcCallSettings writeObjectTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(writeObjectMethodDescriptor) + .build(); + GrpcCallSettings + startResumableWriteTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(startResumableWriteMethodDescriptor) + .build(); + GrpcCallSettings + queryWriteStatusTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(queryWriteStatusMethodDescriptor) + .build(); + + this.readObjectCallable = + callableFactory.createServerStreamingCallable( + readObjectTransportSettings, settings.readObjectSettings(), clientContext); + this.writeObjectCallable = + callableFactory.createClientStreamingCallable( + writeObjectTransportSettings, settings.writeObjectSettings(), clientContext); + this.startResumableWriteCallable = + callableFactory.createUnaryCallable( + startResumableWriteTransportSettings, + settings.startResumableWriteSettings(), + clientContext); + this.queryWriteStatusCallable = + callableFactory.createUnaryCallable( + queryWriteStatusTransportSettings, settings.queryWriteStatusSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + @Override + public ServerStreamingCallable readObjectCallable() { + return readObjectCallable; + } + + @Override + public ClientStreamingCallable writeObjectCallable() { + return writeObjectCallable; + } + + @Override + public UnaryCallable + startResumableWriteCallable() { + return startResumableWriteCallable; + } + + @Override + public UnaryCallable + queryWriteStatusCallable() { + return queryWriteStatusCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java new file mode 100644 index 0000000000..06ee713906 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStub.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Base stub class for the Storage service API. + * + *

      This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public abstract class StorageStub implements BackgroundResource { + + public ServerStreamingCallable readObjectCallable() { + throw new UnsupportedOperationException("Not implemented: readObjectCallable()"); + } + + public ClientStreamingCallable writeObjectCallable() { + throw new UnsupportedOperationException("Not implemented: writeObjectCallable()"); + } + + public UnaryCallable + startResumableWriteCallable() { + throw new UnsupportedOperationException("Not implemented: startResumableWriteCallable()"); + } + + public UnaryCallable + queryWriteStatusCallable() { + throw new UnsupportedOperationException("Not implemented: queryWriteStatusCallable()"); + } + + @Override + public abstract void close(); +} diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java new file mode 100644 index 0000000000..85c8639848 --- /dev/null +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java @@ -0,0 +1,358 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.storage.v2.stub; + +import com.google.api.core.ApiFunction; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.GaxProperties; +import com.google.api.gax.core.GoogleCredentialsProvider; +import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.StatusCode; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.StubSettings; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.storage.v2.QueryWriteStatusRequest; +import com.google.storage.v2.QueryWriteStatusResponse; +import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; +import com.google.storage.v2.StartResumableWriteRequest; +import com.google.storage.v2.StartResumableWriteResponse; +import com.google.storage.v2.WriteObjectRequest; +import com.google.storage.v2.WriteObjectResponse; +import java.io.IOException; +import java.util.List; +import javax.annotation.Generated; +import org.threeten.bp.Duration; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * Settings class to configure an instance of {@link StorageStub}. + * + *

      The default instance has everything set to sensible defaults: + * + *

        + *
      • The default service address (storage.googleapis.com) and default port (443) are used. + *
      • Credentials are acquired automatically through Application Default Credentials. + *
      • Retries are configured for idempotent methods but not for non-idempotent methods. + *
      + * + *

      The builder of this class is recursive, so contained classes are themselves builders. When + * build() is called, the tree of builders is called to create the complete settings object. + * + *

      For example, to set the total timeout of startResumableWrite to 30 seconds: + * + *

      {@code
      + * StorageStubSettings.Builder storageSettingsBuilder = StorageStubSettings.newBuilder();
      + * storageSettingsBuilder
      + *     .startResumableWriteSettings()
      + *     .setRetrySettings(
      + *         storageSettingsBuilder
      + *             .startResumableWriteSettings()
      + *             .getRetrySettings()
      + *             .toBuilder()
      + *             .setTotalTimeout(Duration.ofSeconds(30))
      + *             .build());
      + * StorageStubSettings storageSettings = storageSettingsBuilder.build();
      + * }
      + */ +@Generated("by gapic-generator-java") +public class StorageStubSettings extends StubSettings { + /** The default scopes of the service. */ + private static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/cloud-platform") + .add("https://www.googleapis.com/auth/cloud-platform.read-only") + .add("https://www.googleapis.com/auth/devstorage.full_control") + .add("https://www.googleapis.com/auth/devstorage.read_only") + .add("https://www.googleapis.com/auth/devstorage.read_write") + .build(); + + private final ServerStreamingCallSettings + readObjectSettings; + private final StreamingCallSettings writeObjectSettings; + private final UnaryCallSettings + startResumableWriteSettings; + private final UnaryCallSettings + queryWriteStatusSettings; + + /** Returns the object with the settings used for calls to readObject. */ + public ServerStreamingCallSettings readObjectSettings() { + return readObjectSettings; + } + + /** Returns the object with the settings used for calls to writeObject. */ + public StreamingCallSettings writeObjectSettings() { + return writeObjectSettings; + } + + /** Returns the object with the settings used for calls to startResumableWrite. */ + public UnaryCallSettings + startResumableWriteSettings() { + return startResumableWriteSettings; + } + + /** Returns the object with the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings + queryWriteStatusSettings() { + return queryWriteStatusSettings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public StorageStub createStub() throws IOException { + if (getTransportChannelProvider() + .getTransportName() + .equals(GrpcTransportChannel.getGrpcTransportName())) { + return GrpcStorageStub.create(this); + } + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return InstantiatingExecutorProvider.newBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return "storage.googleapis.com:443"; + } + + /** Returns the default mTLS service endpoint. */ + public static String getDefaultMtlsEndpoint() { + return "storage.mtls.googleapis.com:443"; + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return DEFAULT_SERVICE_SCOPES; + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return InstantiatingGrpcChannelProvider.newBuilder() + .setMaxInboundMessageSize(Integer.MAX_VALUE); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return defaultGrpcTransportProviderBuilder().build(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return ApiClientHeaderProvider.newBuilder() + .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(StorageStubSettings.class)) + .setTransportToken( + GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion()); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected StorageStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + + readObjectSettings = settingsBuilder.readObjectSettings().build(); + writeObjectSettings = settingsBuilder.writeObjectSettings().build(); + startResumableWriteSettings = settingsBuilder.startResumableWriteSettings().build(); + queryWriteStatusSettings = settingsBuilder.queryWriteStatusSettings().build(); + } + + /** Builder for StorageStubSettings. */ + public static class Builder extends StubSettings.Builder { + private final ImmutableList> unaryMethodSettingsBuilders; + private final ServerStreamingCallSettings.Builder + readObjectSettings; + private final StreamingCallSettings.Builder + writeObjectSettings; + private final UnaryCallSettings.Builder + startResumableWriteSettings; + private final UnaryCallSettings.Builder + queryWriteStatusSettings; + private static final ImmutableMap> + RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = + ImmutableMap.builder(); + definitions.put( + "retry_policy_0_codes", + ImmutableSet.copyOf( + Lists.newArrayList( + StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings settings = null; + settings = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofMillis(1000L)) + .setRetryDelayMultiplier(2.0) + .setMaxRetryDelay(Duration.ofMillis(60000L)) + .setInitialRpcTimeout(Duration.ofMillis(60000L)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeout(Duration.ofMillis(60000L)) + .setTotalTimeout(Duration.ofMillis(60000L)) + .build(); + definitions.put("retry_policy_0_params", settings); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + protected Builder() { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(clientContext); + + readObjectSettings = ServerStreamingCallSettings.newBuilder(); + writeObjectSettings = StreamingCallSettings.newBuilder(); + startResumableWriteSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + queryWriteStatusSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + startResumableWriteSettings, queryWriteStatusSettings); + initDefaults(this); + } + + protected Builder(StorageStubSettings settings) { + super(settings); + + readObjectSettings = settings.readObjectSettings.toBuilder(); + writeObjectSettings = settings.writeObjectSettings.toBuilder(); + startResumableWriteSettings = settings.startResumableWriteSettings.toBuilder(); + queryWriteStatusSettings = settings.queryWriteStatusSettings.toBuilder(); + + unaryMethodSettingsBuilders = + ImmutableList.>of( + startResumableWriteSettings, queryWriteStatusSettings); + } + + private static Builder createDefault() { + Builder builder = new Builder(((ClientContext) null)); + + builder.setTransportChannelProvider(defaultTransportChannelProvider()); + builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + builder.setInternalHeaderProvider(defaultApiClientHeaderProviderBuilder().build()); + builder.setEndpoint(getDefaultEndpoint()); + builder.setMtlsEndpoint(getDefaultMtlsEndpoint()); + builder.setSwitchToMtlsEndpointAllowed(true); + + return initDefaults(builder); + } + + private static Builder initDefaults(Builder builder) { + builder + .readObjectSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .startResumableWriteSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + builder + .queryWriteStatusSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + + return builder; + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

      Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods(unaryMethodSettingsBuilders, settingsUpdater); + return this; + } + + public ImmutableList> unaryMethodSettingsBuilders() { + return unaryMethodSettingsBuilders; + } + + /** Returns the builder for the settings used for calls to readObject. */ + public ServerStreamingCallSettings.Builder + readObjectSettings() { + return readObjectSettings; + } + + /** Returns the builder for the settings used for calls to writeObject. */ + public StreamingCallSettings.Builder + writeObjectSettings() { + return writeObjectSettings; + } + + /** Returns the builder for the settings used for calls to startResumableWrite. */ + public UnaryCallSettings.Builder + startResumableWriteSettings() { + return startResumableWriteSettings; + } + + /** Returns the builder for the settings used for calls to queryWriteStatus. */ + public UnaryCallSettings.Builder + queryWriteStatusSettings() { + return queryWriteStatusSettings; + } + + @Override + public StorageStubSettings build() throws IOException { + return new StorageStubSettings(this); + } + } +} diff --git a/version.txt b/version.txt index 7ee7020b38..7ec1d6db40 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.10 +2.1.0