edit-icon download-icon

Use HSF features

Last Updated: Jan 22, 2018

This topic describes the usage instructions and important notes on some of the HSF features.

You can download the demo of all features at the following link: Demo download

Prerequisites

To use HSF features, add the following edas-sdk dependency to the POM file:

  1. <dependency>
  2. <groupId>com.alibaba.edas</groupId>
  3. <artifactId>edas-sdk</artifactId>
  4. <version>1.5.1</version>
  5. </dependency>

Implicit parameter passing

Currently, only string-based parameter passing is supported.

Implicit parameter passing is generally used to replace interface-based passing for passing simple KV data and it is similar to cookies.

  • Pass a single parameter

    Service consumer:

    RpcContext.getContext().setAttachment("key", "args test");

    Service provider:

    String keyVal=RpcContext.getContext().getAttachment("key");

  • Pass multiple parameters

    Service consumer:

    1. Map<String,String> map=new HashMap<String,String>();
    2. map.put("param1", "param1 test");
    3. map.put("param2", "param2 test");
    4. map.put("param3", "param3 test");
    5. map.put("param4", "param4 test");
    6. map.put("param5", "param5 test");
    7. RpcContext rpcContext = RpcContext.getContext();
    8. rpcContext.setAttachments(map);

    Service provider:

    1. Map<String,String> map=rpcContext.getAttachments();
    2. Set<String> set=map.keySet();
    3. for (String key : set) {
    4. System.out.println("map value:"+map.get(key));
    5. }

Asynchronous calls

Asynchronous calls can be implemented by the callback and future methods.

  • Callback

    If the callback method is configured for the consumer, a listener that implements the HSFResponseCallback interface must be configured. After the result is returned, HSF calls the method in HSFResponseCallback.

    Note: The listener of the HSFResponseCallback interface cannot belong to the internal class. Otherwise, the classloader of Pandora returns an error during loading.

    XML configuration:

    1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi"
    2. version="1.1.2">
    3. <hsf:asyncallMethods>
    4. <hsf:method name="ayncTest" type="callback"
    5. listener="com.alibaba.ifree.hsf.consumer.AsynABTestCallbackHandler" />
    6. </hsf:asyncallMethods>
    7. </hsf:consumer>

    The AsynABTestCallbackHandler class implements the HSFResponseCallback interface. The DemoApi interface has the ayncTest method.

    Sample code

    1. public void onAppResponse(Object appResponse) {
    2. //Obtain the value after asynchronous call.
    3. String msg = (String)appResponse;
    4. System.out.println("msg:"+msg);
    5. }

    Note:

    • Method names are used to identify methods. Therefore, overloaded methods are not differentiated. Methods of the same name are set with the same call method.
    • HSF calls cannot be initiated within a call. Otherwise, the I/O thread is suspended and cannot be recovered.
  • Future

    If the future method is configured for the consumer, after a call is initiated, the return result is obtained through public static Object getResponse(long timeout) in HSFResponseFuture.

    XML configuration:

    1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" version="1.1.2" >
    2. <hsf:asyncallMethods>
    3. <hsf:method name="ayncTest" type="future" />
    4. </hsf:asyncallMethods>
    5. </hsf:consumer>

    The sample code is as follows:

    • Asynchronous processing of a single task:

      1. //Initiate a call.
      2. demoApi.ayncTest();
      3. // Process the task.
      4. ...
      5. //Directly obtain the message. (If the result is not required, you can skip this step.)
      6. String msg=(String) HSFResponseFuture.getResponse(3000);
    • Concurrent processing of multiple tasks

      If multiple tasks need to be concurrently processed, you can obtain and store the future object first and use it after the call.

      1. //Define Collection.
      2. List<HSFFuture> futures = new ArrayList<HSFFuture>();
    • Concurrent calls within a method:

      1. //Initiate a call.
      2. demoApi.ayncTest();
      3. //Obtain the future object.
      4. HSFFuture future=HSFResponseFuture.getFuture();
      5. futures.add(future);
      6. //Continue calling other tasks (asynchronous calls are used).
      7. HSFFuture future=HSFResponseFuture.getFuture();
      8. futures.add(future);
      9. // Process the task.
      10. ...
      11. //Obtain and process the data.
      12. for (HSFFuture hsfFuture : futures) {
      13. String msg=(String) hsfFuture.getResponse(3000);
      14. //Process corresponding data.
      15. ...
      16. }

Generalized calls

Generalized calls can combine interfaces, methods, and parameters for remote procedure calls (RPC), without dependency on any service API.

1. Add the “generic” attribute to the consumer’s XML configuration.

  1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" generic="true"/>

Note:“generic” indicates generalized parameters, “true” indicates that generalization is supported, and “false” indicates that generalization is not supported. The default value is “false”.

DemoApi interface method:

  1. public String dealMsg(String msg);
  2. public GenericTestDO dealGenericTestDO(GenericTestDO testDO);

2. Cast the defined service to “GenericService”

  • Import the generalized service interface.

    1. import com.alibaba.dubbo.rpc.service.GenericService
  • Obtain generalized objects.

    • XML loading method

      1. //In a Web project, you can cast the Bean to GenericService.
      2. ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext("hsf-generic-consumer-beans.xml");
      3. GenericService svc = (GenericService) consumerContext.getBean("demoApi");
    • Code subscription method

      1. HSFApiConsumerBean consumerBean = new HSFApiConsumerBean();
      2. consumerBean.setInterfaceName("com.alibaba.demo.api.DemoApi");
      3. consumerBean.setGeneric("true"); // Set generic to true.
      4. consumerBean.setGroup("unittest");
      5. consumerBean.setVersion("1.0.0");
      6. consumerBean.init();
      7. GenericService svc = (GenericService) consumerBean.getObject();

3. Generalized interface

  1. Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException;

Interface parameter description:

  • methodName: Name of the method to be called.

  • parameterTypes: Type of parameters of the method to be called.

  • args: Parameter value to be passed.

4. Generalized calls

  • String-type parameters

    1. svc.$invoke("dealMsg", new String[] { "java.lang.String" }, new Object[] { "hello" })
  • Object parameters, which must be the same on the provider and consumer)

    1. // Construct the entity object GenericTestDO, which has the id and name attributes.
    2. GenericTestDO genericTestDO = new GenericTestDO();
    3. genericTestDO.setId(1980l);
    4. genericTestDO.setName("genericTestDO-tst");
    5. // Use PojoUtils to generate pojo object which represents the metadata information of the service.
    6. Object comp = PojoUtils.generalize(genericTestDO);
    7. // Start the service call.
    8. svc.$invoke("dealGenericTestDO",new String[] { "com.alibaba.demo.generic.domain.GenericTestDO" }, new Object[] { comp });
Thank you! We've received your feedback.