插件扩展

说明

  • 插件是 soul 网关的核心执行者,每个插件在开启的情况下,都会对匹配的流量,进行自己的处理。
  • 在soul 网关里面,插件其实分为2 类。
    • 一类是单一职责的调用链,不能对流量进行自定义的筛选。
    • 另一类,能对匹配的流量,执行自己的职责调用链。
  • 用户可以参考 soul-plugin 模块,新增自己的插件处理,如果有好的公用插件,请把代码提交上来。

单一职责插件

  • 引入如下依赖:
  1. <dependency>
  2. <groupId>org.dromara</groupId>
  3. <artifactId>soul-plugin-api</artifactId>
  4. <version>${last.version}</version>
  5. </dependency>
  • 用户新增一个类 A,直接实现 org.dromara.soul.plugin.api.SoulPlugin
  1. public interface SoulPlugin {
  2. /**
  3. * Process the Web request and (optionally) delegate to the next
  4. * {@code WebFilter} through the given {@link SoulPluginChain}.
  5. *
  6. * @param exchange the current server exchange
  7. * @param chain provides a way to delegate to the next filter
  8. * @return {@code Mono<Void>} to indicate when request processing is complete
  9. */
  10. Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain);
  11. /**
  12. * return plugin order .
  13. * This attribute To determine the plugin execution order in the same type plugin.
  14. *
  15. * @return int order
  16. */
  17. int getOrder();
  18. /**
  19. * acquire plugin name.
  20. * this is plugin name define you must Provide the right name.
  21. * if you impl AbstractSoulPlugin this attribute not use.
  22. *
  23. * @return plugin name.
  24. */
  25. default String named() {
  26. return "";
  27. }
  28. /**
  29. * plugin is execute.
  30. * if return true this plugin can not execute.
  31. *
  32. * @param exchange the current server exchange
  33. * @return default false.
  34. */
  35. default Boolean skip(ServerWebExchange exchange) {
  36. return false;
  37. }
  38. }
  • 接口方法详细说明

    • execute() 方法为核心的执行方法,用户可以在里面自由的实现自己想要的功能。

    • getOrder() 指定插件的排序。

    • named() 指定插件的名称。

    • skip() 在特定的条件下,该插件是否被跳过。

  • 注册成Spring的bean,参考如下,或者直接在实现类上加 @Component 注解。

  1. @Bean
  2. public SoulPlugin a() {
  3. return new A();
  4. }

