From 134e34c6fefc644279780b812e0cb1b6fc6acea7 Mon Sep 17 00:00:00 2001 From: summerji Date: Mon, 14 Dec 2020 21:07:37 -0800 Subject: [PATCH 1/5] Implemente LRO Operation Callable Method sample code --- .../composer/ServiceClientClassComposer.java | 44 +++++++-- .../ServiceClientCommentComposer.java | 7 +- .../ServiceClientSampleCodeComposer.java | 96 ++++++++++++++++++ .../gapic/composer/goldens/EchoClient.golden | 14 ++- .../goldens/asset/AssetServiceClient.java | 16 +++ .../goldens/redis/CloudRedisClient.java | 97 +++++++++++++++++++ 6 files changed, 264 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java index ccd8cafaf2..e9ec95a840 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java @@ -500,7 +500,8 @@ private static List createServiceMethods( resourceNames)); } if (method.hasLro()) { - javaMethods.add(createLroCallableMethod(service, method, types)); + javaMethods.add( + createLroCallableMethod(service, method, types, messageTypes, resourceNames)); } if (method.isPaged()) { javaMethods.add(createPagedCallableMethod(service, method, types)); @@ -680,25 +681,44 @@ private static MethodDefinition createMethodDefaultMethod( } private static MethodDefinition createLroCallableMethod( - Service service, Method method, Map types) { - return createCallableMethod(service, method, types, CallableMethodKind.LRO); + Service service, + Method method, + Map types, + Map messageTypes, + Map resourceNames) { + return createCallableMethod( + service, method, CallableMethodKind.LRO, types, messageTypes, resourceNames); } private static MethodDefinition createCallableMethod( Service service, Method method, Map types) { - return createCallableMethod(service, method, types, CallableMethodKind.REGULAR); + return createCallableMethod( + service, + method, + CallableMethodKind.REGULAR, + types, + Collections.emptyMap(), + Collections.emptyMap()); } private static MethodDefinition createPagedCallableMethod( Service service, Method method, Map types) { - return createCallableMethod(service, method, types, CallableMethodKind.PAGED); + return createCallableMethod( + service, + method, + CallableMethodKind.PAGED, + types, + Collections.emptyMap(), + Collections.emptyMap()); } private static MethodDefinition createCallableMethod( Service service, Method method, + CallableMethodKind callableMethodKind, Map types, - CallableMethodKind callableMethodKind) { + Map messageTypes, + Map resourceNames) { TypeNode rawCallableReturnType = null; if (callableMethodKind.equals(CallableMethodKind.LRO)) { rawCallableReturnType = types.get("OperationCallable"); @@ -740,9 +760,19 @@ private static MethodDefinition createCallableMethod( .setReturnType(returnType) .build(); + Optional sampleCode = Optional.empty(); + // TODO (summerji): Implement sample code for CallableMethodKind.PAGED and + // CallableMethodKind.REGULAR + if (callableMethodKind.equals(CallableMethodKind.LRO)) { + sampleCode = + Optional.of( + ServiceClientSampleCodeComposer.composeRpcLroCallableMethodHeaderSampleCode( + method, types.get(getClientClassName(service)), resourceNames, messageTypes)); + } + return MethodDefinition.builder() .setHeaderCommentStatements( - ServiceClientCommentComposer.createRpcCallableMethodHeaderComment(method)) + ServiceClientCommentComposer.createRpcCallableMethodHeaderComment(method, sampleCode)) .setScope(ScopeNode.PUBLIC) .setIsFinal(true) .setName(methodName) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java index c3b9158d9b..c5ee9a98d6 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientCommentComposer.java @@ -215,7 +215,8 @@ static CommentStatement createMethodSettingsArgComment(String serviceName) { return toSimpleComment(String.format(CREATE_METHOD_SETTINGS_ARG_PATTERN, serviceName)); } - static List createRpcCallableMethodHeaderComment(Method method) { + static List createRpcCallableMethodHeaderComment( + Method method, Optional sampleCode) { JavaDocComment.Builder methodJavadocBuilder = JavaDocComment.builder(); if (method.hasDescription()) { @@ -224,7 +225,9 @@ static List createRpcCallableMethodHeaderComment(Method method } methodJavadocBuilder.addParagraph(METHOD_DESCRIPTION_SAMPLE_CODE_SUMMARY_STRING); - // TODO(summerji): Add sample code here. + if (sampleCode.isPresent()) { + methodJavadocBuilder.addSampleCode(sampleCode.get()); + } return Arrays.asList( CommentComposer.AUTO_GENERATED_METHOD_COMMENT, diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java index b60c329ab5..6d59f71051 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java @@ -15,6 +15,7 @@ package com.google.api.generator.gapic.composer; import com.google.api.gax.core.FixedCredentialsProvider; +import com.google.api.gax.longrunning.OperationFuture; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.ConcreteReference; @@ -289,6 +290,101 @@ public static String composeRpcDefaultMethodHeaderSampleCode( .build()); } + public static String composeRpcLroCallableMethodHeaderSampleCode( + Method method, + TypeNode clientType, + Map resourceNames, + Map messageTypes) { + VariableExpr clientVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName(JavaStyle.toLowerCamelCase(clientType.reference().name())) + .setType(clientType) + .build()); + // Assign method's request variable with the default value. + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("request").setType(method.inputType()).build()); + Message requestMessage = messageTypes.get(method.inputType().reference().simpleName()); + Preconditions.checkNotNull(requestMessage); + Expr requestBuilderExpr = + DefaultValueComposer.createSimpleMessageBuilderExpr( + requestMessage, resourceNames, messageTypes); + List bodyExprs = new ArrayList<>(); + bodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(requestBuilderExpr) + .build()); + TypeNode operationFutureType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(OperationFuture.class) + .setGenerics( + method.lro().responseType().reference(), + method.lro().metadataType().reference()) + .build()); + VariableExpr operationFutureVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("future").setType(operationFutureType).build()); + MethodInvocationExpr rpcMethodInvocationExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(clientVarExpr) + .setMethodName( + String.format("%sOperationCallable", JavaStyle.toLowerCamelCase(method.name()))) + .build(); + rpcMethodInvocationExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(rpcMethodInvocationExpr) + .setMethodName("futureCall") + .setArguments(requestVarExpr) + .setReturnType(operationFutureType) + .build(); + bodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(operationFutureVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(rpcMethodInvocationExpr) + .build()); + List bodyStatements = + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()); + bodyExprs.clear(); + bodyStatements.add(CommentStatement.withComment(LineComment.withComment("Do something;"))); + MethodInvocationExpr futureGetMethodExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(operationFutureVarExpr) + .setMethodName("get") + .setReturnType(method.lro().responseType()) + .build(); + boolean returnVoid = isProtoEmptyType(method.lro().responseType()); + if (returnVoid) { + bodyExprs.add(futureGetMethodExpr); + } else { + VariableExpr responseVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("response") + .setType(method.lro().responseType()) + .build()) + .setIsDecl(true) + .build(); + bodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(responseVarExpr) + .setValueExpr(futureGetMethodExpr) + .build()); + } + bodyStatements.addAll( + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + bodyExprs.clear(); + return SampleCodeWriter.write( + TryCatchStatement.builder() + .setTryResourceExpr(assignClientVariableWithCreateMethodExpr(clientVarExpr)) + .setTryBody(bodyStatements) + .setIsSampleCode(true) + .build()); + } + private static List composeUnaryRpcMethodSampleCodeBodyStatements( Method method, VariableExpr clientVarExpr, 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 15d93be4eb..6e1e81732d 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 @@ -504,7 +504,19 @@ public class EchoClient implements BackgroundResource { } // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** Sample code: */ + /** + * Sample code: + * + *
{@code
+   * 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(); } diff --git a/test/integration/goldens/asset/AssetServiceClient.java b/test/integration/goldens/asset/AssetServiceClient.java index 24702ea4f4..ecfe104374 100644 --- a/test/integration/goldens/asset/AssetServiceClient.java +++ b/test/integration/goldens/asset/AssetServiceClient.java @@ -202,6 +202,22 @@ public final OperationFuture exportAs * export operation usually finishes within 5 minutes. * *

Sample code: + * + *

{@code
+   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
+   *   ExportAssetsRequest request =
+   *       ExportAssetsRequest.newBuilder()
+   *           .setParent(FeedName.ofProjectFeedName("[PROJECT]", "[FEED]").toString())
+   *           .setReadTime(Timestamp.newBuilder().build())
+   *           .addAllAssetTypes(new ArrayList())
+   *           .setOutputConfig(OutputConfig.newBuilder().build())
+   *           .build();
+   *   OperationFuture future =
+   *       assetServiceClient.exportAssetsOperationCallable().futureCall(request);
+   *   // Do something;
+   *   ExportAssetsResponse response = future.get();
+   * }
+   * }
*/ public final OperationCallable exportAssetsOperationCallable() { diff --git a/test/integration/goldens/redis/CloudRedisClient.java b/test/integration/goldens/redis/CloudRedisClient.java index 72ebd6d532..40b756ba86 100644 --- a/test/integration/goldens/redis/CloudRedisClient.java +++ b/test/integration/goldens/redis/CloudRedisClient.java @@ -561,6 +561,21 @@ public final OperationFuture createInstanceAsync( * call DeleteOperation. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   CreateInstanceRequest request =
+   *       CreateInstanceRequest.newBuilder()
+   *           .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+   *           .setInstanceId("instanceId902024336")
+   *           .setInstance(Instance.newBuilder().build())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.createInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable createInstanceOperationCallable() { @@ -658,6 +673,20 @@ public final OperationFuture updateInstanceAsync( * DeleteOperation. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   UpdateInstanceRequest request =
+   *       UpdateInstanceRequest.newBuilder()
+   *           .setUpdateMask(FieldMask.newBuilder().build())
+   *           .setInstance(Instance.newBuilder().build())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.updateInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable updateInstanceOperationCallable() { @@ -765,6 +794,20 @@ public final OperationFuture upgradeInstanceAsync( * Upgrades Redis instance to the newer Redis version specified in the request. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   UpgradeInstanceRequest request =
+   *       UpgradeInstanceRequest.newBuilder()
+   *           .setName(InstanceName.of("[PROJECT]", "[LOCATION]", "[INSTANCE]").toString())
+   *           .setRedisVersion("redisVersion-1972584739")
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.upgradeInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable upgradeInstanceOperationCallable() { @@ -856,6 +899,20 @@ public final OperationFuture importInstanceAsync( * call DeleteOperation. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   ImportInstanceRequest request =
+   *       ImportInstanceRequest.newBuilder()
+   *           .setName("name3373707")
+   *           .setInputConfig(InputConfig.newBuilder().build())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.importInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable importInstanceOperationCallable() { @@ -950,6 +1007,20 @@ public final OperationFuture exportInstanceAsync( * call DeleteOperation. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   ExportInstanceRequest request =
+   *       ExportInstanceRequest.newBuilder()
+   *           .setName("name3373707")
+   *           .setOutputConfig(OutputConfig.newBuilder().build())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.exportInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable exportInstanceOperationCallable() { @@ -1068,6 +1139,19 @@ public final OperationFuture failoverInstanceAsync( * Cloud Memorystore for Redis instance. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   FailoverInstanceRequest request =
+   *       FailoverInstanceRequest.newBuilder()
+   *           .setName(InstanceName.of("[PROJECT]", "[LOCATION]", "[INSTANCE]").toString())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.failoverInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   Instance response = future.get();
+   * }
+   * }
*/ public final OperationCallable failoverInstanceOperationCallable() { @@ -1161,6 +1245,19 @@ public final OperationFuture deleteInstanceAsync( * Deletes a specific Redis instance. Instance stops serving and data is deleted. * *

Sample code: + * + *

{@code
+   * try (CloudRedisClient cloudRedisClient = CloudRedisClient.create()) {
+   *   DeleteInstanceRequest request =
+   *       DeleteInstanceRequest.newBuilder()
+   *           .setName(InstanceName.of("[PROJECT]", "[LOCATION]", "[INSTANCE]").toString())
+   *           .build();
+   *   OperationFuture future =
+   *       cloudRedisClient.deleteInstanceOperationCallable().futureCall(request);
+   *   // Do something;
+   *   future.get();
+   * }
+   * }
*/ public final OperationCallable deleteInstanceOperationCallable() { From fd01194021edea4e7781f68b9a5488b29752178b Mon Sep 17 00:00:00 2001 From: summerji Date: Tue, 15 Dec 2020 13:59:49 -0800 Subject: [PATCH 2/5] Add todo comment --- .../generator/gapic/composer/ServiceClientClassComposer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java index e9ec95a840..c6b3d19fc1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java @@ -692,6 +692,7 @@ private static MethodDefinition createLroCallableMethod( private static MethodDefinition createCallableMethod( Service service, Method method, Map types) { + // TODO(summerji): Implement sample code for callable method and pass in actual map of Messages and ResourceNames return createCallableMethod( service, method, @@ -703,6 +704,7 @@ private static MethodDefinition createCallableMethod( private static MethodDefinition createPagedCallableMethod( Service service, Method method, Map types) { + // TODO(summerji): Implement sample code for paged callable method and pass in actual map of Messages and ResourceNames return createCallableMethod( service, method, From 3a73ee277ccf78d5f14e0833ceebb5013f019614 Mon Sep 17 00:00:00 2001 From: summerji Date: Thu, 17 Dec 2020 00:08:11 -0800 Subject: [PATCH 3/5] Add unit test --- .../composer/ServiceClientClassComposer.java | 13 ++- .../ServiceClientSampleCodeComposer.java | 11 +- .../ServiceClientSampleCodeComposerTest.java | 108 ++++++++++++++++++ 3 files changed, 124 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java index c6b3d19fc1..e90223575f 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java @@ -692,7 +692,8 @@ private static MethodDefinition createLroCallableMethod( private static MethodDefinition createCallableMethod( Service service, Method method, Map types) { - // TODO(summerji): Implement sample code for callable method and pass in actual map of Messages and ResourceNames + // TODO(summerji): Implement sample code for callable method and pass in actual map of Messages + // and ResourceNames return createCallableMethod( service, method, @@ -704,7 +705,8 @@ private static MethodDefinition createCallableMethod( private static MethodDefinition createPagedCallableMethod( Service service, Method method, Map types) { - // TODO(summerji): Implement sample code for paged callable method and pass in actual map of Messages and ResourceNames + // TODO(summerji): Implement sample code for paged callable method and pass in actual map of + // Messages and ResourceNames return createCallableMethod( service, method, @@ -768,8 +770,11 @@ private static MethodDefinition createCallableMethod( if (callableMethodKind.equals(CallableMethodKind.LRO)) { sampleCode = Optional.of( - ServiceClientSampleCodeComposer.composeRpcLroCallableMethodHeaderSampleCode( - method, types.get(getClientClassName(service)), resourceNames, messageTypes)); + ServiceClientSampleCodeComposer.composeLroCallableMethodHeaderSampleCode( + method, + types.get(ClassNames.getServiceClientClassName(service)), + resourceNames, + messageTypes)); } return MethodDefinition.builder() diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java index 6d59f71051..b2fa6c9e02 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java @@ -290,7 +290,7 @@ public static String composeRpcDefaultMethodHeaderSampleCode( .build()); } - public static String composeRpcLroCallableMethodHeaderSampleCode( + public static String composeLroCallableMethodHeaderSampleCode( Method method, TypeNode clientType, Map resourceNames, @@ -310,12 +310,15 @@ public static String composeRpcLroCallableMethodHeaderSampleCode( Expr requestBuilderExpr = DefaultValueComposer.createSimpleMessageBuilderExpr( requestMessage, resourceNames, messageTypes); - List bodyExprs = new ArrayList<>(); - bodyExprs.add( + AssignmentExpr requestAssignmentExpr = AssignmentExpr.builder() .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr(requestBuilderExpr) - .build()); + .build(); + + List bodyExprs = new ArrayList<>(); + bodyExprs.add(requestAssignmentExpr); + TypeNode operationFutureType = TypeNode.withReference( ConcreteReference.builder() diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java index 3e5d82a8b0..b89c138163 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java @@ -1397,4 +1397,112 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_pureUnaryReturnResponse "}"); assertEquals(results, expected); } + + // ================================LRO Callable Method Sample Code ====================// + @Test + public void validComposeLroCallableMethodHeaderSampleCode_withReturnResponse() { + FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); + Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + TypeNode clientType = + TypeNode.withReference( + VaporReference.builder() + .setName("EchoClient") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + TypeNode inputType = + TypeNode.withReference( + VaporReference.builder() + .setName("WaitRequest") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + TypeNode outputType = + TypeNode.withReference( + VaporReference.builder().setName("Operation").setPakkage(LRO_PACKAGE_NAME).build()); + TypeNode responseType = + TypeNode.withReference( + VaporReference.builder() + .setName("WaitResponse") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + TypeNode metadataType = + TypeNode.withReference( + VaporReference.builder() + .setName("WaitMetadata") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + Method method = + Method.builder() + .setName("Wait") + .setInputType(inputType) + .setOutputType(outputType) + .setLro(lro) + .build(); + String results = + ServiceClientSampleCodeComposer.composeLroCallableMethodHeaderSampleCode( + method, clientType, resourceNames, messageTypes); + String expected = + LineFormatter.lines( + "try (EchoClient echoClient = EchoClient.create()) {\n", + " WaitRequest request = WaitRequest.newBuilder().build();\n", + " OperationFuture future =\n", + " echoClient.waitOperationCallable().futureCall(request);\n", + " // Do something;\n", + " WaitResponse response = future.get();\n", + "}"); + assertEquals(results, expected); + } + + @Test + public void validComposeLroCallableMethodHeaderSampleCode_withReturnVoid() { + FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); + Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); + Map messageTypes = Parser.parseMessages(echoFileDescriptor); + TypeNode clientType = + TypeNode.withReference( + VaporReference.builder() + .setName("EchoClient") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + TypeNode inputType = + TypeNode.withReference( + VaporReference.builder() + .setName("WaitRequest") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + TypeNode outputType = + TypeNode.withReference( + VaporReference.builder().setName("Operation").setPakkage(LRO_PACKAGE_NAME).build()); + TypeNode responseType = + TypeNode.withReference( + VaporReference.builder().setName("Empty").setPakkage(PROTO_PACKAGE_NAME).build()); + TypeNode metadataType = + TypeNode.withReference( + VaporReference.builder() + .setName("WaitMetadata") + .setPakkage(SHOWCASE_PACKAGE_NAME) + .build()); + LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + Method method = + Method.builder() + .setName("Wait") + .setInputType(inputType) + .setOutputType(outputType) + .setLro(lro) + .build(); + String results = + ServiceClientSampleCodeComposer.composeLroCallableMethodHeaderSampleCode( + method, clientType, resourceNames, messageTypes); + String expected = + LineFormatter.lines( + "try (EchoClient echoClient = EchoClient.create()) {\n", + " WaitRequest request = WaitRequest.newBuilder().build();\n", + " OperationFuture future =\n", + " echoClient.waitOperationCallable().futureCall(request);\n", + " // Do something;\n", + " future.get();\n", + "}"); + assertEquals(results, expected); + } } From 6719f882b9272a7a9c92626d549d4af42bbb8733 Mon Sep 17 00:00:00 2001 From: summerji Date: Thu, 17 Dec 2020 00:27:15 -0800 Subject: [PATCH 4/5] add comments --- .../gapic/composer/ServiceClientClassComposer.java | 5 +++-- .../composer/ServiceClientSampleCodeComposer.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java index e90223575f..1634f121b7 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java @@ -692,8 +692,9 @@ private static MethodDefinition createLroCallableMethod( private static MethodDefinition createCallableMethod( Service service, Method method, Map types) { - // TODO(summerji): Implement sample code for callable method and pass in actual map of Messages - // and ResourceNames + // TODO(summerji): Implement sample code for callable methods which include stream methods and + // unary methods, + // and pass in actual map of Messages and ResourceNames return createCallableMethod( service, method, diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java index b2fa6c9e02..0c8acf717c 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java @@ -319,6 +319,9 @@ public static String composeLroCallableMethodHeaderSampleCode( List bodyExprs = new ArrayList<>(); bodyExprs.add(requestAssignmentExpr); + // Create OperationFuture variable expr with invoking client's lro callable method. + // e.g. OperationFuture future = + // echoClient.waitOperationCallable().futureCall(request); TypeNode operationFutureType = TypeNode.withReference( ConcreteReference.builder() @@ -348,10 +351,16 @@ public static String composeLroCallableMethodHeaderSampleCode( .setVariableExpr(operationFutureVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr(rpcMethodInvocationExpr) .build()); + List bodyStatements = bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()); bodyExprs.clear(); + // Add a line comment bodyStatements.add(CommentStatement.withComment(LineComment.withComment("Do something;"))); + + // Assign response variable with invoking client's lro method. + // e.g. if return void, future.get(); or, + // e.g. if return other type, WaitResponse response = future.get(); MethodInvocationExpr futureGetMethodExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(operationFutureVarExpr) @@ -380,6 +389,7 @@ public static String composeLroCallableMethodHeaderSampleCode( bodyStatements.addAll( bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); bodyExprs.clear(); + return SampleCodeWriter.write( TryCatchStatement.builder() .setTryResourceExpr(assignClientVariableWithCreateMethodExpr(clientVarExpr)) From b7b7b2ee2d559dc89090f867e87c285b65b8d094 Mon Sep 17 00:00:00 2001 From: summerji Date: Thu, 17 Dec 2020 16:31:37 -0800 Subject: [PATCH 5/5] address the comments --- .../composer/ServiceClientSampleCodeComposer.java | 8 ++++---- .../ServiceClientSampleCodeComposerTest.java | 4 ++-- .../gapic/composer/goldens/EchoClient.golden | 2 +- .../goldens/asset/AssetServiceClient.java | 2 +- .../goldens/redis/CloudRedisClient.java | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java index 0c8acf717c..d26a1f129a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposer.java @@ -319,7 +319,7 @@ public static String composeLroCallableMethodHeaderSampleCode( List bodyExprs = new ArrayList<>(); bodyExprs.add(requestAssignmentExpr); - // Create OperationFuture variable expr with invoking client's lro callable method. + // Create OperationFuture variable expr with invoking client's LRO callable method. // e.g. OperationFuture future = // echoClient.waitOperationCallable().futureCall(request); TypeNode operationFutureType = @@ -356,9 +356,9 @@ public static String composeLroCallableMethodHeaderSampleCode( bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()); bodyExprs.clear(); // Add a line comment - bodyStatements.add(CommentStatement.withComment(LineComment.withComment("Do something;"))); + bodyStatements.add(CommentStatement.withComment(LineComment.withComment("Do something."))); - // Assign response variable with invoking client's lro method. + // Assign response variable with invoking client's LRO method. // e.g. if return void, future.get(); or, // e.g. if return other type, WaitResponse response = future.get(); MethodInvocationExpr futureGetMethodExpr = @@ -494,7 +494,7 @@ private static List composeUnaryLroRpcMethodSampleCodeBodyStatements( VariableExpr clientVarExpr, List rpcMethodArgVarExprs, List bodyExprs) { - // Assign response variable with invoking client's lro method. + // Assign response variable with invoking client's LRO method. // e.g. if return void, echoClient.waitAsync(ttl).get(); or, // e.g. if return other type, WaitResponse response = echoClient.waitAsync(ttl).get(); Expr invokeLroGetMethodExpr = diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java index b89c138163..441bea4c65 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientSampleCodeComposerTest.java @@ -1448,7 +1448,7 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnResponse() { " WaitRequest request = WaitRequest.newBuilder().build();\n", " OperationFuture future =\n", " echoClient.waitOperationCallable().futureCall(request);\n", - " // Do something;\n", + " // Do something.\n", " WaitResponse response = future.get();\n", "}"); assertEquals(results, expected); @@ -1500,7 +1500,7 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnVoid() { " WaitRequest request = WaitRequest.newBuilder().build();\n", " OperationFuture future =\n", " echoClient.waitOperationCallable().futureCall(request);\n", - " // Do something;\n", + " // Do something.\n", " future.get();\n", "}"); assertEquals(results, expected); 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 6e1e81732d..b9585ec489 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 @@ -512,7 +512,7 @@ public class EchoClient implements BackgroundResource { * WaitRequest request = WaitRequest.newBuilder().build(); * OperationFuture future = * echoClient.waitOperationCallable().futureCall(request); - * // Do something; + * // Do something. * WaitResponse response = future.get(); * } * } diff --git a/test/integration/goldens/asset/AssetServiceClient.java b/test/integration/goldens/asset/AssetServiceClient.java index ecfe104374..6a39beb127 100644 --- a/test/integration/goldens/asset/AssetServiceClient.java +++ b/test/integration/goldens/asset/AssetServiceClient.java @@ -214,7 +214,7 @@ public final OperationFuture exportAs * .build(); * OperationFuture future = * assetServiceClient.exportAssetsOperationCallable().futureCall(request); - * // Do something; + * // Do something. * ExportAssetsResponse response = future.get(); * } * } diff --git a/test/integration/goldens/redis/CloudRedisClient.java b/test/integration/goldens/redis/CloudRedisClient.java index 40b756ba86..bf6aba5541 100644 --- a/test/integration/goldens/redis/CloudRedisClient.java +++ b/test/integration/goldens/redis/CloudRedisClient.java @@ -572,7 +572,7 @@ public final OperationFuture createInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.createInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -683,7 +683,7 @@ public final OperationFuture updateInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.updateInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -804,7 +804,7 @@ public final OperationFuture upgradeInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.upgradeInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -909,7 +909,7 @@ public final OperationFuture importInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.importInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -1017,7 +1017,7 @@ public final OperationFuture exportInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.exportInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -1148,7 +1148,7 @@ public final OperationFuture failoverInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.failoverInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * Instance response = future.get(); * } * } @@ -1254,7 +1254,7 @@ public final OperationFuture deleteInstanceAsync( * .build(); * OperationFuture future = * cloudRedisClient.deleteInstanceOperationCallable().futureCall(request); - * // Do something; + * // Do something. * future.get(); * } * }