diff --git a/.github/release-please.yml b/.github/release-please.yml index 9548aceb5e..ddc69395da 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,3 +1,3 @@ releaseType: simple handleGHRelease: true -primaryBranch: master +primaryBranch: main diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dbf5754794..ec62f81cb2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,14 +1,14 @@ on: push: branches: - - master + - main pull_request: name: ci jobs: build: runs-on: ubuntu-latest container: gcr.io/gapic-images/googleapis-bazel:20210105 - # Dockerfile for this image: https://github.com/googleapis/googleapis-discovery/blob/master/Dockerfile + # Dockerfile for this image: https://github.com/googleapis/googleapis-discovery/blob/main/Dockerfile # If you update its version, please also update it below in # 'Cache Bazel files' - unfortunately it cannot accept variables at this # time. diff --git a/CHANGELOG.md b/CHANGELOG.md index 5679cf07f3..47548ec096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 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) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 8cd12949a0..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 diff --git a/README.md b/README.md index bf07953d1b..d9c6914dc9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![codecov](https://codecov.io/gh/googleapis/gapic-generator-java/branch/master/graph/badge.svg?token=3RUU37GX9U)](https://codecov.io/gh/googleapis/gapic-generator-java) +[![codecov](https://codecov.io/gh/googleapis/gapic-generator-java/branch/main/graph/badge.svg?token=3RUU37GX9U)](https://codecov.io/gh/googleapis/gapic-generator-java) # API Client Generator for Java Generates a Java client library from protocol buffers. diff --git a/WORKSPACE b/WORKSPACE index 7468b3246d..91c1361828 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -8,10 +8,10 @@ load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_maven_import_external") # like protobuf will build. http_archive( name = "bazel_skylib", - sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44", + sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", ], ) @@ -32,7 +32,8 @@ jvm_maven_import_external( # 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 = "1.65.1" + +_gax_java_version = "2.4.0" http_archive( name = "com_google_api_gax_java", diff --git a/repositories.bzl b/repositories.bzl index 67493dba45..6091b21171 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -59,18 +59,20 @@ def gapic_generator_java_repositories(): _maybe( http_archive, name = "com_google_googleapis", - strip_prefix = "googleapis-efecdbf96311bb705d619459280ffc651b10844a", + strip_prefix = "googleapis-ba30d8097582039ac4cc4e21b4e4baa426423075", urls = [ - "https://github.com/googleapis/googleapis/archive/efecdbf96311bb705d619459280ffc651b10844a.zip", + "https://github.com/googleapis/googleapis/archive/ba30d8097582039ac4cc4e21b4e4baa426423075.zip", ], ) + # TODO: replace with upstream googleapis-discovery link once + # https://github.com/googleapis/googleapis-discovery/pull/59 is merged _maybe( http_archive, name = "com_google_googleapis_discovery", - strip_prefix = "googleapis-discovery-abf4cec1ce9e02e4d7d650bf66137c347cdd0d44", + strip_prefix = "googleapis-discovery-bb8a053b93ef8698297c41634aa9201f7e075277", urls = [ - "https://github.com/googleapis/googleapis-discovery/archive/abf4cec1ce9e02e4d7d650bf66137c347cdd0d44.zip", + "https://github.com/vam-google/googleapis-discovery/archive/bb8a053b93ef8698297c41634aa9201f7e075277.zip", ], ) diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl index 65cb3617f7..91eb4ddb56 100644 --- a/rules_java_gapic/java_gapic.bzl +++ b/rules_java_gapic/java_gapic.bzl @@ -135,7 +135,7 @@ def _java_gapic_srcjar( if grpc_service_config: file_args_dict[grpc_service_config] = "grpc-service-config" - elif transport != "rest": + 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") @@ -230,16 +230,25 @@ def java_gapic_library( "@javax_annotation_javax_annotation_api//jar", ] - if transport == "rest": + 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", ] - else: + 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, @@ -256,18 +265,29 @@ def java_gapic_library( "@junit_junit//jar", ] - if transport == "rest": + 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", ] - else: + 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) diff --git a/rules_java_gapic/java_gapic_pkg.bzl b/rules_java_gapic/java_gapic_pkg.bzl index a6bca826d2..eb109db524 100644 --- a/rules_java_gapic/java_gapic_pkg.bzl +++ b/rules_java_gapic/java_gapic_pkg.bzl @@ -351,10 +351,12 @@ def java_gapic_assembly_gradle_pkg( grpc_target_dep = ["%s" % grpc_target] if client_deps: - if transport == "rest": - template_label = Label("//rules_java_gapic:resources/gradle/client_rest.gradle.tmpl") - else: + 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, 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_grpc.gradle.tmpl b/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl index 137f38d6f2..5ed53f6401 100644 --- a/rules_java_gapic/resources/gradle/client_grpc.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 index ef16323736..20fab62963 100644 --- a/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl +++ b/rules_java_gapic/resources/gradle/client_rest.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/gradle/wrapper/gradle-wrapper.properties b/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties index 056e712818..4d39c109cf 100644 --- a/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 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/BUILD.bazel b/src/main/java/com/google/api/generator/BUILD.bazel index de7f95f193..4e678b5b7d 100644 --- a/src/main/java/com/google/api/generator/BUILD.bazel +++ b/src/main/java/com/google/api/generator/BUILD.bazel @@ -39,6 +39,7 @@ java_library( "//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/cloud:extended_operations_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/ProtoRegistry.java b/src/main/java/com/google/api/generator/ProtoRegistry.java index da4806bba0..d4cce56dcf 100644 --- a/src/main/java/com/google/api/generator/ProtoRegistry.java +++ b/src/main/java/com/google/api/generator/ProtoRegistry.java @@ -18,6 +18,7 @@ import com.google.api.ClientProto; import com.google.api.FieldBehaviorProto; import com.google.api.ResourceProto; +import com.google.cloud.ExtendedOperationsProto; import com.google.longrunning.OperationsProto; import com.google.protobuf.ExtensionRegistry; @@ -29,5 +30,6 @@ public static void registerAllExtensions(ExtensionRegistry extensionRegistry) { ClientProto.registerAllExtensions(extensionRegistry); ResourceProto.registerAllExtensions(extensionRegistry); FieldBehaviorProto.registerAllExtensions(extensionRegistry); + ExtendedOperationsProto.registerAllExtensions(extensionRegistry); } } 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 888262cbf4..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)); } 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/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/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/TypeNode.java b/src/main/java/com/google/api/generator/engine/ast/TypeNode.java index 99de1a213d..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 @@ -112,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; } @@ -161,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)); } @@ -200,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() @@ -256,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 58fb2b9aa4..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) { 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 a52b584da1..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 = "{"; @@ -751,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 = @@ -759,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(); @@ -772,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); @@ -865,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 9f6eb8954e..60cbc46d03 100644 --- a/src/main/java/com/google/api/generator/gapic/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/BUILD.bazel @@ -9,6 +9,7 @@ filegroup( "//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", 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 3cfcae2c62..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,6 +21,7 @@ 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", 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 5c191b0a27..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,22 +15,21 @@ 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.Service; @@ -76,8 +75,10 @@ public static List generateStubClasses(GapicContext context) { .services() .forEach( s -> { - clazzes.add(ServiceStubClassComposer.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() @@ -85,11 +86,30 @@ public static List generateStubClasses(GapicContext context) { clazzes.add( HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s)); clazzes.add(HttpJsonServiceStubClassComposer.instance().generate(context, s)); - } else { + } 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; @@ -101,14 +121,27 @@ public static List generateClientSettingsClasses(GapicContext contex .services() .forEach( s -> { - clazzes.add(ServiceClientClassComposer.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 { + } 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; @@ -120,7 +153,10 @@ public static List generateMockClasses(GapicContext context, List { if (context.transport() == Transport.REST) { // REST transport tests donot not use mock services. - } else { + } 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)); } @@ -129,35 +165,25 @@ public static List generateMockClasses(GapicContext context, List generateTestClasses(GapicContext context) { - return context.services().stream() - .map( + List clazzes = new ArrayList<>(); + context + .services() + .forEach( s -> { if (context.transport() == Transport.REST) { - return com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer - .instance() - .generate(context, s); - } else { - return ServiceClientTestClassComposer.instance().generate(context, s); + 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)); } - }) - .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"; - } + }); - 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 ec8ef19be4..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 @@ -27,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."; 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 b3f4c7ee74..224bece718 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 @@ -62,7 +62,8 @@ protected TransportContext getTransportContext() { @Override public GapicClass generate(GapicContext context, Service service) { - TypeStore typeStore = createTypes(); + TypeStore typeStore = createTypes(service); + String className = getTransportContext().classNames().getTransportServiceCallableFactoryClassName(service); GapicClass.Kind kind = Kind.STUB; @@ -77,9 +78,9 @@ public GapicClass generate(GapicContext context, Service service) { commentComposer.createTransportServiceCallableFactoryClassHeaderComments( service.name(), service.isDeprecated())) .setAnnotations(createClassAnnotations(service, typeStore)) - .setImplementsTypes(createClassImplements(typeStore)) + .setImplementsTypes(createClassImplements(typeStore, service)) .setName(className) - .setMethods(createClassMethods(typeStore)) + .setMethods(createClassMethods(service, typeStore)) .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); @@ -110,22 +111,23 @@ protected List createClassAnnotations(Service service, TypeStore * @return {@code TypeNode} containing the interface to be implemented by the generated callable * factory class. */ - protected abstract List createClassImplements(TypeStore typeStore); + protected abstract List createClassImplements(TypeStore typeStore, Service service); - protected List createClassMethods(TypeStore typeStore) { + protected List createClassMethods(Service service, TypeStore typeStore) { return Arrays.asList( - createUnaryCallableMethod(typeStore), - createPagedCallableMethod(typeStore), - createBatchingCallableMethod(typeStore), - createOperationCallableMethod(typeStore)); + createUnaryCallableMethod(service, typeStore), + createPagedCallableMethod(service, typeStore), + createBatchingCallableMethod(service, typeStore), + createOperationCallableMethod(service, typeStore)); } - protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + protected MethodDefinition createUnaryCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -140,7 +142,7 @@ protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + protected MethodDefinition createPagedCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; String pagedResponseTemplateName = "PagedListResponseT"; @@ -148,6 +150,7 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, pagedResponseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -162,12 +165,13 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { + protected MethodDefinition createBatchingCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Batching"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -182,9 +186,11 @@ protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected abstract MethodDefinition createOperationCallableMethod(TypeStore typeStore); + protected abstract MethodDefinition createOperationCallableMethod( + Service service, TypeStore typeStore); protected MethodDefinition createGenericCallableMethod( + Service service, TypeStore typeStore, List methodTemplateNames, String returnCallableKindName, @@ -194,6 +200,7 @@ protected MethodDefinition createGenericCallableMethod( String callSettingsVariantName, List callSettingsTemplateObjects) { return createGenericCallableMethod( + service, typeStore, methodTemplateNames, returnCallableKindName, @@ -206,6 +213,7 @@ protected MethodDefinition createGenericCallableMethod( } protected MethodDefinition createGenericCallableMethod( + Service service, TypeStore typeStore, List methodTemplateNames, String returnCallableKindName, @@ -257,7 +265,7 @@ protected MethodDefinition createGenericCallableMethod( .setVariable( Variable.builder() .setName("operationsStub") - .setType(getTransportContext().operationsStubType()) + .setType(getOperationsStubType(service)) .build()) .setIsDecl(true) .build()); @@ -288,8 +296,17 @@ protected MethodDefinition createGenericCallableMethod( .build(); } - private static TypeStore createTypes() { - List concreteClazzes = + protected TypeNode getOperationsStubType(Service service) { + TypeNode opeationsStubType = service.operationServiceStubType(); + if (opeationsStubType == null) { + opeationsStubType = getTransportContext().operationsStubTypes().get(0); + } + return opeationsStubType; + } + + + private TypeStore createTypes(Service service) { + 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 5a38db0562..031f1cc2dd 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 @@ -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.hasStandardLroMethods(); 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 = @@ -708,6 +741,7 @@ private static MethodDefinition createMethodDefaultMethod( method.isPaged() ? typeStore.get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name())) : method.outputType(); + List annotations = new ArrayList<>(); if (method.hasLro()) { LongrunningOperation lro = method.lro(); methodOutputType = @@ -718,6 +752,13 @@ private static MethodDefinition createMethodDefaultMethod( .copyAndSetGenerics( Arrays.asList( lro.responseType().reference(), lro.metadataType().reference()))); + if (method.hasLro() && method.lro().operationServiceStubType() != null) { + annotations.add( + AnnotationNode.withTypeAndDescription( + typeStore.get("BetaApi"), + "The surface for long-running operations is not stable yet and may change in the" + + " future.")); + } } // Construct the method that accepts a request proto. @@ -759,8 +800,7 @@ private static MethodDefinition createMethodDefaultMethod( .setArguments(Arrays.asList(requestArgVarExpr)); if (method.isDeprecated()) { - methodBuilder = - methodBuilder.setAnnotations(Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))); + annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED)); } if (isProtoEmptyType(methodOutputType)) { @@ -772,6 +812,9 @@ private static MethodDefinition createMethodDefaultMethod( methodBuilder = methodBuilder.setReturnExpr(callableMethodExpr).setReturnType(methodOutputType); } + + methodBuilder.setAnnotations(annotations); + return methodBuilder.build(); } @@ -1159,12 +1202,6 @@ 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). @@ -1525,7 +1562,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); @@ -1624,7 +1661,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, @@ -1681,8 +1718,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(), @@ -1727,15 +1762,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 7d01cfbca3..b38ca70edd 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,7 +20,6 @@ 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; @@ -59,6 +58,7 @@ 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.OperationResponse; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -109,12 +109,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 = @@ -196,7 +198,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)); @@ -207,7 +210,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); @@ -409,7 +413,10 @@ private MethodDefinition createRpcTestMethod( .setValueExpr(expectedResponseValExpr) .build()); - if (method.hasLro()) { + if (method.hasLro() + && (method.lro().operationServiceStubType() == null + || !method.lro().responseType().equals(method.outputType()))) { + VariableExpr resultOperationVarExpr = VariableExpr.withVariable( Variable.builder() @@ -470,7 +477,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()) @@ -735,6 +742,9 @@ protected abstract List createStreamingRpcExceptionTestStatements( Map resourceNames, Map messageTypes); + protected abstract Expr createDefaultValue( + MethodArgument methodArg, Map resourceNames); + protected List createRpcExceptionTestStatements( Method method, List methodSignature, @@ -766,7 +776,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()) @@ -840,7 +850,7 @@ protected abstract List createRpcLroExceptionTestCatchBody( */ private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, After.class, @@ -903,24 +913,6 @@ 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; @@ -966,7 +958,7 @@ protected static TypeNode getCallableType(Method protoMethod) { !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 e59e689bb2..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( @@ -726,7 +750,7 @@ private static MethodDefinition createNestedBuilderClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiClientHeaderProvider.class, ApiFunction.class, @@ -791,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() @@ -814,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 034c94c949..b50f15ff38 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,77 +16,49 @@ 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.LongRunningClient; 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.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.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.common.collect.ImmutableList; 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 DOT = "."; 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; @@ -94,256 +66,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()), - (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) { + 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()) { @@ -352,559 +106,169 @@ 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(); + private List createClassMethods( + Service service, Map messageTypes, TypeStore typeStore) { + List methods = new ArrayList<>(); + if (service.hasStandardLroMethods()) { + TypeNode operationsStubType = service.operationServiceStubType(); + methods.addAll(createOperationsStubGetters(typeStore, operationsStubType)); + } - 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()); + if (service.operationPollingMethod() != null) { + methods.addAll(createLongRunningClientGetters(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, TypeNode operationsStubType) { + 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())); + //TODO: refactor this + TypeNode actualOperationsStubType = operationStubTypeIt.next(); + if (operationsStubType != null) { + actualOperationsStubType = operationsStubType; } + + getters.add(createOperationsStubGetterMethodDefinition(actualOperationsStubType, methodName, typeStore)); } - return String.format("create%sCallable", streamName); + + return getters; } - 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 createLongRunningClientGetters(TypeStore typeStore) { + return ImmutableList.of(createCallableGetterMethodDefinition( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)), + "longRunningClient", + ImmutableList.of(AnnotationNode.withType(typeStore.get("BetaApi"))), + typeStore)); } - 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) + private static List createBackgroundResourceMethodOverrides() { + MethodDefinition closeMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setIsAbstract(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; + .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(), @@ -913,52 +277,45 @@ 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)); + 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()))); + 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(); } - 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 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(); } - 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()); + 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/AbstractServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index 1d89768a58..7ec411185f 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 @@ -105,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; @@ -139,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 = @@ -150,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; } @@ -197,11 +199,162 @@ 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(); + // enable self signed JWT. + 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(); + } + + 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); - protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + 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 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) { @@ -815,6 +968,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; @@ -847,11 +1001,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(); @@ -861,31 +1011,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 = @@ -902,6 +1069,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 = @@ -917,7 +1086,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(); } @@ -992,60 +1161,41 @@ private List createDefaultHelperAndGetterMethods( .setReturnExpr(DEFAULT_SERVICE_SCOPES_VAR_EXPR) .build()); - // Create the defaultCredentialsProviderBuilder 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(); - javaMethods.add( - MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultCredentialsProviderBuilder") - .setReturnExpr(credsProviderBuilderExpr) - .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(); @@ -1134,11 +1284,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"; @@ -1234,7 +1383,7 @@ private static List createNestedClassStatements( return statements; } - private static List createNestedClassMethods( + private List createNestedClassMethods( Service service, GapicServiceConfig serviceConfig, TypeNode superType, @@ -1245,7 +1394,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()); @@ -1256,7 +1405,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); @@ -1311,7 +1460,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); } @@ -1581,7 +1732,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); @@ -1606,15 +1772,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() @@ -1638,7 +1821,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t MethodInvocationExpr.builder() .setExprReferenceExpr( MethodInvocationExpr.builder() - .setMethodName("defaultApiClientHeaderProviderBuilder") + .setMethodName(defaultApiClientHeaderProviderBuilder) .build()) .setMethodName("build") .build()) @@ -1681,7 +1864,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t .setScope(ScopeNode.PRIVATE) .setIsStatic(true) .setReturnType(builderType) - .setName("createDefault") + .setName(methodName) .setBody(bodyStatements) .setReturnExpr(returnExpr) .build(); @@ -1808,7 +1991,7 @@ private static MethodDefinition createNestedClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiCallContext.class, ApiClientHeaderProvider.class, @@ -1865,10 +2048,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); @@ -1964,7 +2149,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..3d3aafdaa9 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java @@ -0,0 +1,1115 @@ +// 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.longrunning.OperationSnapshot; +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.LongRunningClient; +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.VaporReference; +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.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.ImmutableList; +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, + OperationSnapshot.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). + TypeNode opeationsStubType = getTransportOperationsStubType(service); + classMemberVarExprs.put( + getTransportContext().transportOperationsStubNames().get(0), + VariableExpr.withVariable( + Variable.builder() + .setName(getTransportContext().transportOperationsStubNames().get(0)) + .setType(opeationsStubType) + .build())); + } + + boolean operationPollingMethod = checkOperationPollingMethod(service); + if (operationPollingMethod) { + VariableExpr longRunningVarExpr = declareLongRunningClient(); + if (longRunningVarExpr != null) { + classMemberVarExprs.put("longRunningClient", longRunningVarExpr); + } + } + + classMemberVarExprs.put( + CALLABLE_FACTORY_MEMBER_NAME, + VariableExpr.withVariable( + Variable.builder() + .setName(CALLABLE_FACTORY_MEMBER_NAME) + .setType(getTransportContext().stubCallableFactoryType()) + .build())); + + Map messageTypes = context.messages(); + List classStatements = + createClassStatements( + service, + protoMethodNameToDescriptorVarExprs, + callableClassMemberVarExprs, + classMemberVarExprs, + messageTypes); + + 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(getTransportContext().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, + Map messageTypes); + + 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 createTypeRegistry(Service service) { + return Arrays.asList(); + } + + protected List createClassStatements( + Service service, + Map protoMethodNameToDescriptorVarExprs, + Map callableClassMemberVarExprs, + Map classMemberVarExprs, + Map messageTypes) { + List classStatements = new ArrayList<>(); + + classStatements.addAll(createTypeRegistry(service)); + if (!classStatements.isEmpty()) { + classStatements.add(EMPTY_LINE_STATEMENT); + } + + for (Statement statement : + createMethodDescriptorVariableDecls( + service, protoMethodNameToDescriptorVarExprs, messageTypes)) { + classStatements.add(statement); + classStatements.add(EMPTY_LINE_STATEMENT); + } + + classStatements.addAll(createClassMemberFieldDeclarations(callableClassMemberVarExprs)); + classStatements.add(EMPTY_LINE_STATEMENT); + + classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs)); + classStatements.add(EMPTY_LINE_STATEMENT); + + return classStatements; + } + + protected List createMethodDescriptorVariableDecls( + Service service, + Map protoMethodNameToDescriptorVarExprs, + Map messageTypes) { + return service.methods().stream() + .map( + m -> + createMethodDescriptorVariableDecl( + service, m, protoMethodNameToDescriptorVarExprs.get(m.name()), messageTypes)) + .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), service)); + 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(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(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(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(getTransportContext().transportOperationsStubNames().get(0)); + // TODO: refactor this + if (generateOperationsStubLogic(service)) { + secondCtorExprs.addAll(createOperationsStubInitExpr( + service, + thisExpr, + operationsStubClassVarExpr, + clientContextVarExpr, + callableFactoryVarExpr)); + } + 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); + + secondCtorStatements.addAll(createLongRunningClient(service, typeStore)); + + // 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); + } + + protected List createOperationsStubInitExpr( + Service service, + Expr thisExpr, + VariableExpr operationsStubClassVarExpr, + VariableExpr clientContextVarExpr, + VariableExpr callableFactoryVarExpr) { + TypeNode opeationsStubType = getTransportOperationsStubType(service); + return Collections.singletonList( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(opeationsStubType) + .setMethodName("create") + .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } + + protected List createLongRunningClient(Service service, TypeStore typeStore) { + return ImmutableList.of(); + } + + protected VariableExpr declareLongRunningClient() { + return null; + } + + 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, Service service) { + 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<>(); + if (service.operationPollingMethod() != null) { + javaMethods.addAll(createLongRunningClientGetters()); + } + 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 boolean checkOperationPollingMethod(Service service) { + for (Method method : service.methods()) { + if (method.isOperationPollingMethod()) { + return true; + } + } + return false; + } + + protected List createLongRunningClientGetters() { + VariableExpr longRunningClient = + VariableExpr.withVariable( + Variable.builder() + .setName("longRunningClient") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .build()); + + return ImmutableList.of( + MethodDefinition.builder() + .setName("longRunningClient") + .setScope(ScopeNode.PUBLIC) + .setIsOverride(true) + .setReturnType( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .setReturnExpr(longRunningClient) + .build()); + } + + private TypeStore createDynamicTypes(Service service, String stubPakkage) { + TypeStore typeStore = new TypeStore(); + typeStore.putAll( + stubPakkage, + Arrays.asList( + getTransportContext().classNames().getTransportServiceStubClassName(service), + getTransportContext().classNames().getServiceStubSettingsClassName(service), + getTransportContext().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, + getTransportContext().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()); + } + + protected TypeNode getTransportOperationsStubType(Service service) { + TypeNode transportOpeationsStubType = service.operationServiceStubType(); + if (transportOpeationsStubType == null) { + transportOpeationsStubType = getTransportContext().transportOperationsStubTypes().get(0); + } else { + transportOpeationsStubType = + TypeNode.withReference( + VaporReference.builder() + .setName("HttpJson" + transportOpeationsStubType.reference().simpleName()) + .setPakkage(transportOpeationsStubType.reference().pakkage()) + .build()); + } + + return transportOpeationsStubType; + } +} 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/DefaultValueComposer.java b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java index 75562d680c..8862984755 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 @@ -27,6 +27,7 @@ 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.VaporReference; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.resourcename.ResourceNameTokenizer; @@ -40,7 +41,6 @@ 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; @@ -54,12 +54,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( @@ -72,10 +73,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())) { @@ -251,9 +263,12 @@ public static Expr createSimpleMessageBuilderExpr( .setStaticReferenceType(message.type()) .setMethodName("newBuilder") .build(); + for (Field field : message.fields()) { if (field.isContainedInOneof() // Avoid colliding fields. - || ((field.isMessage() || field.isEnum()) // Avoid importing unparsed messages. + || ((field.isMessage() + || (field.isEnum() + && message.operationResponse() == null)) // Avoid importing unparsed messages. && !field.isRepeated() && !messageTypes.containsKey(field.type().reference().fullName()))) { continue; @@ -278,7 +293,34 @@ public static Expr createSimpleMessageBuilderExpr( .setReturnType(TypeNode.STRING) .build(); } else { - defaultExpr = createDefaultValue(field, true); + if (message.operationResponse() != null) { + if (field.name().equals(message.operationResponse().statusFieldName())) { + String statusTypeName = message.operationResponse().statusFieldTypeName(); + String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); + + TypeNode statusType = + TypeNode.withReference( + VaporReference.builder() + .setName(statusClassName) + .setPakkage(message.type().reference().fullName()) + .setIsStaticImport(false) + .build()); + defaultExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(statusType).build()) + .setStaticReferenceType(statusType) + .build(); + + } else if (field.name().equals(message.operationResponse().errorCodeFieldName())) { + defaultExpr = + ValueExpr.withValue( + PrimitiveValue.builder().setType(field.type()).setValue("0").build()); + } + } + + if (defaultExpr == null) { + defaultExpr = createDefaultValue(field, true); + } } builderExpr = MethodInvocationExpr.builder() 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 9a291669e2..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.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..38446187e8 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 @@ -19,6 +19,7 @@ import com.google.api.generator.engine.ast.TypeNode; 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 com.google.longrunning.Operation; import java.util.ArrayList; import java.util.Arrays; @@ -41,26 +42,30 @@ public static GrpcServiceCallableFactoryClassComposer instance() { } @Override - protected List createClassImplements(TypeStore typeStore) { + protected List createClassImplements(TypeStore typeStore, Service service) { return Arrays.asList(getTransportContext().stubCallableFactoryType()); } - protected List createClassMethods(TypeStore typeStore) { - List classMethods = new ArrayList<>(super.createClassMethods(typeStore)); + @Override + protected List createClassMethods(Service service, TypeStore typeStore) { + List classMethods = + new ArrayList<>(super.createClassMethods(service, typeStore)); classMethods.addAll( Arrays.asList( - createBidiStreamingCallableMethod(typeStore), - createServerStreamingCallableMethod(typeStore), - createClientStreamingCallableMethod(typeStore))); + createBidiStreamingCallableMethod(service, typeStore), + createServerStreamingCallableMethod(service, typeStore), + createClientStreamingCallableMethod(service, typeStore))); return classMethods; } - protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + @Override + protected MethodDefinition createUnaryCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -75,7 +80,8 @@ protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + @Override + protected MethodDefinition createPagedCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; String pagedResponseTemplateName = "PagedListResponseT"; @@ -83,6 +89,7 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, pagedResponseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -98,13 +105,14 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { } @Override - protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + protected MethodDefinition createOperationCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -117,12 +125,13 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - private MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createBidiStreamingCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "BidiStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -137,12 +146,14 @@ private MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) .collect(Collectors.toList())); } - private MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createServerStreamingCallableMethod( + Service service, TypeStore typeStore) { String methodVariantName = "ServerStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -157,12 +168,14 @@ private MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore .collect(Collectors.toList())); } - private MethodDefinition createClientStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createClientStreamingCallableMethod( + Service service, TypeStore typeStore) { String methodVariantName = "ClientStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, 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 f079aba780..c82de5552c 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 @@ -22,7 +22,6 @@ 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.ScopeNode; import com.google.api.generator.engine.ast.Statement; @@ -31,9 +30,10 @@ 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.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.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; @@ -52,7 +52,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 @@ -73,7 +73,7 @@ public static GrpcServiceStubClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GrpcCallSettings.class, GrpcOperationsStub.class, @@ -85,7 +85,10 @@ private static TypeStore createStaticTypes() { @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr methodDescriptorMaker = MethodInvocationExpr.builder() .setMethodName("newBuilder") @@ -189,18 +192,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) { @@ -267,9 +258,6 @@ private LambdaExpr createRequestParamsExtractorClassInstance(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() 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 2f77f6aa75..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 @@ -596,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 15b05ee765..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 @@ -96,7 +96,7 @@ public static AbstractServiceClientTestClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, LocalChannelProvider.class, @@ -143,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)); @@ -206,15 +207,12 @@ protected MethodDefinition createStartStaticServerMethod( varInitExprs.add(initServiceHelperExpr); varInitExprs.add(startServiceHelperExpr); - List body = new ArrayList<>(); - return MethodDefinition.builder() .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) .setName("startStaticServer") - .setBody(body) .setBody( varInitExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) .build(); @@ -1055,6 +1053,12 @@ protected List createStreamingRpcExceptionTestStatements( 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/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 ceba11ee62..5ace1ea0ea 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 @@ -17,23 +17,18 @@ 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.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.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 { @@ -51,7 +46,7 @@ protected ServiceStubSettingsClassComposer() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, GrpcTransportChannel.class, @@ -60,104 +55,31 @@ 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( + protected List createApiClientHeaderProviderBuilderMethods( Service service, TypeStore typeStore) { - // Create the defaultApiClientHeaderProviderBuilder method. - 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( - FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) - .setMethodName("getGrpcTokenName") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) - .setMethodName("getGrpcVersion") - .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("defaultApiClientHeaderProviderBuilder") - .setReturnExpr(returnExpr) - .build(); + return Collections.singletonList( + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultApiClientHeaderProviderBuilder", + FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName()), + "getGrpcTokenName", + "getGrpcVersion")); } @Override 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..59376001e2 --- /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.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(com.google.api.gax.httpjson.longrunning.stub.OperationsStub.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 80801e31fe..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 @@ -1192,7 +1192,6 @@ private static MethodDefinition createGetFieldValuesMapMethod( .build(); // Outer if-block. - Expr thisExpr = ValueExpr.withValue(ThisObjectValue.withType(thisClassType)); IfStatement outerIfStatement = IfStatement.builder() .setConditionExpr(fieldValuesMapNullCheckExpr) @@ -1247,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( @@ -1572,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. @@ -1647,11 +1644,9 @@ private static ClassDefinition createNestedBuilderClass( .build()); } - for (int i = 0; i < tokens.size(); i++) { - String token = tokens.get(i); - String lowerCamelTokenName = JavaStyle.toLowerCamelCase(token); + for (VariableExpr memberVarExpr : classMemberVarExprs) { VariableExpr currClassTokenVarExpr = - classMemberVarExprs.get(i).toBuilder().setExprReferenceExpr(thisExpr).build(); + memberVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build(); builderCtorBodyExprs.add( AssignmentExpr.builder() .setVariableExpr(currClassTokenVarExpr) @@ -1713,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/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index f9c4045cb9..b295cb8f83 100644 --- 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 @@ -14,16 +14,27 @@ package com.google.api.generator.gapic.composer.rest; -import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; +import com.google.api.gax.rpc.OperationCallable; +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.ConcreteReference; +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.Statement; import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.VaporReference; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; 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 com.google.longrunning.Operation; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -33,10 +44,8 @@ public class HttpJsonServiceCallableFactoryClassComposer private static final HttpJsonServiceCallableFactoryClassComposer INSTANCE = new HttpJsonServiceCallableFactoryClassComposer(); - private static final TypeNode MESSAGE_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(ApiMessage.class)); - private static final TypeNode BACKGROUND_RESOURCE_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(BackgroundResource.class)); + private static final TypeNode DEFAULT_OPERATION_TYPE = + TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); private HttpJsonServiceCallableFactoryClassComposer() { super(RestContext.instance()); @@ -61,22 +70,29 @@ protected List createClassAnnotations(Service service, TypeStore } @Override - protected List createClassImplements(TypeStore typeStore) { + protected List createClassImplements(TypeStore typeStore, Service service) { + TypeNode operationsStubType = getOperationsStubType(service); + + TypeNode operationType = service.operationType(); + if (operationType == null) { + operationType = DEFAULT_OPERATION_TYPE; + } + return Arrays.asList( TypeNode.withReference( getTransportContext() .stubCallableFactoryType() .reference() .copyAndSetGenerics( - Arrays.asList( - MESSAGE_TYPE.reference(), BACKGROUND_RESOURCE_TYPE.reference())))); + Arrays.asList(operationType.reference(), operationsStubType.reference())))); } @Override - protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + protected MethodDefinition createOperationCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); @@ -90,20 +106,148 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { "The surface for long-running operations is not stable yet and may change in the" + " future."); + // Generate generic method without the body + TypeNode operationType = service.operationType(); + if (operationType == null) { + operationType = DEFAULT_OPERATION_TYPE; + } MethodDefinition method = createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, /*returnCallableTemplateNames=*/ methodTemplateNames, /*methodVariantName=*/ methodVariantName, /*httpJsonCallSettingsTemplateObjects=*/ Arrays.asList( - requestTemplateName, MESSAGE_TYPE), + requestTemplateName, operationType), /*callSettingsVariantName=*/ methodVariantName, /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() .map(n -> (Object) n) .collect(Collectors.toList()), Arrays.asList(betaAnnotation)); - return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + + List createOperationCallableBody = new ArrayList<>(); + List arguments = new ArrayList<>(method.arguments()); + + Variable httpJsonCallSettingsVar = arguments.get(0).variable(); + Variable operationCallSettingsVar = arguments.get(1).variable(); + Variable clientContextVar = arguments.get(2).variable(); + Variable operationsStubVar = arguments.get(3).variable(); + // Generate innerCallable + VariableExpr innerCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("innerCallable") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + .build(); + MethodInvocationExpr getInitialCallSettingsExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(operationCallSettingsVar)) + .setMethodName("getInitialCallSettings") + .build(); + MethodInvocationExpr createBaseUnaryCallableExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createBaseUnaryCallable") + .setArguments( + VariableExpr.withVariable(httpJsonCallSettingsVar), + getInitialCallSettingsExpr, + VariableExpr.withVariable(clientContextVar)) + .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build(); + AssignmentExpr innerCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(innerCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(createBaseUnaryCallableExpr) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(innerCallableAssignExpr)); + + // This is a temporary solution + VaporReference requestT = + VaporReference.builder() + .setName("RequestT") + .setPakkage(service.pakkage() + ".stub") + .build(); + + TypeNode initialCallableType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonOperationSnapshotCallable.class) + .setGenerics(requestT, operationType.reference()) + .build()); + + // Generate initialCallable + VariableExpr initialCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("initialCallable") + .setType( + initialCallableType) // TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + // .setTemplateObjects(Arrays.asList(requestTemplateName, "OperationSnapshot")) + .build(); + MethodInvocationExpr getMethodDescriptorExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(httpJsonCallSettingsVar)) + .setMethodName("getMethodDescriptor") + .build(); + MethodInvocationExpr getOperationSnapshotFactoryExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getMethodDescriptorExpr) + .setMethodName("getOperationSnapshotFactory") + .build(); + + TypeNode operationSnapshotCallableType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonOperationSnapshotCallable.class) + .setGenerics(requestT, operationType.reference()) + .build()); + NewObjectExpr initialCallableObject = + NewObjectExpr.builder() + .setType(operationSnapshotCallableType) + .setIsGeneric(true) + .setArguments(innerCallableVarExpr, getOperationSnapshotFactoryExpr) + .build(); + AssignmentExpr initialCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(initialCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(initialCallableObject) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(initialCallableAssignExpr)); + + // Generate return statement + MethodInvocationExpr longRunningClient = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(operationsStubVar)) + .setMethodName("longRunningClient") + .build(); + MethodInvocationExpr createOperationCallable = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createOperationCallable") + .setArguments( + VariableExpr.withVariable(operationCallSettingsVar), + VariableExpr.withVariable(clientContextVar), + longRunningClient, + initialCallableVarExpr) + .setReturnType( + TypeNode.withReference(ConcreteReference.withClazz(OperationCallable.class))) + .build(); + + // Add body and return statement to method + return method + .toBuilder() + .setBody(createOperationCallableBody) + .setReturnExpr(createOperationCallable) + .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 index 901dceacc6..172326176d 100644 --- 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 @@ -19,10 +19,16 @@ 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.HttpJsonLongRunningClient; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; 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.httpjson.longrunning.stub.HttpJsonOperationsStub; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.LongRunningClient; +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.ConcreteReference; @@ -34,36 +40,52 @@ 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.StringObjectValue; +import com.google.api.generator.engine.ast.ThisObjectValue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.VaporReference; 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.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.Message; import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.OperationResponse; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableList; +import com.google.protobuf.TypeRegistry; 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 AbstractServiceStubClassComposer { +public class HttpJsonServiceStubClassComposer extends AbstractTransportServiceStubClassComposer { private static final HttpJsonServiceStubClassComposer INSTANCE = new HttpJsonServiceStubClassComposer(); private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); + private static final VariableExpr TYPE_REGISTRY_VAR_EXPR = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("typeRegistry") + .setType(FIXED_REST_TYPESTORE.get(TypeRegistry.class.getSimpleName())) + .build()) + .build(); protected HttpJsonServiceStubClassComposer() { super(RestContext.instance()); @@ -82,16 +104,26 @@ private static TypeStore createStaticTypes() { InternalApi.class, HashMap.class, HttpJsonCallSettings.class, + HttpJsonOperationSnapshot.class, HttpJsonStubCallableFactory.class, Map.class, ProtoMessageRequestFormatter.class, ProtoMessageResponseParser.class, - ProtoRestSerializer.class)); + ProtoRestSerializer.class, + TypeRegistry.class)); + } + + @Override + protected boolean generateOperationsStubLogic(Service service) { + return service.hasLroMethods(); } @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr expr = MethodInvocationExpr.builder() .setMethodName("newBuilder") @@ -116,6 +148,24 @@ protected Statement createMethodDescriptorVariableDecl( methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); + if (protoMethod.isOperationPollingMethod() || protoMethod.hasLro()) { + expr = + methodMaker + .apply( + "setOperationSnapshotFactory", + setOperationSnapshotFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + } + + if (protoMethod.isOperationPollingMethod()) { + expr = + methodMaker + .apply( + "setPollingRequestFactory", + setPollingRequestFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + } + expr = MethodInvocationExpr.builder() .setMethodName("build") @@ -139,8 +189,11 @@ protected Statement createMethodDescriptorVariableDecl( @Override protected List createOperationsStubGetterMethod( - VariableExpr operationsStubVarExpr) { - return Collections.emptyList(); + Service service, VariableExpr operationsStubVarExpr) { + if (!service.hasStandardLroMethods()) { + return Collections.emptyList(); + } + return super.createOperationsStubGetterMethod(service, operationsStubVarExpr); } @Override @@ -160,6 +213,13 @@ protected Expr createTransportSettingsInitExpr( .setArguments(Arrays.asList(methodDescriptorVarExpr)) .build(); + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setTypeRegistry") + .setArguments(Arrays.asList(TYPE_REGISTRY_VAR_EXPR)) + .build(); + callSettingsBuilderExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(callSettingsBuilderExpr) @@ -311,16 +371,20 @@ private List getRequestFormatterExpr(Method protoMethod) { .apply(expr); extractorVarType = TypeNode.STRING; + boolean asteriskBody = protoMethod.httpBindings().isAsteriskBody(); expr = methodMaker .apply( "setRequestBodyExtractor", Arrays.asList( - createFieldsExtractorClassInstance( + createBodyFieldsExtractorClassInstance( protoMethod, extractorVarType, - protoMethod.httpBindings().bodyParameters(), - "toBody"))) + asteriskBody + ? protoMethod.httpBindings().pathParameters() + : protoMethod.httpBindings().bodyParameters(), + "toBody", + asteriskBody))) .apply(expr); expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); @@ -351,76 +415,479 @@ private List setResponseParserExpr(Method protoMethod) { .setReturnType(protoMethod.outputType()) .build())) .apply(expr); + + expr = + methodMaker + .apply("setDefaultTypeRegistry", Arrays.asList(TYPE_REGISTRY_VAR_EXPR)) + .apply(expr); expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); return Collections.singletonList(expr); } - private Expr createFieldsExtractorClassInstance( - Method method, - TypeNode extractorReturnType, - Set httpBindingFieldNames, - String serializerMethodName) { - List bodyStatements = new ArrayList<>(); + // Generates get[camelCase(fieldName)] + private String getMethodFormat(String fieldName) { + return "get" + JavaStyle.toUpperCamelCase(fieldName); + } - Expr returnExpr = null; - VariableExpr fieldsVarExpr = null; - Expr serializerExpr = null; - if (extractorReturnType.isProtoPrimitiveType()) { - serializerExpr = + // Generates set[camelCase(fieldName)] + private String setMethodFormat(String fieldName) { + return "set" + JavaStyle.toUpperCamelCase(fieldName); + } + + // Generates: [nameVar].append(":").append([requestVar].get[FieldName]()); + private ExprStatement appendField( + VariableExpr nameVar, VariableExpr requestVar, String fieldName) { + BiFunction, Function> + methodMaker = getMethodMaker(); + ValueExpr colonValueExpr = + ValueExpr.builder().setValue(StringObjectValue.builder().setValue(":").build()).build(); + MethodInvocationExpr opNameAppendColonExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(nameVar) + .build(); + MethodInvocationExpr getField = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestVar) + .setMethodName(getMethodFormat(fieldName)) + .build(); + opNameAppendColonExpr = + methodMaker + .apply("append", Collections.singletonList(getField)) + .apply(opNameAppendColonExpr); + return ExprStatement.withExpr(opNameAppendColonExpr); + } + + // returns var.get(num); + private MethodInvocationExpr getExpr(VariableExpr var, String num) { + return MethodInvocationExpr.builder() + .setExprReferenceExpr(var) + .setMethodName("get") + .setArguments( + ValueExpr.builder() + .setValue(PrimitiveValue.builder().setValue(num).setType(TypeNode.INT).build()) + .build()) + .build(); + } + + private List setOperationSnapshotFactoryExpr( + Method protoMethod, Map messageTypes) { + + // Generate input varibles for create() + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.inputType()).setName("request").build()); + VariableExpr responseVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.outputType()).setName("response").build()); + + MethodInvocationExpr buildExpr; + List createBody = new ArrayList<>(4); + + TypeNode httpJsonOperationSnapshotType = + FIXED_REST_TYPESTORE.get(HttpJsonOperationSnapshot.class.getSimpleName()); + TypeNode operationSnapshotType = FIXED_TYPESTORE.get(OperationSnapshot.class.getSimpleName()); + + Message inputOperationMessage = + messageTypes.get(protoMethod.inputType().reference().fullName()); + Message outputOperationMessage = + messageTypes.get(protoMethod.outputType().reference().fullName()); + OperationResponse operationResponse = outputOperationMessage.operationResponse(); + + if (operationResponse == null) { + // AIP-151 LRO + // HttpJsonOperationSnapshot.create(response) + buildExpr = MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) .setMethodName("create") - .setStaticReferenceType( - FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName())) + .setArguments(responseVarExpr) + .setReturnType(operationSnapshotType) .build(); - if (httpBindingFieldNames.isEmpty()) { - returnExpr = ValueExpr.createNullExpr(); - } - } else { - fieldsVarExpr = + BiFunction, Function> + methodMaker = getMethodMaker(); + + // Generate opName + TypeNode stringBuilderType = + TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); + VariableExpr opNameVarExpr = VariableExpr.withVariable( - Variable.builder().setName("fields").setType(extractorReturnType).build()); - Expr fieldsAssignExpr = + Variable.builder().setType(stringBuilderType).setName("opName").build()); + MethodInvocationExpr getId = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.nameFieldName())) + .build(); + Expr opNameObjectExpr = + NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); + AssignmentExpr opNameAssignExpr = AssignmentExpr.builder() - .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(FIXED_REST_TYPESTORE.get(HashMap.class.getSimpleName())) - .setIsGeneric(true) - .build()) + .setVariableExpr(opNameVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(opNameObjectExpr) .build(); + createBody.add(ExprStatement.withExpr(opNameAssignExpr)); + + // Generate compound operation name + if (!protoMethod.isOperationPollingMethod()) { + // TODO: Change to ordered map + Map requestFields = inputOperationMessage.operationRequestFields(); + List fieldAnnotationNames = new ArrayList(requestFields.keySet()); + Collections.sort(fieldAnnotationNames); + for (String fieldName : fieldAnnotationNames) { + createBody.add(appendField(opNameVarExpr, requestVarExpr, requestFields.get(fieldName))); + } + } + + // Generate check for status == done + MethodInvocationExpr getStatusExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.statusFieldName())) + .build(); + + String statusTypeName = operationResponse.statusFieldTypeName(); + String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); - bodyStatements.add(ExprStatement.withExpr(fieldsAssignExpr)); - returnExpr = fieldsVarExpr; + TypeNode opType = + protoMethod.hasLro() ? protoMethod.lro().responseType() : protoMethod.outputType(); - TypeNode serializerVarType = + TypeNode statusType = TypeNode.withReference( - ConcreteReference.builder() - .setClazz(ProtoRestSerializer.class) - .setGenerics(method.inputType().reference()) + VaporReference.builder() + .setName(statusClassName) + .setPakkage(opType.reference().fullName()) + .setIsStaticImport(false) .build()); + VariableExpr statusDoneExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(TypeNode.INT).build()) + .setStaticReferenceType(statusType) + .build(); + MethodInvocationExpr statusEqualsExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(statusDoneExpr) + .setMethodName("equals") + .setArguments(getStatusExpr) + .build(); - VariableExpr serializerVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("serializer").setType(serializerVarType).build()); + // Generate return statement - 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()) + // Generate getter methods from annotations + MethodInvocationExpr opNameToStringExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(opNameVarExpr) + .setMethodName("toString") + .build(); + MethodInvocationExpr getHttpErrorStatusCodeExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.errorCodeFieldName())) + .build(); + MethodInvocationExpr getHttpErrorMessageExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.errorMessageFieldName())) + .build(); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("newBuilder") + .build(); + + newBuilderExpr = + methodMaker + .apply("setName", Collections.singletonList(opNameToStringExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setMetadata", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setDone", Collections.singletonList(statusEqualsExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setResponse", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setError", Arrays.asList(getHttpErrorStatusCodeExpr, getHttpErrorMessageExpr)) + .apply(newBuilderExpr); + + buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(operationSnapshotType) .build(); + } + // Generate lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments( + requestVarExpr.toBuilder().setIsDecl(true).build(), + responseVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + private List setPollingRequestFactoryExpr( + Method protoMethod, Map messageTypes) { + BiFunction, Function> + methodMaker = getMethodMaker(); + + Message inputOperationMessage = + messageTypes.get(protoMethod.inputType().reference().fullName()); - serializerExpr = serializerVarExpr; + List createBody = new ArrayList(1); + + // Generate input variables for create + VariableExpr compoundOperationIdVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.STRING).setName("compoundOperationId").build()) + .build(); + + // Generate idComponenets + TypeNode listStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arrayListStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arraysType = TypeNode.withReference(ConcreteReference.withClazz(Arrays.class)); + VariableExpr idComponentsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("idComponents").setType(listStringType).build()); + MethodInvocationExpr compoundOperationIdSplitExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(compoundOperationIdVarExpr) + .setMethodName("split") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue(":"))) + .setReturnType(arrayListStringType) + .build(); + MethodInvocationExpr asListExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(arraysType) + .setMethodName("asList") + .setArguments(compoundOperationIdSplitExpr) + .setReturnType(arrayListStringType) + .build(); + AssignmentExpr idComponentsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(idComponentsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(asListExpr) + .build(); + createBody.add(ExprStatement.withExpr(idComponentsAssignExpr)); - bodyStatements.add(ExprStatement.withExpr(serializerAssignExpr)); + // Generate return statement + TypeNode getOperationRequestType = TypeNode.withReference(protoMethod.inputType().reference()); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getOperationRequestType) + .setMethodName("newBuilder") + .build(); + BiMap responseFieldsMap = inputOperationMessage.operationResponseFields(); + List responseFieldAnnotationNames = new ArrayList(responseFieldsMap.keySet()); + Collections.sort(responseFieldAnnotationNames); + Set responseFieldsNames = responseFieldsMap.inverse().keySet(); + Set allFieldsNames = inputOperationMessage.fieldMap().keySet(); + ArrayList nonResponseFieldsNames = new ArrayList(); + for (String fieldName : allFieldsNames) { + if (!responseFieldsNames.contains(fieldName)) { + nonResponseFieldsNames.add(fieldName); + } + } + Collections.sort(nonResponseFieldsNames); + int index = 0; + for (String fieldAnnotationName : responseFieldAnnotationNames) { + newBuilderExpr = + methodMaker + .apply( + setMethodFormat(responseFieldsMap.get(fieldAnnotationName)), + Collections.singletonList(getExpr(idComponentsVarExpr, Integer.toString(index)))) + .apply(newBuilderExpr); + index++; } + for (String fieldName : nonResponseFieldsNames) { + newBuilderExpr = + methodMaker + .apply( + setMethodFormat(fieldName), + Collections.singletonList(getExpr(idComponentsVarExpr, Integer.toString(index)))) + .apply(newBuilderExpr); + index++; + } + + MethodInvocationExpr buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(getOperationRequestType) + .build(); + + // Return lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments(compoundOperationIdVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + 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( @@ -463,9 +930,9 @@ private Expr createFieldsExtractorClassInstance( MethodInvocationExpr requestHasExpr = requestFieldHasExprBuilder.build(); ImmutableList.Builder paramsPutArgs = ImmutableList.builder(); - if (fieldsVarExpr != null) { - paramsPutArgs.add(fieldsVarExpr); - } + + paramsPutArgs.add(fieldsVarExpr); + paramsPutArgs.add( ValueExpr.withValue( StringObjectValue.withValue( @@ -474,24 +941,20 @@ private Expr createFieldsExtractorClassInstance( Expr paramsPutExpr = MethodInvocationExpr.builder() - .setExprReferenceExpr(serializerExpr) + .setExprReferenceExpr(serializerVarExpr) .setMethodName(serializerMethodName) .setArguments(paramsPutArgs.build()) .setReturnType(extractorReturnType) .build(); - if (fieldsVarExpr == null) { - returnExpr = paramsPutExpr; + if (httpBindingFieldName.isOptional()) { + bodyStatements.add( + IfStatement.builder() + .setConditionExpr(requestHasExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(paramsPutExpr))) + .build()); } else { - if (httpBindingFieldName.isOptional()) { - bodyStatements.add( - IfStatement.builder() - .setConditionExpr(requestHasExpr) - .setBody(Arrays.asList(ExprStatement.withExpr(paramsPutExpr))) - .build()); - } else { - bodyStatements.add(ExprStatement.withExpr(paramsPutExpr)); - } + bodyStatements.add(ExprStatement.withExpr(paramsPutExpr)); } } @@ -500,7 +963,7 @@ private Expr createFieldsExtractorClassInstance( return LambdaExpr.builder() .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) .setBody(bodyStatements) - .setReturnExpr(returnExpr) + .setReturnExpr(fieldsVarExpr) .build(); } @@ -514,4 +977,197 @@ private List getHttpMethodTypeExpr(Method protoMethod) { .build(); return Collections.singletonList(expr); } + + @Override + protected List createOperationsStubInitExpr( + Service service, + Expr thisExpr, + VariableExpr operationsStubClassVarExpr, + VariableExpr clientContextVarExpr, + VariableExpr callableFactoryVarExpr) { + TypeNode opeationsStubType = getTransportOperationsStubType(service); + String standardOpStub = HttpJsonOperationsStub.class.getName(); + + List arguments = + new ArrayList<>(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)); + if (standardOpStub.equals(opeationsStubType.reference().fullName())) { + arguments.add(TYPE_REGISTRY_VAR_EXPR); + } + + return Collections.singletonList( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(opeationsStubType) + .setMethodName("create") + .setArguments(arguments) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } + + @Override + protected List createLongRunningClient(Service service, TypeStore typeStore) { + Method pollingMethod = service.operationPollingMethod(); + if (pollingMethod != null) { + Expr thisExpr = + ValueExpr.withValue( + ThisObjectValue.withType( + typeStore.get( + getTransportContext() + .classNames() + .getTransportServiceStubClassName(service)))); + + VariableExpr callable = + VariableExpr.withVariable( + Variable.builder() + .setName(pollingMethod.name().toLowerCase() + "Callable") + .setType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()); + VariableExpr methodDescriptor = + VariableExpr.withVariable( + Variable.builder() + .setName(pollingMethod.name().toLowerCase() + "MethodDescriptor") + .setType( + TypeNode.withReference( + ConcreteReference.withClazz(ApiMethodDescriptor.class))) + .build()); + + TypeNode httpJsonLongRunningClientType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonLongRunningClient.class) + .setGenerics( + Arrays.asList( + pollingMethod.inputType().reference(), + pollingMethod.outputType().reference())) + .build()); + + NewObjectExpr HttpJsonLongRunningClient = + NewObjectExpr.builder() + .setType(httpJsonLongRunningClientType) + .setArguments( + Arrays.asList( + callable, + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptor) + .setMethodName("getOperationSnapshotFactory") + .build(), + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptor) + .setMethodName("getPollingRequestFactory") + .build())) + .build(); + + AssignmentExpr assignLongRunningClient = + AssignmentExpr.builder() + .setVariableExpr( + VariableExpr.builder() + .setExprReferenceExpr(thisExpr) + .setVariable( + Variable.builder() + .setName("longRunningClient") + .setType( + TypeNode.withReference( + ConcreteReference.withClazz(LongRunningClient.class))) + .build()) + .build()) + .setValueExpr(HttpJsonLongRunningClient) + .build(); + + return Arrays.asList(ExprStatement.withExpr(assignLongRunningClient)); + } else { + return Collections.emptyList(); + } + } + + @Override + protected VariableExpr declareLongRunningClient() { + return VariableExpr.withVariable( + Variable.builder() + .setName("longRunningClient") + .setType(TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .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")) { + 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)); + } + + @Override + protected List createTypeRegistry(Service service) { + TypeNode typeRegistryType = FIXED_REST_TYPESTORE.get(TypeRegistry.class.getSimpleName()); + + VariableExpr typeRegistryVarExpr = + TYPE_REGISTRY_VAR_EXPR + .toBuilder() + .setIsDecl(true) + .setIsStatic(true) + .setScope(ScopeNode.PRIVATE) + .setIsFinal(true) + .build(); + + Map anyTypes = new HashMap<>(); + for (Method method : service.methods()) { + if (method.hasLro()) { + TypeNode anyType = method.lro().responseType(); + anyTypes.put(anyType.reference().fullName(), anyType); + anyType = method.lro().metadataType(); + anyTypes.put(anyType.reference().fullName(), anyType); + } + } + + Expr typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(typeRegistryType) + .setMethodName("newBuilder") + .build(); + + for (TypeNode anyType : anyTypes.values()) { + typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(typeRegistryBuilderExpr) + .setMethodName("add") + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType(anyType) + .setMethodName("getDescriptor") + .build()) + .build(); + } + + typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(typeRegistryBuilderExpr) + .setMethodName("build") + .setReturnType(typeRegistryType) + .build(); + + return Collections.singletonList( + ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr(typeRegistryVarExpr) + .setValueExpr(typeRegistryBuilderExpr) + .build())); + } } 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 index fc5b385427..2502a9128e 100644 --- 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 @@ -14,16 +14,20 @@ 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.gax.httpjson.longrunning.stub.OperationsStub; 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 = @@ -35,18 +39,35 @@ public abstract class RestContext extends TransportContext { .setCallSettingsClass(HttpJsonCallSettings.class) .setStubCallableFactoryType(classToType(HttpJsonStubCallableFactory.class)) .setMethodDescriptorClass(ApiMethodDescriptor.class) - .setTransportOperationsStubType(null) + .setTransportOperationsStubTypes( + ImmutableList.of(classToType(HttpJsonOperationsStub.class))) + .setTransportOperationsStubNames(ImmutableList.of("httpJsonOperationsStub")) // For httpjson.ServiceSettingsClassComposer - .setInstantiatingChannelProviderClass(InstantiatingHttpJsonChannelProvider.Builder.class) - .setDefaultTransportProviderBuilderName("defaultHttpJsonTransportProviderBuilder") + .setInstantiatingChannelProviderClasses( + ImmutableList.of(InstantiatingHttpJsonChannelProvider.class)) + .setInstantiatingChannelProviderBuilderClasses( + ImmutableList.of(InstantiatingHttpJsonChannelProvider.Builder.class)) + .setDefaultTransportProviderBuilderNames( + ImmutableList.of("defaultHttpJsonTransportProviderBuilder")) + .setTransportApiClientHeaderProviderBuilderNames( + ImmutableList.of("defaultHttpJsonApiClientHeaderProviderBuilder")) // For httpjson.ServiceStubSettingsClassComposer - .setTransportChannelType(classToType(HttpJsonTransportChannel.class)) - .setTransportGetterName("getHttpJsonTransportName") + .setTransportChannelTypes(ImmutableList.of(classToType(HttpJsonTransportChannel.class))) + .setTransportGetterNames(ImmutableList.of("getHttpJsonTransportName")) // For httpjson.HttpJsonServiceCallableFactoryClassComposer .setTransportCallSettingsType(classToType(HttpJsonCallSettings.class)) .setTransportCallableFactoryType(classToType(HttpJsonCallableFactory.class)) - .setOperationsStubType(classToType(BackgroundResource.class)) + // TODO: set to com.google.api.gax.httpjson.longrunning.stub.OperationsStub.class + .setOperationsStubTypes(ImmutableList.of(classToType(OperationsStub.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() { 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 index 5eed17f8f2..9df088bbd7 100644 --- 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 @@ -39,6 +39,7 @@ 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; @@ -61,7 +62,6 @@ public class ServiceClientTestClassComposer extends AbstractServiceClientTestClassComposer { private static final String MOCK_SERVICE_VAR_NAME = "mockService"; - private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; private static final ServiceClientTestClassComposer INSTANCE = new ServiceClientTestClassComposer(); @@ -72,7 +72,7 @@ protected ServiceClientTestClassComposer() { super(RestContext.instance()); } - public static ServiceClientTestClassComposer instance() { + public static AbstractServiceClientTestClassComposer instance() { return INSTANCE; } @@ -125,7 +125,8 @@ protected MethodDefinition createStartStaticServerMethod( Service service, GapicContext context, Map classMemberVarExprs, - TypeStore typeStore) { + TypeStore typeStore, + String newBuilderMethod) { VariableExpr mockServiceVarExpr = classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME); VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); @@ -167,7 +168,7 @@ protected MethodDefinition createStartStaticServerMethod( Expr settingsBuilderExpr = MethodInvocationExpr.builder() .setStaticReferenceType(settingsType) - .setMethodName("newBuilder") + .setMethodName(newBuilderMethod) .build(); Expr transportChannelProviderExpr = @@ -420,7 +421,18 @@ protected MethodDefinition createStreamingRpcTestMethod( Map classMemberVarExprs, Map resourceNames, Map messageTypes) { - return null; + // 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 @@ -513,6 +525,12 @@ protected List createStreamingRpcExceptionTestStatements( 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) { 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 index 9375399546..b12528ec3f 100644 --- 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 @@ -17,23 +17,16 @@ 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.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.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; 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.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 = @@ -58,94 +51,16 @@ private static TypeStore createStaticTypes() { } @Override - protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() { - // Create the defaultHttpJsonTransportProviderBuilder method. - TypeNode returnType = - TypeNode.withReference( - ConcreteReference.withClazz(InstantiatingHttpJsonChannelProvider.Builder.class)); - MethodInvocationExpr transportChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_REST_TYPESTORE.get( - InstantiatingHttpJsonChannelProvider.class.getSimpleName())) - .setMethodName("newBuilder") - .setReturnType(returnType) - .build(); - return MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultHttpJsonTransportProviderBuilder") - .setReturnExpr(transportChannelProviderBuilderExpr) - .build(); - } - - @Override - protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + protected List createApiClientHeaderProviderBuilderMethods( Service service, TypeStore typeStore) { - // Create the defaultApiClientHeaderProviderBuilder method. - 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( - FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName())) - .setMethodName("getHttpJsonTokenName") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType( - FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName())) - .setMethodName("getHttpJsonVersion") - .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("defaultApiClientHeaderProviderBuilder") - .setReturnExpr(returnExpr) - .build(); + return Collections.singletonList( + createApiClientHeaderProviderBuilderMethod( + service, + typeStore, + "defaultApiClientHeaderProviderBuilder", + FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName()), + "getHttpJsonTokenName", + "getHttpJsonVersion")); } @Override 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 ac8d805b59..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 @@ -1310,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()); } 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 1a6c2e1c13..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,11 +28,11 @@ public class TypeStore { public TypeStore() {} - public TypeStore(List concreteClasses) { + public TypeStore(List> concreteClasses) { putConcreteClassses(concreteClasses); } - private void putConcreteClassses(List concreteClasses) { + private void putConcreteClassses(List> concreteClasses) { store.putAll( concreteClasses.stream() .collect( @@ -71,7 +71,7 @@ public void put( .build())); } - public void putAll(List concreteClasses) { + public void putAll(List> concreteClasses) { putConcreteClassses(concreteClasses); } 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/HttpBindings.java b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java index 9ca67cf4c7..171f6b1bf7 100644 --- a/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java +++ b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java @@ -57,6 +57,8 @@ public int compareTo(HttpBinding o) { public abstract Set bodyParameters(); + public abstract boolean isAsteriskBody(); + public static HttpBindings.Builder builder() { return new AutoValue_HttpBindings.Builder() .setPathParameters(ImmutableSet.of()) @@ -93,6 +95,8 @@ public abstract static class Builder { public abstract HttpBindings.Builder setBodyParameters(Set bodyParameters); + public abstract HttpBindings.Builder setIsAsteriskBody(boolean asteriskBody); + public abstract HttpBindings autoBuild(); public HttpBindings build() { diff --git a/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java b/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java index c2b425e2f8..e23e8a6ee3 100644 --- a/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java +++ b/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java @@ -16,6 +16,7 @@ import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; @AutoValue public abstract class LongrunningOperation { @@ -23,22 +24,21 @@ public abstract class LongrunningOperation { public abstract TypeNode metadataType(); - public static LongrunningOperation withTypes(TypeNode responseType, TypeNode metadataType) { - return builder().setResponseType(responseType).setMetadataType(metadataType).build(); - } + @Nullable + public abstract TypeNode operationServiceStubType(); - // Private. - static Builder builder() { + public static Builder builder() { return new AutoValue_LongrunningOperation.Builder(); } - // Private. @AutoValue.Builder - abstract static class Builder { - abstract Builder setResponseType(TypeNode responseType); + public abstract static class Builder { + public abstract Builder setResponseType(TypeNode responseType); + + public abstract Builder setMetadataType(TypeNode metadataType); - abstract Builder setMetadataType(TypeNode metadataType); + public abstract Builder setOperationServiceStubType(TypeNode operationServiceType); - abstract LongrunningOperation build(); + public abstract LongrunningOperation build(); } } 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 c58e62582e..91a5388e37 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 @@ -18,6 +18,8 @@ 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.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.Arrays; @@ -51,6 +53,13 @@ public abstract class Message { public abstract ImmutableMap fieldMap(); + @Nullable + public abstract OperationResponse operationResponse(); + + public abstract Map operationRequestFields(); + + public abstract BiMap operationResponseFields(); + // The resource name annotation (and definition) in this message. Optional. // Expected dto be empty for messages that have no such definition. @Nullable @@ -103,7 +112,9 @@ public static Builder builder() { .setOuterNestedTypes(Collections.emptyList()) .setFields(Collections.emptyList()) .setFieldMap(Collections.emptyMap()) - .setEnumValues(Collections.emptyMap()); + .setEnumValues(Collections.emptyMap()) + .setOperationResponseFields(HashBiMap.create()) + .setOperationRequestFields(Collections.emptyMap()); } @AutoValue.Builder @@ -129,6 +140,13 @@ public Builder setEnumValues(List names, List numbers) { public abstract Builder setOuterNestedTypes(List outerNestedTypes); + public abstract Builder setOperationResponse(OperationResponse operationResponse); + + public abstract Builder setOperationRequestFields(Map operationRequestFields); + + public abstract Builder setOperationResponseFields( + BiMap operationRequestFields); + abstract Builder setFieldMap(Map fieldMap); abstract ImmutableList fields(); 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 56a1403098..286bd8c84e 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 @@ -66,6 +66,8 @@ public boolean isPaged() { // [["content", "error"], ["content", "error", "info"]]. public abstract ImmutableList> methodSignatures(); + public abstract boolean operationPollingMethod(); + public boolean hasLro() { return lro() != null; } @@ -82,6 +84,10 @@ public boolean isMixin() { return mixedInApiName() != null; } + public boolean isOperationPollingMethod() { + return operationPollingMethod(); + } + public abstract Builder toBuilder(); public static Builder builder() { @@ -89,7 +95,8 @@ public static Builder builder() { .setStream(Stream.NONE) .setMethodSignatures(ImmutableList.of()) .setIsBatching(false) - .setIsDeprecated(false); + .setIsDeprecated(false) + .setOperationPollingMethod(false); } public static Stream toStream(boolean isClientStreaming, boolean isServerStreaming) { @@ -131,6 +138,8 @@ public abstract static class Builder { public abstract Builder setIsDeprecated(boolean isDeprecated); + public abstract Builder setOperationPollingMethod(boolean operationPollingMethod); + public abstract Method build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java new file mode 100644 index 0000000000..9ad5ac385f --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java @@ -0,0 +1,50 @@ +/* + * 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.model; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class OperationResponse { + public abstract String nameFieldName(); + + public abstract String statusFieldName(); + + public abstract String errorCodeFieldName(); + + public abstract String errorMessageFieldName(); + + public abstract String statusFieldTypeName(); + + public static Builder builder() { + return new AutoValue_OperationResponse.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setNameFieldName(String nameFieldName); + + public abstract Builder setStatusFieldName(String val); + + public abstract Builder setErrorCodeFieldName(String val); + + public abstract Builder setErrorMessageFieldName(String val); + + public abstract Builder setStatusFieldTypeName(String className); + + public abstract OperationResponse build(); + } +} 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..34d3f97b25 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 @@ -14,6 +14,7 @@ package com.google.api.generator.gapic.model; +import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; @@ -49,6 +50,53 @@ public boolean hasDescription() { return !Strings.isNullOrEmpty(description()); } + public Method operationPollingMethod() { + for (Method method : methods()) { + if (method.isOperationPollingMethod()) { + return method; + } + } + return null; + } + + public TypeNode operationServiceStubType() { + for (Method method : methods()) { + if (method.hasLro() && method.lro().operationServiceStubType() != null) { + // All methods within the same service must have the same operationServiceTypeName if + // present + return method.lro().operationServiceStubType(); + } + } + return null; + } + + public TypeNode operationType() { + for (Method method : methods()) { + if (method.hasLro() && method.lro().operationServiceStubType() != null) { + return method.outputType(); + } + } + return null; + } + + public boolean hasLroMethods() { + for (Method method : methods()) { + if (method.hasLro()) { + return true; + } + } + return false; + } + + public boolean hasStandardLroMethods() { + for (Method method : methods()) { + if (method.hasLro() && method.lro().operationServiceStubType() == null) { + 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/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel index 6cccdd373a..904b7fbf2b 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel @@ -30,6 +30,7 @@ java_library( "@com_google_code_findbugs_jsr305//jar", "@com_google_code_gson//jar", "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/cloud:extended_operations_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/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 26629949ef..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 @@ -104,6 +104,7 @@ private static HttpBindings parseHttpRuleHelper( validateAndConstructHttpBindings(queryParamNames, message, messageTypes, false)) .setBodyParameters( validateAndConstructHttpBindings(bodyParamNames, message, messageTypes, false)) + .setIsAsteriskBody(body.equals(ASTERISK)) .build(); } 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 42e2abaa2f..0338de6374 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 @@ -20,6 +20,7 @@ import com.google.api.ResourceDescriptor; import com.google.api.ResourceProto; 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.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; @@ -30,15 +31,20 @@ import com.google.api.generator.gapic.model.LongrunningOperation; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.OperationResponse; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.ResourceReference; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.utils.ResourceNameConstants; +import com.google.cloud.ExtendedOperationsProto; +import com.google.cloud.OperationResponseMapping; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.longrunning.OperationInfo; @@ -115,8 +121,8 @@ public static GapicContext parse(CodeGeneratorRequest 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); @@ -128,9 +134,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<>(); @@ -171,7 +175,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { Function typeNameFn = r -> r.resourceTypeString().substring(r.resourceTypeString().indexOf("/") + 1); Function, Set> typeStringSetFn = - sr -> sr.stream().map(r -> typeNameFn.apply(r)).collect(Collectors.toSet()); + 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. @@ -202,9 +206,9 @@ 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) + .setServiceYamlProto(serviceYamlProtoOpt.orElse(null)) .setTransport(transport) .build(); } @@ -378,7 +382,7 @@ public static List parseServices( outputMixinServices.addAll( outputMixinServiceSet.stream() .sorted((s1, s2) -> s2.name().compareTo(s1.name())) - .collect(Collectors.toSet())); + .collect(Collectors.toList())); return services; } @@ -533,7 +537,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( @@ -554,6 +558,38 @@ private static Map parseMessages( } } TypeNode messageType = TypeParser.parseType(messageDescriptor); + + List fields = messageDescriptor.getFields(); + HashMap operationRequestFields = new HashMap(); + BiMap operationResponseFields = HashBiMap.create(); + OperationResponse.Builder operationResponse = null; + for (FieldDescriptor fd : fields) { + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationRequestField)) { + String orf = fd.getOptions().getExtension(ExtendedOperationsProto.operationRequestField); + operationRequestFields.put(orf, fd.getName()); + } + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationResponseField)) { + String orf = fd.getOptions().getExtension(ExtendedOperationsProto.operationResponseField); + operationResponseFields.put(orf, fd.getName()); + } + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationField)) { + OperationResponseMapping orm = + fd.getOptions().getExtension(ExtendedOperationsProto.operationField); + if (operationResponse == null) { + operationResponse = OperationResponse.builder(); + } + if (orm.equals(OperationResponseMapping.NAME)) { + operationResponse.setNameFieldName(fd.getName()); + } else if (orm.equals(OperationResponseMapping.STATUS)) { + operationResponse.setStatusFieldName(fd.getName()); + operationResponse.setStatusFieldTypeName(fd.toProto().getTypeName()); + } else if (orm.equals(OperationResponseMapping.ERROR_CODE)) { + operationResponse.setErrorCodeFieldName(fd.getName()); + } else if (orm.equals(OperationResponseMapping.ERROR_MESSAGE)) { + operationResponse.setErrorMessageFieldName(fd.getName()); + } + } + } messages.put( messageType.reference().fullName(), Message.builder() @@ -562,6 +598,9 @@ private static Map parseMessages( .setFullProtoName(messageDescriptor.getFullName()) .setFields(parseFields(messageDescriptor, outputResourceReferencesSeen)) .setOuterNestedTypes(outerNestedTypes) + .setOperationRequestFields(operationRequestFields) + .setOperationResponseFields(operationResponseFields) + .setOperationResponse(operationResponse != null ? operationResponse.build() : null) .build()); return messages; } @@ -664,6 +703,12 @@ static List parseMethods( serviceDescriptor.getName(), protoMethod.getName()); + boolean operationPollingMethod = + protoMethod.getOptions().hasExtension(ExtendedOperationsProto.operationPollingMethod) + ? protoMethod + .getOptions() + .getExtension(ExtendedOperationsProto.operationPollingMethod) + : false; methods.add( methodBuilder .setName(protoMethod.getName()) @@ -671,7 +716,7 @@ static List parseMethods( .setOutputType(TypeParser.parseType(protoMethod.getOutputType())) .setStream( Method.toStream(protoMethod.isClientStreaming(), protoMethod.isServerStreaming())) - .setLro(parseLro(protoMethod, messageTypes)) + .setLro(parseLro(servicePackage, protoMethod, messageTypes)) .setMethodSignatures( MethodSignatureParser.parseMethodSignatures( protoMethod, @@ -684,6 +729,7 @@ static List parseMethods( .setIsBatching(isBatching) .setPageSizeFieldName(parsePageSizeFieldName(protoMethod, messageTypes, transport)) .setIsDeprecated(isDeprecated) + .setOperationPollingMethod(operationPollingMethod) .build()); // Any input type that has a resource reference will need a resource name helper class. @@ -725,18 +771,43 @@ static List parseMethods( @VisibleForTesting static LongrunningOperation parseLro( - MethodDescriptor methodDescriptor, Map messageTypes) { + String servicePackage, MethodDescriptor methodDescriptor, Map messageTypes) { MethodOptions methodOptions = methodDescriptor.getOptions(); - if (!methodOptions.hasExtension(OperationsProto.operationInfo)) { - return null; + + TypeNode operationServiceStubType = null; + String responseTypeName = null; + String metadataTypeName = null; + + if (methodOptions.hasExtension(OperationsProto.operationInfo)) { + OperationInfo lroInfo = + methodDescriptor.getOptions().getExtension(OperationsProto.operationInfo); + responseTypeName = lroInfo.getResponseType(); + metadataTypeName = lroInfo.getMetadataType(); + } + if (methodOptions.hasExtension(ExtendedOperationsProto.operationService)) { + // TODO: support full package name for operations_service annotation value + String opServiceName = methodOptions.getExtension(ExtendedOperationsProto.operationService); + operationServiceStubType = + TypeNode.withReference( + VaporReference.builder() + .setName(opServiceName + "Stub") + .setPakkage(servicePackage + ".stub") + .build()); + + if (responseTypeName == null) { + responseTypeName = methodDescriptor.getOutputType().getFullName(); + } + if (metadataTypeName == null) { + metadataTypeName = methodDescriptor.getOutputType().getFullName(); + } } - OperationInfo lroInfo = - methodDescriptor.getOptions().getExtension(OperationsProto.operationInfo); + if (responseTypeName == null || metadataTypeName == null) { + return null; + } - // These can be short names (e.g. FooMessage) or fully-qualified names with the *proto* package. - String responseTypeName = lroInfo.getResponseType(); - String metadataTypeName = lroInfo.getMetadataType(); + Message responseMessage = null; + Message metadataMessage = null; int lastDotIndex = responseTypeName.lastIndexOf('.'); boolean isResponseTypeNameShortOnly = lastDotIndex < 0; @@ -748,9 +819,6 @@ static LongrunningOperation parseLro( String metadataTypeShortName = lastDotIndex >= 0 ? metadataTypeName.substring(lastDotIndex + 1) : metadataTypeName; - Message responseMessage = null; - Message metadataMessage = null; - // The messageTypes map keys to the Java fully-qualified name. for (Map.Entry messageEntry : messageTypes.entrySet()) { String messageKey = messageEntry.getKey(); @@ -793,7 +861,11 @@ static LongrunningOperation parseLro( "LRO metadata message %s not found in method %s", metadataTypeName, methodDescriptor.getName())); - return LongrunningOperation.withTypes(responseMessage.type(), metadataMessage.type()); + return LongrunningOperation.builder() + .setResponseType(responseMessage.type()) + .setMetadataType(metadataMessage.type()) + .setOperationServiceStubType(operationServiceStubType) + .build(); } @VisibleForTesting @@ -829,7 +901,7 @@ static String parsePageSizeFieldName( @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; } 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 6f1e80ca70..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)) 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 7bc1589feb..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,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 org.junit.Test; 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 f19722f182..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,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 java.util.Arrays; @@ -86,11 +86,6 @@ public void validTryCatchStatement_withResources() { @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()))) @@ -101,18 +96,12 @@ public void validTryCatchStatement_sampleCode() { @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( IllegalStateException.class, - () -> { - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .build()); } @Test @@ -124,13 +113,11 @@ public void invalidTryCatchStatement_catchVariableNotDecl() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .addCatch(variableExpr, Collections.emptyList()) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(variableExpr, Collections.emptyList()) + .build()); } @Test @@ -142,13 +129,11 @@ public void invalidTryCatchStatement_nonExceptionReference() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .addCatch(variableExpr, Collections.emptyList()) - .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 6b9d20ff0b..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; @@ -894,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 902f3ee4a8..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; @@ -334,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() @@ -349,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() @@ -366,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() @@ -644,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(); @@ -1579,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( 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 40de9b259f..5c5f8983ad 100644 --- a/src/test/java/com/google/api/generator/gapic/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/BUILD.bazel @@ -6,6 +6,7 @@ filegroup( "//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", 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 159c97d9b1..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 + [ 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 fd4d5942a4..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; 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 f612b7112d..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; 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 14ac8deeba..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", ] 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 89% 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 b7767f41a6..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,7 +55,7 @@ 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); @@ -68,7 +68,7 @@ public void generateServiceClasses_methodSignatureHasNestedFields() { @Test public void generateServiceClasses_bookshopNameConflicts() { - GapicContext context = TestProtoLoader.instance().parseBookshopService(); + GapicContext context = GrpcTestProtoLoader.instance().parseBookshopService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); 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 d2c1a50708..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,7 +15,7 @@ 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.model.GapicClass; 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 b319bf8b50..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; diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BookshopClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/BookshopClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden 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/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 ddfdcde395..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 @@ -120,7 +120,9 @@ public class DeprecatedServiceStubSettings 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. */ 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 100% 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 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 1de81fd223..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 @@ -440,7 +440,9 @@ public class LoggingServiceV2StubSettings 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. */ 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 7f4117a0b5..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,7 +15,7 @@ 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; @@ -23,7 +23,6 @@ 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; @@ -96,9 +95,8 @@ 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); @@ -140,13 +138,8 @@ 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"); @@ -173,13 +166,8 @@ 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); @@ -204,13 +192,8 @@ 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); 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 44ea5579bf..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,7 +15,7 @@ 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.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; 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 index c2e8ab8726..13ef1cea69 100644 --- 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 @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.rest; -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.composer.common.TestProtoLoader; import com.google.api.generator.gapic.model.GapicContext; 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 index e3e5641f93..53392a549e 100644 --- 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 @@ -27,7 +27,7 @@ public class ServiceStubSettingsClassComposerTest { @Test public void generateServiceStubSettingsClasses_basic() { - GapicContext context = RestTestProtoLoader.instance().parseShowcaseEcho(); + GapicContext context = RestTestProtoLoader.instance().parseCompliance(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceStubSettingsClassComposer.instance().generate(context, echoProtoService); 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 index 3535651104..fe74c48c98 100644 --- 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 @@ -1,60 +1,33 @@ package com.google.showcase.v1beta1.stub; -import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; -import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; - 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.grpc.ProtoOperationTransformers; 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.longrunning.OperationSnapshot; -import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; 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.OperationCallSettings; -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.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.api.gax.rpc.UnaryCallable; 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.longrunning.Operation; -import com.google.showcase.v1beta1.BlockRequest; -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; -import com.google.showcase.v1beta1.WaitRequest; -import com.google.showcase.v1beta1.WaitResponse; +import com.google.showcase.v1beta1.RepeatRequest; +import com.google.showcase.v1beta1.RepeatResponse; 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 EchoStub}. + * Settings class to configure an instance of {@link ComplianceStub}. * *

