0

It is necessary to implement a universal GRPC server as a stub.

Didn't find anything similar for the server, only for the client.

Thank you very much!

kinash
  • 13
  • 1
  • 1
    the IDL does not contain any logic, how will you create a server without any service implementation? – Manuel Jain Jul 13 '21 at 09:53
  • What is it supposed to to? Simply accept the data? – f1sh Jul 13 '21 at 09:55
  • I would like to get a mechanism that would allow creating a server without implementation, which could receive and send the data described in the proto diagram – kinash Jul 13 '21 at 10:04

2 Answers2

0

I believe you would like to use the generated server for testing purposes? If so, there is a practice called service virtualization or API simulation - a subset of the test double family. It allows you to "simulate" or "stub" the real system for the purpose of testing your system under test. Some of those tools allow importing schema files to generate stubs (i.e. Swagger/OpenAPI/Proto/WSDL/...).

Wikipedia contains a list of those tools. Looking at that list today one of those tools that support gRPC is called Traffic Parrot which allows you to create gRPC mocks based on your Proto files. There are also open-source tools like GripMock but it does not generate stubs based on Proto files, you have to create them manually.

Keep in mind, the stub/mock/simulator generated will be only a test double, it will not replicate the full behavior of the system the Proto file corresponds to. The tool that imports the Proto file and generates a server test double can only know the syntax of the messages, not semantics nor the behaviour of the real system.

If you wanted to also replicate partially the semantics of the messages consider a recording of gRPC messages to create service stubs, that way you can see the sample data as well.

Wojtek
  • 1,410
  • 2
  • 16
  • 31
0

If you don't want to process the protobuf messages, then you need to create a Marshaller that serializes to/from byte[], a MethodDescriptor for each method you want to support, and a ServerCallHandler for your application logic. You might find a grpc proxy mockup helpful. Those can be combined together to pass to serverBuilder.addService(ServerServiceDefinition). You can also use ServerCalls to help make a ServerCallHandler.

class ByteMarshaller implements MethodDescriptor.Marshaller<byte[]> {
  @Override public byte[] parse(InputStream stream) {
    try {
      return ByteStreams.toByteArray(stream);
    } catch (IOException ex) {
      throw new RuntimeException();
    }
  }

  @Override public InputStream stream(byte[] value) {
    return new ByteArrayInputStream(value);
  }
};
class YourHandler extends ServerCallHandler<byte[],byte[]> {...}

MethodDescriptor<> desc = MethodDescriptor.<byte[], byte[]>newBuilder()
    // UNKNOWN is fine, but specify the type if you know it
    .setType(MethodDescriptor.MethodType.UNKNOWN)
    .setFullMethodName("package.YourService/Method"))
    .setRequestMarshaller(new ByteMarshaller())
    .setResponseMarshaller(new ByteMarshaller())
    .build();
serverBuilder.addService(
    ServiceDescriptor.newBuilder("package.YourService")
      .addMethod(ServerMethodDefinition.create(desc, new YourHandler()))
      .build());

If you want to parse the protobuf, then you can use DynamicMessage with gRPC's Protobuf Marshaller. A similar client-side question explains that process.

Eric Anderson
  • 24,057
  • 5
  • 55
  • 76