diff --git a/WORKSPACE b/WORKSPACE index 7468b3246d..1b8335256f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -32,7 +32,7 @@ jvm_maven_import_external( # gapic-generator-java dependencies to match the order in googleapis repository, # which in its turn, prioritizes actual generated clients runtime dependencies # over the generator dependencies. -_gax_java_version = "1.65.1" +_gax_java_version = "2.2.0" http_archive( name = "com_google_api_gax_java", diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java index 034c94c949..524f8f6361 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java @@ -52,6 +52,7 @@ import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -159,12 +160,14 @@ public GapicClass generate(GapicContext context, Service service) { .setType(getTransportContext().stubCallableFactoryType()) .build())); + Map messageTypes = context.messages(); List classStatements = createClassStatements( service, protoMethodNameToDescriptorVarExprs, callableClassMemberVarExprs, - classMemberVarExprs); + classMemberVarExprs, + messageTypes); StubCommentComposer commentComposer = new StubCommentComposer(getTransportContext().transportName()); @@ -193,7 +196,7 @@ public GapicClass generate(GapicContext context, Service service) { } protected abstract Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr); + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr, Map messageTypes); protected abstract List createOperationsStubGetterMethod( VariableExpr operationsStubVarExpr); @@ -212,10 +215,11 @@ protected List createClassStatements( Service service, Map protoMethodNameToDescriptorVarExprs, Map callableClassMemberVarExprs, - Map classMemberVarExprs) { + Map classMemberVarExprs, + Map messageTypes) { List classStatements = new ArrayList<>(); for (Statement statement : - createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs)) { + createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs, messageTypes)) { classStatements.add(statement); classStatements.add(EMPTY_LINE_STATEMENT); } @@ -228,12 +232,12 @@ protected List createClassStatements( } protected List createMethodDescriptorVariableDecls( - Service service, Map protoMethodNameToDescriptorVarExprs) { + Service service, Map protoMethodNameToDescriptorVarExprs, Map messageTypes) { return service.methods().stream() .map( m -> createMethodDescriptorVariableDecl( - service, m, protoMethodNameToDescriptorVarExprs.get(m.name()))) + service, m, protoMethodNameToDescriptorVarExprs.get(m.name()), messageTypes)) .collect(Collectors.toList()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java index f079aba780..3fc25a95b2 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java @@ -34,6 +34,7 @@ import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -85,7 +86,10 @@ private static TypeStore createStaticTypes() { @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr methodDescriptorMaker = MethodInvocationExpr.builder() .setMethodName("newBuilder") diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index f9c4045cb9..191c1d15fa 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -16,14 +16,27 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.UnaryCallable; import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.ExprStatement; import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.Statement; import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.VaporReference; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.Service; +import com.google.longrunning.Operation; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -90,6 +103,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { "The surface for long-running operations is not stable yet and may change in the" + " future."); + // Generate generic method without the body MethodDefinition method = createGenericCallableMethod( typeStore, @@ -104,6 +118,119 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .map(n -> (Object) n) .collect(Collectors.toList()), Arrays.asList(betaAnnotation)); - return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + + List createOperationCallableBody = new ArrayList(2); + + List arguments = method.arguments(); + Variable httpJsonCallSettingsVar = arguments.get(0).variable(); + Variable callSettingsVar = arguments.get(1).variable(); + Variable clientContextVar = arguments.get(2).variable(); + Variable operationsStub = arguments.get(3).variable(); + // Generate innerCallable + VariableExpr innerCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("innerCallable") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + .build(); + MethodInvocationExpr getInitialCallSettingsExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(callSettingsVar)) + .setMethodName("getInitialCallSettings") + .build(); + MethodInvocationExpr createBaseUnaryCallableExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createBaseUnaryCallable") + .setArguments( + VariableExpr.withVariable(httpJsonCallSettingsVar), + getInitialCallSettingsExpr, + VariableExpr.withVariable(clientContextVar)) + .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build(); + AssignmentExpr innerCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(innerCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(createBaseUnaryCallableExpr) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(innerCallableAssignExpr)); + + // Generate initialCallable + VariableExpr initialCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("initialCallable") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + .build(); + MethodInvocationExpr getMethodDescriptorExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(httpJsonCallSettingsVar)) + .setMethodName("getMethodDescriptor") + .build(); + MethodInvocationExpr getOperationSnapshotFactoryExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getMethodDescriptorExpr) + .setMethodName("getOperationSnapshotFactory") + .build(); + // This is a temporary solution + VaporReference requestT = + VaporReference.builder() + .setName("RequestT") + .setPakkage("com.google.cloud.compute.v1.stub") + .build(); + TypeNode operationSnapshotCallableType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonOperationSnapshotCallable.class) + .setGenerics(requestT, ConcreteReference.withClazz(Operation.class)) + .build()); + NewObjectExpr initialCallableObject = + NewObjectExpr.builder() + .setType(operationSnapshotCallableType) + .setIsGeneric(true) + .setArguments(innerCallableVarExpr, getOperationSnapshotFactoryExpr) + .build(); + AssignmentExpr initialCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(initialCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(initialCallableObject) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(initialCallableAssignExpr)); + + // Generate return statement + MethodInvocationExpr longRunningClient = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(operationsStub)) + .setMethodName("longRunningClient") + .build(); + MethodInvocationExpr createOperationCallable = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createOperationCallable") + .setArguments( + VariableExpr.withVariable(callSettingsVar), + VariableExpr.withVariable(clientContextVar), + longRunningClient, + initialCallableVarExpr) + .setReturnType( + TypeNode.withReference(ConcreteReference.withClazz(OperationCallable.class))) + .build(); + + // Add body and return statement to method + return method + .toBuilder() + .setBody(createOperationCallableBody) + .setReturnExpr(createOperationCallable) + .build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index 901dceacc6..66fdfb2b4e 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -19,10 +19,12 @@ import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.FieldsExtractor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; import com.google.api.gax.httpjson.ProtoMessageResponseParser; import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; @@ -34,16 +36,19 @@ import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; import com.google.api.generator.engine.ast.StringObjectValue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -91,7 +96,10 @@ private static TypeStore createStaticTypes() { @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr expr = MethodInvocationExpr.builder() .setMethodName("newBuilder") @@ -116,6 +124,22 @@ protected Statement createMethodDescriptorVariableDecl( methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); + // System.out.println(protoMethod.outputType().reference().simpleName()); + if (protoMethod.outputType().reference().simpleName().equals("Operation")) { + expr = + methodMaker + .apply( + "setOperationSnapshotFactory", + setOperationSnapshotFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + expr = + methodMaker + .apply( + "setPollingRequestFactory", + setPollingRequestFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + } + expr = MethodInvocationExpr.builder() .setMethodName("build") @@ -356,6 +380,277 @@ private List setResponseParserExpr(Method protoMethod) { return Collections.singletonList(expr); } + private List setOperationSnapshotFactoryExpr( + Method protoMethod, Map messageTypes) { + + BiFunction, Function> + methodMaker = getMethodMaker(); + + // Generate input varibles for create() + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.inputType()).setName("request").build()); + VariableExpr responseVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.outputType()).setName("response").build()); + + List createBody = new ArrayList(4); + + // Generate opName + // This will be replaced and edited based on annotations + TypeNode stringBuilderType = + TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); + VariableExpr opNameVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(stringBuilderType).setName("opName").build()); + MethodInvocationExpr getId = + MethodInvocationExpr.builder() + .setMethodName("getId") + .setExprReferenceExpr(responseVarExpr) + .build(); + Expr opNameObjectExpr = + NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); + AssignmentExpr opNameAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(opNameVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(opNameObjectExpr) + .build(); + createBody.add(ExprStatement.withExpr(opNameAssignExpr)); + + // Generate changes opName + // This will be replaced and edited based on annotations + MethodInvocationExpr requestGetProjectExpr = + MethodInvocationExpr.builder() + .setMethodName("getProject") + .setExprReferenceExpr(requestVarExpr) + .build(); + ValueExpr colonValueExpr = + ValueExpr.builder().setValue(StringObjectValue.builder().setValue(":").build()).build(); + MethodInvocationExpr opNameAppendColonProjectExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(opNameVarExpr) + .build(); + opNameAppendColonProjectExpr = + methodMaker + .apply("append", Collections.singletonList(requestGetProjectExpr)) + .apply(opNameAppendColonProjectExpr); + createBody.add(ExprStatement.withExpr(opNameAppendColonProjectExpr)); + + // Generate changes to opName + MethodInvocationExpr requestGetRegionExpr = + MethodInvocationExpr.builder() + .setMethodName("getRegion") + .setExprReferenceExpr(requestVarExpr) + .build(); + MethodInvocationExpr opNameAppendColonRegionExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(opNameVarExpr) + .build(); + opNameAppendColonRegionExpr = + methodMaker + .apply("append", Collections.singletonList(requestGetRegionExpr)) + .apply(opNameAppendColonRegionExpr); + createBody.add(ExprStatement.withExpr(opNameAppendColonRegionExpr)); + + // Generate check status expression + // This will be replaced and edited based on annotations + MethodInvocationExpr getStatusExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getStatus") + .build(); + TypeNode statusType = + TypeNode.withReference( + VaporReference.builder() + .setName("Status") + .setPakkage("com.google.cloud.compute.v1") + .setIsStaticImport(false) + .build()); + VariableExpr statusDoneExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(TypeNode.INT).build()) + .setStaticReferenceType(statusType) + .build(); + MethodInvocationExpr statusEqualsExpr = + methodMaker.apply("equals", Collections.singletonList(statusDoneExpr)).apply(getStatusExpr); + + // Generate return statement + TypeNode httpJsonOperationSnapshotType = + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonOperationSnapshot.class)); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("newBuilder") + .build(); + MethodInvocationExpr opNameToStringExpr = + MethodInvocationExpr.builder() + .setMethodName("toString") + .setExprReferenceExpr(opNameVarExpr) + .build(); + // This will be replaced and edited based on annotations + MethodInvocationExpr getHttpErrorStatusCodeExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getHttpErrorStatusCode") + .build(); + // This will be replaced and edited based on annotations + MethodInvocationExpr getHttpErrorMessageExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getHttpErrorMessage") + .build(); + newBuilderExpr = + methodMaker + .apply("setName", Collections.singletonList(opNameToStringExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setMetadata", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setDone", Collections.singletonList(statusEqualsExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setResponse", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setError", Arrays.asList(getHttpErrorStatusCodeExpr, getHttpErrorMessageExpr)) + .apply(newBuilderExpr); + TypeNode operationSnapshotType = + TypeNode.withReference( + ConcreteReference.builder().setClazz(OperationSnapshot.class).build()); + MethodInvocationExpr buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(operationSnapshotType) + .build(); + + // Generate lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments( + requestVarExpr.toBuilder().setIsDecl(true).build(), + responseVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + private List setPollingRequestFactoryExpr( + Method protoMethod, Map messageTypes) { + + BiFunction, Function> + methodMaker = getMethodMaker(); + + List createBody = new ArrayList(1); + + // Generate input variables for create + VariableExpr compoundOperationIdVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.STRING).setName("compoundOperationId").build()) + .build(); + + // Generate idComponenets + TypeNode listStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arrayListStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arraysType = TypeNode.withReference(ConcreteReference.withClazz(Arrays.class)); + VariableExpr idComponentsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("idComponents").setType(listStringType).build()); + MethodInvocationExpr compoundOperationIdSplitExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(compoundOperationIdVarExpr) + .setMethodName("split") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue(":"))) + .setReturnType(arrayListStringType) + .build(); + MethodInvocationExpr asListExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(arraysType) + .setMethodName("asList") + .setArguments(compoundOperationIdSplitExpr) + .setReturnType(arrayListStringType) + .build(); + AssignmentExpr idComponentsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(idComponentsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(asListExpr) + .build(); + createBody.add(ExprStatement.withExpr(idComponentsAssignExpr)); + + // Generate return statement + // This will be replaced and edited based on annotations + TypeNode getRegionOperationRequestType = + TypeNode.withReference( + VaporReference.builder() + .setName("GetRegionOperationRequest") + .setPakkage("com.google.cloud.compute.v1") + .setIsStaticImport(false) + .build()); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getRegionOperationRequestType) + .setMethodName("newBuilder") + .build(); + newBuilderExpr = + methodMaker + .apply("setOperation", Collections.singletonList(getExpr(idComponentsVarExpr, "0"))) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setProject", Collections.singletonList(getExpr(idComponentsVarExpr, "1"))) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setRegion", Collections.singletonList(getExpr(idComponentsVarExpr, "2"))) + .apply(newBuilderExpr); + MethodInvocationExpr buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(getRegionOperationRequestType) + .build(); + + // Return lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments(compoundOperationIdVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + // returns var.get(num); + private MethodInvocationExpr getExpr(VariableExpr var, String num) { + return MethodInvocationExpr.builder() + .setExprReferenceExpr(var) + .setMethodName("get") + .setArguments( + ValueExpr.builder() + .setValue(PrimitiveValue.builder().setValue(num).setType(TypeNode.INT).build()) + .build()) + .build(); + } + private Expr createFieldsExtractorClassInstance( Method method, TypeNode extractorReturnType, diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index 7d6032778d..0b58310417 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -5,6 +5,7 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.ApiMessage; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -13,6 +14,8 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.stub.RequestT; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -63,6 +66,14 @@ public class HttpJsonComplianceCallableFactory OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java index afa275a6f5..49347e5792 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java @@ -21,6 +21,7 @@ import com.google.api.gax.httpjson.ApiMessage; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -29,6 +30,7 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -79,6 +81,14 @@ OperationCallable createOperationCallable( OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java index d8d960d342..e2d4a26060 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -26,21 +26,26 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; import com.google.api.gax.httpjson.ProtoMessageResponseParser; import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.AddressAggregatedList; import com.google.cloud.compute.v1.AddressList; import com.google.cloud.compute.v1.AggregatedListAddressesRequest; import com.google.cloud.compute.v1.DeleteAddressRequest; +import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.InsertAddressRequest; import com.google.cloud.compute.v1.ListAddressesRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Status; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -137,6 +142,28 @@ public class HttpJsonAddressesStub extends AddressesStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (DeleteAddressRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private static final ApiMethodDescriptor insertMethodDescriptor = @@ -174,6 +201,28 @@ public class HttpJsonAddressesStub extends AddressesStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (InsertAddressRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private static final ApiMethodDescriptor listMethodDescriptor = diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java index 6dac14a84e..6113b5f496 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -21,6 +21,7 @@ import com.google.api.gax.httpjson.ApiMessage; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -29,6 +30,7 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -79,6 +81,14 @@ OperationCallable createOperationCallable( OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java index 9d90915792..47bc6a36a7 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -23,16 +23,20 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; import com.google.api.gax.httpjson.ProtoMessageResponseParser; import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Status; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -79,6 +83,28 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (GetRegionOperationRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private final UnaryCallable getCallable;