Custom filter

更新时间:
复制 MD 格式

SOFARPC provides robust scalability and offers Service Provider Interface (SPI) capabilities for each module.

SOFARPC processes request and response filter chains as follows:

  • It uses multiple filters to intercept and process requests and responses.

  • It lets you create custom filter extensions. Custom filters run after the built-in filters.

This topic describes how to create and activate a custom filter class.

Custom filter class

A custom filter class must inherit the com.alipay.sofa.rpc.filter.Filter class. The following example shows how to do this:

package com.alipay.sofa.rpc.customfilter;

import com.alipay.sofa.rpc.core.exception.SofaRpcException;
import com.alipay.sofa.rpc.core.request.SofaRequest;
import com.alipay.sofa.rpc.core.response.SofaResponse;
import com.alipay.sofa.rpc.filter.Filter;
import com.alipay.sofa.rpc.filter.FilterInvoker;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;

public class CustomEchoFilter extends Filter{

/**
     * Logger for CustomEchoFilter
     **/
private static final Logger LOGGER =LoggerFactory.getLogger(CustomEchoFilter.class);

@Override
public boolean needToLoad(FilterInvoker invoker){
  // Decide whether to load this filter based on specific conditions.
  return true;
}

@Override
public SofaResponse invoke(FilterInvoker invoker,SofaRequest request) throws SofaRpcException{
        // Print the request before the call.
        LOGGER.info("echo request : {}, {}", request.getInterfaceName()+"."+ request.getMethod(),
        request.getMethodArgs());

        // Continue the call.
       SofaResponse response = invoker.invoke(request);

       // Print the return value after the call.
       if(response ==null){
            return response;
       }else if(response.isError()){
            LOGGER.info("server rpc error: {}", response.getErrorMsg());
       }else{
            Object ret = response.getAppResponse();
            if(ret instanceof Throwable){
                LOGGER.error("server biz error: {}",(Throwable) ret);
            }else{
                LOGGER.info("echo response : {}", response.getAppResponse());
            }
       }
       return response;
    }
}

Activating a custom filter class

A custom filter class can be activated in the following ways:

  • Using the API

    This method lets you specify the provider or consumer where the filter takes effect. The following example shows how to do this:

    // Service provider
    providerConfig.setFilterRef(Arrays.asList(new CustomFilter()));
    // Service consumer
    consumerConfig.setFilterRef(Arrays.asList(new CustomFilter()));
  • Using the @Extension annotation, an extension file, and code injection

    Follow these steps:

    1. Process the custom filter class.

      @Extension("customer")
      public class CustomFilter extends Filter{
           @Override
           public boolean needToLoad(FilterInvoker invoker){
                return true;
           }
          @Override
          public SofaResponse invoke(FilterInvoker invoker,SofaRequest request) throws SofaRpcException{
               SofaResponse response = invoker.invoke(request);
               return response;
          }
      }
    2. Create an extension file.

      • File name: The file name must end with `Filter`. For example, com.alipay.sofa.rpc.filter.Filter.

      • File path: The file must be in the fixed path META-INF/services/sofa-rpc/.

      For example, the full path is META-INF/services/sofa-rpc/com.alipay.sofa.rpc.filter.Filter. The content of the extension file is as follows:

      customer=com.alipay.sofa.rpc.custom.CustomFilter
    3. Inject the code.

      // Service provider
      providerConfig.setFilter(Arrays.asList(“customer”));
      // Service consumer
      consumerConfig.setFilter(Arrays.asList(“customer”));
  • Using the @Extension annotation, an extension file, and the @AutoActive annotation

    Follow these steps:

    1. Process the custom filter class.

      @Extension(“customer”)
      @AutoActive(providerSide =true, consumerSide =true)
      public class customerFilter extends Filter{
           @Override
           public boolean needToLoad(FilterInvoker invoker){
              return true;
           }
           @Override
           public SofaResponse invoke(FilterInvoker invoker,SofaRequest request) throws SofaRpcException{
               SofaResponse response = invoker.invoke(request);
               return response;
           }
      }
      Note

      Using the @Extension and @AutoActive annotations for the filter class eliminates the need for code injection. This applies the filter to all providers and consumers. The providerSide parameter specifies whether the filter is active on the server-side. The consumerSide parameter specifies whether the filter is active on the client.

    2. Create an extension file.

      • File name: The file name must end with `Filter`. For example, com.alipay.sofa.rpc.filter.Filter.

      • File path: The file must be in the fixed path META-INF/services/sofa-rpc/.

      For example, the full path is META-INF/services/sofa-rpc/com.alipay.sofa.rpc.filter.Filter. The content of the extension file is as follows:

      customer=com.alipay.sofa.rpc.custom.CustomFilter