Here is the new flatbuffer schema:
https://github.com/spacewander/incubator-apisix/blob/step1/apisix/plugins/ext-plugin/ext-plugin.fbs

Zexuan Luo <spacewan...@apache.org> 于2021年4月16日周五 下午2:52写道:
>
> 1. Background
>
> APISIX currently only supports writing plugins in Lua. If other
> languages are supported, it will greatly broaden the APISIX ecosystem
> and user base.
>
> 2. Solution
>
> Since WASM is not yet mature, we consider implementing it through local IPC.
>
> For the sake of discussion, the following will assume that the plugin
> is written in Java. However, in practice, our solution can be
> interfaced with other languages.
>
> 2.1 Terminology
>
> Several terms are defined here.
>
> Plugin Runner: The service that runs the plugin, written in the same
> language as the plugin. In the first version, we assume that there
> will be only one Plugin Runner.
>
> 2.2 Plugin Runner lifecycle
>
> To simplify user operation and reduce the difficulty of upgrading,
> Plugin Runner is managed by APISIX.
>
> APISIX starts the Plugin Runner when it starts and ends it when it
> ends. if the Plugin Runner quits in the middle, APISIX will restart it
> automatically.
>
> 2.3 Timing of APISIX communication with Plugin Runner
>
> ```
> Router ----> Global Plugin (written in Lua) ---> Ext Plugin
> (ext-plugin-pre-req) ----> Lua Plugin (Router)
> ---> Ext plugin (ext-plugin-post-req) ---> Upstream
> ```
>
> Running the Ext Plugin in the Global Plugin is not supported at this
> time, as the global logic can be executed uniformly in the Plugin
> Runner.
>
> Running Ext Plugin after getting an upstream response is not supported
> at this time. We can support it later with a buffering response.
>
> ext-plugin-pre runs before all non-global Lua plugins, and
> ext-plugin-post runs after all non-global Lua plugins.
>
> 2.4 How APISIX communicates with Plugin Runner
>
> APISIX communicates with Plugin Runner through a unix socket. The
> communication protocol is as follows.
>
> 2.4.1 Communication format
>
> ```
> 1 byte of type + 3 bytes of length + data
> ```
>
> The type can be 0 ~ 7, and the length can be [0, 8M). data length is
> determined by length.
> Since Ext Plugin usually does not exchange too much data, 8M should be
> enough. The reason for taking 4 bytes is to keep the header small
> enough to be read efficiently.
>
> The current type takes the following values.
>
> 0 means error
> 1 means prepare_conf
> 2 means http_req_call
>
> The data is serialized in capnproto, a binary serialization format.
>
> capnproto is supported by many programming languages:
> https://capnproto.org/otherlang.html
>
> The advantages of choosing capnproto are.
> 1. focus on serialization performance
> 2. partial deserialization support, so that decode can be done only
> when it is needed
>
> 2.4.2 Communication steps
>
> Each ext plugin will have the following configuration.
>
> ```
> {
>     "conf": [
>         {
>             "name": "configuration name",
>             "value": "configuration value"
>         }
>     ],
>     "extra_info": [
>                 ...
>     ]
> }
> ```
>
> conf can be used to set the execution configuration of the
> plugin-related requests inside Plugin Runner.
>
> The default data sent to Plugin Runner is only the most common
> information. If you want additional information, you need to declare
> it in extra_info beforehand.
>
> To save communication costs, conf is sent separately.
>
> 1. APISIX will check if conf has a corresponding token in the local cache.
>  2. If not, APISIX sends a prepare_conf request to ask Plugin Runner
> to cache the conf and return a token.
> (Note that Plugin Runner's cache time needs to be longer than APISIX's
> cache time.)
> 3. APISIX sends an http_req_call request to Plugin Runner.
> 4. Plugin Runner executes the request and returns a response to APISIX.
> 5. APISIX processes the request based on the response
>
> 2.4.3 proto
>
> Refer to https://capnproto.org/language.html
>
> The following is the proto for error
>
> response
> ```
> enum ErrorCode {
>     BAD_REQUEST @0; # Plugin Runner can't understand APISIX
>     SERVICE_UNAVAILABLE @1; # Plugin Runner can't handle the request
>     CONF_TOKEN_NOT_FOUND @2;
> }
> struct ErrorResp {
>     Code @0 :ErrorCode;
> }
> ```
>
> The following is the proto of prepare_conf
>
> request
> ```
> struct PrepareConfReq {
>     conf @0 :List(Pair);
> }
> ```
>
> Response
> ```
> struct PrepareConfResp {
>     conf_token @0 :UInt32;
> }
> ```
>
> Here is the proto for http_req_call
>
> request
> ```
> struct Pair {
>     name @0 :Text;
>     value @1 :Text;
> }
> struct PairData {
>     name @0 :Text;
>     value @1 :Data;
> }
> enum Method {
>         GET @0;
>         ...
> }
>
> struct HTTPReqCallReq {
>     id @0 :UInt32;
>     src_ip @1 :Data;
>
>     method @2 :Method;
>
>     path @3 :Text;
>     args @4 :List(Pair);
>     headers @5 :List(Pair);
>
>     conf_token @6 :UInt32;
>
>     extra_info @7 :List(PairData);
> }
> ```
>
> Response
> ```
> struct HTTPReqCallResp {
>     id @0 :UInt32;
>
>     struct Stop {
>         status @0 :UInt16;
>         headers @1 :List(Pair);
>         body @2 :Data;
>     }
>     struct Rewrite {
>         path @0 :Text;
>         headers @1 :List(Pair);
>         # Note that args are modified in full.
>         # Either empty, meaning no args need to be moved
>         # or the entire modified args, not the incrementally changed parts
>         args @2 :List(Pair);
>     }
>
>     # What needs to be done when the response is received action
>     action :union {
>         # Do nothing
>         continue @1 :Void;
>         # Equivalent to core.response.exit(status, body), allowing
> additional headers to be set
>         stop @2 :Stop;
>         # Rewrite the request
>         rewrite @3 :Rewrite;
>     }
> }
> ```
>
> 2.4.4 Error handling
>
> Logging and returning 503 error codes
>
> 2.4.5 Environment variables
>
> APISIX configures the Plugin Runner with a number of environment
> variables when it is started.
>
> APISIX_LISTEN_ADDRESS: the address that the Plugin Runner needs to listen to
> APISIX_CONF_EXPIRE_TIME: Plugin Runner needs to cache conf for longer than 
> this

Reply via email to