From 7e9abbb8b7a7b75e6a7cee1a3a832fe503086f4a Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 25 Nov 2020 13:58:21 -0800 Subject: [PATCH 1/5] fix: handle empty method_signature in parsing protos --- .../protoparser/MethodSignatureParser.java | 5 +++ .../gapic/protoparser/ParserTest.java | 31 +++++++++++++++++-- .../api/generator/gapic/testdata/echo.proto | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java index ebf877d133..06fcb0b357 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java @@ -23,6 +23,7 @@ import com.google.api.generator.gapic.model.ResourceReference; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.protobuf.Descriptors.MethodDescriptor; import java.util.ArrayList; @@ -59,6 +60,10 @@ public static List> parseMethodSignatures( // Example from Expand in echo.proto: // stringSigs: ["content,error", "content,error,info"]. for (String stringSig : stringSigs) { + if (Strings.isNullOrEmpty(stringSig)) { + continue; + } + List argumentNames = new ArrayList<>(); Map> argumentNameToOverloads = new HashMap<>(); diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index f3c696b9f1..c56a38ed2c 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -187,8 +187,9 @@ public void parseLro_missingMetadataType() { @Test public void parseMethodSignatures_empty() { // TODO(miraleung): Move this to MethodSignatureParserTest. - MethodDescriptor chatWithInfoMethodDescriptor = echoService.getMethods().get(5); - TypeNode inputType = TypeParser.parseType(chatWithInfoMethodDescriptor.getInputType()); + MethodDescriptor methodDescriptor = echoService.getMethods().get(3); + assertEquals("Chat", methodDescriptor.getName()); + TypeNode inputType = TypeParser.parseType(methodDescriptor.getInputType()); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -198,7 +199,31 @@ public void parseMethodSignatures_empty() { echoService, ECHO_PACKAGE, messageTypes, resourceNames, outputResourceNames); assertThat( MethodSignatureParser.parseMethodSignatures( - chatWithInfoMethodDescriptor, + methodDescriptor, + ECHO_PACKAGE, + inputType, + messageTypes, + resourceNames, + outputResourceNames)) + .isEmpty(); + } + + @Test + public void parseMethodSignatures_emptyString() { + // TODO(miraleung): Move this to MethodSignatureParserTest. + MethodDescriptor methodDescriptor = echoService.getMethods().get(5); + assertEquals("PagedExpand", methodDescriptor.getName()); + TypeNode inputType = TypeParser.parseType(methodDescriptor.getInputType()); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); + Set outputResourceNames = new HashSet<>(); + + List methods = + Parser.parseMethods( + echoService, ECHO_PACKAGE, messageTypes, resourceNames, outputResourceNames); + assertThat( + MethodSignatureParser.parseMethodSignatures( + methodDescriptor, ECHO_PACKAGE, inputType, messageTypes, diff --git a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto index 19058ab680..854956ffcc 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto +++ b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto @@ -96,6 +96,7 @@ service Echo { post: "/v1beta1/echo:pagedExpand" body: "*" }; + option (google.api.method_signature) = ""; } // This method will wait the requested amount of and then return. From 3e21503a4ae5c1ef2059d34e4e30ed1b62978a88 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 25 Nov 2020 14:01:15 -0800 Subject: [PATCH 2/5] fix: add google/type:type_java_proto as default test dep --- rules_java_gapic/java_gapic.bzl | 1 + test/integration/BUILD.bazel | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl index e76ecd4682..b178c397e8 100644 --- a/rules_java_gapic/java_gapic.bzl +++ b/rules_java_gapic/java_gapic.bzl @@ -197,6 +197,7 @@ def java_gapic_library( # Test deps. actual_test_deps = test_deps + actual_deps + [ + "@com_google_googleapis//google/type:type_java_proto", # Commonly used. "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", "@com_google_api_gax_java//gax:gax_testlib", "@com_google_code_gson_gson//jar", diff --git a/test/integration/BUILD.bazel b/test/integration/BUILD.bazel index 597e389b17..59b65ac274 100644 --- a/test/integration/BUILD.bazel +++ b/test/integration/BUILD.bazel @@ -55,7 +55,6 @@ java_gapic_library( "@com_google_googleapis//google/cloud/asset/v1:asset_java_proto", "@com_google_googleapis//google/iam/v1:iam_java_proto", "@com_google_googleapis//google/identity/accesscontextmanager/v1:accesscontextmanager_proto", - "@com_google_googleapis//google/type:type_java_proto", ], ) @@ -75,7 +74,6 @@ java_gapic_assembly_gradle_pkg( "@com_google_googleapis//google/cloud/asset/v1:asset_java_proto", "@com_google_googleapis//google/cloud/asset/v1:asset_proto", "@com_google_googleapis//google/cloud/orgpolicy/v1:orgpolicy_java_proto", - "@com_google_googleapis//google/identity/accesscontextmanager/type:type_java_proto", "@com_google_googleapis//google/identity/accesscontextmanager/v1:accesscontextmanager_java_proto", ], ) From bcecb1f345399329d85cb12c6fe6c1d04d881c62 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 25 Nov 2020 17:41:43 -0800 Subject: [PATCH 3/5] fix: support singleton resource names in parsing and codegen --- .../protoparser/ResourceReferenceParser.java | 23 +- .../ResourceNameHelperClassComposerTest.java | 22 ++ .../gapic/composer/goldens/AgentName.golden | 249 ++++++++++++++++++ .../ResourceReferenceParserTest.java | 10 +- 4 files changed, 289 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParser.java index 68233dc83e..a32b61e318 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParser.java @@ -70,10 +70,8 @@ public static List parseResourceNames( Preconditions.checkNotNull( resourceName, String.format( - "No resource definition found for reference with type %s", - resourceReference.resourceTypeString()) - + "\nDEL: " - + resourceNames.keySet()); + "No resource definition found for reference with type %s", + resourceReference.resourceTypeString())); if (!resourceReference.isChildType() || resourceName.isOnlyWildcard()) { return Arrays.asList(resourceName); } @@ -189,17 +187,20 @@ static Optional parseParentPattern(String pattern) { return Optional.empty(); } + int lastTokenIndex = tokens.length - 2; + int minLengthWithParent = 4; + // Singleton patterns, e.g. projects/{project}/agent. + if (!lastToken.contains("{")) { + minLengthWithParent = 3; + lastTokenIndex = tokens.length - 1; + } + // No fully-formed parent. Expected: ancestors/{ancestor}/childNodes/{child_node}. - if (tokens.length < 4) { + if (tokens.length < minLengthWithParent) { return Optional.empty(); } - Preconditions.checkState( - lastToken.contains("{"), - String.format( - "Pattern %s must end with a brace-encapsulated variable, e.g. {foobar}", pattern)); - - return Optional.of(String.join(SLASH, Arrays.asList(tokens).subList(0, tokens.length - 2))); + return Optional.of(String.join(SLASH, Arrays.asList(tokens).subList(0, lastTokenIndex))); } @VisibleForTesting diff --git a/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java index 5532738d73..acb47db274 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java @@ -216,4 +216,26 @@ public void generateResourceNameClass_testingBlueprintPatternWithNonSlashSeparat Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "TestName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } + + @Test + public void generateResourceNameClass_childSingleton() { + ResourceName agentResname = + ResourceName.builder() + .setVariableName("agent") + .setPakkage("com.google.cloud.dialogflow.v2beta1") + .setResourceTypeString("dialogflow.googleapis.com/Agent") + .setPatterns( + Arrays.asList( + "projects/{project}/locations/{location}/agent", "projects/{project}/agent")) + .setParentMessageName("Agent") + .setDescription("This is a description") + .build(); + + GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(agentResname); + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "AgentName.golden", visitor.write()); + Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "AgentName.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden new file mode 100644 index 0000000000..c722cdd4f7 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden @@ -0,0 +1,249 @@ +package com.google.cloud.dialogflow.v2beta1; + +import com.google.api.core.BetaApi; +import com.google.api.pathtemplate.PathTemplate; +import com.google.api.pathtemplate.ValidationException; +import com.google.api.resourcenames.ResourceName; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +@Generated("by gapic-generator-java") +public class AgentName implements ResourceName { + private static final PathTemplate PROJECT_LOCATION = + PathTemplate.createWithoutUrlEncoding("projects/{project}/locations/{location}/agent"); + private static final PathTemplate PROJECT = + PathTemplate.createWithoutUrlEncoding("projects/{project}/agent"); + private volatile Map fieldValuesMap; + private PathTemplate pathTemplate; + private String fixedValue; + private final String project; + private final String location; + + @Deprecated + protected AgentName() { + project = null; + location = null; + } + + private AgentName(Builder builder) { + project = Preconditions.checkNotNull(builder.getProject()); + location = Preconditions.checkNotNull(builder.getLocation()); + pathTemplate = PROJECT_LOCATION; + } + + private AgentName(ProjectBuilder builder) { + project = Preconditions.checkNotNull(builder.getProject()); + location = null; + pathTemplate = PROJECT; + } + + public String getProject() { + return project; + } + + public String getLocation() { + return location; + } + + public static Builder newBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static Builder newProjectLocationBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static ProjectBuilder newProjectBuilder() { + return new ProjectBuilder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + public static AgentName of(String project, String location) { + return newBuilder().setProject(project).setLocation(location).build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static AgentName ofProjectLocationName(String project, String location) { + return newBuilder().setProject(project).setLocation(location).build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static AgentName ofProjectName(String project) { + return newProjectBuilder().setProject(project).build(); + } + + public static String format(String project, String location) { + return newBuilder().setProject(project).setLocation(location).build().toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectLocationName(String project, String location) { + return newBuilder().setProject(project).setLocation(location).build().toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectName(String project) { + return newProjectBuilder().setProject(project).build().toString(); + } + + public static AgentName parse(String formattedString) { + if (formattedString.isEmpty()) { + return null; + } + if (PROJECT_LOCATION.matches(formattedString)) { + Map matchMap = PROJECT_LOCATION.match(formattedString); + return ofProjectLocationName(matchMap.get("project"), matchMap.get("location")); + } else if (PROJECT.matches(formattedString)) { + Map matchMap = PROJECT.match(formattedString); + return ofProjectName(matchMap.get("project")); + } + throw new ValidationException("AgentName.parse: formattedString not in valid format"); + } + + public static List parseList(List formattedStrings) { + List list = new ArrayList<>(formattedStrings.size()); + for (String formattedString : formattedStrings) { + list.add(parse(formattedString)); + } + return list; + } + + public static List toStringList(List values) { + List list = new ArrayList<>(values.size()); + for (AgentName value : values) { + if (Objects.isNull(value)) { + list.add(""); + } else { + list.add(value.toString()); + } + } + return list; + } + + public static boolean isParsableFrom(String formattedString) { + return PROJECT_LOCATION.matches(formattedString) || PROJECT.matches(formattedString); + } + + @Override + public Map getFieldValuesMap() { + if (Objects.isNull(fieldValuesMap)) { + synchronized (this) { + if (Objects.isNull(fieldValuesMap)) { + ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); + if (!Objects.isNull(project)) { + fieldMapBuilder.put("project", project); + } + if (!Objects.isNull(location)) { + fieldMapBuilder.put("location", location); + } + fieldValuesMap = fieldMapBuilder.build(); + } + } + } + return fieldValuesMap; + } + + public String getFieldValue(String fieldName) { + return getFieldValuesMap().get(fieldName); + } + + @Override + public String toString() { + return !Objects.isNull(fixedValue) ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + AgentName that = ((AgentName) o); + return Objects.equals(this.project, that.project) + && Objects.equals(this.location, that.location); + } + return false; + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Objects.hashCode(fixedValue); + h *= 1000003; + h ^= Objects.hashCode(project); + h *= 1000003; + h ^= Objects.hashCode(location); + return h; + } + + /** Builder for projects/{project}/locations/{location}/agent. */ + public static class Builder { + private String project; + private String location; + + protected Builder() {} + + public String getProject() { + return project; + } + + public String getLocation() { + return location; + } + + public Builder setProject(String project) { + this.project = project; + return this; + } + + public Builder setLocation(String location) { + this.location = location; + return this; + } + + private Builder(AgentName agentName) { + Preconditions.checkArgument( + Objects.equals(agentName.pathTemplate, PROJECT_LOCATION), + "toBuilder is only supported when AgentName has the pattern of projects/{project}/locations/{location}/agent"); + project = agentName.project; + location = agentName.location; + } + + public AgentName build() { + return new AgentName(this); + } + } + + /** Builder for projects/{project}/agent. */ + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static class ProjectBuilder { + private String project; + + protected ProjectBuilder() {} + + public String getProject() { + return project; + } + + public ProjectBuilder setProject(String project) { + this.project = project; + return this; + } + + public AgentName build() { + return new AgentName(this); + } + } +} diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java index c2cae61f88..346431d2c5 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java @@ -113,11 +113,12 @@ public void parseParentResourceName_badPattern() { ResourceReferenceParser.parseParentResourceName( "projects/{project}/billingAccounts", MAIN_PACKAGE, - null, - MAIN_PACKAGE, + "com.google.cloud.billing.v1", "cloudbilling.googleapis.com/Feature", + null, new HashMap()); - assertFalse(parentResourceNameOpt.isPresent()); + assertTrue(parentResourceNameOpt.isPresent()); + assertEquals("projects/{project}", parentResourceNameOpt.get().patterns().get(0)); } @Test @@ -159,7 +160,8 @@ public void parseParentPattern_insufficientPathComponents() { public void parseParentPattern_lastComponentIsNotAVariable() { Optional parentPatternOpt = ResourceReferenceParser.parseParentPattern("projects/{project}/foobars"); - assertFalse(parentPatternOpt.isPresent()); + assertTrue(parentPatternOpt.isPresent()); + assertEquals("projects/{project}", parentPatternOpt.get()); } @Test From d22c29ffd7d3f3ca35c293a24cbadb9d697b99eb Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 25 Nov 2020 17:45:43 -0800 Subject: [PATCH 4/5] fix: generate param-less RPC Java methods for empty sigs --- .../ServiceClientTestClassComposer.java | 4 +- .../protoparser/MethodSignatureParser.java | 2 + .../gapic/composer/goldens/EchoClient.golden | 124 ++++++++++++++++++ .../composer/goldens/EchoClientTest.golden | 111 ++++++++++++++-- .../composer/goldens/EchoSettings.golden | 14 ++ .../gapic/composer/goldens/EchoStub.golden | 10 ++ .../composer/goldens/EchoStubSettings.golden | 93 ++++++++++++- .../composer/goldens/GrpcEchoStub.golden | 37 ++++++ .../composer/goldens/MockEchoImpl.golden | 15 +++ .../gapic/protoparser/ParserTest.java | 65 +++++---- .../api/generator/gapic/testdata/echo.proto | 9 +- 11 files changed, 439 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java index 6a5a4802f9..eb630063a7 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java @@ -424,6 +424,7 @@ private static List createTestMethods( service, Collections.emptyList(), 0, + true, classMemberVarExprs, resourceNames, messageTypes)); @@ -444,6 +445,7 @@ private static List createTestMethods( service, method.methodSignatures().get(i), i, + false, classMemberVarExprs, resourceNames, messageTypes)); @@ -467,6 +469,7 @@ private static MethodDefinition createRpcTestMethod( Service service, List methodSignature, int variantIndex, + boolean isRequestArg, Map classMemberVarExprs, Map resourceNames, Map messageTypes) { @@ -584,7 +587,6 @@ private static MethodDefinition createRpcTestMethod( methodStatements.add(EMPTY_LINE_STATEMENT); // Construct the request or method arguments. - boolean isRequestArg = methodSignature.isEmpty(); VariableExpr requestVarExpr = null; Message requestMessage = null; List argExprs = new ArrayList<>(); diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java index 06fcb0b357..b811c6bb9b 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java @@ -27,6 +27,7 @@ import com.google.common.collect.Lists; import com.google.protobuf.Descriptors.MethodDescriptor; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -61,6 +62,7 @@ public static List> parseMethodSignatures( // stringSigs: ["content,error", "content,error,info"]. for (String stringSig : stringSigs) { if (Strings.isNullOrEmpty(stringSig)) { + signatures.add(Collections.emptyList()); continue; } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden index 2accd6e59d..c4745c9892 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden @@ -143,6 +143,16 @@ public class EchoClient implements BackgroundResource { return operationsClient; } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * @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. /** * @param parent @@ -280,6 +290,38 @@ public class EchoClient implements BackgroundResource { return stub.pagedExpandCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * @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. + /** + * @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: */ + public final UnaryCallable + simplePagedExpandPagedCallable() { + return stub.simplePagedExpandPagedCallable(); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** Sample code: */ + public final UnaryCallable simplePagedExpandCallable() { + return stub.simplePagedExpandCallable(); + } + // AUTO-GENERATED DOCUMENTATION AND METHOD. /** * @param ttl @@ -445,4 +487,86 @@ public class EchoClient implements BackgroundResource { 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, + new ApiFunction() { + @Override + public SimplePagedExpandPagedResponse apply(SimplePagedExpandPage input) { + return 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/goldens/EchoClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClientTest.golden index a78f8da333..4bf64b3348 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClientTest.golden @@ -1,6 +1,7 @@ package com.google.showcase.v1beta1; import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.grpc.GaxGrpcProperties; @@ -81,6 +82,44 @@ public class EchoClientTest { EchoResponse.newBuilder().setContent("content951530617").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()) + .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").build(); + mockEcho.addResponse(expectedResponse); + ResourceName parent = FoobarName.ofProjectFoobarName("[PROJECT]", "[FOOBAR]"); EchoResponse actualResponse = client.echo(parent); @@ -98,7 +137,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest() throws Exception { + public void echoExceptionTest2() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -112,7 +151,7 @@ public class EchoClientTest { } @Test - public void echoTest2() throws Exception { + public void echoTest3() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -134,7 +173,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest2() throws Exception { + public void echoExceptionTest3() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -148,7 +187,7 @@ public class EchoClientTest { } @Test - public void echoTest3() throws Exception { + public void echoTest4() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -170,7 +209,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest3() throws Exception { + public void echoExceptionTest4() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -184,7 +223,7 @@ public class EchoClientTest { } @Test - public void echoTest4() throws Exception { + public void echoTest5() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -206,7 +245,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest4() throws Exception { + public void echoExceptionTest5() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -220,7 +259,7 @@ public class EchoClientTest { } @Test - public void echoTest5() throws Exception { + public void echoTest6() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -242,7 +281,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest5() throws Exception { + public void echoExceptionTest6() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -256,7 +295,7 @@ public class EchoClientTest { } @Test - public void echoTest6() throws Exception { + public void echoTest7() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -278,7 +317,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest6() throws Exception { + public void echoExceptionTest7() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -292,7 +331,7 @@ public class EchoClientTest { } @Test - public void echoTest7() throws Exception { + public void echoTest8() throws Exception { EchoResponse expectedResponse = EchoResponse.newBuilder().setContent("content951530617").build(); mockEcho.addResponse(expectedResponse); @@ -316,7 +355,7 @@ public class EchoClientTest { } @Test - public void echoExceptionTest7() throws Exception { + public void echoExceptionTest8() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockEcho.addException(exception); @@ -587,6 +626,52 @@ public class EchoClientTest { } } + @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("page_token1630607433") + .build(); + client.simplePagedExpand(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } + @Test public void waitTest() throws Exception { WaitResponse expectedResponse = diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden index f5b7b86c32..ceb903e029 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden @@ -1,6 +1,7 @@ package com.google.showcase.v1beta1; import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; import com.google.api.core.ApiFunction; import com.google.api.core.BetaApi; @@ -88,6 +89,12 @@ public class EchoSettings extends ClientSettings { 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(); @@ -232,6 +239,13 @@ public class EchoSettings extends ClientSettings { 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(); diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden index 2b6ddd9a7e..9d3eac8add 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden @@ -1,6 +1,7 @@ package com.google.showcase.v1beta1.stub; import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.rpc.BidiStreamingCallable; @@ -63,6 +64,15 @@ public abstract class EchoStub implements BackgroundResource { throw new UnsupportedOperationException("Not implemented: pagedExpandCallable()"); } + public UnaryCallable + simplePagedExpandPagedCallable() { + throw new UnsupportedOperationException("Not implemented: simplePagedExpandPagedCallable()"); + } + + public UnaryCallable simplePagedExpandCallable() { + throw new UnsupportedOperationException("Not implemented: simplePagedExpandCallable()"); + } + public OperationCallable waitOperationCallable() { throw new UnsupportedOperationException("Not implemented: waitOperationCallable()"); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden index 4c6cb32c83..bd4d6aa083 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden @@ -1,6 +1,7 @@ package com.google.showcase.v1beta1.stub; import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; @@ -96,6 +97,9 @@ public class EchoStubSettings extends StubSettings { private final StreamingCallSettings chatAgainSettings; private final PagedCallSettings pagedExpandSettings; + private final PagedCallSettings< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> + simplePagedExpandSettings; private final UnaryCallSettings waitSettings; private final OperationCallSettings waitOperationSettings; @@ -137,6 +141,42 @@ public class EchoStubSettings extends StubSettings { } }; + private static final PagedListDescriptor + SIMPLE_PAGED_EXPAND_PAGE_STR_DESC = + new PagedListDescriptor() { + @Override + public String emptyToken() { + return ""; + } + + @Override + public PagedExpandRequest injectToken(PagedExpandRequest payload, String token) { + return PagedExpandRequest.newBuilder(payload).setPageToken(token).build(); + } + + @Override + public PagedExpandRequest injectPageSize(PagedExpandRequest payload, int pageSize) { + return PagedExpandRequest.newBuilder(payload).setPageSize(pageSize).build(); + } + + @Override + public Integer extractPageSize(PagedExpandRequest payload) { + return payload.getPageSize(); + } + + @Override + public String extractNextToken(PagedExpandResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(PagedExpandResponse payload) { + return Objects.isNull(payload.getResponsesList()) + ? ImmutableList.of() + : payload.getResponsesList(); + } + }; + private static final PagedListResponseFactory< PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> PAGED_EXPAND_PAGE_STR_FACT = @@ -154,6 +194,23 @@ public class EchoStubSettings extends StubSettings { } }; + private static final PagedListResponseFactory< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> + SIMPLE_PAGED_EXPAND_PAGE_STR_FACT = + new PagedListResponseFactory< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse>() { + @Override + public ApiFuture getFuturePagedResponse( + UnaryCallable callable, + PagedExpandRequest request, + ApiCallContext context, + ApiFuture futureResponse) { + PageContext pageContext = + PageContext.create(callable, SIMPLE_PAGED_EXPAND_PAGE_STR_DESC, request, context); + return SimplePagedExpandPagedResponse.createAsync(pageContext, futureResponse); + } + }; + /** Returns the object with the settings used for calls to echo. */ public UnaryCallSettings echoSettings() { return echoSettings; @@ -185,6 +242,12 @@ public class EchoStubSettings extends StubSettings { return pagedExpandSettings; } + /** Returns the object with the settings used for calls to simplePagedExpand. */ + public PagedCallSettings + simplePagedExpandSettings() { + return simplePagedExpandSettings; + } + /** Returns the object with the settings used for calls to wait. */ public UnaryCallSettings waitSettings() { return waitSettings; @@ -274,6 +337,7 @@ public class EchoStubSettings extends StubSettings { chatSettings = settingsBuilder.chatSettings().build(); chatAgainSettings = settingsBuilder.chatAgainSettings().build(); pagedExpandSettings = settingsBuilder.pagedExpandSettings().build(); + simplePagedExpandSettings = settingsBuilder.simplePagedExpandSettings().build(); waitSettings = settingsBuilder.waitSettings().build(); waitOperationSettings = settingsBuilder.waitOperationSettings().build(); blockSettings = settingsBuilder.blockSettings().build(); @@ -290,6 +354,9 @@ public class EchoStubSettings extends StubSettings { private final PagedCallSettings.Builder< PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> pagedExpandSettings; + private final PagedCallSettings.Builder< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> + simplePagedExpandSettings; private final UnaryCallSettings.Builder waitSettings; private final OperationCallSettings.Builder waitOperationSettings; @@ -350,13 +417,18 @@ public class EchoStubSettings extends StubSettings { chatSettings = StreamingCallSettings.newBuilder(); chatAgainSettings = StreamingCallSettings.newBuilder(); pagedExpandSettings = PagedCallSettings.newBuilder(PAGED_EXPAND_PAGE_STR_FACT); + simplePagedExpandSettings = PagedCallSettings.newBuilder(SIMPLE_PAGED_EXPAND_PAGE_STR_FACT); waitSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); waitOperationSettings = OperationCallSettings.newBuilder(); blockSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( - echoSettings, pagedExpandSettings, waitSettings, blockSettings); + echoSettings, + pagedExpandSettings, + simplePagedExpandSettings, + waitSettings, + blockSettings); initDefaults(this); } @@ -369,13 +441,18 @@ public class EchoStubSettings extends StubSettings { chatSettings = settings.chatSettings.toBuilder(); chatAgainSettings = settings.chatAgainSettings.toBuilder(); pagedExpandSettings = settings.pagedExpandSettings.toBuilder(); + simplePagedExpandSettings = settings.simplePagedExpandSettings.toBuilder(); waitSettings = settings.waitSettings.toBuilder(); waitOperationSettings = settings.waitOperationSettings.toBuilder(); blockSettings = settings.blockSettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( - echoSettings, pagedExpandSettings, waitSettings, blockSettings); + echoSettings, + pagedExpandSettings, + simplePagedExpandSettings, + waitSettings, + blockSettings); } private static Builder createDefault() { @@ -405,6 +482,11 @@ public class EchoStubSettings extends StubSettings { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + builder + .simplePagedExpandSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder .waitSettings() .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) @@ -489,6 +571,13 @@ public class EchoStubSettings extends StubSettings { return pagedExpandSettings; } + /** Returns the builder for the settings used for calls to simplePagedExpand. */ + public PagedCallSettings.Builder< + PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> + simplePagedExpandSettings() { + return simplePagedExpandSettings; + } + /** Returns the builder for the settings used for calls to wait. */ public UnaryCallSettings.Builder waitSettings() { return waitSettings; diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden index 6cfd500bc0..530d060444 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden @@ -1,6 +1,7 @@ package com.google.showcase.v1beta1.stub; import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse; +import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse; import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.core.BackgroundResourceAggregation; @@ -88,6 +89,16 @@ public class GrpcEchoStub extends EchoStub { ProtoUtils.marshaller(PagedExpandResponse.getDefaultInstance())) .build(); + private static final MethodDescriptor + simplePagedExpandMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.showcase.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) @@ -112,6 +123,9 @@ public class GrpcEchoStub extends EchoStub { 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; @@ -170,6 +184,10 @@ public class GrpcEchoStub extends EchoStub { GrpcCallSettings.newBuilder() .setMethodDescriptor(pagedExpandMethodDescriptor) .build(); + GrpcCallSettings simplePagedExpandTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(simplePagedExpandMethodDescriptor) + .build(); GrpcCallSettings waitTransportSettings = GrpcCallSettings.newBuilder() .setMethodDescriptor(waitMethodDescriptor) @@ -200,6 +218,16 @@ public class GrpcEchoStub extends EchoStub { 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); @@ -246,6 +274,15 @@ public class GrpcEchoStub extends EchoStub { return pagedExpandPagedCallable; } + public UnaryCallable simplePagedExpandCallable() { + return simplePagedExpandCallable; + } + + public UnaryCallable + simplePagedExpandPagedCallable() { + return simplePagedExpandPagedCallable; + } + public UnaryCallable waitCallable() { return waitCallable; } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden index e3652b66d8..779c195f71 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden @@ -177,6 +177,21 @@ public class MockEchoImpl extends EchoImplBase { } } + @Override + public void simplePagedExpand( + PagedExpandRequest request, StreamObserver responseObserver) { + Object response = responses.remove(); + if (response instanceof PagedExpandResponse) { + requests.add(request); + responseObserver.onNext(((PagedExpandResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError(new IllegalArgumentException("Unrecognized response type")); + } + } + @Override public void wait(WaitRequest request, StreamObserver responseObserver) { Object response = responses.remove(); diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index c56a38ed2c..1e41473c1a 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -38,6 +38,7 @@ import com.google.showcase.v1beta1.TestingOuterClass; import com.google.testgapic.v1beta1.LockerProto; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -102,7 +103,7 @@ public void parseMethods_basic() { Parser.parseMethods( echoService, ECHO_PACKAGE, messageTypes, resourceNames, outputResourceNames); - assertEquals(8, methods.size()); + assertEquals(9, methods.size()); // Methods should appear in the same order as in the protobuf file. Method echoMethod = methods.get(0); @@ -111,7 +112,7 @@ public void parseMethods_basic() { // Detailed method signature parsing tests are in a separate unit test. List> methodSignatures = echoMethod.methodSignatures(); - assertEquals(7, methodSignatures.size()); + assertEquals(8, methodSignatures.size()); Method expandMethod = methods.get(1); assertEquals("Expand", expandMethod.name()); @@ -154,10 +155,10 @@ public void parseMethods_basicLro() { Parser.parseMethods( echoService, ECHO_PACKAGE, messageTypes, resourceNames, outputResourceNames); - assertEquals(8, methods.size()); + assertEquals(9, methods.size()); // Methods should appear in the same order as in the protobuf file. - Method waitMethod = methods.get(6); + Method waitMethod = methods.get(7); assertEquals("Wait", waitMethod.name()); assertTrue(waitMethod.hasLro()); TypeNode waitResponseType = messageTypes.get("WaitResponse").type(); @@ -169,7 +170,8 @@ public void parseMethods_basicLro() { @Test public void parseLro_missingResponseType() { Map messageTypes = Parser.parseMessages(echoFileDescriptor); - MethodDescriptor waitMethodDescriptor = echoService.getMethods().get(6); + MethodDescriptor waitMethodDescriptor = echoService.getMethods().get(7); + assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("WaitResponse"); assertThrows( NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); @@ -178,7 +180,8 @@ public void parseLro_missingResponseType() { @Test public void parseLro_missingMetadataType() { Map messageTypes = Parser.parseMessages(echoFileDescriptor); - MethodDescriptor waitMethodDescriptor = echoService.getMethods().get(6); + MethodDescriptor waitMethodDescriptor = echoService.getMethods().get(7); + assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("WaitMetadata"); assertThrows( NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); @@ -187,8 +190,8 @@ public void parseLro_missingMetadataType() { @Test public void parseMethodSignatures_empty() { // TODO(miraleung): Move this to MethodSignatureParserTest. - MethodDescriptor methodDescriptor = echoService.getMethods().get(3); - assertEquals("Chat", methodDescriptor.getName()); + MethodDescriptor methodDescriptor = echoService.getMethods().get(5); + assertEquals("PagedExpand", methodDescriptor.getName()); TypeNode inputType = TypeParser.parseType(methodDescriptor.getInputType()); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); @@ -209,10 +212,10 @@ public void parseMethodSignatures_empty() { } @Test - public void parseMethodSignatures_emptyString() { + public void parseMethodSignatures_validArgstAndEmptyString() { // TODO(miraleung): Move this to MethodSignatureParserTest. - MethodDescriptor methodDescriptor = echoService.getMethods().get(5); - assertEquals("PagedExpand", methodDescriptor.getName()); + MethodDescriptor methodDescriptor = echoService.getMethods().get(0); + assertEquals("Echo", methodDescriptor.getName()); TypeNode inputType = TypeParser.parseType(methodDescriptor.getInputType()); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); @@ -221,15 +224,17 @@ public void parseMethodSignatures_emptyString() { List methods = Parser.parseMethods( echoService, ECHO_PACKAGE, messageTypes, resourceNames, outputResourceNames); - assertThat( - MethodSignatureParser.parseMethodSignatures( - methodDescriptor, - ECHO_PACKAGE, - inputType, - messageTypes, - resourceNames, - outputResourceNames)) - .isEmpty(); + List> methodArgs = + MethodSignatureParser.parseMethodSignatures( + methodDescriptor, + ECHO_PACKAGE, + inputType, + messageTypes, + resourceNames, + outputResourceNames); + assertEquals(Collections.emptyList(), methodArgs.get(0)); + assertEquals(1, methodArgs.get(1).size()); + assertEquals("parent", methodArgs.get(1).get(0).name()); } @Test @@ -248,10 +253,14 @@ public void parseMethodSignatures_basic() { messageTypes, resourceNames, outputResourceNames); - assertEquals(7, methodSignatures.size()); + assertEquals(8, methodSignatures.size()); - // Signature contents: ["parent"]. + // Signature contents: []. List methodArgs = methodSignatures.get(0); + assertEquals(Collections.emptyList(), methodArgs); + + // Signature contents: ["parent"]. + methodArgs = methodSignatures.get(1); assertEquals(1, methodArgs.size()); MethodArgument argument = methodArgs.get(0); TypeNode resourceNameType = @@ -260,14 +269,14 @@ public void parseMethodSignatures_basic() { assertMethodArgumentEquals("parent", resourceNameType, ImmutableList.of(), argument); // Signature contents: ["error"]. - methodArgs = methodSignatures.get(1); + methodArgs = methodSignatures.get(2); assertEquals(1, methodArgs.size()); argument = methodArgs.get(0); assertMethodArgumentEquals( "error", TypeNode.withReference(createStatusReference()), ImmutableList.of(), argument); // Signature contents: ["name"], resource helper variant. - methodArgs = methodSignatures.get(2); + methodArgs = methodSignatures.get(3); assertEquals(1, methodArgs.size()); argument = methodArgs.get(0); TypeNode foobarNameType = @@ -276,25 +285,25 @@ public void parseMethodSignatures_basic() { assertMethodArgumentEquals("name", foobarNameType, ImmutableList.of(), argument); // Signature contents: ["content"]. - methodArgs = methodSignatures.get(3); + methodArgs = methodSignatures.get(4); assertEquals(1, methodArgs.size()); argument = methodArgs.get(0); assertMethodArgumentEquals("content", TypeNode.STRING, ImmutableList.of(), argument); // Signature contents: ["name"], String variant. - methodArgs = methodSignatures.get(4); + methodArgs = methodSignatures.get(5); assertEquals(1, methodArgs.size()); argument = methodArgs.get(0); assertMethodArgumentEquals("name", TypeNode.STRING, ImmutableList.of(), argument); // Signature contents: ["parent"], String variant. - methodArgs = methodSignatures.get(5); + methodArgs = methodSignatures.get(6); assertEquals(1, methodArgs.size()); argument = methodArgs.get(0); assertMethodArgumentEquals("parent", TypeNode.STRING, ImmutableList.of(), argument); // Signature contents: ["content", "severity"]. - methodArgs = methodSignatures.get(6); + methodArgs = methodSignatures.get(7); assertEquals(2, methodArgs.size()); argument = methodArgs.get(0); assertMethodArgumentEquals("content", TypeNode.STRING, ImmutableList.of(), argument); diff --git a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto index 854956ffcc..136ee598f8 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto +++ b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto @@ -57,6 +57,7 @@ service Echo { 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 @@ -77,7 +78,6 @@ service Echo { post: "/v1beta1/echo:collect" body: "*" }; - option (google.api.method_signature) = "content"; } // This method, upon receiving a request on the stream, the same content will @@ -96,6 +96,13 @@ service Echo { post: "/v1beta1/echo:pagedExpand" body: "*" }; + } + + rpc SimplePagedExpand(PagedExpandRequest) returns (PagedExpandResponse) { + option (google.api.http) = { + post: "/v1beta1/echo:pagedExpand" + body: "*" + }; option (google.api.method_signature) = ""; } From 2db362d420e7b5bb6acfdd96d9eb9f013d9438d7 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 25 Nov 2020 18:27:17 -0800 Subject: [PATCH 5/5] fix: merge master --- src/test/java/com/google/api/generator/gapic/testdata/echo.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto index d5587fb104..136ee598f8 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/echo.proto +++ b/src/test/java/com/google/api/generator/gapic/testdata/echo.proto @@ -96,7 +96,6 @@ service Echo { post: "/v1beta1/echo:pagedExpand" body: "*" }; - option (google.api.method_signature) = ""; } rpc SimplePagedExpand(PagedExpandRequest) returns (PagedExpandResponse) {