Normal calls depend on the JAR packages of consumers, whereas generic calls do not depend on second-party packages. The latter uses GenericService to pass the name of the method to be called, the method signature, and parameter settings during a service call. Generic calls are applicable to gateway applications without depending on service-specific second-party packages. hsf-ops service testing depends on generic calls.

Configure generic calls for HSF services through API programming

You can set generic to true in HSFConsumerBean so that the HSF consumer ignores failed interface loading.

HSFApiConsumerBean hsfApiConsumerBean = new HSFApiConsumerBean();
hsfApiConsumerBean.setInterfaceName("com.alibaba.middleware.hsf.guide.api.service.OrderService");
hsfApiConsumerBean.setVersion("1.0.0");
hsfApiConsumerBean.setGroup("HSF");
// Set generic call configuration.
hsfApiConsumerBean.setGeneric("true");
hsfApiConsumerBean.init(true);

// Retrieve the proxy through the generic interface.
GenericService genericOrderService = (GenericService) hsfApiConsumerBean.getObject();
// ---------------------- Call -----------------------//
// Initiate an HSF generic call and return Map-type results.
Map orderModelMap = (Map) genericOrderService.$invoke("queryOrder",
                            // Array-type input parameters of the method (xxx.getClass().getName())
                            new String[] { Long.class.getName() },
                            // Parameter. If it is of the plain old Java object (POJO) type, it must be converted to the Map type.
                            new Object[] { 1L});

The provider can locate the $invoke method provided by GenericService based on the name of the actually called method, input parameter type, and parameters that are included in the method. Provider-dependent API JAR packages are not used here. Any input parameters of the custom data transfer object (DTO) type must be converted to the Map type that can be serialized by the consumer.

Method signature and input parameters of a call
  • Methods do not have input parameters and only support methodName: service.$invoke("sayHello", null, null).
  • The generic method type is supported, such as List<String>. Only java.util.List is passed, that is, the value of List.class.getName(). Do not pass java.util.List<String>. Otherwise, the method may not be located.
  • If the format is uncertain, the caller can write a unit test with dependency on the second-party package for generic call. A POJO bean of the Map type can be created by using the generalize() method of the HSF-provided com.taobao.hsf.util.PojoUtils tool class.
    Map pojoMap = (Map) PojoUtils.generalize(new OrderModel());
  • Pass the demo with POJO-type parameters.
     class User {
        private String name;
        private int age;
        // Use the standard POJO format. The getter and setter methods are omitted here.
       }
    
       // Directly use the Map type to construct POJO-type generic parameters.
       Map param = new HashMap<String, Object>();
       param.put("age", 11);
       param.put("name","Miles");
       // Input the "class" field to indicate the real type of the POJO parameter (which must be supported by the provider) when the input parameter is a subclass of the declared parameter type.
       param.put("class", "com.taobao.User");

Configure generic calls for HSF services through Spring configuration

Spring is a framework widely used by applications. You can configure HSF services through Spring XML. The following XML configuration has the same effect as the preceding API programming:

<bean id="CallHelloWorld" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean">
    <! --Set the interface for service subscription. -->
    <property name="interfaceName" value="com.alibaba.middleware.hsf.guide.api.service.OrderService"/>
    <! --Set the version of the service. -->
    <property name="version" value="1.0.0"/>
    <! --Set the group to which the service belongs. -->
    <property name="group" value="HSF"/>
    <property name="generic" value="true"/>
</bean>

Note

  • By default, the routing rule does not take effect if the consumer does not include the interface class in a generic call.
  • In this case, the generic call performs worse than a normal call.
  • Configure to throw service exceptions: -Dhsf.generic.throw.exception=true. The default value is false, indicating to generalize exceptions into returned results of the Map type.

    When the exception class exists locally, UndeclaredThrowableException is thrown if the exception (which does not declared by com.taobao.hsf.remoting.service.GenericService) does not belong to the RuntimeException type or its subtypes. The real exception can be retrieved through getCause.

    When the exception class does not exist locally, com.taobao.hsf.util.GenericInvocationException is thrown.