OK, if it is a development kit, I want to know whether it is really a
runtime? Because eventually, whether debugging is friendly or not, rely on
this.

Sheng Wu 吴晟
Twitter, wusheng1108


Daming <[email protected]> 于2021年4月27日周二 上午9:57写道:

> PDK stands for Plugin Development Kit.
> It is a good choice to build on spring-boot in the initial stage.
> Because it is very friendly and easy to get started for Java
> developers(plugins developers).
>
>
> Sheng Wu <[email protected]> 于2021年4月27日周二 上午9:31写道:
> >
> > I can't see the detail from the graph.
> > But if we are speaking of Java and Spring gateway ecosystem, you should
> > know, that is not just interfaces.
> > Spring boot, annotation system, IoC, AOP are all going to be there. So,
> > basically, I would recommend you to boot the codes as all Spring-based
> > applications did.
> > BTW, I am not sure what PDK means.
> >
> > And about debugging, once your APISIX process could access the JVM
> through
> > a socket with manual localhost:port, it is fine for the Java developer to
> > start this sidecar in the IDEA.
> >
> > Sheng Wu 吴晟
> > Twitter, wusheng1108
> >
> >
> > ZhengSong Tu <[email protected]> 于2021年4月26日周一 上午11:47写道:
> >
> > > I have sketched the flow of the java side of the plugin runner
> > > [image: APISIX 运行 Java 插件.png]
> > >
> > > And I have some questions to clarify.
> > >
> > > 1. How does the plugin runner load the client's code?
> > >     It's up to each runner to figure it out according to its own
> > > language's ecology. Take java as an example,
> > > the user develops with the PDK provided by us, and packages the custom
> > > plugin code into a jar and puts it in the specified location. When the
> > > plugin runner starts, it loads the jar package in this location by
> means of
> > > a custom dynamic ClassLoader or something like that.
> > >
> > > 2. How do users develop?
> > >     Just provide the filter chain like Spring Cloud Gateway. Users can
> > > register their own filters. And the PDK is a jar, with some defined
> > > interfaces such as pre, post, etc., and some objects such as request,
> > > header, etc.
> > >
> > > 3. How to debug?
> > >     Option 1:  APISIX provides debugging mode for java plugins, this
> time
> > > it is not APISIX to start the plugin runner, but the user himself
> downloads
> > > the plugin runner code and runs the main method to start it, so as to
> > > construct a request to access APISIX, APISIX will pass the context of
> the
> > > request to the plugin runner, and then use it to debug java code.
> > >     Option 2:  java remote debug.
> > >
> > >
> > >
> > > Zexuan Luo <[email protected]> 于2021年4月19日周一 下午6:18写道:
> > >
> > >> Here is the new flatbuffer schema:
> > >>
> > >>
> https://github.com/spacewander/incubator-apisix/blob/step1/apisix/plugins/ext-plugin/ext-plugin.fbs
> > >>
> > >> Zexuan Luo <[email protected]> 于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