匹配流量处理插件

  • 引入如下依赖:
  1. <dependency>
  2. <groupId>org.dromara</groupId>
  3. <artifactId>soul-plugin-base</artifactId>
  4. <version>${last.version}</version>
  5. </dependency>
  • 新增一个类A,继承 org.dromara.soul.plugin.base.AbstractSoulPlugin

  • 以下是参考:

  1. /**
  2. * This is your custom plugin.
  3. * He is running in after before plugin, implement your own functionality.
  4. * extends AbstractSoulPlugin so you must user soul-admin And add related plug-in development.
  5. *
  6. * @author xiaoyu(Myth)
  7. */
  8. public class CustomPlugin extends AbstractSoulPlugin {
  9. /**
  10. * return plugin order .
  11. * The same plugin he executes in the same order.
  12. *
  13. * @return int
  14. */
  15. @Override
  16. public int getOrder() {
  17. return 0;
  18. }
  19. /**
  20. * acquire plugin name.
  21. * return you custom plugin name.
  22. * It must be the same name as the plug-in you added in the admin background.
  23. *
  24. * @return plugin name.
  25. */
  26. @Override
  27. public String named() {
  28. return "soul";
  29. }
  30. /**
  31. * plugin is execute.
  32. * Do I need to skip.
  33. * if you need skip return true.
  34. *
  35. * @param exchange the current server exchange
  36. * @return default false.
  37. */
  38. @Override
  39. public Boolean skip(final ServerWebExchange exchange) {
  40. return false;
  41. }
  42. @Override
  43. protected Mono<Void> doExecute(ServerWebExchange exchange, SoulPluginChain chain, SelectorZkDTO selector, RuleZkDTO rule) {
  44. LOGGER.debug(".......... function plugin start..............");
  45. /*
  46. * Processing after your selector matches the rule.
  47. * rule.getHandle() is you Customize the json string to be processed.
  48. * for this example.
  49. * Convert your custom json string pass to an entity class.
  50. */
  51. final String ruleHandle = rule.getHandle();
  52. final Test test = GsonUtils.getInstance().fromJson(ruleHandle, Test.class);
  53. /*
  54. * Then do your own business processing.
  55. * The last execution chain.execute(exchange).
  56. * Let it continue on the chain until the end.
  57. */
  58. System.out.println(test.toString());
  59. return chain.execute(exchange);
  60. }
  61. }
  • 详细讲解:

    • 继承该类的插件,插件会进行选择器规则匹配,那如何来设置呢?

    • 首先在 soul-admin 后台 —>插件管理中,新增一个插件,注意 名称与 你自定义插件的 named() 方法要一致。

    • 重新登陆 soul-admin 后台 ,你会发现在插件列表就多了一个你刚新增的插件,你就可以进行选择器规则匹配

    • 在规则中,有个 handler 字段,是你自定义处理数据,在 doExecute() 方法中,通过 final String ruleHandle = rule.getHandle(); 获取,然后进行你的操作。

  • 注册成Spring的bean,参考如下或者直接在实现类上加 @Component 注解。

  1. @Bean
  2. public SoulPlugin a() {
  3. return new A();
  4. }

订阅你的插件数据,进行自定义的处理

  • 新增一个类A,实现 org.dromara.soul.plugin.base.handler.PluginDataHandler
  1. public interface PluginDataHandler {
  2. /**
  3. * Handler plugin.
  4. *
  5. * @param pluginData the plugin data
  6. */
  7. default void handlerPlugin(PluginData pluginData) {
  8. }
  9. /**
  10. * Remove plugin.
  11. *
  12. * @param pluginData the plugin data
  13. */
  14. default void removePlugin(PluginData pluginData) {
  15. }
  16. /**
  17. * Handler selector.
  18. *
  19. * @param selectorData the selector data
  20. */
  21. default void handlerSelector(SelectorData selectorData) {
  22. }
  23. /**
  24. * Remove selector.
  25. *
  26. * @param selectorData the selector data
  27. */
  28. default void removeSelector(SelectorData selectorData) {
  29. }
  30. /**
  31. * Handler rule.
  32. *
  33. * @param ruleData the rule data
  34. */
  35. default void handlerRule(RuleData ruleData) {
  36. }
  37. /**
  38. * Remove rule.
  39. *
  40. * @param ruleData the rule data
  41. */
  42. default void removeRule(RuleData ruleData) {
  43. }
  44. /**
  45. * Plugin named string.
  46. *
  47. * @return the string
  48. */
  49. String pluginNamed();
  50. }
  • 注意 pluginNamed() 要和你自定义的插件名称相同。

  • 注册成Spring的bean,参考如下或者直接在实现类上加 @Component 注解。

  1. @Bean
  2. public PluginDataHandler a() {
  3. return new A();
  4. }

不使用 SelectorList 以及 RulesList

不是所有的插件都需要这两者。

因此我们提供以下两个方法,写在 CustomPlugin 中。

  1. @Override
  2. protected Mono<Void> handleSelectorIsNull(final String pluginName,
  3. final ServerWebExchange exchange,
  4. final SoulPluginChain chain) {
  5. return doExecute(exchange, chain, null, null);
  6. }
  7. @Override
  8. protected Mono<Void> handleRuleIsNull(final String pluginName,
  9. final ServerWebExchange exchange,
  10. final SoulPluginChain chain) {
  11. return doExecute(exchange, chain, null, null);
  12. }
  • 注意,当如果没有重写的时候,由于没有 SelectorList 以及 RulesList 会导致你的插件无效。