Custom Plugin
Description#
- Plugins are core executors of soul gateway. Every plugin handles matched requests when enabled.
- There are two kinds of plugins in the soul gateway.
- The first type is a call chain with a single responsibility, and traffic cannot be customized.
- The other one can do its own chain of responsibility for matched traffic.
- You could reference from soul-plugin module and develop plugins by yourself. Please fire pull requests of your wonderful plugins without hesitate.
Single Responsibility Plugins#
- Add following dependency:
<dependency> <groupId>org.dromara</groupId> <artifactId>soul-plugin-api</artifactId> <version>${last.version}</version> </dependency>- Declare a new class named "A" and implements
org.dromara.soul.plugin.api.SoulPlugin
public interface SoulPlugin { /** * Process the Web request and (optionally) delegate to the next * {@code WebFilter} through the given {@link SoulPluginChain}. * * @param exchange the current server exchange * @param chain provides a way to delegate to the next filter * @return {@code Mono<Void>} to indicate when request processing is complete */ Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain); /** * return plugin order . * This attribute To determine the plugin execution order in the same type plugin. * * @return int order */ int getOrder(); /** * acquire plugin name. * this is plugin name define you must offer the right name. * if you impl AbstractSoulPlugin this attribute not use. * * @return plugin name. */ default String named() { return ""; } /** * plugin is execute. * if return true this plugin can not execute. * * @param exchange the current server exchange * @return default false. */ default Boolean skip(ServerWebExchange exchange) { return false; }}
Detailed instruction of interface methods:
execute()core method, you can do any task here freely.getOrder()get the order of current plugin.named()acquire the name of specific plugin.skip()determines whether this plugin should be skipped under certain conditions.- Register plugin in Spring as a Bean, or simply apply
@Componentin implementation class.
@Bean public SoulPlugin a() { return new A(); }Matching Traffic Processing Plugin#
- Introduce the following dependency:
<dependency> <groupId>org.dromara</groupId> <artifactId>soul-plugin-base</artifactId> <version>${last.version}</version> </dependency>Add a new class A, inherit from
org.dromara.soul.plugin.base.AbstractSoulPluginexamples down below:
/** * This is your custom plugin. * He is running in after before plugin, implement your own functionality. * extends AbstractSoulPlugin so you must user soul-admin And add related plug-in development. * * @author xiaoyu(Myth) */public class CustomPlugin extends AbstractSoulPlugin { /** * return plugin order . * The same plugin he executes in the same order. * * @return int */ @Override public int getOrder() { return 0; }
/** * acquire plugin name. * return you custom plugin name. * It must be the same name as the plug-in you added in the admin background. * * @return plugin name. */ @Override public String named() { return "soul"; }
/** * plugin is execute. * Do I need to skip. * if you need skip return true. * * @param exchange the current server exchange * @return default false. */ @Override public Boolean skip(final ServerWebExchange exchange) { return false; }
@Override protected Mono<Void> doExecute(ServerWebExchange exchange, SoulPluginChain chain, SelectorZkDTO selector, RuleZkDTO rule) { LOGGER.debug(".......... function plugin start.............."); /* * Processing after your selector matches the rule. * rule.getHandle() is you Customize the json string to be processed. * for this example. * Convert your custom json string pass to an entity class. */ final String ruleHandle = rule.getHandle();
final Test test = GsonUtils.getInstance().fromJson(ruleHandle, Test.class);
/* * Then do your own business processing. * The last execution chain.execute(exchange). * Let it continue on the chain until the end. */ System.out.println(test.toString()); return chain.execute(exchange); }}
Detailed explanation:
Plugins will match the selector rule for customized plugins inherit from this abstract class. Following steps guide you to config your plugins.
Firstly define a new plugin in
soul-admin, please mind that your plugin name should match the named() method overridden in your class.Re-login
soul-admin, the plugin you added now showing on plugin-list page, you can choose selectors for matching.There is a field named
handlerin rules, it is customized json string to be processed. You can process data after acquiring a ruleHandle (final String ruleHandle = rule.getHandle();) indoExecute()method.
Register plugin in Spring as a Bean, or simply apply
@Componentin implementation class.
@Bean public SoulPlugin a() { return new A(); }Subscribe your plugin data and do customized jobs#
- Declare a new class named "A" and implements
org.dromara.soul.plugin.base.handler.PluginDataHandler
public interface PluginDataHandler { /** * Handler plugin. * * @param pluginData the plugin data */ default void handlerPlugin(PluginData pluginData) { } /** * Remove plugin. * * @param pluginData the plugin data */ default void removePlugin(PluginData pluginData) { } /** * Handler selector. * * @param selectorData the selector data */ default void handlerSelector(SelectorData selectorData) { } /** * Remove selector. * * @param selectorData the selector data */ default void removeSelector(SelectorData selectorData) { } /** * Handler rule. * * @param ruleData the rule data */ default void handlerRule(RuleData ruleData) { } /** * Remove rule. * * @param ruleData the rule data */ default void removeRule(RuleData ruleData) { } /** * Plugin named string. * * @return the string */ String pluginNamed(); }- Ensure
pluginNamed()is same as the plugin name you defined. - Register defined class as a Spring Bean, or simply apply
@Componentin implementation class.
@Bean public PluginDataHandler a() { return new A(); }Do not use SelectorList and RulesList#
Not all plugins need both.
Therefore, we provide the following two methods, written in CustomPlugin.
@Override protected Mono<Void> handleSelectorIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) { return doExecute(exchange, chain, null, null); }
@Override protected Mono<Void> handleRuleIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) { return doExecute(exchange, chain, null, null); }- Note that if there is no rewriting, your plug-in will be invalid due to the absence of SelectorList and RulesList.