Browse Source

fix grpc MethodDescriptor fullMethodName problem

Fixes gh-2910
pull/2938/head
jiangyuan04 2 years ago committed by spencergibb
parent
commit
3d44588745
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 6
      docs/src/main/asciidoc/spring-cloud-gateway.adoc
  2. BIN
      spring-cloud-gateway-integration-tests/grpc/src/main/proto/hello.pb
  3. 1
      spring-cloud-gateway-integration-tests/grpc/src/main/proto/hello.proto
  4. 24
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java

6
docs/src/main/asciidoc/spring-cloud-gateway.adoc

@ -1849,7 +1849,7 @@ src/main/resources/proto/hello.proto @@ -1849,7 +1849,7 @@ src/main/resources/proto/hello.proto
* `protoFile` Proto definition file.
* `service` Fully qualified name of the service that will handle the request.
* `service` Short name of the service that will handle the request.
* `method` Method name in the service that will handle the request.
@ -1887,12 +1887,12 @@ spring: @@ -1887,12 +1887,12 @@ spring:
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: com.example.grpcserver.hello.HelloService
service: HelloService
method: hello
----
When a request is made through the gateway to `/json/hello` the request will be transformed using the definition provided in `hello.proto`, sent to `com.example.grpcserver.hello.HelloService/hello`, and transform the response back to JSON.
When a request is made through the gateway to `/json/hello` the request will be transformed using the definition provided in `hello.proto`, sent to `HelloService/hello`, and transform the response back to JSON.
By default, it will create a `NettyChannel` using the default `TrustManagerFactory`. However, this `TrustManager` can be customized by creating a bean of type `GrpcSslConfigurer`:

BIN
spring-cloud-gateway-integration-tests/grpc/src/main/proto/hello.pb

Binary file not shown.

1
spring-cloud-gateway-integration-tests/grpc/src/main/proto/hello.proto

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.springframework.cloud.gateway.tests.grpc";
package org.springframework.cloud.gateway.tests.grpc;
message HelloRequest {
optional string firstName = 1;

24
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java

@ -192,9 +192,12 @@ public class JsonToGrpcGatewayFilterFactory @@ -192,9 +192,12 @@ public class JsonToGrpcGatewayFilterFactory
descriptor = DescriptorProtos.FileDescriptorProto.parseFrom(descriptorFile.getInputStream())
.getDescriptorForType();
Descriptors.Descriptor outputType = getOutputTypeDescriptor(config, descriptorFile.getInputStream());
Descriptors.MethodDescriptor methodDescriptor = getMethodDescriptor(config,
descriptorFile.getInputStream());
Descriptors.ServiceDescriptor serviceDescriptor = methodDescriptor.getService();
Descriptors.Descriptor outputType = methodDescriptor.getOutputType();
clientCall = createClientCallForType(config, outputType);
clientCall = createClientCallForType(config, serviceDescriptor, outputType);
ProtobufSchema schema = ProtobufSchemaLoader.std.load(protoFile.getInputStream());
ProtobufSchema responseType = schema.withRootType(outputType.getName());
@ -220,18 +223,19 @@ public class JsonToGrpcGatewayFilterFactory @@ -220,18 +223,19 @@ public class JsonToGrpcGatewayFilterFactory
}
private ClientCall<DynamicMessage, DynamicMessage> createClientCallForType(Config config,
Descriptors.Descriptor outputType) {
Descriptors.ServiceDescriptor serviceDescriptor, Descriptors.Descriptor outputType) {
MethodDescriptor.Marshaller<DynamicMessage> marshaller = ProtoUtils
.marshaller(DynamicMessage.newBuilder(outputType).build());
MethodDescriptor<DynamicMessage, DynamicMessage> methodDescriptor = MethodDescriptor
.<DynamicMessage, DynamicMessage>newBuilder().setType(MethodDescriptor.MethodType.UNKNOWN)
.setFullMethodName(MethodDescriptor.generateFullMethodName(config.getService(), config.getMethod()))
.setFullMethodName(MethodDescriptor.generateFullMethodName(serviceDescriptor.getFullName(),
config.getMethod()))
.setRequestMarshaller(marshaller).setResponseMarshaller(marshaller).build();
Channel channel = createChannel();
return channel.newCall(methodDescriptor, CallOptions.DEFAULT);
}
private Descriptors.Descriptor getOutputTypeDescriptor(Config config, InputStream descriptorFile)
private Descriptors.MethodDescriptor getMethodDescriptor(Config config, InputStream descriptorFile)
throws IOException, Descriptors.DescriptorValidationException {
DescriptorProtos.FileDescriptorSet fileDescriptorSet = DescriptorProtos.FileDescriptorSet
.parseFrom(descriptorFile);
@ -239,11 +243,15 @@ public class JsonToGrpcGatewayFilterFactory @@ -239,11 +243,15 @@ public class JsonToGrpcGatewayFilterFactory
Descriptors.FileDescriptor fileDescriptor = Descriptors.FileDescriptor.buildFrom(fileProto,
new Descriptors.FileDescriptor[0]);
List<Descriptors.MethodDescriptor> methods = fileDescriptor.findServiceByName(config.getService())
.getMethods();
Descriptors.ServiceDescriptor serviceDescriptor = fileDescriptor.findServiceByName(config.getService());
if (serviceDescriptor == null) {
throw new NoSuchElementException("No Service found");
}
List<Descriptors.MethodDescriptor> methods = serviceDescriptor.getMethods();
return methods.stream().filter(method -> method.getName().equals(config.getMethod())).findFirst()
.orElseThrow(() -> new NoSuchElementException("No Method found")).getOutputType();
.orElseThrow(() -> new NoSuchElementException("No Method found"));
}
private ManagedChannel createChannel() {

Loading…
Cancel
Save