From 83a3af9348eaed7d9216c65a4b0250cabbf545ec Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Sat, 24 Oct 2020 14:13:04 -0700 Subject: [PATCH] [ggj][codegen] feat: add GrpcPublisherStub test to exercise HTTP subfields (#403) * fix: refactor requestBuilder into separate method in ServiceClientClassComposer * feat: add varargs to AnonClass and ref setter methods * feat: add HTTP annotation parsing/validation * feat: Generate RequestParamsExtractor in GrpcServiceStub * feat: add GrpcPublisherStub test to exercise HTTP subfields --- .../GrpcServiceStubClassComposerTest.java | 32 ++ .../composer/goldens/GrpcPublisherStub.golden | 438 ++++++++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java index 402d94450a..28f7bec18f 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java @@ -26,10 +26,13 @@ import com.google.api.generator.test.framework.Utils; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; +import com.google.pubsub.v1.PubsubProto; import com.google.showcase.v1beta1.EchoOuterClass; import com.google.showcase.v1beta1.TestingOuterClass; +import google.cloud.CommonResources; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -82,4 +85,33 @@ public void generateGrpcServiceStubClass_httpBindings() { Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcTestingStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } + + @Test + public void generateGrpcServiceStubClass_httpBindingsWithSubMessageFields() { + FileDescriptor serviceFileDescriptor = PubsubProto.getDescriptor(); + FileDescriptor commonResourcesFileDescriptor = CommonResources.getDescriptor(); + ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); + assertEquals("Publisher", serviceDescriptor.getName()); + + Map resourceNames = new HashMap<>(); + resourceNames.putAll(Parser.parseResourceNames(serviceFileDescriptor)); + resourceNames.putAll(Parser.parseResourceNames(commonResourcesFileDescriptor)); + + Map messageTypes = Parser.parseMessages(serviceFileDescriptor); + + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + serviceFileDescriptor, messageTypes, resourceNames, outputResourceNames); + + Service service = services.get(0); + GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(service, messageTypes); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "GrpcPublisherStub.golden", visitor.write()); + Path goldenFilePath = + Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcPublisherStub.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden new file mode 100644 index 0000000000..719c3d3e03 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden @@ -0,0 +1,438 @@ +package com.google.pubsub.v1.stub; + +import static com.google.pubsub.v1.PublisherClient.ListTopicSnapshotsPagedResponse; +import static com.google.pubsub.v1.PublisherClient.ListTopicSubscriptionsPagedResponse; +import static com.google.pubsub.v1.PublisherClient.ListTopicsPagedResponse; + +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.RequestParamsExtractor; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.common.collect.ImmutableMap; +import com.google.longrunning.stub.GrpcOperationsStub; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.DetachSubscriptionRequest; +import com.google.pubsub.v1.DetachSubscriptionResponse; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListTopicSnapshotsRequest; +import com.google.pubsub.v1.ListTopicSnapshotsResponse; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.UpdateTopicRequest; +import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +/** + * gRPC stub implementation for the Publisher service API. + * + *

This class is for advanced usage and reflects the underlying API directly. + */ +@Generated("by gapic-generator-java") +public class GrpcPublisherStub extends PublisherStub { + private static final MethodDescriptor createTopicMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/CreateTopic") + .setRequestMarshaller(ProtoUtils.marshaller(Topic.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Topic.getDefaultInstance())) + .build(); + + private static final MethodDescriptor updateTopicMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/UpdateTopic") + .setRequestMarshaller(ProtoUtils.marshaller(UpdateTopicRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Topic.getDefaultInstance())) + .build(); + + private static final MethodDescriptor publishMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/Publish") + .setRequestMarshaller(ProtoUtils.marshaller(PublishRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(PublishResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor getTopicMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/GetTopic") + .setRequestMarshaller(ProtoUtils.marshaller(GetTopicRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Topic.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + listTopicsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/ListTopics") + .setRequestMarshaller(ProtoUtils.marshaller(ListTopicsRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(ListTopicsResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse> + listTopicSubscriptionsMethodDescriptor = + MethodDescriptor + .newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/ListTopicSubscriptions") + .setRequestMarshaller( + ProtoUtils.marshaller(ListTopicSubscriptionsRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(ListTopicSubscriptionsResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + listTopicSnapshotsMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/ListTopicSnapshots") + .setRequestMarshaller( + ProtoUtils.marshaller(ListTopicSnapshotsRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(ListTopicSnapshotsResponse.getDefaultInstance())) + .build(); + + private static final MethodDescriptor deleteTopicMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/DeleteTopic") + .setRequestMarshaller(ProtoUtils.marshaller(DeleteTopicRequest.getDefaultInstance())) + .setResponseMarshaller(ProtoUtils.marshaller(Empty.getDefaultInstance())) + .build(); + + private static final MethodDescriptor + detachSubscriptionMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.pubsub.v1.Publisher/DetachSubscription") + .setRequestMarshaller( + ProtoUtils.marshaller(DetachSubscriptionRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(DetachSubscriptionResponse.getDefaultInstance())) + .build(); + + private final UnaryCallable createTopicCallable; + private final UnaryCallable updateTopicCallable; + private final UnaryCallable publishCallable; + private final UnaryCallable getTopicCallable; + private final UnaryCallable listTopicsCallable; + private final UnaryCallable listTopicsPagedCallable; + private final UnaryCallable + listTopicSubscriptionsCallable; + private final UnaryCallable + listTopicSubscriptionsPagedCallable; + private final UnaryCallable + listTopicSnapshotsCallable; + private final UnaryCallable + listTopicSnapshotsPagedCallable; + private final UnaryCallable deleteTopicCallable; + private final UnaryCallable + detachSubscriptionCallable; + + private final BackgroundResource backgroundResources; + private final GrpcOperationsStub operationsStub; + private final GrpcStubCallableFactory callableFactory; + + public static final GrpcPublisherStub create(PublisherStubSettings settings) throws IOException { + return new GrpcPublisherStub(settings, ClientContext.create(settings)); + } + + public static final GrpcPublisherStub create(ClientContext clientContext) throws IOException { + return new GrpcPublisherStub(PublisherStubSettings.newBuilder().build(), clientContext); + } + + public static final GrpcPublisherStub create( + ClientContext clientContext, GrpcStubCallableFactory callableFactory) throws IOException { + return new GrpcPublisherStub( + PublisherStubSettings.newBuilder().build(), clientContext, callableFactory); + } + + protected GrpcPublisherStub(PublisherStubSettings settings, ClientContext clientContext) + throws IOException { + this(settings, clientContext, new GrpcPublisherCallableFactory()); + } + + protected GrpcPublisherStub( + PublisherStubSettings settings, + ClientContext clientContext, + GrpcStubCallableFactory callableFactory) + throws IOException { + this.callableFactory = callableFactory; + this.operationsStub = GrpcOperationsStub.create(clientContext, callableFactory); + + GrpcCallSettings createTopicTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(createTopicMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(Topic request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("name", String.valueOf(request.getName())); + return params.build(); + } + }) + .build(); + GrpcCallSettings updateTopicTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(updateTopicMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(UpdateTopicRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic.name", String.valueOf(request.getTopic().getName())); + return params.build(); + } + }) + .build(); + GrpcCallSettings publishTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(publishMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(PublishRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); + } + }) + .build(); + GrpcCallSettings getTopicTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(getTopicMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(GetTopicRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); + } + }) + .build(); + GrpcCallSettings listTopicsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(listTopicsMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(ListTopicsRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("project", String.valueOf(request.getProject())); + return params.build(); + } + }) + .build(); + GrpcCallSettings + listTopicSubscriptionsTransportSettings = + GrpcCallSettings + .newBuilder() + .setMethodDescriptor(listTopicSubscriptionsMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(ListTopicSubscriptionsRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); + } + }) + .build(); + GrpcCallSettings + listTopicSnapshotsTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(listTopicSnapshotsMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(ListTopicSnapshotsRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); + } + }) + .build(); + GrpcCallSettings deleteTopicTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(deleteTopicMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(DeleteTopicRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("topic", String.valueOf(request.getTopic())); + return params.build(); + } + }) + .build(); + GrpcCallSettings + detachSubscriptionTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(detachSubscriptionMethodDescriptor) + .setParamsExtractor( + new RequestParamsExtractor() { + @Override + public Map extract(DetachSubscriptionRequest request) { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("subscription", String.valueOf(request.getSubscription())); + return params.build(); + } + }) + .build(); + + this.createTopicCallable = + callableFactory.createUnaryCallable( + createTopicTransportSettings, settings.createTopicSettings(), clientContext); + this.updateTopicCallable = + callableFactory.createUnaryCallable( + updateTopicTransportSettings, settings.updateTopicSettings(), clientContext); + this.publishCallable = + callableFactory.createUnaryCallable( + publishTransportSettings, settings.publishSettings(), clientContext); + this.getTopicCallable = + callableFactory.createUnaryCallable( + getTopicTransportSettings, settings.getTopicSettings(), clientContext); + this.listTopicsCallable = + callableFactory.createUnaryCallable( + listTopicsTransportSettings, settings.listTopicsSettings(), clientContext); + this.listTopicsPagedCallable = + callableFactory.createPagedCallable( + listTopicsTransportSettings, settings.listTopicsSettings(), clientContext); + this.listTopicSubscriptionsCallable = + callableFactory.createUnaryCallable( + listTopicSubscriptionsTransportSettings, + settings.listTopicSubscriptionsSettings(), + clientContext); + this.listTopicSubscriptionsPagedCallable = + callableFactory.createPagedCallable( + listTopicSubscriptionsTransportSettings, + settings.listTopicSubscriptionsSettings(), + clientContext); + this.listTopicSnapshotsCallable = + callableFactory.createUnaryCallable( + listTopicSnapshotsTransportSettings, + settings.listTopicSnapshotsSettings(), + clientContext); + this.listTopicSnapshotsPagedCallable = + callableFactory.createPagedCallable( + listTopicSnapshotsTransportSettings, + settings.listTopicSnapshotsSettings(), + clientContext); + this.deleteTopicCallable = + callableFactory.createUnaryCallable( + deleteTopicTransportSettings, settings.deleteTopicSettings(), clientContext); + this.detachSubscriptionCallable = + callableFactory.createUnaryCallable( + detachSubscriptionTransportSettings, + settings.detachSubscriptionSettings(), + clientContext); + + this.backgroundResources = + new BackgroundResourceAggregation(clientContext.getBackgroundResources()); + } + + public GrpcOperationsStub getOperationsStub() { + return operationsStub; + } + + public UnaryCallable createTopicCallable() { + return createTopicCallable; + } + + public UnaryCallable updateTopicCallable() { + return updateTopicCallable; + } + + public UnaryCallable publishCallable() { + return publishCallable; + } + + public UnaryCallable getTopicCallable() { + return getTopicCallable; + } + + public UnaryCallable listTopicsCallable() { + return listTopicsCallable; + } + + public UnaryCallable listTopicsPagedCallable() { + return listTopicsPagedCallable; + } + + public UnaryCallable + listTopicSubscriptionsCallable() { + return listTopicSubscriptionsCallable; + } + + public UnaryCallable + listTopicSubscriptionsPagedCallable() { + return listTopicSubscriptionsPagedCallable; + } + + public UnaryCallable + listTopicSnapshotsCallable() { + return listTopicSnapshotsCallable; + } + + public UnaryCallable + listTopicSnapshotsPagedCallable() { + return listTopicSnapshotsPagedCallable; + } + + public UnaryCallable deleteTopicCallable() { + return deleteTopicCallable; + } + + public UnaryCallable + detachSubscriptionCallable() { + return detachSubscriptionCallable; + } + + @Override + public final void close() { + shutdown(); + } + + @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); + } +}