The default instance has everything set to sensible defaults: * @@ -67,214 +40,73 @@ import org.threeten.bp.Duration; *

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 echo to 30 seconds: + *

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

{@code
- * EchoStubSettings.Builder echoSettingsBuilder = EchoStubSettings.newBuilder();
- * echoSettingsBuilder
- *     .echoSettings()
+ * ComplianceStubSettings.Builder complianceSettingsBuilder = ComplianceStubSettings.newBuilder();
+ * complianceSettingsBuilder
+ *     .repeatDataBodySettings()
  *     .setRetrySettings(
- *         echoSettingsBuilder
- *             .echoSettings()
+ *         complianceSettingsBuilder
+ *             .repeatDataBodySettings()
  *             .getRetrySettings()
  *             .toBuilder()
  *             .setTotalTimeout(Duration.ofSeconds(30))
  *             .build());
- * EchoStubSettings echoSettings = echoSettingsBuilder.build();
+ * ComplianceStubSettings complianceSettings = complianceSettingsBuilder.build();
  * }
*/ @BetaApi @Generated("by gapic-generator-java") -public class EchoStubSettings extends StubSettings { +public class ComplianceStubSettings 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").build(); - - private final UnaryCallSettings echoSettings; - private final ServerStreamingCallSettings expandSettings; - private final StreamingCallSettings collectSettings; - private final StreamingCallSettings chatSettings; - private final StreamingCallSettings chatAgainSettings; - private final PagedCallSettings - pagedExpandSettings; - private final PagedCallSettings< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings; - private final UnaryCallSettings waitSettings; - private final OperationCallSettings - waitOperationSettings; - private final UnaryCallSettings blockSettings; - private final UnaryCallSettings collideNameSettings; - - private static final PagedListDescriptor - PAGED_EXPAND_PAGE_STR_DESC = - new PagedListDescriptor() { - @Override - public String emptyToken() { - return ""; - } - - @Override - public PagedExpandRequest injectToken(PagedExpandRequest payload, String token) { - return PagedExpandRequest.newBuilder(payload).setPageToken(token).build(); - } - - @Override - public PagedExpandRequest injectPageSize(PagedExpandRequest payload, int pageSize) { - return PagedExpandRequest.newBuilder(payload).setPageSize(pageSize).build(); - } - - @Override - public Integer extractPageSize(PagedExpandRequest payload) { - return payload.getPageSize(); - } - - @Override - public String extractNextToken(PagedExpandResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(PagedExpandResponse payload) { - return payload.getResponsesList() == null - ? ImmutableList.of() - : payload.getResponsesList(); - } - }; - - private static final PagedListDescriptor - SIMPLE_PAGED_EXPAND_PAGE_STR_DESC = - new PagedListDescriptor() { - @Override - public String emptyToken() { - return ""; - } - - @Override - public PagedExpandRequest injectToken(PagedExpandRequest payload, String token) { - return PagedExpandRequest.newBuilder(payload).setPageToken(token).build(); - } - - @Override - public PagedExpandRequest injectPageSize(PagedExpandRequest payload, int pageSize) { - return PagedExpandRequest.newBuilder(payload).setPageSize(pageSize).build(); - } - - @Override - public Integer extractPageSize(PagedExpandRequest payload) { - return payload.getPageSize(); - } - - @Override - public String extractNextToken(PagedExpandResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(PagedExpandResponse payload) { - return payload.getResponsesList() == null - ? ImmutableList.of() - : payload.getResponsesList(); - } - }; - - private static final PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - PAGED_EXPAND_PAGE_STR_FACT = - new PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse>() { - @Override - public ApiFuture getFuturePagedResponse( - UnaryCallable callable, - PagedExpandRequest request, - ApiCallContext context, - ApiFuture futureResponse) { - PageContext pageContext = - PageContext.create(callable, PAGED_EXPAND_PAGE_STR_DESC, request, context); - return PagedExpandPagedResponse.createAsync(pageContext, futureResponse); - } - }; - - private static final PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - SIMPLE_PAGED_EXPAND_PAGE_STR_FACT = - new PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse>() { - @Override - public ApiFuture getFuturePagedResponse( - UnaryCallable callable, - PagedExpandRequest request, - ApiCallContext context, - ApiFuture futureResponse) { - PageContext pageContext = - PageContext.create(callable, SIMPLE_PAGED_EXPAND_PAGE_STR_DESC, request, context); - return SimplePagedExpandPagedResponse.createAsync(pageContext, futureResponse); - } - }; - - /** Returns the object with the settings used for calls to echo. */ - public UnaryCallSettings echoSettings() { - return echoSettings; - } - - /** Returns the object with the settings used for calls to expand. */ - public ServerStreamingCallSettings expandSettings() { - return expandSettings; - } - - /** Returns the object with the settings used for calls to collect. */ - public StreamingCallSettings collectSettings() { - return collectSettings; - } - - /** Returns the object with the settings used for calls to chat. */ - public StreamingCallSettings chatSettings() { - return chatSettings; + 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 chatAgain. */ - public StreamingCallSettings chatAgainSettings() { - return chatAgainSettings; + /** 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 pagedExpand. */ - public PagedCallSettings - pagedExpandSettings() { - return pagedExpandSettings; + /** 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 simplePagedExpand. */ - public PagedCallSettings - simplePagedExpandSettings() { - return simplePagedExpandSettings; + /** 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 wait. */ - public UnaryCallSettings waitSettings() { - return waitSettings; + /** 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 wait. */ - public OperationCallSettings waitOperationSettings() { - return waitOperationSettings; - } - - /** Returns the object with the settings used for calls to block. */ - public UnaryCallSettings blockSettings() { - return blockSettings; - } - - /** Returns the object with the settings used for calls to collideName. */ - public UnaryCallSettings collideNameSettings() { - return collideNameSettings; + /** 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 EchoStub createStub() throws IOException { + public ComplianceStub createStub() throws IOException { if (getTransportChannelProvider() .getTransportName() .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { - return HttpJsonEchoStub.create(this); + return HttpJsonComplianceStub.create(this); } throw new UnsupportedOperationException( String.format( @@ -303,7 +135,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. */ @@ -319,7 +153,8 @@ public class EchoStubSettings extends StubSettings { @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(EchoStubSettings.class)) + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(ComplianceStubSettings.class)) .setTransportToken( GaxHttpJsonProperties.getHttpJsonTokenName(), GaxHttpJsonProperties.getHttpJsonVersion()); @@ -340,54 +175,38 @@ public class EchoStubSettings extends StubSettings { return new Builder(this); } - protected EchoStubSettings(Builder settingsBuilder) throws IOException { + protected ComplianceStubSettings(Builder settingsBuilder) throws IOException { super(settingsBuilder); - echoSettings = settingsBuilder.echoSettings().build(); - expandSettings = settingsBuilder.expandSettings().build(); - collectSettings = settingsBuilder.collectSettings().build(); - chatSettings = settingsBuilder.chatSettings().build(); - chatAgainSettings = settingsBuilder.chatAgainSettings().build(); - pagedExpandSettings = settingsBuilder.pagedExpandSettings().build(); - simplePagedExpandSettings = settingsBuilder.simplePagedExpandSettings().build(); - waitSettings = settingsBuilder.waitSettings().build(); - waitOperationSettings = settingsBuilder.waitOperationSettings().build(); - blockSettings = settingsBuilder.blockSettings().build(); - collideNameSettings = settingsBuilder.collideNameSettings().build(); + 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 EchoStubSettings. */ - public static class Builder extends StubSettings.Builder { + /** Builder for ComplianceStubSettings. */ + public static class Builder extends StubSettings.Builder { private final ImmutableList> unaryMethodSettingsBuilders; - private final UnaryCallSettings.Builder echoSettings; - private final ServerStreamingCallSettings.Builder expandSettings; - private final StreamingCallSettings.Builder collectSettings; - private final StreamingCallSettings.Builder chatSettings; - private final StreamingCallSettings.Builder chatAgainSettings; - private final PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - pagedExpandSettings; - private final PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings; - private final UnaryCallSettings.Builder waitSettings; - private final OperationCallSettings.Builder - waitOperationSettings; - private final UnaryCallSettings.Builder blockSettings; - private final UnaryCallSettings.Builder collideNameSettings; + 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( - "retry_policy_1_codes", - ImmutableSet.copyOf( - Lists.newArrayList( - StatusCode.Code.UNAVAILABLE, StatusCode.Code.UNKNOWN))); - definitions.put( - "no_retry_0_codes", ImmutableSet.copyOf(Lists.newArrayList())); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -396,25 +215,8 @@ public class EchoStubSettings extends StubSettings { static { ImmutableMap.Builder definitions = ImmutableMap.builder(); RetrySettings settings = null; - settings = - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(100L)) - .setRetryDelayMultiplier(2.0) - .setMaxRetryDelay(Duration.ofMillis(3000L)) - .setInitialRpcTimeout(Duration.ofMillis(10000L)) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ofMillis(10000L)) - .setTotalTimeout(Duration.ofMillis(10000L)) - .build(); - definitions.put("retry_policy_1_params", settings); - settings = - RetrySettings.newBuilder() - .setInitialRpcTimeout(Duration.ofMillis(5000L)) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ofMillis(5000L)) - .setTotalTimeout(Duration.ofMillis(5000L)) - .build(); - definitions.put("no_retry_0_params", settings); + settings = RetrySettings.newBuilder().setRpcTimeoutMultiplier(1.0).build(); + definitions.put("no_retry_params", settings); RETRY_PARAM_DEFINITIONS = definitions.build(); } @@ -425,52 +227,43 @@ public class EchoStubSettings extends StubSettings { protected Builder(ClientContext clientContext) { super(clientContext); - echoSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - expandSettings = ServerStreamingCallSettings.newBuilder(); - collectSettings = StreamingCallSettings.newBuilder(); - chatSettings = StreamingCallSettings.newBuilder(); - chatAgainSettings = StreamingCallSettings.newBuilder(); - pagedExpandSettings = PagedCallSettings.newBuilder(PAGED_EXPAND_PAGE_STR_FACT); - simplePagedExpandSettings = PagedCallSettings.newBuilder(SIMPLE_PAGED_EXPAND_PAGE_STR_FACT); - waitSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - waitOperationSettings = OperationCallSettings.newBuilder(); - blockSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - collideNameSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataBodySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataBodyInfoSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataQuerySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataSimplePathSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathTrailingResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( - echoSettings, - pagedExpandSettings, - simplePagedExpandSettings, - waitSettings, - blockSettings, - collideNameSettings); + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); initDefaults(this); } - protected Builder(EchoStubSettings settings) { + protected Builder(ComplianceStubSettings settings) { super(settings); - echoSettings = settings.echoSettings.toBuilder(); - expandSettings = settings.expandSettings.toBuilder(); - collectSettings = settings.collectSettings.toBuilder(); - chatSettings = settings.chatSettings.toBuilder(); - chatAgainSettings = settings.chatAgainSettings.toBuilder(); - pagedExpandSettings = settings.pagedExpandSettings.toBuilder(); - simplePagedExpandSettings = settings.simplePagedExpandSettings.toBuilder(); - waitSettings = settings.waitSettings.toBuilder(); - waitOperationSettings = settings.waitOperationSettings.toBuilder(); - blockSettings = settings.blockSettings.toBuilder(); - collideNameSettings = settings.collideNameSettings.toBuilder(); + 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( - echoSettings, - pagedExpandSettings, - simplePagedExpandSettings, - waitSettings, - blockSettings, - collideNameSettings); + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); } private static Builder createDefault() { @@ -488,62 +281,34 @@ public class EchoStubSettings extends StubSettings { private static Builder initDefaults(Builder builder) { builder - .echoSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); - - builder - .expandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + .repeatDataBodySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .pagedExpandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + .repeatDataBodyInfoSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .simplePagedExpandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataQuerySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .waitSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataSimplePathSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .blockSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataPathResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .collideNameSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); - - builder - .waitOperationSettings() - .setInitialCallSettings( - UnaryCallSettings.newUnaryCallSettingsBuilder() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")) - .build()) - .setResponseTransformer( - ProtoOperationTransformers.ResponseTransformer.create(WaitResponse.class)) - .setMetadataTransformer( - ProtoOperationTransformers.MetadataTransformer.create(WaitMetadata.class)) - .setPollingAlgorithm( - OperationTimedPollAlgorithm.create( - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(5000L)) - .setRetryDelayMultiplier(1.5) - .setMaxRetryDelay(Duration.ofMillis(45000L)) - .setInitialRpcTimeout(Duration.ZERO) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ZERO) - .setTotalTimeout(Duration.ofMillis(300000L)) - .build())); + .repeatDataPathTrailingResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); return builder; } @@ -563,71 +328,41 @@ public class EchoStubSettings extends StubSettings { return unaryMethodSettingsBuilders; } - /** Returns the builder for the settings used for calls to echo. */ - public UnaryCallSettings.Builder echoSettings() { - return echoSettings; - } - - /** Returns the builder for the settings used for calls to expand. */ - public ServerStreamingCallSettings.Builder expandSettings() { - return expandSettings; - } - - /** Returns the builder for the settings used for calls to collect. */ - public StreamingCallSettings.Builder collectSettings() { - return collectSettings; - } - - /** Returns the builder for the settings used for calls to chat. */ - public StreamingCallSettings.Builder chatSettings() { - return chatSettings; - } - - /** Returns the builder for the settings used for calls to chatAgain. */ - public StreamingCallSettings.Builder chatAgainSettings() { - return chatAgainSettings; - } - - /** Returns the builder for the settings used for calls to pagedExpand. */ - public PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - pagedExpandSettings() { - return pagedExpandSettings; + /** 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 simplePagedExpand. */ - public PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings() { - return simplePagedExpandSettings; + /** 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 wait. */ - public UnaryCallSettings.Builder waitSettings() { - return waitSettings; + /** 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 wait. */ - @BetaApi( - "The surface for use by generated code is not stable yet and may change in the future.") - public OperationCallSettings.Builder - waitOperationSettings() { - return waitOperationSettings; + /** 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 block. */ - public UnaryCallSettings.Builder blockSettings() { - return blockSettings; + /** 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 collideName. */ - public UnaryCallSettings.Builder collideNameSettings() { - return collideNameSettings; + /** Returns the builder for the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings() { + return repeatDataPathTrailingResourceSettings; } @Override - public EchoStubSettings build() throws IOException { - return new EchoStubSettings(this); + 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 index 7d6032778d..6f5e7eab3b 100644 --- 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 @@ -1,11 +1,11 @@ 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.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallSettings; @@ -13,6 +13,7 @@ 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 com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -24,7 +25,7 @@ import javax.annotation.Generated; @BetaApi @Generated("by gapic-generator-java") public class HttpJsonComplianceCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -59,10 +60,18 @@ public class HttpJsonComplianceCallableFactory @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, - BackgroundResource operationsStub) { - return null; + OperationsStub operationsStub) { + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + HttpJsonOperationSnapshotCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } 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 index 5324f21655..6b6a701df9 100644 --- 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 @@ -13,6 +13,7 @@ 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.protobuf.TypeRegistry; import com.google.showcase.v1beta1.RepeatRequest; import com.google.showcase.v1beta1.RepeatResponse; import java.io.IOException; @@ -33,6 +34,8 @@ import javax.annotation.Generated; @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 TypeRegistry typeRegistry = TypeRegistry.newBuilder().build(); + private static final ApiMethodDescriptor repeatDataBodyMethodDescriptor = ApiMethodDescriptor.newBuilder() @@ -57,12 +60,12 @@ public class HttpJsonComplianceStub extends ComplianceStub { }) .setRequestBodyExtractor( request -> - ProtoRestSerializer.create() - .toBody("serverVerify", request.getServerVerify())) + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) .build()) .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -97,6 +100,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -131,6 +135,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -177,6 +182,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -221,6 +227,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -262,6 +269,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -316,27 +324,33 @@ public class HttpJsonComplianceStub extends ComplianceStub { HttpJsonCallSettings repeatDataBodyTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataBodyMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataBodyInfoTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataBodyInfoMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataQueryTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataQueryMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataSimplePathTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataSimplePathMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataPathResourceTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataPathResourceMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataPathTrailingResourceTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataPathTrailingResourceMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); this.repeatDataBodyCallable = 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 4031df1c0a..397e0ec2c2 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; @@ -55,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( @@ -104,7 +102,11 @@ public void composeClassHeaderMethodSampleCode_firstMethodIsNotUnaryRpc() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1252,7 +1254,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroUnaryRpcWithNoMethodArgumen .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1305,7 +1311,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroRpcWithReturnResponseType() .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1372,7 +1382,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroRpcWithReturnVoid() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1528,7 +1542,11 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_hasLroMethodWithReturnR .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1581,7 +1599,11 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_hasLroMethodWithReturnV .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1732,7 +1754,11 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnResponse() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1784,7 +1810,11 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnVoid() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -2348,7 +2378,11 @@ public void validComposeRegularCallableMethodHeaderSampleCode_lroRpc() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -2399,7 +2433,11 @@ public void validComposeRegularCallableMethodHeaderSampleCode_lroRpcWithReturnVo .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") 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 b00985942f..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; 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/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 468e1e392f..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,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.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; 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 d9a31c9fd4..428b5156d9 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; @@ -201,7 +201,7 @@ public void parseLro_missingResponseType() { assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("com.google.showcase.v1beta1.WaitResponse"); assertThrows( - NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); + NullPointerException.class, () -> Parser.parseLro("", waitMethodDescriptor, messageTypes)); } @Test @@ -211,7 +211,7 @@ public void parseLro_missingMetadataType() { assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("com.google.showcase.v1beta1.WaitMetadata"); assertThrows( - NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); + NullPointerException.class, () -> Parser.parseLro("", waitMethodDescriptor, messageTypes)); } @Test @@ -224,15 +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, - Transport.GRPC); assertThat( MethodSignatureParser.parseMethodSignatures( methodDescriptor, @@ -254,15 +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, - Transport.GRPC); 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/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/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java index 1860b0cca4..af1cc6dd1f 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 @@ -54,6 +54,7 @@ * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } @@ -190,6 +191,7 @@ public final OperationsClient getOperationsClient() { * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ExportAssetsResponse response = assetServiceClient.exportAssetsAsync(request).get(); * } @@ -225,6 +227,7 @@ public final OperationFuture exportAs * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * OperationFuture future = * assetServiceClient.exportAssetsOperationCallable().futureCall(request); @@ -260,6 +263,7 @@ public final OperationFuture exportAs * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = assetServiceClient.exportAssetsCallable().futureCall(request); * // Do something. @@ -340,6 +344,7 @@ public final ListAssetsPagedResponse listAssets(String parent) { * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * for (Asset element : assetServiceClient.listAssets(request).iterateAll()) { * // doThingsWith(element); @@ -370,6 +375,7 @@ public final ListAssetsPagedResponse listAssets(ListAssetsRequest request) { * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = assetServiceClient.listAssetsPagedCallable().futureCall(request); * // Do something. @@ -399,6 +405,7 @@ public final UnaryCallable listAsset * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * while (true) { * ListAssetsResponse response = assetServiceClient.listAssetsCallable().call(request); @@ -437,6 +444,7 @@ public final UnaryCallable listAssetsCall * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } @@ -468,6 +476,7 @@ public final BatchGetAssetsHistoryResponse batchGetAssetsHistory( * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = * assetServiceClient.batchGetAssetsHistoryCallable().futureCall(request); @@ -924,8 +933,8 @@ public final UnaryCallable deleteFeedCallable() { *
  • `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. + *
  • `NOT state:ACTIVE` to find Cloud 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. @@ -985,6 +994,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * for (ResourceSearchResult element : * assetServiceClient.searchAllResources(request).iterateAll()) { @@ -1019,6 +1029,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * ApiFuture future = * assetServiceClient.searchAllResourcesPagedCallable().futureCall(request); @@ -1052,6 +1063,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * while (true) { * SearchAllResourcesResponse response = @@ -1314,8 +1326,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1335,7 +1347,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final OperationFuture< - AnalyzeIamPolicyLongrunningResponse, AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningResponse, AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningAsync(AnalyzeIamPolicyLongrunningRequest request) { return analyzeIamPolicyLongrunningOperationCallable().futureCall(request); } @@ -1348,8 +1360,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1360,7 +1372,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * .setAnalysisQuery(IamPolicyAnalysisQuery.newBuilder().build()) * .setOutputConfig(IamPolicyAnalysisOutputConfig.newBuilder().build()) * .build(); - * OperationFuture + * OperationFuture * future = * assetServiceClient.analyzeIamPolicyLongrunningOperationCallable().futureCall(request); * // Do something. @@ -1371,7 +1383,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r public final OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { return stub.analyzeIamPolicyLongrunningOperationCallable(); } @@ -1384,8 +1396,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1408,6 +1420,60 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r return stub.analyzeIamPolicyLongrunningCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Analyze moving a resource to a specified destination without kicking off the actual move. The + * analysis is best effort depending on the user's permissions of viewing different hierarchical + * policies and configurations. The policies and configuration are subject to change before the + * actual resource migration takes place. + * + *

    Sample code: + * + *

    {@code
    +   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
    +   *   AnalyzeMoveRequest request =
    +   *       AnalyzeMoveRequest.newBuilder()
    +   *           .setResource("resource-341064690")
    +   *           .setDestinationParent("destinationParent-1733659048")
    +   *           .build();
    +   *   AnalyzeMoveResponse response = assetServiceClient.analyzeMove(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 AnalyzeMoveResponse analyzeMove(AnalyzeMoveRequest request) { + return analyzeMoveCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Analyze moving a resource to a specified destination without kicking off the actual move. The + * analysis is best effort depending on the user's permissions of viewing different hierarchical + * policies and configurations. The policies and configuration are subject to change before the + * actual resource migration takes place. + * + *

    Sample code: + * + *

    {@code
    +   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
    +   *   AnalyzeMoveRequest request =
    +   *       AnalyzeMoveRequest.newBuilder()
    +   *           .setResource("resource-341064690")
    +   *           .setDestinationParent("destinationParent-1733659048")
    +   *           .build();
    +   *   ApiFuture future =
    +   *       assetServiceClient.analyzeMoveCallable().futureCall(request);
    +   *   // Do something.
    +   *   AnalyzeMoveResponse response = future.get();
    +   * }
    +   * }
    + */ + public final UnaryCallable analyzeMoveCallable() { + return stub.analyzeMoveCallable(); + } + @Override public final void close() { stub.close(); 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 de8ca67414..41f50cea3a 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 @@ -113,6 +113,7 @@ public void exportAssetsTest() throws Exception { .addAllAssetTypes(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setOutputConfig(OutputConfig.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); ExportAssetsResponse actualResponse = client.exportAssetsAsync(request).get(); @@ -127,6 +128,8 @@ public void exportAssetsTest() throws Exception { Assert.assertEquals(request.getAssetTypesList(), actualRequest.getAssetTypesList()); Assert.assertEquals(request.getContentType(), actualRequest.getContentType()); Assert.assertEquals(request.getOutputConfig(), actualRequest.getOutputConfig()); + Assert.assertEquals( + request.getRelationshipTypesList(), actualRequest.getRelationshipTypesList()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -146,6 +149,7 @@ public void exportAssetsExceptionTest() throws Exception { .addAllAssetTypes(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setOutputConfig(OutputConfig.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); client.exportAssetsAsync(request).get(); Assert.fail("No exception raised"); @@ -258,6 +262,7 @@ public void batchGetAssetsHistoryTest() throws Exception { .addAllAssetNames(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setReadTimeWindow(TimeWindow.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); BatchGetAssetsHistoryResponse actualResponse = client.batchGetAssetsHistory(request); @@ -272,6 +277,8 @@ public void batchGetAssetsHistoryTest() throws Exception { Assert.assertEquals(request.getAssetNamesList(), actualRequest.getAssetNamesList()); Assert.assertEquals(request.getContentType(), actualRequest.getContentType()); Assert.assertEquals(request.getReadTimeWindow(), actualRequest.getReadTimeWindow()); + Assert.assertEquals( + request.getRelationshipTypesList(), actualRequest.getRelationshipTypesList()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -290,6 +297,7 @@ public void batchGetAssetsHistoryExceptionTest() throws Exception { .addAllAssetNames(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setReadTimeWindow(TimeWindow.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); client.batchGetAssetsHistory(request); Assert.fail("No exception raised"); @@ -308,6 +316,7 @@ public void createFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -351,6 +360,7 @@ public void getFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -394,6 +404,7 @@ public void getFeedTest2() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -473,6 +484,7 @@ public void updateFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -777,4 +789,50 @@ public void analyzeIamPolicyLongrunningExceptionTest() throws Exception { Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); } } + + @Test + public void analyzeMoveTest() throws Exception { + AnalyzeMoveResponse expectedResponse = + AnalyzeMoveResponse.newBuilder().addAllMoveAnalysis(new ArrayList()).build(); + mockAssetService.addResponse(expectedResponse); + + AnalyzeMoveRequest request = + AnalyzeMoveRequest.newBuilder() + .setResource("resource-341064690") + .setDestinationParent("destinationParent-1733659048") + .build(); + + AnalyzeMoveResponse actualResponse = client.analyzeMove(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockAssetService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + AnalyzeMoveRequest actualRequest = ((AnalyzeMoveRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getResource(), actualRequest.getResource()); + Assert.assertEquals(request.getDestinationParent(), actualRequest.getDestinationParent()); + Assert.assertEquals(request.getView(), actualRequest.getView()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void analyzeMoveExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockAssetService.addException(exception); + + try { + AnalyzeMoveRequest request = + AnalyzeMoveRequest.newBuilder() + .setResource("resource-341064690") + .setDestinationParent("destinationParent-1733659048") + .build(); + client.analyzeMove(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } } 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 df338c00a9..8bca7d5631 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 @@ -154,12 +154,17 @@ public UnaryCallSettings deleteFeedSettings() { public OperationCallSettings< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return ((AssetServiceStubSettings) getStubSettings()) .analyzeIamPolicyLongrunningOperationSettings(); } + /** Returns the object with the settings used for calls to analyzeMove. */ + public UnaryCallSettings analyzeMoveSettings() { + return ((AssetServiceStubSettings) getStubSettings()).analyzeMoveSettings(); + } + public static final AssetServiceSettings create(AssetServiceStubSettings stub) throws IOException { return new AssetServiceSettings.Builder(stub.toBuilder()).build(); @@ -338,11 +343,17 @@ public UnaryCallSettings.Builder deleteFeedSettings() public OperationCallSettings.Builder< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return getStubSettingsBuilder().analyzeIamPolicyLongrunningOperationSettings(); } + /** Returns the builder for the settings used for calls to analyzeMove. */ + public UnaryCallSettings.Builder + analyzeMoveSettings() { + return getStubSettingsBuilder().analyzeMoveSettings(); + } + @Override public AssetServiceSettings build() throws IOException { return new AssetServiceSettings(this); 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 643691d8d4..f72ed1eaa6 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 @@ -310,4 +310,25 @@ public void analyzeIamPolicyLongrunning( Exception.class.getName()))); } } + + @Override + public void analyzeMove( + AnalyzeMoveRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof AnalyzeMoveResponse) { + requests.add(request); + responseObserver.onNext(((AnalyzeMoveResponse) 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 AnalyzeMove, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + AnalyzeMoveResponse.class.getName(), + Exception.class.getName()))); + } + } } 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 ea1187e7ac..05ba5ae5ea 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 @@ -16,6 +16,9 @@ "AnalyzeIamPolicyLongrunning": { "methods": ["analyzeIamPolicyLongrunningAsync", "analyzeIamPolicyLongrunningOperationCallable", "analyzeIamPolicyLongrunningCallable"] }, + "AnalyzeMove": { + "methods": ["analyzeMove", "analyzeMoveCallable"] + }, "BatchGetAssetsHistory": { "methods": ["batchGetAssetsHistory", "batchGetAssetsHistoryCallable"] }, 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 27db247ed3..d07bbc1fb7 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 @@ -31,6 +31,7 @@ * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } 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 462d7e2922..f3b324ba29 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 @@ -23,10 +23,13 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; 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.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; import com.google.cloud.asset.v1.CreateFeedRequest; @@ -132,7 +135,7 @@ public UnaryCallable deleteFeedCallable() { public OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { throw new UnsupportedOperationException( "Not implemented: analyzeIamPolicyLongrunningOperationCallable()"); @@ -144,6 +147,10 @@ public UnaryCallable deleteFeedCallable() { "Not implemented: analyzeIamPolicyLongrunningCallable()"); } + public UnaryCallable analyzeMoveCallable() { + throw new UnsupportedOperationException("Not implemented: analyzeMoveCallable()"); + } + @Override public abstract void close(); } 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 d5f851bb3b..30012d98c6 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 @@ -46,10 +46,13 @@ 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.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; 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.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.Asset; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; @@ -147,8 +150,9 @@ public class AssetServiceStubSettings extends StubSettings + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings; + private final UnaryCallSettings analyzeMoveSettings; private static final PagedListDescriptor LIST_ASSETS_PAGE_STR_DESC = @@ -413,11 +417,16 @@ public UnaryCallSettings deleteFeedSettings() { public OperationCallSettings< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return analyzeIamPolicyLongrunningOperationSettings; } + /** Returns the object with the settings used for calls to analyzeMove. */ + public UnaryCallSettings analyzeMoveSettings() { + return analyzeMoveSettings; + } + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public AssetServiceStub createStub() throws IOException { if (getTransportChannelProvider() @@ -452,7 +461,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. */ @@ -508,6 +519,7 @@ protected AssetServiceStubSettings(Builder settingsBuilder) throws IOException { settingsBuilder.analyzeIamPolicyLongrunningSettings().build(); analyzeIamPolicyLongrunningOperationSettings = settingsBuilder.analyzeIamPolicyLongrunningOperationSettings().build(); + analyzeMoveSettings = settingsBuilder.analyzeMoveSettings().build(); } /** Builder for AssetServiceStubSettings. */ @@ -543,8 +555,10 @@ public static class Builder extends StubSettings.Builder + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings; + private final UnaryCallSettings.Builder + analyzeMoveSettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; @@ -564,6 +578,7 @@ public static class Builder extends StubSettings.BuildernewArrayList(StatusCode.Code.UNAVAILABLE))); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -613,6 +628,8 @@ public static class Builder extends StubSettings.Builder>of( @@ -652,7 +670,8 @@ protected Builder(ClientContext clientContext) { searchAllResourcesSettings, searchAllIamPoliciesSettings, analyzeIamPolicySettings, - analyzeIamPolicyLongrunningSettings); + analyzeIamPolicyLongrunningSettings, + analyzeMoveSettings); initDefaults(this); } @@ -675,6 +694,7 @@ protected Builder(AssetServiceStubSettings settings) { settings.analyzeIamPolicyLongrunningSettings.toBuilder(); analyzeIamPolicyLongrunningOperationSettings = settings.analyzeIamPolicyLongrunningOperationSettings.toBuilder(); + analyzeMoveSettings = settings.analyzeMoveSettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -689,7 +709,8 @@ protected Builder(AssetServiceStubSettings settings) { searchAllResourcesSettings, searchAllIamPoliciesSettings, analyzeIamPolicySettings, - analyzeIamPolicyLongrunningSettings); + analyzeIamPolicyLongrunningSettings, + analyzeMoveSettings); } private static Builder createDefault() { @@ -766,6 +787,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 + .analyzeMoveSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + builder .exportAssetsOperationSettings() .setInitialCallSettings( @@ -804,7 +830,7 @@ private static Builder initDefaults(Builder builder) { AnalyzeIamPolicyLongrunningResponse.class)) .setMetadataTransformer( ProtoOperationTransformers.MetadataTransformer.create( - AnalyzeIamPolicyLongrunningRequest.class)) + AnalyzeIamPolicyLongrunningMetadata.class)) .setPollingAlgorithm( OperationTimedPollAlgorithm.create( RetrySettings.newBuilder() @@ -920,11 +946,17 @@ public UnaryCallSettings.Builder deleteFeedSettings() public OperationCallSettings.Builder< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return analyzeIamPolicyLongrunningOperationSettings; } + /** Returns the builder for the settings used for calls to analyzeMove. */ + public UnaryCallSettings.Builder + analyzeMoveSettings() { + return analyzeMoveSettings; + } + @Override public AssetServiceStubSettings build() throws IOException { return new AssetServiceStubSettings(this); 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 d884f02bf9..d467435938 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 @@ -27,10 +27,13 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; 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.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; import com.google.cloud.asset.v1.CreateFeedRequest; @@ -180,6 +183,16 @@ public class GrpcAssetServiceStub extends AssetServiceStub { .setResponseMarshaller(ProtoUtils.marshaller(Operation.getDefaultInstance())) .build(); + private static final MethodDescriptor + analyzeMoveMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.cloud.asset.v1.AssetService/AnalyzeMove") + .setRequestMarshaller(ProtoUtils.marshaller(AnalyzeMoveRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(AnalyzeMoveResponse.getDefaultInstance())) + .build(); + private final UnaryCallable exportAssetsCallable; private final OperationCallable exportAssetsOperationCallable; @@ -207,8 +220,9 @@ public class GrpcAssetServiceStub extends AssetServiceStub { private final OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable; + private final UnaryCallable analyzeMoveCallable; private final BackgroundResource backgroundResources; private final GrpcOperationsStub operationsStub; @@ -382,6 +396,16 @@ protected GrpcAssetServiceStub( return params.build(); }) .build(); + GrpcCallSettings analyzeMoveTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(analyzeMoveMethodDescriptor) + .setParamsExtractor( + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); + }) + .build(); this.exportAssetsCallable = callableFactory.createUnaryCallable( @@ -452,6 +476,9 @@ protected GrpcAssetServiceStub( settings.analyzeIamPolicyLongrunningOperationSettings(), clientContext, operationsStub); + this.analyzeMoveCallable = + callableFactory.createUnaryCallable( + analyzeMoveTransportSettings, settings.analyzeMoveSettings(), clientContext); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); @@ -553,11 +580,16 @@ public UnaryCallable deleteFeedCallable() { public OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { return analyzeIamPolicyLongrunningOperationCallable; } + @Override + public UnaryCallable analyzeMoveCallable() { + return analyzeMoveCallable; + } + @Override public final void close() { try { 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 index eb9db7ce24..f9039b41df 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java @@ -20,9 +20,11 @@ import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.longrunning.OperationFuture; 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.OperationCallable; import com.google.api.gax.rpc.PageContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.stub.AddressesStub; @@ -46,9 +48,10 @@ *
    {@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);
    + *   for (Map.Entry element :
    + *       addressesClient.aggregatedList(project).iterateAll()) {
    + *     // doThingsWith(element);
    + *   }
      * }
      * }
    * @@ -284,7 +287,7 @@ public final AggregatedListPagedResponse aggregatedList(AggregatedListAddressesR * String project = "project-309310695"; * String region = "region-934795532"; * String address = "address-1147692044"; - * Operation response = addressesClient.delete(project, region, address); + * Operation response = addressesClient.deleteAsync(project, region, address).get(); * } * } * @@ -293,14 +296,15 @@ public final AggregatedListPagedResponse aggregatedList(AggregatedListAddressesR * @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) { + public final OperationFuture deleteAsync( + String project, String region, String address) { DeleteAddressRequest request = DeleteAddressRequest.newBuilder() .setProject(project) .setRegion(region) .setAddress(address) .build(); - return delete(request); + return deleteAsync(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -318,15 +322,44 @@ public final Operation delete(String project, String region, String address) { * .setRegion("region-934795532") * .setRequestId("requestId693933066") * .build(); - * Operation response = addressesClient.delete(request); + * Operation response = addressesClient.deleteAsync(request).get(); * } * } * * @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); + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + public final OperationFuture deleteAsync(DeleteAddressRequest request) { + return deleteOperationCallable().futureCall(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();
    +   *   OperationFuture future =
    +   *       addressesClient.deleteOperationCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final OperationCallable + deleteOperationCallable() { + return stub.deleteOperationCallable(); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -365,7 +398,7 @@ public final UnaryCallable deleteCallable() { * String project = "project-309310695"; * String region = "region-934795532"; * Address addressResource = Address.newBuilder().build(); - * Operation response = addressesClient.insert(project, region, addressResource); + * Operation response = addressesClient.insertAsync(project, region, addressResource).get(); * } * } * @@ -374,14 +407,15 @@ public final UnaryCallable deleteCallable() { * @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) { + public final OperationFuture insertAsync( + String project, String region, Address addressResource) { InsertAddressRequest request = InsertAddressRequest.newBuilder() .setProject(project) .setRegion(region) .setAddressResource(addressResource) .build(); - return insert(request); + return insertAsync(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -399,15 +433,44 @@ public final Operation insert(String project, String region, Address addressReso * .setRegion("region-934795532") * .setRequestId("requestId693933066") * .build(); - * Operation response = addressesClient.insert(request); + * Operation response = addressesClient.insertAsync(request).get(); * } * } * * @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); + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + public final OperationFuture insertAsync(InsertAddressRequest request) { + return insertOperationCallable().futureCall(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();
    +   *   OperationFuture future =
    +   *       addressesClient.insertOperationCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final OperationCallable + insertOperationCallable() { + return stub.insertOperationCallable(); } // AUTO-GENERATED DOCUMENTATION AND METHOD. 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 index bc7d9c2a16..ec3f75047c 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java @@ -28,6 +28,7 @@ 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.Operation.Status; import com.google.cloud.compute.v1.stub.HttpJsonAddressesStub; import com.google.common.collect.Lists; import java.io.IOException; @@ -36,6 +37,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import javax.annotation.Generated; import org.junit.After; import org.junit.AfterClass; @@ -140,8 +142,8 @@ public void deleteTest() throws Exception { .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setHttpErrorStatusCode(0) + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -150,8 +152,9 @@ public void deleteTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) @@ -163,7 +166,7 @@ public void deleteTest() throws Exception { String region = "region-934795532"; String address = "address-1147692044"; - Operation actualResponse = client.delete(project, region, address); + Operation actualResponse = client.deleteAsync(project, region, address).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); @@ -192,10 +195,9 @@ public void deleteExceptionTest() throws Exception { String project = "project-309310695"; String region = "region-934795532"; String address = "address-1147692044"; - client.delete(project, region, address); + client.deleteAsync(project, region, address).get(); Assert.fail("No exception raised"); - } catch (InvalidArgumentException e) { - // Expected exception. + } catch (ExecutionException e) { } } @@ -209,8 +211,8 @@ public void insertTest() throws Exception { .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setHttpErrorStatusCode(0) + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -219,8 +221,9 @@ public void insertTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) @@ -232,7 +235,7 @@ public void insertTest() throws Exception { String region = "region-934795532"; Address addressResource = Address.newBuilder().build(); - Operation actualResponse = client.insert(project, region, addressResource); + Operation actualResponse = client.insertAsync(project, region, addressResource).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); @@ -261,10 +264,9 @@ public void insertExceptionTest() throws Exception { String project = "project-309310695"; String region = "region-934795532"; Address addressResource = Address.newBuilder().build(); - client.insert(project, region, addressResource); + client.insertAsync(project, region, addressResource).get(); Assert.fail("No exception raised"); - } catch (InvalidArgumentException e) { - // Expected exception. + } catch (ExecutionException e) { } } 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 index d2dc359f73..58fbc804d6 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java @@ -27,6 +27,7 @@ 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.OperationCallSettings; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.StubSettings; import com.google.api.gax.rpc.TransportChannelProvider; @@ -51,15 +52,15 @@ *

    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: + *

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

    {@code
      * AddressesSettings.Builder addressesSettingsBuilder = AddressesSettings.newBuilder();
      * addressesSettingsBuilder
    - *     .deleteSettings()
    + *     .aggregatedListSettings()
      *     .setRetrySettings(
      *         addressesSettingsBuilder
    - *             .deleteSettings()
    + *             .aggregatedListSettings()
      *             .getRetrySettings()
      *             .toBuilder()
      *             .setTotalTimeout(Duration.ofSeconds(30))
    @@ -82,11 +83,23 @@ public UnaryCallSettings deleteSettings() {
         return ((AddressesStubSettings) getStubSettings()).deleteSettings();
       }
     
    +  /** Returns the object with the settings used for calls to delete. */
    +  public OperationCallSettings
    +      deleteOperationSettings() {
    +    return ((AddressesStubSettings) getStubSettings()).deleteOperationSettings();
    +  }
    +
       /** 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 insert. */
    +  public OperationCallSettings
    +      insertOperationSettings() {
    +    return ((AddressesStubSettings) getStubSettings()).insertOperationSettings();
    +  }
    +
       /** Returns the object with the settings used for calls to list. */
       public PagedCallSettings listSettings() {
         return ((AddressesStubSettings) getStubSettings()).listSettings();
    @@ -201,11 +214,23 @@ public UnaryCallSettings.Builder deleteSettings
           return getStubSettingsBuilder().deleteSettings();
         }
     
    +    /** Returns the builder for the settings used for calls to delete. */
    +    public OperationCallSettings.Builder
    +        deleteOperationSettings() {
    +      return getStubSettingsBuilder().deleteOperationSettings();
    +    }
    +
         /** 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 insert. */
    +    public OperationCallSettings.Builder
    +        insertOperationSettings() {
    +      return getStubSettingsBuilder().insertOperationSettings();
    +    }
    +
         /** Returns the builder for the settings used for calls to list. */
         public PagedCallSettings.Builder
             listSettings() {
    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
    index fb6a5e296d..09fb0b090a 100644
    --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java
    +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java
    @@ -222,6 +222,112 @@ public final UnaryCallable getCallable() {
         return stub.getCallable();
       }
     
    +  // AUTO-GENERATED DOCUMENTATION AND METHOD.
    +  /**
    +   * Waits for the specified Operation resource to return as `DONE` or for the request to approach
    +   * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from
    +   * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then
    +   * returns the current state of the operation, which might be `DONE` or still in progress.
    +   *
    +   * 

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   String project = "project-309310695";
    +   *   String region = "region-934795532";
    +   *   String operation = "operation1662702951";
    +   *   Operation response = regionOperationsClient.wait(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 wait(String project, String region, String operation) { + WaitRegionOperationRequest request = + WaitRegionOperationRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setOperation(operation) + .build(); + return wait(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Waits for the specified Operation resource to return as `DONE` or for the request to approach + * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from + * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then + * returns the current state of the operation, which might be `DONE` or still in progress. + * + *

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   WaitRegionOperationRequest request =
    +   *       WaitRegionOperationRequest.newBuilder()
    +   *           .setOperation("operation1662702951")
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .build();
    +   *   Operation response = regionOperationsClient.wait(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 wait(WaitRegionOperationRequest request) { + return waitCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Waits for the specified Operation resource to return as `DONE` or for the request to approach + * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from + * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then + * returns the current state of the operation, which might be `DONE` or still in progress. + * + *

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   WaitRegionOperationRequest request =
    +   *       WaitRegionOperationRequest.newBuilder()
    +   *           .setOperation("operation1662702951")
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .build();
    +   *   ApiFuture future = regionOperationsClient.waitCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final UnaryCallable waitCallable() { + return stub.waitCallable(); + } + @Override public final void close() { stub.close(); 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 index 7f6b78232a..c1a2c78519 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java @@ -25,6 +25,7 @@ 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.Operation.Status; import com.google.cloud.compute.v1.stub.HttpJsonRegionOperationsStub; import java.io.IOException; import java.util.ArrayList; @@ -82,8 +83,8 @@ public void getTest() throws Exception { .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setHttpErrorStatusCode(0) + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -92,8 +93,9 @@ public void getTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) @@ -140,4 +142,74 @@ public void getExceptionTest() throws Exception { // Expected exception. } } + + @Test + public void waitTest() 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(0) + .setId(3355) + .setInsertTime("insertTime966165798") + .setKind("kind3292052") + .setName("name3373707") + .setOperationType("operationType91999553") + .setProgress(-1001078227) + .setRegion("region-934795532") + .setSelfLink("selfLink1191800166") + .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) + .setStatusMessage("statusMessage-958704715") + .setTargetId(-815576439) + .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.wait(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 waitExceptionTest() 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.wait(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 index 4e0ffca9d4..91cabed69d 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java @@ -72,6 +72,11 @@ public UnaryCallSettings getSettings() { return ((RegionOperationsStubSettings) getStubSettings()).getSettings(); } + /** Returns the object with the settings used for calls to wait. */ + public UnaryCallSettings waitSettings() { + return ((RegionOperationsStubSettings) getStubSettings()).waitSettings(); + } + public static final RegionOperationsSettings create(RegionOperationsStubSettings stub) throws IOException { return new RegionOperationsSettings.Builder(stub.toBuilder()).build(); @@ -175,6 +180,11 @@ public UnaryCallSettings.Builder getSettin return getStubSettingsBuilder().getSettings(); } + /** Returns the builder for the settings used for calls to wait. */ + public UnaryCallSettings.Builder waitSettings() { + return getStubSettingsBuilder().waitSettings(); + } + @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 index 14eb0320fd..a56d0a2382 100644 --- 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 @@ -14,10 +14,10 @@ "methods": ["aggregatedList", "aggregatedList", "aggregatedListPagedCallable", "aggregatedListCallable"] }, "Delete": { - "methods": ["delete", "delete", "deleteCallable"] + "methods": ["deleteAsync", "deleteAsync", "deleteOperationCallable", "deleteCallable"] }, "Insert": { - "methods": ["insert", "insert", "insertCallable"] + "methods": ["insertAsync", "insertAsync", "insertOperationCallable", "insertCallable"] }, "List": { "methods": ["list", "list", "listPagedCallable", "listCallable"] @@ -33,6 +33,9 @@ "rpcs": { "Get": { "methods": ["get", "get", "getCallable"] + }, + "Wait": { + "methods": ["wait", "wait", "waitCallable"] } } } 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 index 941f3ab751..e525d9c7df 100644 --- 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 @@ -28,9 +28,10 @@ *
    {@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);
    + *   for (Map.Entry element :
    + *       addressesClient.aggregatedList(project).iterateAll()) {
    + *     // doThingsWith(element);
    + *   }
      * }
      * }
    * 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 index b7d7f6e590..9ae394b7ca 100644 --- 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 @@ -20,6 +20,7 @@ import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.AddressAggregatedList; import com.google.cloud.compute.v1.AddressList; @@ -49,10 +50,18 @@ public abstract class AddressesStub implements BackgroundResource { throw new UnsupportedOperationException("Not implemented: aggregatedListCallable()"); } + public OperationCallable deleteOperationCallable() { + throw new UnsupportedOperationException("Not implemented: deleteOperationCallable()"); + } + public UnaryCallable deleteCallable() { throw new UnsupportedOperationException("Not implemented: deleteCallable()"); } + public OperationCallable insertOperationCallable() { + throw new UnsupportedOperationException("Not implemented: insertOperationCallable()"); + } + public UnaryCallable insertCallable() { throw new UnsupportedOperationException("Not implemented: insertCallable()"); } 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 index 69e3c4d6c0..b998276981 100644 --- 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 @@ -28,10 +28,14 @@ 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.httpjson.ProtoOperationTransformers; +import com.google.api.gax.longrunning.OperationSnapshot; +import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; 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.OperationCallSettings; import com.google.api.gax.rpc.PageContext; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.PagedListDescriptor; @@ -76,15 +80,15 @@ *

    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: + *

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

    {@code
      * AddressesStubSettings.Builder addressesSettingsBuilder = AddressesStubSettings.newBuilder();
      * addressesSettingsBuilder
    - *     .deleteSettings()
    + *     .aggregatedListSettings()
      *     .setRetrySettings(
      *         addressesSettingsBuilder
    - *             .deleteSettings()
    + *             .aggregatedListSettings()
      *             .getRetrySettings()
      *             .toBuilder()
      *             .setTotalTimeout(Duration.ofSeconds(30))
    @@ -105,7 +109,11 @@ public class AddressesStubSettings extends StubSettings {
               AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse>
           aggregatedListSettings;
       private final UnaryCallSettings deleteSettings;
    +  private final OperationCallSettings
    +      deleteOperationSettings;
       private final UnaryCallSettings insertSettings;
    +  private final OperationCallSettings
    +      insertOperationSettings;
       private final PagedCallSettings
           listSettings;
     
    @@ -243,11 +251,23 @@ public UnaryCallSettings deleteSettings() {
         return deleteSettings;
       }
     
    +  /** Returns the object with the settings used for calls to delete. */
    +  public OperationCallSettings
    +      deleteOperationSettings() {
    +    return deleteOperationSettings;
    +  }
    +
       /** 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 insert. */
    +  public OperationCallSettings
    +      insertOperationSettings() {
    +    return insertOperationSettings;
    +  }
    +
       /** Returns the object with the settings used for calls to list. */
       public PagedCallSettings listSettings() {
         return listSettings;
    @@ -287,7 +307,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. */
    @@ -329,7 +351,9 @@ protected AddressesStubSettings(Builder settingsBuilder) throws IOException {
     
         aggregatedListSettings = settingsBuilder.aggregatedListSettings().build();
         deleteSettings = settingsBuilder.deleteSettings().build();
    +    deleteOperationSettings = settingsBuilder.deleteOperationSettings().build();
         insertSettings = settingsBuilder.insertSettings().build();
    +    insertOperationSettings = settingsBuilder.insertOperationSettings().build();
         listSettings = settingsBuilder.listSettings().build();
       }
     
    @@ -340,7 +364,11 @@ public static class Builder extends StubSettings.Builder
             aggregatedListSettings;
         private final UnaryCallSettings.Builder deleteSettings;
    +    private final OperationCallSettings.Builder
    +        deleteOperationSettings;
         private final UnaryCallSettings.Builder insertSettings;
    +    private final OperationCallSettings.Builder
    +        insertOperationSettings;
         private final PagedCallSettings.Builder
             listSettings;
         private static final ImmutableMap>
    @@ -395,7 +423,9 @@ protected Builder(ClientContext clientContext) {
     
           aggregatedListSettings = PagedCallSettings.newBuilder(AGGREGATED_LIST_PAGE_STR_FACT);
           deleteSettings = UnaryCallSettings.newUnaryCallSettingsBuilder();
    +      deleteOperationSettings = OperationCallSettings.newBuilder();
           insertSettings = UnaryCallSettings.newUnaryCallSettingsBuilder();
    +      insertOperationSettings = OperationCallSettings.newBuilder();
           listSettings = PagedCallSettings.newBuilder(LIST_PAGE_STR_FACT);
     
           unaryMethodSettingsBuilders =
    @@ -409,7 +439,9 @@ protected Builder(AddressesStubSettings settings) {
     
           aggregatedListSettings = settings.aggregatedListSettings.toBuilder();
           deleteSettings = settings.deleteSettings.toBuilder();
    +      deleteOperationSettings = settings.deleteOperationSettings.toBuilder();
           insertSettings = settings.insertSettings.toBuilder();
    +      insertOperationSettings = settings.insertOperationSettings.toBuilder();
           listSettings = settings.listSettings.toBuilder();
     
           unaryMethodSettingsBuilders =
    @@ -451,6 +483,54 @@ private static Builder initDefaults(Builder builder) {
               .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes"))
               .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params"));
     
    +      builder
    +          .deleteOperationSettings()
    +          .setInitialCallSettings(
    +              UnaryCallSettings
    +                  .newUnaryCallSettingsBuilder()
    +                  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes"))
    +                  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params"))
    +                  .build())
    +          .setResponseTransformer(
    +              ProtoOperationTransformers.ResponseTransformer.create(Operation.class))
    +          .setMetadataTransformer(
    +              ProtoOperationTransformers.MetadataTransformer.create(Operation.class))
    +          .setPollingAlgorithm(
    +              OperationTimedPollAlgorithm.create(
    +                  RetrySettings.newBuilder()
    +                      .setInitialRetryDelay(Duration.ofMillis(5000L))
    +                      .setRetryDelayMultiplier(1.5)
    +                      .setMaxRetryDelay(Duration.ofMillis(45000L))
    +                      .setInitialRpcTimeout(Duration.ZERO)
    +                      .setRpcTimeoutMultiplier(1.0)
    +                      .setMaxRpcTimeout(Duration.ZERO)
    +                      .setTotalTimeout(Duration.ofMillis(300000L))
    +                      .build()));
    +
    +      builder
    +          .insertOperationSettings()
    +          .setInitialCallSettings(
    +              UnaryCallSettings
    +                  .newUnaryCallSettingsBuilder()
    +                  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes"))
    +                  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params"))
    +                  .build())
    +          .setResponseTransformer(
    +              ProtoOperationTransformers.ResponseTransformer.create(Operation.class))
    +          .setMetadataTransformer(
    +              ProtoOperationTransformers.MetadataTransformer.create(Operation.class))
    +          .setPollingAlgorithm(
    +              OperationTimedPollAlgorithm.create(
    +                  RetrySettings.newBuilder()
    +                      .setInitialRetryDelay(Duration.ofMillis(5000L))
    +                      .setRetryDelayMultiplier(1.5)
    +                      .setMaxRetryDelay(Duration.ofMillis(45000L))
    +                      .setInitialRpcTimeout(Duration.ZERO)
    +                      .setRpcTimeoutMultiplier(1.0)
    +                      .setMaxRpcTimeout(Duration.ZERO)
    +                      .setTotalTimeout(Duration.ofMillis(300000L))
    +                      .build()));
    +
           return builder;
         }
     
    @@ -481,11 +561,27 @@ public UnaryCallSettings.Builder deleteSettings
           return deleteSettings;
         }
     
    +    /** Returns the builder for the settings used for calls to delete. */
    +    @BetaApi(
    +        "The surface for use by generated code is not stable yet and may change in the future.")
    +    public OperationCallSettings.Builder
    +        deleteOperationSettings() {
    +      return deleteOperationSettings;
    +    }
    +
         /** 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 insert. */
    +    @BetaApi(
    +        "The surface for use by generated code is not stable yet and may change in the future.")
    +    public OperationCallSettings.Builder
    +        insertOperationSettings() {
    +      return insertOperationSettings;
    +    }
    +
         /** Returns the builder for the settings used for calls to list. */
         public PagedCallSettings.Builder
             listSettings() {
    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
    index afa275a6f5..2290fc6952 100644
    --- 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
    @@ -17,10 +17,9 @@
     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.HttpJsonOperationSnapshotCallable;
     import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
     import com.google.api.gax.rpc.BatchingCallSettings;
     import com.google.api.gax.rpc.ClientContext;
    @@ -29,6 +28,7 @@
     import com.google.api.gax.rpc.PagedCallSettings;
     import com.google.api.gax.rpc.UnaryCallSettings;
     import com.google.api.gax.rpc.UnaryCallable;
    +import com.google.cloud.compute.v1.Operation;
     import javax.annotation.Generated;
     
     // AUTO-GENERATED DOCUMENTATION AND CLASS.
    @@ -40,7 +40,7 @@
     @Generated("by gapic-generator-java")
     @BetaApi
     public class HttpJsonAddressesCallableFactory
    -    implements HttpJsonStubCallableFactory {
    +    implements HttpJsonStubCallableFactory {
     
       @Override
       public  UnaryCallable createUnaryCallable(
    @@ -75,10 +75,18 @@ public  UnaryCallable createBatchingCa
       @Override
       public 
           OperationCallable createOperationCallable(
    -          HttpJsonCallSettings httpJsonCallSettings,
    +          HttpJsonCallSettings httpJsonCallSettings,
               OperationCallSettings callSettings,
               ClientContext clientContext,
    -          BackgroundResource operationsStub) {
    -    return null;
    +          RegionOperationsStub operationsStub) {
    +    UnaryCallable innerCallable =
    +        HttpJsonCallableFactory.createBaseUnaryCallable(
    +            httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
    +    HttpJsonOperationSnapshotCallable initialCallable =
    +        new HttpJsonOperationSnapshotCallable(
    +            innerCallable,
    +            httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory());
    +    return HttpJsonCallableFactory.createOperationCallable(
    +        callSettings, clientContext, operationsStub.longRunningClient(), initialCallable);
       }
     }
    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
    index d8d960d342..679bfc1ae2 100644
    --- 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
    @@ -26,11 +26,14 @@
     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.HttpJsonOperationSnapshot;
     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.longrunning.OperationSnapshot;
     import com.google.api.gax.rpc.ClientContext;
    +import com.google.api.gax.rpc.OperationCallable;
     import com.google.api.gax.rpc.UnaryCallable;
     import com.google.cloud.compute.v1.AddressAggregatedList;
     import com.google.cloud.compute.v1.AddressList;
    @@ -39,6 +42,8 @@
     import com.google.cloud.compute.v1.InsertAddressRequest;
     import com.google.cloud.compute.v1.ListAddressesRequest;
     import com.google.cloud.compute.v1.Operation;
    +import com.google.cloud.compute.v1.Operation.Status;
    +import com.google.protobuf.TypeRegistry;
     import java.io.IOException;
     import java.util.ArrayList;
     import java.util.HashMap;
    @@ -56,6 +61,9 @@
     @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 TypeRegistry typeRegistry =
    +      TypeRegistry.newBuilder().add(Operation.getDescriptor()).build();
    +
       private static final ApiMethodDescriptor
           aggregatedListMethodDescriptor =
               ApiMethodDescriptor.newBuilder()
    @@ -101,6 +109,7 @@ public class HttpJsonAddressesStub extends AddressesStub {
                   .setResponseParser(
                       ProtoMessageResponseParser.newBuilder()
                           .setDefaultInstance(AddressAggregatedList.getDefaultInstance())
    +                      .setDefaultTypeRegistry(typeRegistry)
                           .build())
                   .build();
     
    @@ -136,7 +145,21 @@ public class HttpJsonAddressesStub extends AddressesStub {
               .setResponseParser(
                   ProtoMessageResponseParser.newBuilder()
                       .setDefaultInstance(Operation.getDefaultInstance())
    +                  .setDefaultTypeRegistry(typeRegistry)
                       .build())
    +          .setOperationSnapshotFactory(
    +              (DeleteAddressRequest request, Operation response) -> {
    +                StringBuilder opName = new StringBuilder(response.getName());
    +                opName.append(":").append(request.getProject());
    +                opName.append(":").append(request.getRegion());
    +                return HttpJsonOperationSnapshot.newBuilder()
    +                    .setName(opName.toString())
    +                    .setMetadata(response)
    +                    .setDone(Status.DONE.equals(response.getStatus()))
    +                    .setResponse(response)
    +                    .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage())
    +                    .build();
    +              })
               .build();
     
       private static final ApiMethodDescriptor insertMethodDescriptor =
    @@ -173,7 +196,21 @@ public class HttpJsonAddressesStub extends AddressesStub {
               .setResponseParser(
                   ProtoMessageResponseParser.newBuilder()
                       .setDefaultInstance(Operation.getDefaultInstance())
    +                  .setDefaultTypeRegistry(typeRegistry)
                       .build())
    +          .setOperationSnapshotFactory(
    +              (InsertAddressRequest request, Operation response) -> {
    +                StringBuilder opName = new StringBuilder(response.getName());
    +                opName.append(":").append(request.getProject());
    +                opName.append(":").append(request.getRegion());
    +                return HttpJsonOperationSnapshot.newBuilder()
    +                    .setName(opName.toString())
    +                    .setMetadata(response)
    +                    .setDone(Status.DONE.equals(response.getStatus()))
    +                    .setResponse(response)
    +                    .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage())
    +                    .build();
    +              })
               .build();
     
       private static final ApiMethodDescriptor listMethodDescriptor =
    @@ -214,6 +251,7 @@ public class HttpJsonAddressesStub extends AddressesStub {
               .setResponseParser(
                   ProtoMessageResponseParser.newBuilder()
                       .setDefaultInstance(AddressList.getDefaultInstance())
    +                  .setDefaultTypeRegistry(typeRegistry)
                       .build())
               .build();
     
    @@ -222,11 +260,16 @@ public class HttpJsonAddressesStub extends AddressesStub {
       private final UnaryCallable
           aggregatedListPagedCallable;
       private final UnaryCallable deleteCallable;
    +  private final OperationCallable
    +      deleteOperationCallable;
       private final UnaryCallable insertCallable;
    +  private final OperationCallable
    +      insertOperationCallable;
       private final UnaryCallable listCallable;
       private final UnaryCallable listPagedCallable;
     
       private final BackgroundResource backgroundResources;
    +  private final HttpJsonRegionOperationsStub httpJsonOperationsStub;
       private final HttpJsonStubCallableFactory callableFactory;
     
       public static final HttpJsonAddressesStub create(AddressesStubSettings settings)
    @@ -265,23 +308,29 @@ protected HttpJsonAddressesStub(
           HttpJsonStubCallableFactory callableFactory)
           throws IOException {
         this.callableFactory = callableFactory;
    +    this.httpJsonOperationsStub =
    +        HttpJsonRegionOperationsStub.create(clientContext, callableFactory);
     
         HttpJsonCallSettings
             aggregatedListTransportSettings =
                 HttpJsonCallSettings.newBuilder()
                     .setMethodDescriptor(aggregatedListMethodDescriptor)
    +                .setTypeRegistry(typeRegistry)
                     .build();
         HttpJsonCallSettings deleteTransportSettings =
             HttpJsonCallSettings.newBuilder()
                 .setMethodDescriptor(deleteMethodDescriptor)
    +            .setTypeRegistry(typeRegistry)
                 .build();
         HttpJsonCallSettings insertTransportSettings =
             HttpJsonCallSettings.newBuilder()
                 .setMethodDescriptor(insertMethodDescriptor)
    +            .setTypeRegistry(typeRegistry)
                 .build();
         HttpJsonCallSettings listTransportSettings =
             HttpJsonCallSettings.newBuilder()
                 .setMethodDescriptor(listMethodDescriptor)
    +            .setTypeRegistry(typeRegistry)
                 .build();
     
         this.aggregatedListCallable =
    @@ -293,9 +342,21 @@ protected HttpJsonAddressesStub(
         this.deleteCallable =
             callableFactory.createUnaryCallable(
                 deleteTransportSettings, settings.deleteSettings(), clientContext);
    +    this.deleteOperationCallable =
    +        callableFactory.createOperationCallable(
    +            deleteTransportSettings,
    +            settings.deleteOperationSettings(),
    +            clientContext,
    +            httpJsonOperationsStub);
         this.insertCallable =
             callableFactory.createUnaryCallable(
                 insertTransportSettings, settings.insertSettings(), clientContext);
    +    this.insertOperationCallable =
    +        callableFactory.createOperationCallable(
    +            insertTransportSettings,
    +            settings.insertOperationSettings(),
    +            clientContext,
    +            httpJsonOperationsStub);
         this.listCallable =
             callableFactory.createUnaryCallable(
                 listTransportSettings, settings.listSettings(), clientContext);
    @@ -334,11 +395,21 @@ public UnaryCallable deleteCallable() {
         return deleteCallable;
       }
     
    +  @Override
    +  public OperationCallable deleteOperationCallable() {
    +    return deleteOperationCallable;
    +  }
    +
       @Override
       public UnaryCallable insertCallable() {
         return insertCallable;
       }
     
    +  @Override
    +  public OperationCallable insertOperationCallable() {
    +    return insertOperationCallable;
    +  }
    +
       @Override
       public UnaryCallable listCallable() {
         return listCallable;
    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
    index 6dac14a84e..16d93e6f94 100644
    --- 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
    @@ -17,11 +17,11 @@
     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.HttpJsonOperationSnapshotCallable;
     import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
    +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub;
     import com.google.api.gax.rpc.BatchingCallSettings;
     import com.google.api.gax.rpc.ClientContext;
     import com.google.api.gax.rpc.OperationCallSettings;
    @@ -29,6 +29,7 @@
     import com.google.api.gax.rpc.PagedCallSettings;
     import com.google.api.gax.rpc.UnaryCallSettings;
     import com.google.api.gax.rpc.UnaryCallable;
    +import com.google.longrunning.Operation;
     import javax.annotation.Generated;
     
     // AUTO-GENERATED DOCUMENTATION AND CLASS.
    @@ -40,7 +41,7 @@
     @Generated("by gapic-generator-java")
     @BetaApi
     public class HttpJsonRegionOperationsCallableFactory
    -    implements HttpJsonStubCallableFactory {
    +    implements HttpJsonStubCallableFactory {
     
       @Override
       public  UnaryCallable createUnaryCallable(
    @@ -75,10 +76,18 @@ public  UnaryCallable createBatchingCa
       @Override
       public 
           OperationCallable createOperationCallable(
    -          HttpJsonCallSettings httpJsonCallSettings,
    +          HttpJsonCallSettings httpJsonCallSettings,
               OperationCallSettings callSettings,
               ClientContext clientContext,
    -          BackgroundResource operationsStub) {
    -    return null;
    +          OperationsStub operationsStub) {
    +    UnaryCallable innerCallable =
    +        HttpJsonCallableFactory.createBaseUnaryCallable(
    +            httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
    +    HttpJsonOperationSnapshotCallable initialCallable =
    +        new HttpJsonOperationSnapshotCallable(
    +            innerCallable,
    +            httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory());
    +    return HttpJsonCallableFactory.createOperationCallable(
    +        callSettings, clientContext, operationsStub.longRunningClient(), initialCallable);
       }
     }
    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
    index 9d90915792..0f081f8c40 100644
    --- 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
    @@ -23,16 +23,24 @@
     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.HttpJsonLongRunningClient;
    +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot;
     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.longrunning.OperationSnapshot;
     import com.google.api.gax.rpc.ClientContext;
    +import com.google.api.gax.rpc.LongRunningClient;
     import com.google.api.gax.rpc.UnaryCallable;
     import com.google.cloud.compute.v1.GetRegionOperationRequest;
     import com.google.cloud.compute.v1.Operation;
    +import com.google.cloud.compute.v1.Operation.Status;
    +import com.google.cloud.compute.v1.WaitRegionOperationRequest;
    +import com.google.protobuf.TypeRegistry;
     import java.io.IOException;
     import java.util.ArrayList;
    +import java.util.Arrays;
     import java.util.HashMap;
     import java.util.List;
     import java.util.Map;
    @@ -48,6 +56,8 @@
     @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 TypeRegistry typeRegistry = TypeRegistry.newBuilder().build();
    +
       private static final ApiMethodDescriptor
           getMethodDescriptor =
               ApiMethodDescriptor.newBuilder()
    @@ -78,12 +88,69 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub {
                   .setResponseParser(
                       ProtoMessageResponseParser.newBuilder()
                           .setDefaultInstance(Operation.getDefaultInstance())
    +                      .setDefaultTypeRegistry(typeRegistry)
    +                      .build())
    +              .setOperationSnapshotFactory(
    +                  (GetRegionOperationRequest request, Operation response) -> {
    +                    StringBuilder opName = new StringBuilder(response.getName());
    +                    return HttpJsonOperationSnapshot.newBuilder()
    +                        .setName(opName.toString())
    +                        .setMetadata(response)
    +                        .setDone(Status.DONE.equals(response.getStatus()))
    +                        .setResponse(response)
    +                        .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage())
    +                        .build();
    +                  })
    +              .setPollingRequestFactory(
    +                  compoundOperationId -> {
    +                    List idComponents = Arrays.asList(compoundOperationId.split(":"));
    +                    return GetRegionOperationRequest.newBuilder()
    +                        .setOperation(idComponents.get(0))
    +                        .setProject(idComponents.get(1))
    +                        .setRegion(idComponents.get(2))
    +                        .build();
    +                  })
    +              .build();
    +
    +  private static final ApiMethodDescriptor
    +      waitMethodDescriptor =
    +          ApiMethodDescriptor.newBuilder()
    +              .setFullMethodName("google.cloud.compute.v1.RegionOperations/Wait")
    +              .setHttpMethod(HttpMethods.POST)
    +              .setRequestFormatter(
    +                  ProtoMessageRequestFormatter.newBuilder()
    +                      .setPath(
    +                          "/compute/v1/projects/projects/{project}/regions/{region}/operations/{operation}/wait",
    +                          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())
    +                      .setDefaultTypeRegistry(typeRegistry)
                           .build())
                   .build();
     
       private final UnaryCallable getCallable;
    +  private final UnaryCallable waitCallable;
     
       private final BackgroundResource backgroundResources;
    +  private final LongRunningClient longRunningClient;
       private final HttpJsonStubCallableFactory callableFactory;
     
       public static final HttpJsonRegionOperationsStub create(RegionOperationsStubSettings settings)
    @@ -128,12 +195,26 @@ protected HttpJsonRegionOperationsStub(
         HttpJsonCallSettings getTransportSettings =
             HttpJsonCallSettings.newBuilder()
                 .setMethodDescriptor(getMethodDescriptor)
    +            .setTypeRegistry(typeRegistry)
    +            .build();
    +    HttpJsonCallSettings waitTransportSettings =
    +        HttpJsonCallSettings.newBuilder()
    +            .setMethodDescriptor(waitMethodDescriptor)
    +            .setTypeRegistry(typeRegistry)
                 .build();
     
         this.getCallable =
             callableFactory.createUnaryCallable(
                 getTransportSettings, settings.getSettings(), clientContext);
    +    this.waitCallable =
    +        callableFactory.createUnaryCallable(
    +            waitTransportSettings, settings.waitSettings(), clientContext);
     
    +    this.longRunningClient =
    +        new HttpJsonLongRunningClient(
    +            getCallable,
    +            getMethodDescriptor.getOperationSnapshotFactory(),
    +            getMethodDescriptor.getPollingRequestFactory());
         this.backgroundResources =
             new BackgroundResourceAggregation(clientContext.getBackgroundResources());
       }
    @@ -142,6 +223,7 @@ protected HttpJsonRegionOperationsStub(
       public static List getMethodDescriptors() {
         List methodDescriptors = new ArrayList<>();
         methodDescriptors.add(getMethodDescriptor);
    +    methodDescriptors.add(waitMethodDescriptor);
         return methodDescriptors;
       }
     
    @@ -150,6 +232,16 @@ public UnaryCallable getCallable() {
         return getCallable;
       }
     
    +  @Override
    +  public UnaryCallable waitCallable() {
    +    return waitCallable;
    +  }
    +
    +  @Override
    +  public LongRunningClient longRunningClient() {
    +    return longRunningClient;
    +  }
    +
       @Override
       public final void close() {
         try {
    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
    index c3019038cb..2d40fa610a 100644
    --- 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
    @@ -16,10 +16,13 @@
     
     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.rpc.LongRunningClient;
     import com.google.api.gax.rpc.UnaryCallable;
     import com.google.cloud.compute.v1.GetRegionOperationRequest;
     import com.google.cloud.compute.v1.Operation;
    +import com.google.cloud.compute.v1.WaitRegionOperationRequest;
     import javax.annotation.Generated;
     
     // AUTO-GENERATED DOCUMENTATION AND CLASS.
    @@ -31,10 +34,19 @@
     @Generated("by gapic-generator-java")
     public abstract class RegionOperationsStub implements BackgroundResource {
     
    +  @BetaApi
    +  public LongRunningClient longRunningClient() {
    +    throw new UnsupportedOperationException("Not implemented: longRunningClient()");
    +  }
    +
       public UnaryCallable getCallable() {
         throw new UnsupportedOperationException("Not implemented: getCallable()");
       }
     
    +  public UnaryCallable waitCallable() {
    +    throw new UnsupportedOperationException("Not implemented: waitCallable()");
    +  }
    +
       @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
    index ebcf98e4f7..365c834255 100644
    --- 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
    @@ -33,6 +33,7 @@
     import com.google.api.gax.rpc.UnaryCallSettings;
     import com.google.cloud.compute.v1.GetRegionOperationRequest;
     import com.google.cloud.compute.v1.Operation;
    +import com.google.cloud.compute.v1.WaitRegionOperationRequest;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
    @@ -85,12 +86,18 @@ public class RegionOperationsStubSettings extends StubSettings getSettings;
    +  private final UnaryCallSettings waitSettings;
     
       /** Returns the object with the settings used for calls to get. */
       public UnaryCallSettings getSettings() {
         return getSettings;
       }
     
    +  /** Returns the object with the settings used for calls to wait. */
    +  public UnaryCallSettings waitSettings() {
    +    return waitSettings;
    +  }
    +
       @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
       public RegionOperationsStub createStub() throws IOException {
         if (getTransportChannelProvider()
    @@ -125,7 +132,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. */
    @@ -167,12 +176,14 @@ protected RegionOperationsStubSettings(Builder settingsBuilder) throws IOExcepti
         super(settingsBuilder);
     
         getSettings = settingsBuilder.getSettings().build();
    +    waitSettings = settingsBuilder.waitSettings().build();
       }
     
       /** Builder for RegionOperationsStubSettings. */
       public static class Builder extends StubSettings.Builder {
         private final ImmutableList> unaryMethodSettingsBuilders;
         private final UnaryCallSettings.Builder getSettings;
    +    private final UnaryCallSettings.Builder waitSettings;
         private static final ImmutableMap>
             RETRYABLE_CODE_DEFINITIONS;
     
    @@ -184,6 +195,7 @@ public static class Builder extends StubSettings.BuildernewArrayList(
                       StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE)));
    +      definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList()));
           RETRYABLE_CODE_DEFINITIONS = definitions.build();
         }
     
    @@ -203,6 +215,8 @@ public static class Builder extends StubSettings.Builder>of(getSettings);
    +      unaryMethodSettingsBuilders =
    +          ImmutableList.>of(getSettings, waitSettings);
           initDefaults(this);
         }
     
    @@ -223,8 +239,10 @@ protected Builder(RegionOperationsStubSettings settings) {
           super(settings);
     
           getSettings = settings.getSettings.toBuilder();
    +      waitSettings = settings.waitSettings.toBuilder();
     
    -      unaryMethodSettingsBuilders = ImmutableList.>of(getSettings);
    +      unaryMethodSettingsBuilders =
    +          ImmutableList.>of(getSettings, waitSettings);
         }
     
         private static Builder createDefault() {
    @@ -246,6 +264,11 @@ private static Builder initDefaults(Builder builder) {
               .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes"))
               .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params"));
     
    +      builder
    +          .waitSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes"))
    +          .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params"));
    +
           return builder;
         }
     
    @@ -269,6 +292,11 @@ public UnaryCallSettings.Builder getSettin
           return getSettings;
         }
     
    +    /** Returns the builder for the settings used for calls to wait. */
    +    public UnaryCallSettings.Builder waitSettings() {
    +      return waitSettings;
    +    }
    +
         @Override
         public RegionOperationsStubSettings build() throws IOException {
           return new RegionOperationsStubSettings(this);
    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 45338c519e..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
    @@ -150,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. */
    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 0c1876afa5..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
    @@ -137,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. */
    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 830ca8ca8d..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
    @@ -657,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. */
    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 614a5b7c98..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
    @@ -316,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. */
    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 942d01f547..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
    @@ -526,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. */
    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 ae4a0acbb2..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
    @@ -456,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. */
    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 5694e24035..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
    @@ -224,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. */
    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 a6adbe6945..01e6bd03a6 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
    @@ -485,6 +485,7 @@ public final Subscription createSubscription(
        *           .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
        *           .setRetryPolicy(RetryPolicy.newBuilder().build())
        *           .setDetached(true)
    +   *           .setTopicMessageRetentionDuration(Duration.newBuilder().build())
        *           .build();
        *   Subscription response = subscriptionAdminClient.createSubscription(request);
        * }
    @@ -529,6 +530,7 @@ public final Subscription createSubscription(Subscription request) {
        *           .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
        *           .setRetryPolicy(RetryPolicy.newBuilder().build())
        *           .setDetached(true)
    +   *           .setTopicMessageRetentionDuration(Duration.newBuilder().build())
        *           .build();
        *   ApiFuture future =
        *       subscriptionAdminClient.createSubscriptionCallable().futureCall(request);
    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 dd1bd27dac..9d53a7554a 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
    @@ -149,6 +149,7 @@ public void createSubscriptionTest() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -209,6 +210,7 @@ public void createSubscriptionTest2() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -269,6 +271,7 @@ public void createSubscriptionTest3() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -329,6 +332,7 @@ public void createSubscriptionTest4() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -389,6 +393,7 @@ public void getSubscriptionTest() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -439,6 +444,7 @@ public void getSubscriptionTest2() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    @@ -489,6 +495,7 @@ public void updateSubscriptionTest() throws Exception {
                 .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build())
                 .setRetryPolicy(RetryPolicy.newBuilder().build())
                 .setDetached(true)
    +            .setTopicMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockSubscriber.addResponse(expectedResponse);
     
    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 802fe3e940..be0a3a2e42 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
    @@ -237,6 +237,7 @@ public final Topic createTopic(String name) {
        *           .setKmsKeyName("kmsKeyName412586233")
        *           .setSchemaSettings(SchemaSettings.newBuilder().build())
        *           .setSatisfiesPzs(true)
    +   *           .setMessageRetentionDuration(Duration.newBuilder().build())
        *           .build();
        *   Topic response = topicAdminClient.createTopic(request);
        * }
    @@ -266,6 +267,7 @@ public final Topic createTopic(Topic request) {
        *           .setKmsKeyName("kmsKeyName412586233")
        *           .setSchemaSettings(SchemaSettings.newBuilder().build())
        *           .setSatisfiesPzs(true)
    +   *           .setMessageRetentionDuration(Duration.newBuilder().build())
        *           .build();
        *   ApiFuture future = topicAdminClient.createTopicCallable().futureCall(request);
        *   // Do something.
    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 09b8de0f90..02d6a55850 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
    @@ -37,6 +37,7 @@
     import com.google.iam.v1.TestIamPermissionsResponse;
     import com.google.protobuf.AbstractMessage;
     import com.google.protobuf.ByteString;
    +import com.google.protobuf.Duration;
     import com.google.protobuf.Empty;
     import com.google.protobuf.FieldMask;
     import com.google.pubsub.v1.DeleteTopicRequest;
    @@ -125,6 +126,7 @@ public void createTopicTest() throws Exception {
                 .setKmsKeyName("kmsKeyName412586233")
                 .setSchemaSettings(SchemaSettings.newBuilder().build())
                 .setSatisfiesPzs(true)
    +            .setMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockPublisher.addResponse(expectedResponse);
     
    @@ -168,6 +170,7 @@ public void createTopicTest2() throws Exception {
                 .setKmsKeyName("kmsKeyName412586233")
                 .setSchemaSettings(SchemaSettings.newBuilder().build())
                 .setSatisfiesPzs(true)
    +            .setMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockPublisher.addResponse(expectedResponse);
     
    @@ -211,6 +214,7 @@ public void updateTopicTest() throws Exception {
                 .setKmsKeyName("kmsKeyName412586233")
                 .setSchemaSettings(SchemaSettings.newBuilder().build())
                 .setSatisfiesPzs(true)
    +            .setMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockPublisher.addResponse(expectedResponse);
     
    @@ -341,6 +345,7 @@ public void getTopicTest() throws Exception {
                 .setKmsKeyName("kmsKeyName412586233")
                 .setSchemaSettings(SchemaSettings.newBuilder().build())
                 .setSatisfiesPzs(true)
    +            .setMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockPublisher.addResponse(expectedResponse);
     
    @@ -384,6 +389,7 @@ public void getTopicTest2() throws Exception {
                 .setKmsKeyName("kmsKeyName412586233")
                 .setSchemaSettings(SchemaSettings.newBuilder().build())
                 .setSatisfiesPzs(true)
    +            .setMessageRetentionDuration(Duration.newBuilder().build())
                 .build();
         mockPublisher.addResponse(expectedResponse);
     
    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 e5ea4e34bc..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
    @@ -490,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. */
    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 00489c3f74..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
    @@ -254,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. */
    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 00ad4dd1c6..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
    @@ -395,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. */
    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 c6e6faa442..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
    @@ -306,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. */
    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
    index 7a10ecf5e4..85c8639848 100644
    --- a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java
    +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java
    @@ -157,7 +157,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. */
    diff --git a/version.txt b/version.txt
    index 38f77a65b3..7ec1d6db40 100644
    --- a/version.txt
    +++ b/version.txt
    @@ -1 +1 @@
    -2.0.1
    +2.1.0