apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.55k stars 26.44k forks source link

Generate Google Protobuf object TypeDefinition.#PR:4011 #4010

Closed vio-lin closed 5 years ago

vio-lin commented 5 years ago

As for dubbo service test, it is convient to use Generic reference. But for GooglePb test this approach is not work. We are going to support google protobuf for Generic reference.

  1. ServiceDefinition should be able to support google protobuf Metadata.
  2. Generic invocation should be able to send json String to GenericFilter.
  3. GenericFilter should be able to parse json String to Google Protobuf Object for the request.
  4. GenericFilter should be able to parse Google Protobuf Object to json String for the response.

For (1), PR #4011 is going to support that. For (2), already support by dubbo. For (3),#4, PR #3975 already fixed that.

For (1) (PR #4011):

  1. we change TypeDefinitionBuilder to use SPI to load TypeBuilderList.
  2. extended TypeBuilder in ProtobufTypeBuilder class, while user is able to extend that.
  3. ProtobufTypedBuilder is able to parse google protobuf class to TypeDefinition.
  4. We keep similar logic as TypeDefinitionBuilder,so the TypeDefiniton generated by GooglePb will be equals to which generate by java POJO.

How to use?

  1. get google protobuf Metadata from ServiceDefinition. test client get metaData form metaData reporter.

  2. parse google protobuf metadata to json string for the user (eg: Dubbo Admin portal). TypeDefinition -> json String

  3. send json string with parameter to GenericFilter.

    consumer.xml
    <!-- generate proxy for the remote service, then demoService can be used in the same way as the
    local regular interface -->
    <dubbo:reference url ="dubbo://localhost:20880/org.apache.dubbo.demo.protobuf.api.ProtobufDemoService"
                     id="demoService" check="false" interface="org.apache.dubbo.rpc.service.GenericService" generic="proto"/>
    GenericService genericService = context.getBean("demoService", GenericService.class);
    String methodName = "sayHello";
    String[] requestType = new String[]{GooglePBRequestType.class.getName()};
    // TODO this requestStr could generate from serviceMetaData. a new TypeDefinition is create will push next
    String requestStr = "{ \"req\": \"some Message\" }";
    Object[] request = new Object[]{requestStr};
    String hello = (String) genericService.$invoke(methodName,requestType,request);
vio-lin commented 5 years ago

already merged