Generic Call
Generic call for invoking the service when the caller does not have the API (SDK) provided by the service provider.
Note
Generic calls are suitable for older versions of the Dubbo communication protocol. If you are using the triple protocol from version 3.3 and onwards, please use the HTTP application/json capabilities provided by the triple protocol to directly initiate service calls. Relevant examples can be found in Gateway Access Instructions.
A generic call (client generic call) refers to invoking the service when the caller does not have the service provider’s API (SDK) and can still obtain the call result. The caller can invoke the corresponding interface through a generic call by knowing the fully qualified class name and method name of the service interface.
Usage Scenarios
Generic calls can initiate requests to all services through a universal GenericService interface. Typical use cases include:
Gateway Service: When building a gateway service, the service gateway acts as the caller for all RPC services without relying on the service provider’s API. Therefore, it requires support for generic calls.
Testing Platform: When creating a platform to test RPC calls, users can input group names, interfaces, method names, etc., to test the corresponding RPC services. Similar to the gateway, it should not depend on the service provider’s API, hence requiring support for generic calls.
Usage Method
Please refer to the complete source code of this example at dubbo-samples-generic-call.
The example includes the following Dubbo service definitions and implementations.
Service interface definition:
public interface HelloService {
String sayHello(String name);
CompletableFuture<String> sayHelloAsync(String name);
CompletableFuture<Person> sayHelloAsyncComplex(String name);
CompletableFuture<GenericType<Person>> sayHelloAsyncGenericComplex(String name);
}
Service implementation and publishing:
@DubboService
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "sayHello: " + name;
}
@Override
public CompletableFuture<String> sayHelloAsync(String name) {
// ...
}
@Override
public CompletableFuture<Person> sayHelloAsyncComplex(String name) {
// ...
}
@Override
public CompletableFuture<GenericType<Person>> sayHelloAsyncGenericComplex(String name) {
// ...
}
}
API Invocation Method
For the above Dubbo service, we can initiate calls directly through the generic call API.
private GenericService genericService;
public static void main(String[] args) throws Exception {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("generic-call-consumer");
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
applicationConfig.setRegistry(registryConfig);
referenceConfig.setApplication(applicationConfig);
referenceConfig.setGeneric("true");
// do not wait for result, 'false' by default
referenceConfig.setAsync(true);
referenceConfig.setTimeout(7000);
genericService = referenceConfig.get();
}
public static void invokeSayHello() throws InterruptedException {
Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});
CountDownLatch latch = new CountDownLatch(1);
CompletableFuture<String> future = RpcContext.getContext().getCompletableFuture();
future.whenComplete((value, t) -> {
System.err.println("invokeSayHello(whenComplete): " + value);
latch.countDown();
});
System.err.println("invokeSayHello(return): " + result);
latch.await();
}
- When setting
ReferenceConfig
, usesetGeneric("true")
to enable generic calls. - After configuring
ReferenceConfig
, usereferenceConfig.get()
to get the instance of theGenericService
class. - Use its
$invoke
method to get the result. - Other settings are consistent with normal service call configuration.
Spring Invocation Method
In Spring, there are various ways to expose services and discover services, such as XML and annotations. Here, XML is used as an example.
No changes are needed on the producer side.
The existing
dubbo:reference
tag on the consumer side should have thegeneric=true
attribute added.
<dubbo:reference id="helloService" generic = "true" interface="org.apache.dubbo.samples.generic.call.api.HelloService"/>
Obtain the Bean container and retrieve the
GenericService
instance via the Bean container.Call the
$invoke
method to get the result.
private static GenericService genericService;
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/generic-impl-consumer.xml");
context.start();
// The name of the service corresponding bean is determined by the id of the xml tag.
genericService = context.getBean("helloService");
// Obtain the result.
Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});
}
Feedback
Was this page helpful?
Yes No
Last modified September 30, 2024: Update & Translate Overview Docs (#3040) (d37ebceaea7)