Skip to content

插件

通过本文档可了解插件的机制,定义及开发。

定义

java
package kunlun.proxy;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;

public interface Plugin {

    /**
     * 插件名称
     * @return
     */
    String name();

    /**
     * 插件执行顺序
     * @return
     */
    short order();

    /**
     * 是否阻塞式插件
     * @return
     */
    default boolean blocked() {
        return false;
    }

    /**
     * 插件加载时执行
     * @param engine
     */
    default void init(RouteEngine engine) {
    }

    /**
     * 插件卸载时执行
     * @param completionHandler
     */
    default void close(Handler<AsyncResult<Void>> completionHandler) {
        if (null != completionHandler) {
            completionHandler.handle(Future.succeededFuture());
        }
    }

    /**
     * intercept routing context. must be thread safe.
     *
     * @param ctx
     * @param config
     */
    void intercept(RoutingContext ctx, JsonObject config);
}

示例

以下代码实现类似 Nginx 中 ngx_http_proxy_module 模块下 proxy_redirect 指令作用。

java
package kunlun.proxy.plugin;

import io.vertx.core.http.HttpHeaders;
import io.vertx.core.json.JsonObject;
import kunlun.proxy.Phase;
import kunlun.proxy.Plugin;
import kunlun.proxy.RoutingContext;
import kunlun.util.KeyValue;

import java.util.List;

public final class ResponseRedirectPlugin implements Plugin {

    public static final String NAME = "response-redirect";
    public static final short ORDER = Phase.REWRITE.order(22);

    @Override
    public String name() {
        return NAME;
    }

    @Override
    public short order() {
        return ORDER;
    }

    @Override
    public void intercept(RoutingContext ctx, JsonObject config) {

        ResponseRedirectOptions options = new ResponseRedirectOptions(config);
        List<KeyValue> replacements = options.getReplacements();
        if (null != replacements) {
            // add header handler
            ctx.addHeadersFilter(headers -> {
                String location = headers.get(HttpHeaders.LOCATION);

                // no 30x response.
                if (null == location) {
                    return headers;
                }

                for (KeyValue replacement : replacements) {
                    try {
                        location = location.replaceAll(replacement.getKey(), replacement.getValue());
                    } catch (Exception ignore) {
                        // ignore
                    }
                }

                return headers.set(HttpHeaders.LOCATION, location);
            });
        }
        ctx.next();
    }
}

加载

插件通过 SPI 方式加载,请在resources目录下创建 META-INF/services/kunlun.proxy.Plugin 文件,内容示例如下:

kunlun.proxy.plugin.ResponseRedirectPlugin