From 3b2dec6adf46823eeb6859e93362e63f00d84ffc Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Fri, 21 Jan 2022 16:43:48 -0800 Subject: [PATCH] feat: add server streaming support for REST transport (#902) This PR depends on https://github.com/googleapis/gax-java/pull/1599 --- WORKSPACE | 2 +- ...ctServiceCallableFactoryClassComposer.java | 22 +++++++++++++ ...pcServiceCallableFactoryClassComposer.java | 22 ------------- ...onServiceCallableFactoryClassComposer.java | 8 +++++ .../HttpJsonServiceStubClassComposer.java | 32 +++++++++++++++++++ .../HttpJsonComplianceCallableFactory.golden | 12 +++++++ .../goldens/HttpJsonComplianceStub.golden | 6 ++++ .../HttpJsonAddressesCallableFactory.java | 12 +++++++ .../v1/stub/HttpJsonAddressesStub.java | 4 +++ ...tpJsonRegionOperationsCallableFactory.java | 12 +++++++ .../v1/stub/HttpJsonRegionOperationsStub.java | 2 ++ 11 files changed, 111 insertions(+), 23 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index c389bed58e..767c6560b6 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -33,7 +33,7 @@ jvm_maven_import_external( # which in its turn, prioritizes actual generated clients runtime dependencies # over the generator dependencies. -_gax_java_version = "2.7.1" +_gax_java_version = "2.10.0" http_archive( name = "com_google_api_gax_java", diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java index 0c2fc84036..8b4e72124d 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java @@ -189,6 +189,28 @@ protected MethodDefinition createBatchingCallableMethod(Service service, TypeSto protected abstract MethodDefinition createOperationCallableMethod( Service service, TypeStore typeStore); + protected MethodDefinition createServerStreamingCallableMethod( + Service service, TypeStore typeStore) { + String methodVariantName = "ServerStreaming"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); + return createGenericCallableMethod( + service, + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + protected MethodDefinition createGenericCallableMethod( Service service, TypeStore typeStore, diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java index 581066f3e6..e193bb7444 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java @@ -146,28 +146,6 @@ private MethodDefinition createBidiStreamingCallableMethod(Service service, Type .collect(Collectors.toList())); } - private MethodDefinition createServerStreamingCallableMethod( - Service service, TypeStore typeStore) { - String methodVariantName = "ServerStreaming"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); - return createGenericCallableMethod( - service, - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList()), - /*callSettingsVariantName=*/ methodVariantName, - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - } - private MethodDefinition createClientStreamingCallableMethod( Service service, TypeStore typeStore) { String methodVariantName = "ClientStreaming"; 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 88ccc1e0c9..9a973a2b76 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 @@ -87,6 +87,14 @@ protected List createClassImplements(Service service, TypeStore typeSt Arrays.asList(operationType.reference(), operationsStubType.reference())))); } + @Override + protected List createClassMethods(Service service, TypeStore typeStore) { + List classMethods = + new ArrayList<>(super.createClassMethods(service, typeStore)); + classMethods.addAll(Arrays.asList(createServerStreamingCallableMethod(service, typeStore))); + return classMethods; + } + @Override protected MethodDefinition createOperationCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Operation"; 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 7b9b05f160..19bd60aae7 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 @@ -17,6 +17,7 @@ import com.google.api.client.http.HttpMethods; import com.google.api.core.InternalApi; import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.ApiMethodDescriptor.MethodType; import com.google.api.gax.httpjson.FieldsExtractor; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonLongRunningClient; @@ -143,6 +144,7 @@ protected Statement createMethodDescriptorVariableDecl( .apply(expr); expr = methodMaker.apply("setHttpMethod", getHttpMethodTypeExpr(protoMethod)).apply(expr); + expr = methodMaker.apply("setType", getMethodTypeExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); @@ -977,6 +979,36 @@ private List getHttpMethodTypeExpr(Method protoMethod) { return Collections.singletonList(expr); } + private List getMethodTypeExpr(Method protoMethod) { + MethodType methodType; + switch (protoMethod.stream()) { + case NONE: + methodType = MethodType.UNARY; + break; + case SERVER: + methodType = MethodType.SERVER_STREAMING; + break; + case CLIENT: + // Not feasible to suppor in REST + case BIDI: + // Not feasible to suppor in REST + default: + throw new UnsupportedOperationException( + String.format( + "Methods of type %s are not supported by REST transport", protoMethod.stream())); + } + EnumRefExpr expr = + EnumRefExpr.builder() + .setName(methodType.toString()) + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ApiMethodDescriptor.MethodType.class) + .build())) + .build(); + return Collections.singletonList(expr); + } + @Override protected List createOperationsStubInitExpr( Service service, 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 6f5e7eab3b..6e9ff65f91 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 @@ -11,6 +11,8 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; import com.google.longrunning.Operation; @@ -74,4 +76,14 @@ public class HttpJsonComplianceCallableFactory return HttpJsonCallableFactory.createOperationCallable( callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden index 6b6a701df9..8744b02704 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden @@ -41,6 +41,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataBody") .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -74,6 +75,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataBodyInfo") .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -109,6 +111,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataQuery") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -144,6 +147,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataSimplePath") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -191,6 +195,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.showcase.v1beta1.Compliance/RepeatDataPathResource") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -237,6 +242,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setFullMethodName( "google.showcase.v1beta1.Compliance/RepeatDataPathTrailingResource") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( 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 2290fc6952..b01a2875ca 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 @@ -26,6 +26,8 @@ import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.Operation; @@ -89,4 +91,14 @@ OperationCallable createOperationCallable( return HttpJsonCallableFactory.createOperationCallable( callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } } diff --git a/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 679bfc1ae2..8258d0fba0 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 @@ -69,6 +69,7 @@ public class HttpJsonAddressesStub extends AddressesStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.Addresses/AggregatedList") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -117,6 +118,7 @@ public class HttpJsonAddressesStub extends AddressesStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.Addresses/Delete") .setHttpMethod(HttpMethods.DELETE) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -166,6 +168,7 @@ public class HttpJsonAddressesStub extends AddressesStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.Addresses/Insert") .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -217,6 +220,7 @@ public class HttpJsonAddressesStub extends AddressesStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.Addresses/List") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( 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 16d93e6f94..17973ca845 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 @@ -27,6 +27,8 @@ import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallSettings; +import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; import com.google.longrunning.Operation; @@ -90,4 +92,14 @@ OperationCallable createOperationCallable( return HttpJsonCallableFactory.createOperationCallable( callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } + + @Override + public + ServerStreamingCallable createServerStreamingCallable( + HttpJsonCallSettings httpJsonCallSettings, + ServerStreamingCallSettings callSettings, + ClientContext clientContext) { + return HttpJsonCallableFactory.createServerStreamingCallable( + httpJsonCallSettings, callSettings, clientContext); + } } diff --git a/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 0f081f8c40..f944b14813 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 @@ -63,6 +63,7 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.RegionOperations/Get") .setHttpMethod(HttpMethods.GET) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath( @@ -117,6 +118,7 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { ApiMethodDescriptor.newBuilder() .setFullMethodName("google.cloud.compute.v1.RegionOperations/Wait") .setHttpMethod(HttpMethods.POST) + .setType(ApiMethodDescriptor.MethodType.UNARY) .setRequestFormatter( ProtoMessageRequestFormatter.newBuilder() .setPath(