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 e8f8a05681..b30416a015 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 @@ -55,6 +55,8 @@ public class ServiceClientCommentComposer { "To customize credentials:"; private static final String SERVICE_DESCRIPTION_ENDPOINT_SUMMARY_STRING = "To customize the endpoint:"; + private static final String SERVICE_DESCRIPTION_TRANSPORT_SUMMARY_STRING = + "To use %s transport (instead of %s) for sending an receiving requests over the wire:"; private static final String SERVICE_DESCRIPTION_SAMPLE_REFERENCE_STRING = "Please refer to the GitHub repository's samples for more quickstart code snippets."; @@ -112,7 +114,10 @@ public static List createClassHeaderComments( Service service, String classMethodSampleCode, String credentialsSampleCode, - String endpointSampleCode) { + String endpointSampleCode, + String transportSampleCode, + String primaryTransport, + String secondaryTransport) { JavaDocComment.Builder classHeaderJavadocBuilder = JavaDocComment.builder(); if (service.hasDescription()) { classHeaderJavadocBuilder = @@ -146,6 +151,12 @@ public static List createClassHeaderComments( classHeaderJavadocBuilder.addSampleCode(credentialsSampleCode); classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_ENDPOINT_SUMMARY_STRING); classHeaderJavadocBuilder.addSampleCode(endpointSampleCode); + if (transportSampleCode != null) { + classHeaderJavadocBuilder.addParagraph( + String.format( + SERVICE_DESCRIPTION_TRANSPORT_SUMMARY_STRING, secondaryTransport, primaryTransport)); + classHeaderJavadocBuilder.addSampleCode(transportSampleCode); + } classHeaderJavadocBuilder.addParagraph(SERVICE_DESCRIPTION_SAMPLE_REFERENCE_STRING); diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java index 8bdfa60ab4..5303f6d680 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java @@ -188,7 +188,7 @@ private static List createClassImplements(TypeStore typeStore) { return Arrays.asList(typeStore.get("BackgroundResource")); } - private static List createClassHeaderComments( + protected List createClassHeaderComments( Service service, TypeStore typeStore, Map resourceNames, @@ -208,7 +208,10 @@ private static List createClassHeaderComments( service, SampleCodeWriter.writeInlineSample(classMethodSampleCode.body()), SampleCodeWriter.writeInlineSample(credentialsSampleCode.body()), - SampleCodeWriter.writeInlineSample(endpointSampleCode.body())); + SampleCodeWriter.writeInlineSample(endpointSampleCode.body()), + null, + null, + null); } private List createClassMethods( 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 index 7529b002cf..e600ada5d2 100644 --- 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 @@ -14,7 +14,21 @@ package com.google.api.generator.gapic.composer.grpcrest; +import com.google.api.generator.engine.ast.CommentStatement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.gapic.composer.comment.ServiceClientCommentComposer; import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer; +import com.google.api.generator.gapic.composer.samplecode.SampleCodeWriter; +import com.google.api.generator.gapic.composer.samplecode.ServiceClientHeaderSampleComposer; +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.Message; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Sample; +import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; +import java.util.List; +import java.util.Map; public class ServiceClientClassComposer extends AbstractServiceClientClassComposer { private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer(); @@ -26,4 +40,37 @@ protected ServiceClientClassComposer() { public static ServiceClientClassComposer instance() { return INSTANCE; } + + @Override + protected List createClassHeaderComments( + Service service, + TypeStore typeStore, + Map resourceNames, + Map messageTypes, + List samples) { + TypeNode clientType = typeStore.get(ClassNames.getServiceClientClassName(service)); + TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); + Sample classMethodSampleCode = + ServiceClientHeaderSampleComposer.composeClassHeaderSample( + service, clientType, resourceNames, messageTypes); + Sample credentialsSampleCode = + ServiceClientHeaderSampleComposer.composeSetCredentialsSample(clientType, settingsType); + Sample endpointSampleCode = + ServiceClientHeaderSampleComposer.composeSetEndpointSample(clientType, settingsType); + Sample transportSampleCode = + ServiceClientHeaderSampleComposer.composeTransportSample( + clientType, settingsType, "defaultHttpJsonTransportProviderBuilder"); + samples.addAll( + Arrays.asList( + classMethodSampleCode, credentialsSampleCode, endpointSampleCode, transportSampleCode)); + + return ServiceClientCommentComposer.createClassHeaderComments( + service, + SampleCodeWriter.writeInlineSample(classMethodSampleCode.body()), + SampleCodeWriter.writeInlineSample(credentialsSampleCode.body()), + SampleCodeWriter.writeInlineSample(endpointSampleCode.body()), + SampleCodeWriter.writeInlineSample(transportSampleCode.body()), + "gRPC", + "REST (HTTP1.1/JSON)"); + } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientHeaderSampleComposer.java b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientHeaderSampleComposer.java index 4ad29804f6..e3673dc7a9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientHeaderSampleComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientHeaderSampleComposer.java @@ -277,6 +277,76 @@ public static Sample composeSetEndpointSample(TypeNode clientType, TypeNode sett return Sample.builder().setBody(sampleBody).setRegionTag(regionTag).build(); } + public static Sample composeTransportSample( + TypeNode clientType, TypeNode settingsType, String transportProviderMethod) { + String settingsName = JavaStyle.toLowerCamelCase(settingsType.reference().name()); + String clientName = JavaStyle.toLowerCamelCase(clientType.reference().name()); + VariableExpr settingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName(settingsName).setType(settingsType).build()); + MethodInvocationExpr newBuilderMethodExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("newBuilder") + .build(); + MethodInvocationExpr transportChannelProviderArg = + MethodInvocationExpr.builder() + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName(transportProviderMethod) + .build()) + .setMethodName("build") + .build(); + MethodInvocationExpr credentialsMethodExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderMethodExpr) + .setArguments(transportChannelProviderArg) + .setMethodName("setTransportChannelProvider") + .build(); + MethodInvocationExpr buildMethodExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credentialsMethodExpr) + .setReturnType(settingsType) + .setMethodName("build") + .build(); + Expr initSettingsVarExpr = + AssignmentExpr.builder() + .setVariableExpr(settingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(buildMethodExpr) + .build(); + + // Initialized client with create() method. + // e.g. EchoClient echoClient = EchoClient.create(echoSettings); + VariableExpr clientVarExpr = + VariableExpr.withVariable( + Variable.builder().setName(clientName).setType(clientType).build()); + MethodInvocationExpr createMethodExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(clientType) + .setArguments(settingsVarExpr) + .setMethodName("create") + .setReturnType(clientType) + .build(); + String rpcName = createMethodExpr.methodIdentifier().name(); + Expr initClientVarExpr = + AssignmentExpr.builder() + .setVariableExpr(clientVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(createMethodExpr) + .build(); + + List sampleBody = + Arrays.asList( + ExprStatement.withExpr(initSettingsVarExpr), ExprStatement.withExpr(initClientVarExpr)); + RegionTag regionTag = + RegionTag.builder() + .setServiceName(clientName) + .setRpcName(rpcName) + .setOverloadDisambiguation("setCredentialsProvider") + .build(); + return Sample.builder().setBody(sampleBody).setRegionTag(regionTag).build(); + } + // Create a list of RPC method arguments' variable expressions. private static List createArgumentVariableExprs(List arguments) { return arguments.stream() diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestTestProtoLoader.java new file mode 100644 index 0000000000..375204be59 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestTestProtoLoader.java @@ -0,0 +1,84 @@ +// Copyright 2022 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.api.generator.gapic.composer.common.TestProtoLoader; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.GapicServiceConfig; +import com.google.api.generator.gapic.model.Message; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.model.Transport; +import com.google.api.generator.gapic.protoparser.Parser; +import com.google.api.generator.gapic.protoparser.ServiceConfigParser; +import com.google.longrunning.OperationsProto; +import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.ServiceDescriptor; +import com.google.showcase.grpcrest.v1beta1.EchoGrpcrest; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public class GrpcRestTestProtoLoader extends TestProtoLoader { + private static final GrpcRestTestProtoLoader INSTANCE = new GrpcRestTestProtoLoader(); + + protected GrpcRestTestProtoLoader() { + super(Transport.GRPC_REST, "src/test/resources/"); + } + + public static GrpcRestTestProtoLoader instance() { + return INSTANCE; + } + + @Override + public GapicContext parseShowcaseEcho() { + FileDescriptor echoFileDescriptor = EchoGrpcrest.getDescriptor(); + + ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); + assertEquals("Echo", echoServiceDescriptor.getName()); + + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + Map operationMessageTypes = + Parser.parseMessages(OperationsProto.getDescriptor()); + messageTypes.putAll(operationMessageTypes); + Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); + + String jsonFilename = "showcase_grpc_service_config.json"; + Path jsonPath = Paths.get(getTestFilesDirectory(), jsonFilename); + Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); + assertTrue(configOpt.isPresent()); + GapicServiceConfig config = configOpt.get(); + + return GapicContext.builder() + .setMessages(messageTypes) + .setResourceNames(resourceNames) + .setServices(services) + .setServiceConfig(config) + .setHelperResourceNames(outputResourceNames) + .setTransport(getTransport()) + .build(); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceCallableFactoryClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceCallableFactoryClassComposerTest.java new file mode 100644 index 0000000000..dc6adc72fe --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceCallableFactoryClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.grpc.GrpcServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class GrpcServiceCallableFactoryClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + GrpcServiceCallableFactoryClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "GrpcEchoCallableFactory.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcEchoCallableFactory.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceStubClassComposerTest.java new file mode 100644 index 0000000000..f9385b56b1 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/GrpcServiceStubClassComposerTest.java @@ -0,0 +1,41 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.grpc.GrpcServiceStubClassComposer; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class GrpcServiceStubClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "GrpcEchoStub.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcEchoStub.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceCallableFactoryClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceCallableFactoryClassComposerTest.java new file mode 100644 index 0000000000..249013974f --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceCallableFactoryClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.rest.HttpJsonServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class HttpJsonServiceCallableFactoryClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "HttpJsonEchoCallableFactory.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "HttpJsonEchoCallableFactory.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposerTest.java new file mode 100644 index 0000000000..23d0a9adb3 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2022 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 static com.google.api.generator.test.framework.Assert.assertCodeEquals; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class HttpJsonServiceClientTestClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + HttpJsonServiceClientTestClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "EchoClientHttpJsonTest.golden", visitor.write()); + Path goldenFilePath = + Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClientHttpJsonTest.golden"); + assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposerTest.java new file mode 100644 index 0000000000..87f21c8872 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposerTest.java @@ -0,0 +1,41 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class HttpJsonServiceStubClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + HttpJsonServiceStubClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "HttpJsonEchoStub.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "HttpJsonEchoStub.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposerTest.java new file mode 100644 index 0000000000..ff499acd8b --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposerTest.java @@ -0,0 +1,40 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceClientClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = ServiceClientClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "EchoClient.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClient.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientTestClassComposerTest.java new file mode 100644 index 0000000000..d7d4053f07 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientTestClassComposerTest.java @@ -0,0 +1,43 @@ +// Copyright 2022 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 static com.google.api.generator.test.framework.Assert.assertCodeEquals; + +import com.google.api.generator.engine.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.composer.grpc.ServiceClientTestClassComposer; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceClientTestClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = + ServiceClientTestClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "EchoClientTest.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClientTest.golden"); + assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposerTest.java new file mode 100644 index 0000000000..8ccca9269b --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposerTest.java @@ -0,0 +1,40 @@ +// Copyright 2022 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.writer.JavaWriterVisitor; +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.test.framework.Assert; +import com.google.api.generator.test.framework.Utils; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; + +public class ServiceSettingsClassComposerTest { + @Test + public void generateServiceClasses() { + GapicContext context = GrpcRestTestProtoLoader.instance().parseShowcaseEcho(); + Service echoProtoService = context.services().get(0); + GapicClass clazz = ServiceSettingsClassComposer.instance().generate(context, echoProtoService); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "EchoSettings.golden", visitor.write()); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoSettings.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClient.golden new file mode 100644 index 0000000000..b54b8bbb64 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClient.golden @@ -0,0 +1,992 @@ +package com.google.showcase.grpcrest.v1beta1; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.longrunning.OperationsClient; +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.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.resourcenames.ResourceName; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.longrunning.Operation; +import com.google.protobuf.Duration; +import com.google.protobuf.Timestamp; +import com.google.rpc.Status; +import com.google.showcase.grpcrest.v1beta1.stub.EchoStub; +import com.google.showcase.grpcrest.v1beta1.stub.EchoStubSettings; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * This class provides the ability to make remote calls to the backing service through method calls + * that map to API methods. Sample code to get started: + * + *
{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * try (EchoClient echoClient = EchoClient.create()) {
+ *   EchoResponse response = echoClient.echo();
+ * }
+ * }
+ * + *

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

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

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

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

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

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

To customize credentials: + * + *

{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * EchoSettings echoSettings =
+ *     EchoSettings.newBuilder()
+ *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ *         .build();
+ * EchoClient echoClient = EchoClient.create(echoSettings);
+ * }
+ * + *

To customize the endpoint: + * + *

{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * EchoSettings echoSettings = EchoSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * EchoClient echoClient = EchoClient.create(echoSettings);
+ * }
+ * + *

To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending an receiving requests over + * the wire: + * + *

{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * EchoSettings echoSettings =
+ *     EchoSettings.newBuilder()
+ *         .setTransportChannelProvider(
+ *             EchoSettings.defaultHttpJsonTransportProviderBuilder().build())
+ *         .build();
+ * EchoClient echoClient = EchoClient.create(echoSettings);
+ * }
+ * + *

Please refer to the GitHub repository's samples for more quickstart code snippets. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class EchoClient implements BackgroundResource { + private final EchoSettings settings; + private final EchoStub stub; + private final OperationsClient httpJsonOperationsClient; + private final com.google.longrunning.OperationsClient operationsClient; + + /** Constructs an instance of EchoClient with default settings. */ + public static final EchoClient create() throws IOException { + return create(EchoSettings.newBuilder().build()); + } + + /** + * Constructs an instance of EchoClient, using the given settings. The channels are created based + * on the settings passed in, or defaults for any settings that are not set. + */ + public static final EchoClient create(EchoSettings settings) throws IOException { + return new EchoClient(settings); + } + + /** + * Constructs an instance of EchoClient, using the given stub for making calls. This is for + * advanced usage - prefer using create(EchoSettings). + */ + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public static final EchoClient create(EchoStub stub) { + return new EchoClient(stub); + } + + /** + * Constructs an instance of EchoClient, using the given settings. This is protected so that it is + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected EchoClient(EchoSettings settings) throws IOException { + this.settings = settings; + this.stub = ((EchoStubSettings) settings.getStubSettings()).createStub(); + this.operationsClient = + com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub()); + this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub()); + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + protected EchoClient(EchoStub stub) { + this.settings = null; + this.stub = stub; + this.operationsClient = + com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub()); + this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub()); + } + + public final EchoSettings getSettings() { + return settings; + } + + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") + public EchoStub getStub() { + return stub; + } + + /** + * Returns the OperationsClient that can be used to query the status of a long-running operation + * returned by another API method call. + */ + public final com.google.longrunning.OperationsClient getOperationsClient() { + return operationsClient; + } + + /** + * Returns the OperationsClient that can be used to query the status of a long-running operation + * returned by another API method call. + */ + public final OperationsClient getHttpJsonOperationsClient() { + return httpJsonOperationsClient; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *

{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoResponse response = echoClient.echo();
+   * }
+   * }
+ * + * @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 EchoResponse echo() { + EchoRequest request = EchoRequest.newBuilder().build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+   *   EchoResponse response = echoClient.echo(parent);
+   * }
+   * }
+ * + * @param parent + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(ResourceName parent) { + EchoRequest request = + EchoRequest.newBuilder().setParent(parent == null ? null : parent.toString()).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   Status error = Status.newBuilder().build();
+   *   EchoResponse response = echoClient.echo(error);
+   * }
+   * }
+ * + * @param error + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(Status error) { + EchoRequest request = EchoRequest.newBuilder().setError(error).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   FoobarName name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+   *   EchoResponse response = echoClient.echo(name);
+   * }
+   * }
+ * + * @param name + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(FoobarName name) { + EchoRequest request = + EchoRequest.newBuilder().setName(name == null ? null : name.toString()).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   String content = "content951530617";
+   *   EchoResponse response = echoClient.echo(content);
+   * }
+   * }
+ * + * @param content + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(String content) { + EchoRequest request = EchoRequest.newBuilder().setContent(content).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   String name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString();
+   *   EchoResponse response = echoClient.echo(name);
+   * }
+   * }
+ * + * @param name + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(String name) { + EchoRequest request = EchoRequest.newBuilder().setName(name).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   String parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString();
+   *   EchoResponse response = echoClient.echo(parent);
+   * }
+   * }
+ * + * @param parent + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(String parent) { + EchoRequest request = EchoRequest.newBuilder().setParent(parent).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   String content = "content951530617";
+   *   Severity severity = Severity.forNumber(0);
+   *   EchoResponse response = echoClient.echo(content, severity);
+   * }
+   * }
+ * + * @param content + * @param severity + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final EchoResponse echo(String content, Severity severity) { + EchoRequest request = + EchoRequest.newBuilder().setContent(content).setSeverity(severity).build(); + return echo(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   EchoResponse response = echoClient.echo(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 EchoResponse echo(EchoRequest request) { + return echoCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   ApiFuture future = echoClient.echoCallable().futureCall(request);
+   *   // Do something.
+   *   EchoResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable echoCallable() { + return stub.echoCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   ExpandRequest request =
+   *       ExpandRequest.newBuilder().setContent("content951530617").setInfo("info3237038").build();
+   *   ServerStream stream = echoClient.expandCallable().call(request);
+   *   for (EchoResponse response : stream) {
+   *     // Do something when a response is received.
+   *   }
+   * }
+   * }
+ */ + public final ServerStreamingCallable expandCallable() { + return stub.expandCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   for (EchoResponse element : echoClient.pagedExpand(request).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final PagedExpandPagedResponse pagedExpand(PagedExpandRequest request) { + return pagedExpandPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   ApiFuture future = echoClient.pagedExpandPagedCallable().futureCall(request);
+   *   // Do something.
+   *   for (EchoResponse element : future.get().iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable + pagedExpandPagedCallable() { + return stub.pagedExpandPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   while (true) {
+   *     PagedExpandResponse response = echoClient.pagedExpandCallable().call(request);
+   *     for (EchoResponse element : response.getResponsesList()) {
+   *       // doThingsWith(element);
+   *     }
+   *     String nextPageToken = response.getNextPageToken();
+   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
+   *       request = request.toBuilder().setPageToken(nextPageToken).build();
+   *     } else {
+   *       break;
+   *     }
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable pagedExpandCallable() { + return stub.pagedExpandCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   for (EchoResponse element : echoClient.simplePagedExpand().iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final SimplePagedExpandPagedResponse simplePagedExpand() { + PagedExpandRequest request = PagedExpandRequest.newBuilder().build(); + return simplePagedExpand(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   for (EchoResponse element : echoClient.simplePagedExpand(request).iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final SimplePagedExpandPagedResponse simplePagedExpand(PagedExpandRequest request) { + return simplePagedExpandPagedCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   ApiFuture future =
+   *       echoClient.simplePagedExpandPagedCallable().futureCall(request);
+   *   // Do something.
+   *   for (EchoResponse element : future.get().iterateAll()) {
+   *     // doThingsWith(element);
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable + simplePagedExpandPagedCallable() { + return stub.simplePagedExpandPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   PagedExpandRequest request =
+   *       PagedExpandRequest.newBuilder()
+   *           .setContent("content951530617")
+   *           .setPageSize(883849137)
+   *           .setPageToken("pageToken873572522")
+   *           .build();
+   *   while (true) {
+   *     PagedExpandResponse response = echoClient.simplePagedExpandCallable().call(request);
+   *     for (EchoResponse element : response.getResponsesList()) {
+   *       // doThingsWith(element);
+   *     }
+   *     String nextPageToken = response.getNextPageToken();
+   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
+   *       request = request.toBuilder().setPageToken(nextPageToken).build();
+   *     } else {
+   *       break;
+   *     }
+   *   }
+   * }
+   * }
+ */ + public final UnaryCallable simplePagedExpandCallable() { + return stub.simplePagedExpandCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   Duration ttl = Duration.newBuilder().build();
+   *   WaitResponse response = echoClient.waitAsync(ttl).get();
+   * }
+   * }
+ * + * @param ttl + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final OperationFuture waitAsync(Duration ttl) { + WaitRequest request = WaitRequest.newBuilder().setTtl(ttl).build(); + return waitAsync(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   Timestamp endTime = Timestamp.newBuilder().build();
+   *   WaitResponse response = echoClient.waitAsync(endTime).get();
+   * }
+   * }
+ * + * @param endTime + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final OperationFuture waitAsync(Timestamp endTime) { + WaitRequest request = WaitRequest.newBuilder().setEndTime(endTime).build(); + return waitAsync(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   WaitRequest request = WaitRequest.newBuilder().build();
+   *   WaitResponse response = echoClient.waitAsync(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 OperationFuture waitAsync(WaitRequest request) { + return waitOperationCallable().futureCall(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   WaitRequest request = WaitRequest.newBuilder().build();
+   *   OperationFuture future =
+   *       echoClient.waitOperationCallable().futureCall(request);
+   *   // Do something.
+   *   WaitResponse response = future.get();
+   * }
+   * }
+ */ + public final OperationCallable waitOperationCallable() { + return stub.waitOperationCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   WaitRequest request = WaitRequest.newBuilder().build();
+   *   ApiFuture future = echoClient.waitCallable().futureCall(request);
+   *   // Do something.
+   *   Operation response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable waitCallable() { + return stub.waitCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   BlockRequest request = BlockRequest.newBuilder().build();
+   *   BlockResponse response = echoClient.block(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 BlockResponse block(BlockRequest request) { + return blockCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   BlockRequest request = BlockRequest.newBuilder().build();
+   *   ApiFuture future = echoClient.blockCallable().futureCall(request);
+   *   // Do something.
+   *   BlockResponse response = future.get();
+   * }
+   * }
+ */ + public final UnaryCallable blockCallable() { + return stub.blockCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   Object response = echoClient.collideName(request);
+   * }
+   * }
+ * + * @param request The request object containing all of the parameters for the API call. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Object collideName(EchoRequest request) { + return collideNameCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Sample code: + * + *
{@code
+   * // This snippet has been automatically generated for illustrative purposes only.
+   * // It may require modifications to work in your environment.
+   * try (EchoClient echoClient = EchoClient.create()) {
+   *   EchoRequest request =
+   *       EchoRequest.newBuilder()
+   *           .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+   *           .setSeverity(Severity.forNumber(0))
+   *           .setFoobar(Foobar.newBuilder().build())
+   *           .build();
+   *   ApiFuture future = echoClient.collideNameCallable().futureCall(request);
+   *   // Do something.
+   *   Object response = future.get();
+   * }
+   * }
+   */
+  public final UnaryCallable collideNameCallable() {
+    return stub.collideNameCallable();
+  }
+
+  @Override
+  public final void close() {
+    stub.close();
+  }
+
+  @Override
+  public void shutdown() {
+    stub.shutdown();
+  }
+
+  @Override
+  public boolean isShutdown() {
+    return stub.isShutdown();
+  }
+
+  @Override
+  public boolean isTerminated() {
+    return stub.isTerminated();
+  }
+
+  @Override
+  public void shutdownNow() {
+    stub.shutdownNow();
+  }
+
+  @Override
+  public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException {
+    return stub.awaitTermination(duration, unit);
+  }
+
+  public static class PagedExpandPagedResponse
+      extends AbstractPagedListResponse<
+          PagedExpandRequest,
+          PagedExpandResponse,
+          EchoResponse,
+          PagedExpandPage,
+          PagedExpandFixedSizeCollection> {
+
+    public static ApiFuture createAsync(
+        PageContext context,
+        ApiFuture futureResponse) {
+      ApiFuture futurePage =
+          PagedExpandPage.createEmptyPage().createPageAsync(context, futureResponse);
+      return ApiFutures.transform(
+          futurePage, input -> new PagedExpandPagedResponse(input), MoreExecutors.directExecutor());
+    }
+
+    private PagedExpandPagedResponse(PagedExpandPage page) {
+      super(page, PagedExpandFixedSizeCollection.createEmptyCollection());
+    }
+  }
+
+  public static class PagedExpandPage
+      extends AbstractPage {
+
+    private PagedExpandPage(
+        PageContext context,
+        PagedExpandResponse response) {
+      super(context, response);
+    }
+
+    private static PagedExpandPage createEmptyPage() {
+      return new PagedExpandPage(null, null);
+    }
+
+    @Override
+    protected PagedExpandPage createPage(
+        PageContext context,
+        PagedExpandResponse response) {
+      return new PagedExpandPage(context, response);
+    }
+
+    @Override
+    public ApiFuture createPageAsync(
+        PageContext context,
+        ApiFuture futureResponse) {
+      return super.createPageAsync(context, futureResponse);
+    }
+  }
+
+  public static class PagedExpandFixedSizeCollection
+      extends AbstractFixedSizeCollection<
+          PagedExpandRequest,
+          PagedExpandResponse,
+          EchoResponse,
+          PagedExpandPage,
+          PagedExpandFixedSizeCollection> {
+
+    private PagedExpandFixedSizeCollection(List pages, int collectionSize) {
+      super(pages, collectionSize);
+    }
+
+    private static PagedExpandFixedSizeCollection createEmptyCollection() {
+      return new PagedExpandFixedSizeCollection(null, 0);
+    }
+
+    @Override
+    protected PagedExpandFixedSizeCollection createCollection(
+        List pages, int collectionSize) {
+      return new PagedExpandFixedSizeCollection(pages, collectionSize);
+    }
+  }
+
+  public static class SimplePagedExpandPagedResponse
+      extends AbstractPagedListResponse<
+          PagedExpandRequest,
+          PagedExpandResponse,
+          EchoResponse,
+          SimplePagedExpandPage,
+          SimplePagedExpandFixedSizeCollection> {
+
+    public static ApiFuture createAsync(
+        PageContext context,
+        ApiFuture futureResponse) {
+      ApiFuture futurePage =
+          SimplePagedExpandPage.createEmptyPage().createPageAsync(context, futureResponse);
+      return ApiFutures.transform(
+          futurePage,
+          input -> new SimplePagedExpandPagedResponse(input),
+          MoreExecutors.directExecutor());
+    }
+
+    private SimplePagedExpandPagedResponse(SimplePagedExpandPage page) {
+      super(page, SimplePagedExpandFixedSizeCollection.createEmptyCollection());
+    }
+  }
+
+  public static class SimplePagedExpandPage
+      extends AbstractPage<
+          PagedExpandRequest, PagedExpandResponse, EchoResponse, SimplePagedExpandPage> {
+
+    private SimplePagedExpandPage(
+        PageContext context,
+        PagedExpandResponse response) {
+      super(context, response);
+    }
+
+    private static SimplePagedExpandPage createEmptyPage() {
+      return new SimplePagedExpandPage(null, null);
+    }
+
+    @Override
+    protected SimplePagedExpandPage createPage(
+        PageContext context,
+        PagedExpandResponse response) {
+      return new SimplePagedExpandPage(context, response);
+    }
+
+    @Override
+    public ApiFuture createPageAsync(
+        PageContext context,
+        ApiFuture futureResponse) {
+      return super.createPageAsync(context, futureResponse);
+    }
+  }
+
+  public static class SimplePagedExpandFixedSizeCollection
+      extends AbstractFixedSizeCollection<
+          PagedExpandRequest,
+          PagedExpandResponse,
+          EchoResponse,
+          SimplePagedExpandPage,
+          SimplePagedExpandFixedSizeCollection> {
+
+    private SimplePagedExpandFixedSizeCollection(
+        List pages, int collectionSize) {
+      super(pages, collectionSize);
+    }
+
+    private static SimplePagedExpandFixedSizeCollection createEmptyCollection() {
+      return new SimplePagedExpandFixedSizeCollection(null, 0);
+    }
+
+    @Override
+    protected SimplePagedExpandFixedSizeCollection createCollection(
+        List pages, int collectionSize) {
+      return new SimplePagedExpandFixedSizeCollection(pages, collectionSize);
+    }
+  }
+}
diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientHttpJsonTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientHttpJsonTest.golden
new file mode 100644
index 0000000000..14a0782783
--- /dev/null
+++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientHttpJsonTest.golden
@@ -0,0 +1,747 @@
+package com.google.showcase.grpcrest.v1beta1;
+
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.PagedExpandPagedResponse;
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.SimplePagedExpandPagedResponse;
+
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.testing.MockHttpService;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ApiExceptionFactory;
+import com.google.api.gax.rpc.InvalidArgumentException;
+import com.google.api.gax.rpc.StatusCode;
+import com.google.api.gax.rpc.testing.FakeStatusCode;
+import com.google.api.resourcenames.ResourceName;
+import com.google.common.collect.Lists;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Any;
+import com.google.protobuf.Duration;
+import com.google.protobuf.Timestamp;
+import com.google.rpc.Status;
+import com.google.showcase.grpcrest.v1beta1.stub.HttpJsonEchoStub;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Generated;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+@Generated("by gapic-generator-java")
+public class EchoClientHttpJsonTest {
+  private static MockHttpService mockService;
+  private static EchoClient client;
+
+  @BeforeClass
+  public static void startStaticServer() throws IOException {
+    mockService =
+        new MockHttpService(
+            HttpJsonEchoStub.getMethodDescriptors(), EchoSettings.getDefaultEndpoint());
+    EchoSettings settings =
+        EchoSettings.newHttpJsonBuilder()
+            .setTransportChannelProvider(
+                EchoSettings.defaultHttpJsonTransportProviderBuilder()
+                    .setHttpTransport(mockService)
+                    .build())
+            .setCredentialsProvider(NoCredentialsProvider.create())
+            .build();
+    client = EchoClient.create(settings);
+  }
+
+  @AfterClass
+  public static void stopServer() {
+    client.close();
+  }
+
+  @Before
+  public void setUp() {}
+
+  @After
+  public void tearDown() throws Exception {
+    mockService.reset();
+  }
+
+  @Test
+  public void echoTest() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    EchoResponse actualResponse = client.echo();
+    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 echoExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      EchoRequest request =
+          EchoRequest.newBuilder()
+              .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setSeverity(Severity.forNumber(0))
+              .setFoobar(Foobar.newBuilder().build())
+              .build();
+      client.echo(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest2() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+
+    EchoResponse actualResponse = client.echo(parent);
+    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 echoExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+      client.echo(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest3() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    Status error = Status.newBuilder().build();
+
+    EchoResponse actualResponse = client.echo(error);
+    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 echoExceptionTest3() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      Status error = Status.newBuilder().build();
+      client.echo(error);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest4() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    FoobarName name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+
+    EchoResponse actualResponse = client.echo(name);
+    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 echoExceptionTest4() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      FoobarName name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+      client.echo(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest5() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String content = "content951530617";
+
+    EchoResponse actualResponse = client.echo(content);
+    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 echoExceptionTest5() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String content = "content951530617";
+      client.echo(content);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest6() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "name3373707";
+
+    EchoResponse actualResponse = client.echo(name);
+    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 echoExceptionTest6() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "name3373707";
+      client.echo(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest7() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "parent-995424086";
+
+    EchoResponse actualResponse = client.echo(parent);
+    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 echoExceptionTest7() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "parent-995424086";
+      client.echo(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest8() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String content = "content951530617";
+    Severity severity = Severity.forNumber(0);
+
+    EchoResponse actualResponse = client.echo(content, severity);
+    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 echoExceptionTest8() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String content = "content951530617";
+      Severity severity = Severity.forNumber(0);
+      client.echo(content, severity);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void expandTest() throws Exception {}
+
+  @Test
+  public void expandExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+  }
+
+  @Test
+  public void pagedExpandTest() throws Exception {
+    EchoResponse responsesElement = EchoResponse.newBuilder().build();
+    PagedExpandResponse expectedResponse =
+        PagedExpandResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllResponses(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    PagedExpandRequest request =
+        PagedExpandRequest.newBuilder()
+            .setContent("content951530617")
+            .setPageSize(883849137)
+            .setPageToken("pageToken873572522")
+            .build();
+
+    PagedExpandPagedResponse pagedListResponse = client.pagedExpand(request);
+
+    List resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getResponsesList().get(0), resources.get(0));
+
+    List actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void pagedExpandExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      PagedExpandRequest request =
+          PagedExpandRequest.newBuilder()
+              .setContent("content951530617")
+              .setPageSize(883849137)
+              .setPageToken("pageToken873572522")
+              .build();
+      client.pagedExpand(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void simplePagedExpandTest() throws Exception {
+    EchoResponse responsesElement = EchoResponse.newBuilder().build();
+    PagedExpandResponse expectedResponse =
+        PagedExpandResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllResponses(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    SimplePagedExpandPagedResponse pagedListResponse = client.simplePagedExpand();
+
+    List resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getResponsesList().get(0), resources.get(0));
+
+    List actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void simplePagedExpandExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      PagedExpandRequest request =
+          PagedExpandRequest.newBuilder()
+              .setContent("content951530617")
+              .setPageSize(883849137)
+              .setPageToken("pageToken873572522")
+              .build();
+      client.simplePagedExpand(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void waitTest() throws Exception {
+    WaitResponse expectedResponse =
+        WaitResponse.newBuilder().setContent("content951530617").build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("waitTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    Duration ttl = Duration.newBuilder().build();
+
+    WaitResponse actualResponse = client.waitAsync(ttl).get();
+    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 {
+      Duration ttl = Duration.newBuilder().build();
+      client.waitAsync(ttl).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void waitTest2() throws Exception {
+    WaitResponse expectedResponse =
+        WaitResponse.newBuilder().setContent("content951530617").build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("waitTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    Timestamp endTime = Timestamp.newBuilder().build();
+
+    WaitResponse actualResponse = client.waitAsync(endTime).get();
+    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 waitExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      Timestamp endTime = Timestamp.newBuilder().build();
+      client.waitAsync(endTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void blockTest() throws Exception {
+    BlockResponse expectedResponse =
+        BlockResponse.newBuilder().setContent("content951530617").build();
+    mockService.addResponse(expectedResponse);
+
+    BlockRequest request = BlockRequest.newBuilder().build();
+
+    BlockResponse actualResponse = client.block(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void blockExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      BlockRequest request = BlockRequest.newBuilder().build();
+      client.block(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void collideNameTest() throws Exception {
+    Object expectedResponse = Object.newBuilder().setContent("content951530617").build();
+    mockService.addResponse(expectedResponse);
+
+    EchoRequest request =
+        EchoRequest.newBuilder()
+            .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setSeverity(Severity.forNumber(0))
+            .setFoobar(Foobar.newBuilder().build())
+            .build();
+
+    Object actualResponse = client.collideName(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = 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 collideNameExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      EchoRequest request =
+          EchoRequest.newBuilder()
+              .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setSeverity(Severity.forNumber(0))
+              .setFoobar(Foobar.newBuilder().build())
+              .build();
+      client.collideName(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+}
diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientTest.golden
new file mode 100644
index 0000000000..1b9556231e
--- /dev/null
+++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoClientTest.golden
@@ -0,0 +1,716 @@
+package com.google.showcase.grpcrest.v1beta1;
+
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.PagedExpandPagedResponse;
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.SimplePagedExpandPagedResponse;
+
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.GaxGrpcProperties;
+import com.google.api.gax.grpc.testing.LocalChannelProvider;
+import com.google.api.gax.grpc.testing.MockGrpcService;
+import com.google.api.gax.grpc.testing.MockServiceHelper;
+import com.google.api.gax.grpc.testing.MockStreamObserver;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.InvalidArgumentException;
+import com.google.api.gax.rpc.ServerStreamingCallable;
+import com.google.api.gax.rpc.StatusCode;
+import com.google.api.resourcenames.ResourceName;
+import com.google.common.collect.Lists;
+import com.google.longrunning.Operation;
+import com.google.protobuf.AbstractMessage;
+import com.google.protobuf.Any;
+import com.google.protobuf.Duration;
+import com.google.protobuf.Timestamp;
+import com.google.rpc.Status;
+import io.grpc.StatusRuntimeException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Generated;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+@Generated("by gapic-generator-java")
+public class EchoClientTest {
+  private static MockEcho mockEcho;
+  private static MockServiceHelper mockServiceHelper;
+  private LocalChannelProvider channelProvider;
+  private EchoClient client;
+
+  @BeforeClass
+  public static void startStaticServer() {
+    mockEcho = new MockEcho();
+    mockServiceHelper =
+        new MockServiceHelper(
+            UUID.randomUUID().toString(), Arrays.asList(mockEcho));
+    mockServiceHelper.start();
+  }
+
+  @AfterClass
+  public static void stopServer() {
+    mockServiceHelper.stop();
+  }
+
+  @Before
+  public void setUp() throws IOException {
+    mockServiceHelper.reset();
+    channelProvider = mockServiceHelper.createChannelProvider();
+    EchoSettings settings =
+        EchoSettings.newBuilder()
+            .setTransportChannelProvider(channelProvider)
+            .setCredentialsProvider(NoCredentialsProvider.create())
+            .build();
+    client = EchoClient.create(settings);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    client.close();
+  }
+
+  @Test
+  public void echoTest() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    EchoResponse actualResponse = client.echo();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      EchoRequest request =
+          EchoRequest.newBuilder()
+              .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setSeverity(Severity.forNumber(0))
+              .setFoobar(Foobar.newBuilder().build())
+              .build();
+      client.echo(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest2() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+
+    EchoResponse actualResponse = client.echo(parent);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(parent.toString(), actualRequest.getParent());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest2() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+      client.echo(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest3() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    Status error = Status.newBuilder().build();
+
+    EchoResponse actualResponse = client.echo(error);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(error, actualRequest.getError());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest3() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      Status error = Status.newBuilder().build();
+      client.echo(error);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest4() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    FoobarName name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+
+    EchoResponse actualResponse = client.echo(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(name.toString(), actualRequest.getName());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest4() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      FoobarName name = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]");
+      client.echo(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest5() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    String content = "content951530617";
+
+    EchoResponse actualResponse = client.echo(content);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(content, actualRequest.getContent());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest5() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      String content = "content951530617";
+      client.echo(content);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest6() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    String name = "name3373707";
+
+    EchoResponse actualResponse = client.echo(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(name, actualRequest.getName());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest6() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      String name = "name3373707";
+      client.echo(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest7() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    String parent = "parent-995424086";
+
+    EchoResponse actualResponse = client.echo(parent);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(parent, actualRequest.getParent());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest7() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      String parent = "parent-995424086";
+      client.echo(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void echoTest8() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    String content = "content951530617";
+    Severity severity = Severity.forNumber(0);
+
+    EchoResponse actualResponse = client.echo(content, severity);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(content, actualRequest.getContent());
+    Assert.assertEquals(severity, actualRequest.getSeverity());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void echoExceptionTest8() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      String content = "content951530617";
+      Severity severity = Severity.forNumber(0);
+      client.echo(content, severity);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void expandTest() throws Exception {
+    EchoResponse expectedResponse =
+        EchoResponse.newBuilder()
+            .setContent("content951530617")
+            .setSeverity(Severity.forNumber(0))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+    ExpandRequest request =
+        ExpandRequest.newBuilder().setContent("content951530617").setInfo("info3237038").build();
+
+    MockStreamObserver responseObserver = new MockStreamObserver<>();
+
+    ServerStreamingCallable callable = client.expandCallable();
+    callable.serverStreamingCall(request, responseObserver);
+
+    List actualResponses = responseObserver.future().get();
+    Assert.assertEquals(1, actualResponses.size());
+    Assert.assertEquals(expectedResponse, actualResponses.get(0));
+  }
+
+  @Test
+  public void expandExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+    ExpandRequest request =
+        ExpandRequest.newBuilder().setContent("content951530617").setInfo("info3237038").build();
+
+    MockStreamObserver responseObserver = new MockStreamObserver<>();
+
+    ServerStreamingCallable callable = client.expandCallable();
+    callable.serverStreamingCall(request, responseObserver);
+
+    try {
+      List actualResponses = responseObserver.future().get();
+      Assert.fail("No exception thrown");
+    } catch (ExecutionException e) {
+      Assert.assertTrue(e.getCause() instanceof InvalidArgumentException);
+      InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause());
+      Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode());
+    }
+  }
+
+  @Test
+  public void pagedExpandTest() throws Exception {
+    EchoResponse responsesElement = EchoResponse.newBuilder().build();
+    PagedExpandResponse expectedResponse =
+        PagedExpandResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllResponses(Arrays.asList(responsesElement))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    PagedExpandRequest request =
+        PagedExpandRequest.newBuilder()
+            .setContent("content951530617")
+            .setPageSize(883849137)
+            .setPageToken("pageToken873572522")
+            .build();
+
+    PagedExpandPagedResponse pagedListResponse = client.pagedExpand(request);
+
+    List resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getResponsesList().get(0), resources.get(0));
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    PagedExpandRequest actualRequest = ((PagedExpandRequest) actualRequests.get(0));
+
+    Assert.assertEquals(request.getContent(), actualRequest.getContent());
+    Assert.assertEquals(request.getPageSize(), actualRequest.getPageSize());
+    Assert.assertEquals(request.getPageToken(), actualRequest.getPageToken());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void pagedExpandExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      PagedExpandRequest request =
+          PagedExpandRequest.newBuilder()
+              .setContent("content951530617")
+              .setPageSize(883849137)
+              .setPageToken("pageToken873572522")
+              .build();
+      client.pagedExpand(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void simplePagedExpandTest() throws Exception {
+    EchoResponse responsesElement = EchoResponse.newBuilder().build();
+    PagedExpandResponse expectedResponse =
+        PagedExpandResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllResponses(Arrays.asList(responsesElement))
+            .build();
+    mockEcho.addResponse(expectedResponse);
+
+    SimplePagedExpandPagedResponse pagedListResponse = client.simplePagedExpand();
+
+    List resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getResponsesList().get(0), resources.get(0));
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    PagedExpandRequest actualRequest = ((PagedExpandRequest) actualRequests.get(0));
+
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void simplePagedExpandExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      PagedExpandRequest request =
+          PagedExpandRequest.newBuilder()
+              .setContent("content951530617")
+              .setPageSize(883849137)
+              .setPageToken("pageToken873572522")
+              .build();
+      client.simplePagedExpand(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void waitTest() throws Exception {
+    WaitResponse expectedResponse =
+        WaitResponse.newBuilder().setContent("content951530617").build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("waitTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockEcho.addResponse(resultOperation);
+
+    Duration ttl = Duration.newBuilder().build();
+
+    WaitResponse actualResponse = client.waitAsync(ttl).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    WaitRequest actualRequest = ((WaitRequest) actualRequests.get(0));
+
+    Assert.assertEquals(ttl, actualRequest.getTtl());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void waitExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      Duration ttl = Duration.newBuilder().build();
+      client.waitAsync(ttl).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+      Assert.assertEquals(InvalidArgumentException.class, e.getCause().getClass());
+      InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause());
+      Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode());
+    }
+  }
+
+  @Test
+  public void waitTest2() throws Exception {
+    WaitResponse expectedResponse =
+        WaitResponse.newBuilder().setContent("content951530617").build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("waitTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockEcho.addResponse(resultOperation);
+
+    Timestamp endTime = Timestamp.newBuilder().build();
+
+    WaitResponse actualResponse = client.waitAsync(endTime).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    WaitRequest actualRequest = ((WaitRequest) actualRequests.get(0));
+
+    Assert.assertEquals(endTime, actualRequest.getEndTime());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void waitExceptionTest2() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      Timestamp endTime = Timestamp.newBuilder().build();
+      client.waitAsync(endTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+      Assert.assertEquals(InvalidArgumentException.class, e.getCause().getClass());
+      InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause());
+      Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode());
+    }
+  }
+
+  @Test
+  public void blockTest() throws Exception {
+    BlockResponse expectedResponse =
+        BlockResponse.newBuilder().setContent("content951530617").build();
+    mockEcho.addResponse(expectedResponse);
+
+    BlockRequest request = BlockRequest.newBuilder().build();
+
+    BlockResponse actualResponse = client.block(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    BlockRequest actualRequest = ((BlockRequest) actualRequests.get(0));
+
+    Assert.assertEquals(request.getResponseDelay(), actualRequest.getResponseDelay());
+    Assert.assertEquals(request.getError(), actualRequest.getError());
+    Assert.assertEquals(request.getSuccess(), actualRequest.getSuccess());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void blockExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      BlockRequest request = BlockRequest.newBuilder().build();
+      client.block(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void collideNameTest() throws Exception {
+    Object expectedResponse = Object.newBuilder().setContent("content951530617").build();
+    mockEcho.addResponse(expectedResponse);
+
+    EchoRequest request =
+        EchoRequest.newBuilder()
+            .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+            .setSeverity(Severity.forNumber(0))
+            .setFoobar(Foobar.newBuilder().build())
+            .build();
+
+    Object actualResponse = client.collideName(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List actualRequests = mockEcho.getRequests();
+    Assert.assertEquals(1, actualRequests.size());
+    EchoRequest actualRequest = ((EchoRequest) actualRequests.get(0));
+
+    Assert.assertEquals(request.getName(), actualRequest.getName());
+    Assert.assertEquals(request.getParent(), actualRequest.getParent());
+    Assert.assertEquals(request.getContent(), actualRequest.getContent());
+    Assert.assertEquals(request.getError(), actualRequest.getError());
+    Assert.assertEquals(request.getSeverity(), actualRequest.getSeverity());
+    Assert.assertEquals(request.getFoobar(), actualRequest.getFoobar());
+    Assert.assertTrue(
+        channelProvider.isHeaderSent(
+            ApiClientHeaderProvider.getDefaultApiClientHeaderKey(),
+            GaxGrpcProperties.getDefaultApiClientHeaderPattern()));
+  }
+
+  @Test
+  public void collideNameExceptionTest() throws Exception {
+    StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT);
+    mockEcho.addException(exception);
+
+    try {
+      EchoRequest request =
+          EchoRequest.newBuilder()
+              .setName(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setParent(FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]").toString())
+              .setSeverity(Severity.forNumber(0))
+              .setFoobar(Foobar.newBuilder().build())
+              .build();
+      client.collideName(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+}
diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoSettings.golden
new file mode 100644
index 0000000000..b3c9486aea
--- /dev/null
+++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/EchoSettings.golden
@@ -0,0 +1,267 @@
+package com.google.showcase.grpcrest.v1beta1;
+
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.PagedExpandPagedResponse;
+import static com.google.showcase.grpcrest.v1beta1.EchoClient.SimplePagedExpandPagedResponse;
+
+import com.google.api.core.ApiFunction;
+import com.google.api.core.BetaApi;
+import com.google.api.gax.core.GoogleCredentialsProvider;
+import com.google.api.gax.core.InstantiatingExecutorProvider;
+import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.ClientSettings;
+import com.google.api.gax.rpc.OperationCallSettings;
+import com.google.api.gax.rpc.PagedCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallSettings;
+import com.google.api.gax.rpc.StubSettings;
+import com.google.api.gax.rpc.TransportChannelProvider;
+import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.longrunning.Operation;
+import com.google.showcase.grpcrest.v1beta1.stub.EchoStubSettings;
+import java.io.IOException;
+import java.util.List;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * Settings class to configure an instance of {@link EchoClient}.
+ *
+ * 

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

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

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

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

{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * EchoSettings.Builder echoSettingsBuilder = EchoSettings.newBuilder();
+ * echoSettingsBuilder
+ *     .echoSettings()
+ *     .setRetrySettings(
+ *         echoSettingsBuilder
+ *             .echoSettings()
+ *             .getRetrySettings()
+ *             .toBuilder()
+ *             .setTotalTimeout(Duration.ofSeconds(30))
+ *             .build());
+ * EchoSettings echoSettings = echoSettingsBuilder.build();
+ * }
+ */ +@BetaApi +@Generated("by gapic-generator-java") +public class EchoSettings extends ClientSettings { + + /** Returns the object with the settings used for calls to echo. */ + public UnaryCallSettings echoSettings() { + return ((EchoStubSettings) getStubSettings()).echoSettings(); + } + + /** Returns the object with the settings used for calls to expand. */ + public ServerStreamingCallSettings expandSettings() { + return ((EchoStubSettings) getStubSettings()).expandSettings(); + } + + /** Returns the object with the settings used for calls to pagedExpand. */ + public PagedCallSettings + pagedExpandSettings() { + return ((EchoStubSettings) getStubSettings()).pagedExpandSettings(); + } + + /** Returns the object with the settings used for calls to simplePagedExpand. */ + public PagedCallSettings + simplePagedExpandSettings() { + return ((EchoStubSettings) getStubSettings()).simplePagedExpandSettings(); + } + + /** Returns the object with the settings used for calls to wait. */ + public UnaryCallSettings waitSettings() { + return ((EchoStubSettings) getStubSettings()).waitSettings(); + } + + /** Returns the object with the settings used for calls to wait. */ + public OperationCallSettings waitOperationSettings() { + return ((EchoStubSettings) getStubSettings()).waitOperationSettings(); + } + + /** Returns the object with the settings used for calls to block. */ + public UnaryCallSettings blockSettings() { + return ((EchoStubSettings) getStubSettings()).blockSettings(); + } + + /** Returns the object with the settings used for calls to collideName. */ + public UnaryCallSettings collideNameSettings() { + return ((EchoStubSettings) getStubSettings()).collideNameSettings(); + } + + public static final EchoSettings create(EchoStubSettings stub) throws IOException { + return new EchoSettings.Builder(stub.toBuilder()).build(); + } + + /** Returns a builder for the default ExecutorProvider for this service. */ + public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder() { + return EchoStubSettings.defaultExecutorProviderBuilder(); + } + + /** Returns the default service endpoint. */ + public static String getDefaultEndpoint() { + return EchoStubSettings.getDefaultEndpoint(); + } + + /** Returns the default service scopes. */ + public static List getDefaultServiceScopes() { + return EchoStubSettings.getDefaultServiceScopes(); + } + + /** Returns a builder for the default credentials for this service. */ + public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { + return EchoStubSettings.defaultCredentialsProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() { + return EchoStubSettings.defaultGrpcTransportProviderBuilder(); + } + + /** Returns a builder for the default ChannelProvider for this service. */ + public static InstantiatingHttpJsonChannelProvider.Builder + defaultHttpJsonTransportProviderBuilder() { + return EchoStubSettings.defaultHttpJsonTransportProviderBuilder(); + } + + public static TransportChannelProvider defaultTransportChannelProvider() { + return EchoStubSettings.defaultTransportChannelProvider(); + } + + @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") + public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { + return EchoStubSettings.defaultApiClientHeaderProviderBuilder(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder() { + return Builder.createDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newHttpJsonBuilder() { + return Builder.createHttpJsonDefault(); + } + + /** Returns a new builder for this class. */ + public static Builder newBuilder(ClientContext clientContext) { + return new Builder(clientContext); + } + + /** Returns a builder containing all the values of this settings class. */ + public Builder toBuilder() { + return new Builder(this); + } + + protected EchoSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + /** Builder for EchoSettings. */ + public static class Builder extends ClientSettings.Builder { + + protected Builder() throws IOException { + this(((ClientContext) null)); + } + + protected Builder(ClientContext clientContext) { + super(EchoStubSettings.newBuilder(clientContext)); + } + + protected Builder(EchoSettings settings) { + super(settings.getStubSettings().toBuilder()); + } + + protected Builder(EchoStubSettings.Builder stubSettings) { + super(stubSettings); + } + + private static Builder createDefault() { + return new Builder(EchoStubSettings.newBuilder()); + } + + private static Builder createHttpJsonDefault() { + return new Builder(EchoStubSettings.newHttpJsonBuilder()); + } + + public EchoStubSettings.Builder getStubSettingsBuilder() { + return ((EchoStubSettings.Builder) getStubSettings()); + } + + /** + * Applies the given settings updater function to all of the unary API methods in this service. + * + *

Note: This method does not support applying settings to streaming methods. + */ + public Builder applyToAllUnaryMethods( + ApiFunction, Void> settingsUpdater) { + super.applyToAllUnaryMethods( + getStubSettingsBuilder().unaryMethodSettingsBuilders(), settingsUpdater); + return this; + } + + /** Returns the builder for the settings used for calls to echo. */ + public UnaryCallSettings.Builder echoSettings() { + return getStubSettingsBuilder().echoSettings(); + } + + /** Returns the builder for the settings used for calls to expand. */ + public ServerStreamingCallSettings.Builder expandSettings() { + return getStubSettingsBuilder().expandSettings(); + } + + /** Returns the builder for the settings used for calls to pagedExpand. */ + public PagedCallSettings.Builder< + PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> + pagedExpandSettings() { + return getStubSettingsBuilder().pagedExpandSettings(); + } + + /** Returns the builder for the settings used for calls to simplePagedExpand. */ + public PagedCallSettings.Builder< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> + simplePagedExpandSettings() { + return getStubSettingsBuilder().simplePagedExpandSettings(); + } + + /** Returns the builder for the settings used for calls to wait. */ + public UnaryCallSettings.Builder waitSettings() { + return getStubSettingsBuilder().waitSettings(); + } + + /** Returns the builder for the settings used for calls to wait. */ + public OperationCallSettings.Builder + waitOperationSettings() { + return getStubSettingsBuilder().waitOperationSettings(); + } + + /** Returns the builder for the settings used for calls to block. */ + public UnaryCallSettings.Builder blockSettings() { + return getStubSettingsBuilder().blockSettings(); + } + + /** Returns the builder for the settings used for calls to collideName. */ + public UnaryCallSettings.Builder collideNameSettings() { + return getStubSettingsBuilder().collideNameSettings(); + } + + @Override + public EchoSettings build() throws IOException { + return new EchoSettings(this); + } + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoCallableFactory.golden new file mode 100644 index 0000000000..99bb588409 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoCallableFactory.golden @@ -0,0 +1,99 @@ +package com.google.showcase.grpcrest.v1beta1.stub; + +import com.google.api.core.BetaApi; +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcCallableFactory; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.BatchingCallSettings; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.ClientStreamingCallable; +import com.google.api.gax.rpc.OperationCallSettings; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StreamingCallSettings; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.OperationsStub; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC callable factory implementation for the Echo service API. + * + *

This class is for advanced usage. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class GrpcEchoCallableFactory implements GrpcStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + GrpcCallSettings grpcCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createUnaryCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + GrpcCallSettings grpcCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createPagedCallable(grpcCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + GrpcCallSettings grpcCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBatchingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + OperationCallable createOperationCallable( + GrpcCallSettings grpcCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + OperationsStub operationsStub) { + return GrpcCallableFactory.createOperationCallable( + grpcCallSettings, callSettings, clientContext, operationsStub); + } + + @Override + public + BidiStreamingCallable createBidiStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createBidiStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + GrpcCallSettings grpcCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createServerStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } + + @Override + public + ClientStreamingCallable createClientStreamingCallable( + GrpcCallSettings grpcCallSettings, + StreamingCallSettings callSettings, + ClientContext clientContext) { + return GrpcCallableFactory.createClientStreamingCallable( + grpcCallSettings, callSettings, clientContext); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoStub.golden new file mode 100644 index 0000000000..eefefb4aaa --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/GrpcEchoStub.golden @@ -0,0 +1,312 @@ +package com.google.showcase.grpcrest.v1beta1.stub; + +import static com.google.showcase.grpcrest.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.grpcrest.v1beta1.EchoClient.SimplePagedExpandPagedResponse; + +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.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.showcase.grpcrest.v1beta1.BlockRequest; +import com.google.showcase.grpcrest.v1beta1.BlockResponse; +import com.google.showcase.grpcrest.v1beta1.EchoRequest; +import com.google.showcase.grpcrest.v1beta1.EchoResponse; +import com.google.showcase.grpcrest.v1beta1.ExpandRequest; +import com.google.showcase.grpcrest.v1beta1.Object; +import com.google.showcase.grpcrest.v1beta1.PagedExpandRequest; +import com.google.showcase.grpcrest.v1beta1.PagedExpandResponse; +import com.google.showcase.grpcrest.v1beta1.WaitMetadata; +import com.google.showcase.grpcrest.v1beta1.WaitRequest; +import com.google.showcase.grpcrest.v1beta1.WaitResponse; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the Echo service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class GrpcEchoStub extends EchoStub { + private static final MethodDescriptor echoMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Echo") + .setRequestMarshaller(ProtoUtils.marshaller(EchoRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(EchoResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor expandMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Expand") + .setRequestMarshaller(ProtoUtils.marshaller(ExpandRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(EchoResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + pagedExpandMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/PagedExpand") + .setRequestMarshaller(ProtoUtils.marshaller(PagedExpandRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(PagedExpandResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + simplePagedExpandMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/SimplePagedExpand") + .setRequestMarshaller(ProtoUtils.marshaller(PagedExpandRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(PagedExpandResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor waitMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Wait") + .setRequestMarshaller(ProtoUtils.marshaller(WaitRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Operation.getDefaultInstance())) + .build(); + + private static final MethodDescriptor blockMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Block") + .setRequestMarshaller(ProtoUtils.marshaller(BlockRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(BlockResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor collideNameMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/CollideName") + .setRequestMarshaller(ProtoUtils.marshaller(EchoRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Object.getDefaultInstance())) + .build(); + + private final UnaryCallable echoCallable; + private final ServerStreamingCallable expandCallable; + private final UnaryCallable pagedExpandCallable; + private final UnaryCallable + pagedExpandPagedCallable; + private final UnaryCallable simplePagedExpandCallable; + private final UnaryCallable + simplePagedExpandPagedCallable; + private final UnaryCallable waitCallable; + private final OperationCallable waitOperationCallable; + private final UnaryCallable blockCallable; + private final UnaryCallable collideNameCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + public static final GrpcEchoStub create(EchoStubSettings settings) throws IOException { + return new GrpcEchoStub(settings, ClientContext.create(settings)); + } + + public static final GrpcEchoStub create(ClientContext clientContext) throws IOException { + return new GrpcEchoStub(EchoStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcEchoStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcEchoStub(EchoStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of GrpcEchoStub, using the given settings. This is protected so that it + * is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected GrpcEchoStub(EchoStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcEchoCallableFactory()); + } + + /** + * Constructs an instance of GrpcEchoStub, using the given settings. This is protected so that it + * is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected GrpcEchoStub( + EchoStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings echoTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(echoMethodDescriptor) + .build(); + GrpcCallSettings expandTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(expandMethodDescriptor) + .build(); + GrpcCallSettings pagedExpandTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(pagedExpandMethodDescriptor) + .build(); + GrpcCallSettings simplePagedExpandTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(simplePagedExpandMethodDescriptor) + .build(); + GrpcCallSettings waitTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(waitMethodDescriptor) + .build(); + GrpcCallSettings blockTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(blockMethodDescriptor) + .build(); + GrpcCallSettings collideNameTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(collideNameMethodDescriptor) + .build(); + + this.echoCallable = + callableFactory.createUnaryCallable( + echoTransportSettings, settings.echoSettings(), clientContext); + this.expandCallable = + callableFactory.createServerStreamingCallable( + expandTransportSettings, settings.expandSettings(), clientContext); + this.pagedExpandCallable = + callableFactory.createUnaryCallable( + pagedExpandTransportSettings, settings.pagedExpandSettings(), clientContext); + this.pagedExpandPagedCallable = + callableFactory.createPagedCallable( + pagedExpandTransportSettings, settings.pagedExpandSettings(), clientContext); + this.simplePagedExpandCallable = + callableFactory.createUnaryCallable( + simplePagedExpandTransportSettings, + settings.simplePagedExpandSettings(), + clientContext); + this.simplePagedExpandPagedCallable = + callableFactory.createPagedCallable( + simplePagedExpandTransportSettings, + settings.simplePagedExpandSettings(), + clientContext); + this.waitCallable = + callableFactory.createUnaryCallable( + waitTransportSettings, settings.waitSettings(), clientContext); + this.waitOperationCallable = + callableFactory.createOperationCallable( + waitTransportSettings, settings.waitOperationSettings(), clientContext, operationsStub); + this.blockCallable = + callableFactory.createUnaryCallable( + blockTransportSettings, settings.blockSettings(), clientContext); + this.collideNameCallable = + callableFactory.createUnaryCallable( + collideNameTransportSettings, settings.collideNameSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + @Override + public UnaryCallable echoCallable() { + return echoCallable; + } + + @Override + public ServerStreamingCallable expandCallable() { + return expandCallable; + } + + @Override + public UnaryCallable pagedExpandCallable() { + return pagedExpandCallable; + } + + @Override + public UnaryCallable pagedExpandPagedCallable() { + return pagedExpandPagedCallable; + } + + @Override + public UnaryCallable simplePagedExpandCallable() { + return simplePagedExpandCallable; + } + + @Override + public UnaryCallable + simplePagedExpandPagedCallable() { + return simplePagedExpandPagedCallable; + } + + @Override + public UnaryCallable waitCallable() { + return waitCallable; + } + + @Override + public OperationCallable waitOperationCallable() { + return waitOperationCallable; + } + + @Override + public UnaryCallable blockCallable() { + return blockCallable; + } + + @Override + public UnaryCallable collideNameCallable() { + return collideNameCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoCallableFactory.golden new file mode 100644 index 0000000000..3996e0747e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoCallableFactory.golden @@ -0,0 +1,89 @@ +package com.google.showcase.grpcrest.v1beta1.stub; + +import com.google.api.core.BetaApi; +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; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallSettings; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST callable factory implementation for the Echo service API. + * + *

This class is for advanced usage. + */ +@BetaApi +@Generated("by gapic-generator-java") +public class HttpJsonEchoCallableFactory + implements HttpJsonStubCallableFactory { + + @Override + public UnaryCallable createUnaryCallable( + HttpJsonCallSettings httpJsonCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createUnaryCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public + UnaryCallable createPagedCallable( + HttpJsonCallSettings httpJsonCallSettings, + PagedCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createPagedCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @Override + public UnaryCallable createBatchingCallable( + HttpJsonCallSettings httpJsonCallSettings, + BatchingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createBatchingCallable( + httpJsonCallSettings, callSettings, clientContext); + } + + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") + @Override + public + OperationCallable createOperationCallable( + HttpJsonCallSettings httpJsonCallSettings, + OperationCallSettings callSettings, + ClientContext clientContext, + 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); + } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoStub.golden new file mode 100644 index 0000000000..1796b414b7 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpcrest/goldens/HttpJsonEchoStub.golden @@ -0,0 +1,524 @@ +package com.google.showcase.grpcrest.v1beta1.stub; + +import static com.google.showcase.grpcrest.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.grpcrest.v1beta1.EchoClient.SimplePagedExpandPagedResponse; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.core.BackgroundResourceAggregation; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.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.ClientContext; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; +import com.google.protobuf.TypeRegistry; +import com.google.showcase.grpcrest.v1beta1.BlockRequest; +import com.google.showcase.grpcrest.v1beta1.BlockResponse; +import com.google.showcase.grpcrest.v1beta1.EchoRequest; +import com.google.showcase.grpcrest.v1beta1.EchoResponse; +import com.google.showcase.grpcrest.v1beta1.ExpandRequest; +import com.google.showcase.grpcrest.v1beta1.Object; +import com.google.showcase.grpcrest.v1beta1.PagedExpandRequest; +import com.google.showcase.grpcrest.v1beta1.PagedExpandResponse; +import com.google.showcase.grpcrest.v1beta1.WaitMetadata; +import com.google.showcase.grpcrest.v1beta1.WaitRequest; +import com.google.showcase.grpcrest.v1beta1.WaitResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * REST stub implementation for the Echo service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@BetaApi +@Generated("by gapic-generator-java") +@BetaApi("A restructuring of stub classes is planned, so this may break in the future") +public class HttpJsonEchoStub extends EchoStub { + private static final TypeRegistry typeRegistry = + TypeRegistry.newBuilder() + .add(WaitResponse.getDescriptor()) + .add(WaitMetadata.getDescriptor()) + .build(); + + private static final ApiMethodDescriptor echoMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Echo") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:echo", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(EchoResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor expandMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Expand") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.SERVER_STREAMING) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:expand", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(EchoResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + pagedExpandMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/PagedExpand") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:pagedExpand", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(PagedExpandResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor + simplePagedExpandMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/SimplePagedExpand") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:pagedExpand", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(PagedExpandResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor waitMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Wait") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:wait", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .setOperationSnapshotFactory( + (WaitRequest request, Operation response) -> + HttpJsonOperationSnapshot.create(response)) + .build(); + + private static final ApiMethodDescriptor blockMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/Block") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:block", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(BlockResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private static final ApiMethodDescriptor collideNameMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.showcase.grpcrest.v1beta1.Echo/CollideName") + .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/echo:foo", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Object.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + + private final UnaryCallable echoCallable; + private final ServerStreamingCallable expandCallable; + private final UnaryCallable pagedExpandCallable; + private final UnaryCallable + pagedExpandPagedCallable; + private final UnaryCallable simplePagedExpandCallable; + private final UnaryCallable + simplePagedExpandPagedCallable; + private final UnaryCallable waitCallable; + private final OperationCallable waitOperationCallable; + private final UnaryCallable blockCallable; + private final UnaryCallable collideNameCallable; + + private final BackgroundResource backgroundResources; + private final HttpJsonOperationsStub httpJsonOperationsStub; + private final HttpJsonStubCallableFactory callableFactory; + + public static final HttpJsonEchoStub create(EchoStubSettings settings) throws IOException { + return new HttpJsonEchoStub(settings, ClientContext.create(settings)); + } + + public static final HttpJsonEchoStub create(ClientContext clientContext) throws IOException { + return new HttpJsonEchoStub(EchoStubSettings.newHttpJsonBuilder().build(), clientContext); + } + + public static final HttpJsonEchoStub create( + ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException { + return new HttpJsonEchoStub( + EchoStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory); + } + + /** + * Constructs an instance of HttpJsonEchoStub, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected HttpJsonEchoStub(EchoStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new HttpJsonEchoCallableFactory()); + } + + /** + * Constructs an instance of HttpJsonEchoStub, using the given settings. This is protected so that + * it is easy to make a subclass, but otherwise, the static factory methods should be preferred. + */ + protected HttpJsonEchoStub( + EchoStubSettings settings, + ClientContext clientContext, + HttpJsonStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.httpJsonOperationsStub = + HttpJsonOperationsStub.create(clientContext, callableFactory, typeRegistry); + + HttpJsonCallSettings echoTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(echoMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings expandTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(expandMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings pagedExpandTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(pagedExpandMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings + simplePagedExpandTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(simplePagedExpandMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings waitTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(waitMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings blockTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(blockMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + HttpJsonCallSettings collideNameTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(collideNameMethodDescriptor) + .setTypeRegistry(typeRegistry) + .build(); + + this.echoCallable = + callableFactory.createUnaryCallable( + echoTransportSettings, settings.echoSettings(), clientContext); + this.expandCallable = + callableFactory.createServerStreamingCallable( + expandTransportSettings, settings.expandSettings(), clientContext); + this.pagedExpandCallable = + callableFactory.createUnaryCallable( + pagedExpandTransportSettings, settings.pagedExpandSettings(), clientContext); + this.pagedExpandPagedCallable = + callableFactory.createPagedCallable( + pagedExpandTransportSettings, settings.pagedExpandSettings(), clientContext); + this.simplePagedExpandCallable = + callableFactory.createUnaryCallable( + simplePagedExpandTransportSettings, + settings.simplePagedExpandSettings(), + clientContext); + this.simplePagedExpandPagedCallable = + callableFactory.createPagedCallable( + simplePagedExpandTransportSettings, + settings.simplePagedExpandSettings(), + clientContext); + this.waitCallable = + callableFactory.createUnaryCallable( + waitTransportSettings, settings.waitSettings(), clientContext); + this.waitOperationCallable = + callableFactory.createOperationCallable( + waitTransportSettings, + settings.waitOperationSettings(), + clientContext, + httpJsonOperationsStub); + this.blockCallable = + callableFactory.createUnaryCallable( + blockTransportSettings, settings.blockSettings(), clientContext); + this.collideNameCallable = + callableFactory.createUnaryCallable( + collideNameTransportSettings, settings.collideNameSettings(), clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + @InternalApi + public static List getMethodDescriptors() { + List methodDescriptors = new ArrayList<>(); + methodDescriptors.add(echoMethodDescriptor); + methodDescriptors.add(expandMethodDescriptor); + methodDescriptors.add(pagedExpandMethodDescriptor); + methodDescriptors.add(simplePagedExpandMethodDescriptor); + methodDescriptors.add(waitMethodDescriptor); + methodDescriptors.add(blockMethodDescriptor); + methodDescriptors.add(collideNameMethodDescriptor); + return methodDescriptors; + } + + public HttpJsonOperationsStub getHttpJsonOperationsStub() { + return httpJsonOperationsStub; + } + + @Override + public UnaryCallable echoCallable() { + return echoCallable; + } + + @Override + public ServerStreamingCallable expandCallable() { + return expandCallable; + } + + @Override + public UnaryCallable pagedExpandCallable() { + return pagedExpandCallable; + } + + @Override + public UnaryCallable pagedExpandPagedCallable() { + return pagedExpandPagedCallable; + } + + @Override + public UnaryCallable simplePagedExpandCallable() { + return simplePagedExpandCallable; + } + + @Override + public UnaryCallable + simplePagedExpandPagedCallable() { + return simplePagedExpandPagedCallable; + } + + @Override + public UnaryCallable waitCallable() { + return waitCallable; + } + + @Override + public OperationCallable waitOperationCallable() { + return waitOperationCallable; + } + + @Override + public UnaryCallable blockCallable() { + return blockCallable; + } + + @Override + public UnaryCallable collideNameCallable() { + return collideNameCallable; + } + + @Override + public final void close() { + try { + backgroundResources.close(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Failed to close resource", e); + } + } + + @Override + public void shutdown() { + backgroundResources.shutdown(); + } + + @Override + public boolean isShutdown() { + return backgroundResources.isShutdown(); + } + + @Override + public boolean isTerminated() { + return backgroundResources.isTerminated(); + } + + @Override + public void shutdownNow() { + backgroundResources.shutdownNow(); + } + + @Override + public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { + return backgroundResources.awaitTermination(duration, unit); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java index 1efb7fd67b..e8eccd9eec 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposerTest.java @@ -26,7 +26,7 @@ public class HttpJsonServiceStubClassComposerTest { @Test - public void generateHttpJsonServiceStubClass_simple() { + public void generateServiceClasses() { GapicContext context = RestTestProtoLoader.instance().parseCompliance(); Service echoProtoService = context.services().get(0); GapicClass clazz = diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java index 028f4cca14..55ca4c5f57 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposerTest.java @@ -27,7 +27,7 @@ public class ServiceClientTestClassComposerTest { @Test - public void generateClientTest_echoClient() { + public void generateServiceClasses() { GapicContext context = RestTestProtoLoader.instance().parseCompliance(); Service echoProtoService = context.services().get(0); GapicClass clazz = 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 53392a549e..309467cd2d 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 @@ -26,7 +26,7 @@ public class ServiceStubSettingsClassComposerTest { @Test - public void generateServiceStubSettingsClasses_basic() { + public void generateServiceClasses() { GapicContext context = RestTestProtoLoader.instance().parseCompliance(); Service echoProtoService = context.services().get(0); GapicClass clazz = diff --git a/src/test/proto/echo_grpcrest.proto b/src/test/proto/echo_grpcrest.proto new file mode 100644 index 0000000000..7568b8bc04 --- /dev/null +++ b/src/test/proto/echo_grpcrest.proto @@ -0,0 +1,276 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "google/rpc/status.proto"; + +package google.showcase.grpcrest.v1beta1; + +option go_package = "github.com/googleapis/gapic-showcase-grpcrest/server/genproto"; +option java_package = "com.google.showcase.grpcrest.v1beta1"; +option java_multiple_files = true; + +option (google.api.resource_definition) = { + type: "showcase.googleapis.com/AnythingGoes" + pattern: "*" +}; + +// This service is used showcase the four main types of rpcs - unary, server +// side streaming, client side streaming, and bidirectional streaming. This +// service also exposes methods that explicitly implement server delay, and +// paginated calls. Set the 'showcase-trailer' metadata key on any method +// to have the values echoed in the response trailers. +service Echo { + // This service is meant to only run locally on the port 7469 (keypad digits + // for "show"). + option (google.api.default_host) = "localhost:7469"; + option (google.api.oauth_scopes) = + "https://www.googleapis.com/auth/cloud-platform"; + + // This method simply echos the request. This method is showcases unary rpcs. + rpc Echo(EchoRequest) returns (EchoResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:echo" + body: "*" + }; + option (google.api.method_signature) = "content"; + option (google.api.method_signature) = "error"; + option (google.api.method_signature) = "content,severity"; + option (google.api.method_signature) = "name"; + option (google.api.method_signature) = "parent"; + option (google.api.method_signature) = ""; + } + + // This method split the given content into words and will pass each word back + // through the stream. This method showcases server-side streaming rpcs. + rpc Expand(ExpandRequest) returns (stream EchoResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:expand" + body: "*" + }; + option (google.api.method_signature) = "content,error"; + } + + // This is similar to the Expand method but instead of returning a stream of + // expanded words, this method returns a paged list of expanded words. + rpc PagedExpand(PagedExpandRequest) returns (PagedExpandResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:pagedExpand" + body: "*" + }; + } + + rpc SimplePagedExpand(PagedExpandRequest) returns (PagedExpandResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:pagedExpand" + body: "*" + }; + option (google.api.method_signature) = ""; + } + + // This method will wait the requested amount of and then return. + // This method showcases how a client handles a request timing out. + rpc Wait(WaitRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/echo:wait" + body: "*" + }; + option (google.longrunning.operation_info) = { + response_type: "WaitResponse" + metadata_type: "WaitMetadata" + }; + option (google.api.method_signature) = "end_time"; + option (google.api.method_signature) = "ttl"; + } + + // This method will block (wait) for the requested amount of time + // and then return the response or error. + // This method showcases how a client handles delays or retries. + rpc Block(BlockRequest) returns (BlockResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:block" + body: "*" + }; + }; + + // This method primarily tests Java name collisions by using the Object + // message. + rpc CollideName(EchoRequest) returns (Object) { + option (google.api.http) = { + post: "/v1beta1/echo:foo" + body: "*" + }; + } +} + +// A severity enum used to test enum capabilities in GAPIC surfaces +enum Severity { + UNNECESSARY = 0; + NECESSARY = 1; + URGENT = 2; + CRITICAL = 3; +} + +message Foobar { + option (google.api.resource) = { + type: "showcase.googleapis.com/Foobar" + pattern: "projects/{project}/foobars/{foobar}" + pattern: "projects/{project}/chocolate/variants/{variant}/foobars/{foobar}" + pattern: "foobars/{foobar}" + pattern: "bar_foos/{bar_foo}/foobars/{foobar}" + pattern: "*" + }; + + string name = 1; + string info = 2; +} + +// The request message used for the Echo, Collect and Chat methods. +// If content or opt are set in this message then the request will succeed. +// If status is set in this message +// then the status will be returned as an error. +message EchoRequest { + string name = 5 [ + (google.api.resource_reference).type = "showcase.googleapis.com/Foobar", + (google.api.field_behavior) = REQUIRED + ]; + + string parent = 6 [ + (google.api.resource_reference).child_type = + "showcase.googleapis.com/AnythingGoes", + (google.api.field_behavior) = REQUIRED + ]; + + oneof response { + // The content to be echoed by the server. + string content = 1; + + // The error to be thrown by the server. + google.rpc.Status error = 2; + } + + // The severity to be echoed by the server. + Severity severity = 3; + + Foobar foobar = 4; +} + +// The response message for the Echo methods. +message EchoResponse { + // The content specified in the request. + string content = 1; + + // The severity specified in the request. + Severity severity = 2; +} + +// Tests name collisions with java.lang.Object. +message Object { + // The content specified in the request. + string content = 1; +} + +// The request message for the Expand method. +message ExpandRequest { + // The content that will be split into words and returned on the stream. + string content = 1; + + // The error that is thrown after all words are sent on the stream. + google.rpc.Status error = 2; + + string info = 3; +} + +// The request for the PagedExpand method. +message PagedExpandRequest { + // The string to expand. + string content = 1 [(google.api.field_behavior) = REQUIRED]; + + // The amount of words to returned in each page. + int32 page_size = 2; + + // The position of the page to be returned. + string page_token = 3; +} + +// The response for the PagedExpand method. +message PagedExpandResponse { + // The words that were expanded. + repeated EchoResponse responses = 1; + + // The next page token. + string next_page_token = 2; +} + +// The request for Wait method. +message WaitRequest { + oneof end { + // The time that this operation will complete. + google.protobuf.Timestamp end_time = 1; + + // The duration of this operation. + google.protobuf.Duration ttl = 4; + } + + oneof response { + // The error that will be returned by the server. If this code is specified + // to be the OK rpc code, an empty response will be returned. + google.rpc.Status error = 2; + + // The response to be returned on operation completion. + WaitResponse success = 3; + } +} + +// The result of the Wait operation. +message WaitResponse { + // This content of the result. + string content = 1; +} + +// The metadata for Wait operation. +message WaitMetadata { + // The time that this operation will complete. + google.protobuf.Timestamp end_time = 1; +} + +// The request for Block method. +message BlockRequest { + // The amount of time to block before returning a response. + google.protobuf.Duration response_delay = 1; + + oneof response { + // The error that will be returned by the server. If this code is specified + // to be the OK rpc code, an empty response will be returned. + google.rpc.Status error = 2; + + // The response to be returned that will signify successful method call. + BlockResponse success = 3; + } +} + +// The response for Block method. +message BlockResponse { + // This content can contain anything, the server will not depend on a value + // here. + string content = 1; +}