spacewander commented on a change in pull request #3363:
URL: https://github.com/apache/apisix/pull/3363#discussion_r563416326



##########
File path: apisix/plugins/fault-injection.lua
##########
@@ -15,13 +15,66 @@
 -- limitations under the License.
 --
 local core = require("apisix.core")
+local expr = require("resty.expr.v1")
 
 local sleep = core.sleep
 local random = math.random
+local ipairs = ipairs
 
 local plugin_name   = "fault-injection"
 
 
+local vars_schema = {

Review comment:
       I think we need to remove the `vars_schema`.
   1. we can do the check better with `expr.new` when checking the schema.
   2. when `not`/`or` is supported directly in the expr, this schema is 
outdated.
   3. this schema contains many incorrect hardcoded limitations, like the 
`maxLength` of operator is `2` (not enough for `has`), and an expression may 
contain 4 elements if `!` is used, etc.

##########
File path: doc/plugins/fault-injection.md
##########
@@ -30,11 +30,43 @@ Fault injection plugin, this plugin can be used with other 
plugins and will be e
 | abort.http_status | integer | required    |         | [200, ...] | 
user-specified http code returned to the client. |
 | abort.body        | string  | optional    |         |            | response 
data returned to the client. Nginx variable can be used inside, like `client 
addr: $remote_addr\n`           |
 | abort.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be aborted.            |
+| abort.vars        | array[] | optional    |         |            | The rules 
for executing fault injection will only be executed when the rules are matched. 
`vars` is a list consisting of one or more [[var, operator, val]] elements, 
like this: [[[var, operator, val],[var, operator, val]], ...]. For example: 
[[["arg_name", "==", "json"]]], indicating that the current request parameter 
name is json. The var here is consistent with the naming of Nginx internal 
variables, so request_uri, host, etc. can also be used; for the operator part, 
the currently supported operators are ==, ~=, ~~, >, <, in, has and !. For 
specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 | delay.duration    | number  | required    |         |            | delay 
time (can be decimal).                     |
 | delay.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be delayed.            |
+| delay.vars        | array[] | optional    |         |            | Execute 
the request delay rule, and the request will be delayed only after the rule 
matches. `vars` is a list consisting of one or more [[var, operator, val]] 
elements, like this: [[[var, operator, val],[var, operator, val]], ...]. For 
example: [[["arg_name", "==", "json"]]], indicating that the current request 
parameter name is json. The var here is consistent with the naming of Nginx 
internal variables, so request_uri, host, etc. can also be used; for the 
operator part, the currently supported operators are ==, ~=, ~~, >, <, in, has 
and !. For specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 
 Note: One of `abort` and `delay` must be specified.
 
+`vars` is composed of a three-level array structure, as shown below:
+
+```json
+array[
+    array[
+        array[]
+    ],
+    array[
+        array[]
+    ],
+    ......
+]
+```
+
+It can implement the `and/or` relationship between rules flexibly, such as the 
following three expressions:
+
+```json
+[
+    [
+        [ "arg_name","==","jack" ],
+        [ "arg_age","==",18 ]
+    ],
+    [
+        [ "arg_name2","==","allen" ]
+    ]
+]
+```
+
+Indicates that the relationship between the first two expressions is `and`, 
and the relationship between the first two expressions and the third expression 
is `or`.

Review comment:
       What `Indicates`? There is a grammar error in the sentence.

##########
File path: apisix/plugins/fault-injection.lua
##########
@@ -77,11 +151,30 @@ end
 function _M.rewrite(conf, ctx)
     core.log.info("plugin rewrite phase, conf: ", core.json.delay_encode(conf))
 
-    if conf.delay and sample_hit(conf.delay.percentage) then
+    local err
+    local abort_vars = true
+    if conf.abort and conf.abort.vars then
+        abort_vars, err = vars_match(conf.abort.vars, ctx)
+        if err then
+            return 500, err
+        end
+    end
+    core.log.info("abort_vars: ", abort_vars)
+
+    local delay_vars = true
+    if conf.delay and conf.delay.vars then
+        delay_vars, err = vars_match(conf.delay.vars, ctx)
+        if err then
+            return 500, err

Review comment:
       Ditto

##########
File path: doc/plugins/fault-injection.md
##########
@@ -30,11 +30,43 @@ Fault injection plugin, this plugin can be used with other 
plugins and will be e
 | abort.http_status | integer | required    |         | [200, ...] | 
user-specified http code returned to the client. |
 | abort.body        | string  | optional    |         |            | response 
data returned to the client. Nginx variable can be used inside, like `client 
addr: $remote_addr\n`           |
 | abort.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be aborted.            |
+| abort.vars        | array[] | optional    |         |            | The rules 
for executing fault injection will only be executed when the rules are matched. 
`vars` is a list consisting of one or more [[var, operator, val]] elements, 
like this: [[[var, operator, val],[var, operator, val]], ...]. For example: 
[[["arg_name", "==", "json"]]], indicating that the current request parameter 
name is json. The var here is consistent with the naming of Nginx internal 
variables, so request_uri, host, etc. can also be used; for the operator part, 
the currently supported operators are ==, ~=, ~~, >, <, in, has and !. For 
specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |

Review comment:
       I think the description can be simpler. It has been repeated for too 
many times.
   We can say it is a list of `expression`, which is from the lua-resty-expr. 
That is all.

##########
File path: apisix/plugins/fault-injection.lua
##########
@@ -64,6 +119,25 @@ local function sample_hit(percentage)
 end
 
 
+local function vars_match(vars, ctx)
+    local match_result
+    for _, var in ipairs(vars) do
+        local expr, err = expr.new(var)
+        if err then
+            core.log.error("vars expression does not match: ", err)

Review comment:
       Should be `failed to create vars expression`, we haven't matched it yet.

##########
File path: doc/plugins/fault-injection.md
##########
@@ -30,11 +30,43 @@ Fault injection plugin, this plugin can be used with other 
plugins and will be e
 | abort.http_status | integer | required    |         | [200, ...] | 
user-specified http code returned to the client. |
 | abort.body        | string  | optional    |         |            | response 
data returned to the client. Nginx variable can be used inside, like `client 
addr: $remote_addr\n`           |
 | abort.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be aborted.            |
+| abort.vars        | array[] | optional    |         |            | The rules 
for executing fault injection will only be executed when the rules are matched. 
`vars` is a list consisting of one or more [[var, operator, val]] elements, 
like this: [[[var, operator, val],[var, operator, val]], ...]. For example: 
[[["arg_name", "==", "json"]]], indicating that the current request parameter 
name is json. The var here is consistent with the naming of Nginx internal 
variables, so request_uri, host, etc. can also be used; for the operator part, 
the currently supported operators are ==, ~=, ~~, >, <, in, has and !. For 
specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 | delay.duration    | number  | required    |         |            | delay 
time (can be decimal).                     |
 | delay.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be delayed.            |
+| delay.vars        | array[] | optional    |         |            | Execute 
the request delay rule, and the request will be delayed only after the rule 
matches. `vars` is a list consisting of one or more [[var, operator, val]] 
elements, like this: [[[var, operator, val],[var, operator, val]], ...]. For 
example: [[["arg_name", "==", "json"]]], indicating that the current request 
parameter name is json. The var here is consistent with the naming of Nginx 
internal variables, so request_uri, host, etc. can also be used; for the 
operator part, the currently supported operators are ==, ~=, ~~, >, <, in, has 
and !. For specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 
 Note: One of `abort` and `delay` must be specified.
 
+`vars` is composed of a three-level array structure, as shown below:

Review comment:
       The `vars` is a list of `expression` which is from the lua-resty-expr.

##########
File path: doc/plugins/fault-injection.md
##########
@@ -30,11 +30,43 @@ Fault injection plugin, this plugin can be used with other 
plugins and will be e
 | abort.http_status | integer | required    |         | [200, ...] | 
user-specified http code returned to the client. |
 | abort.body        | string  | optional    |         |            | response 
data returned to the client. Nginx variable can be used inside, like `client 
addr: $remote_addr\n`           |
 | abort.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be aborted.            |
+| abort.vars        | array[] | optional    |         |            | The rules 
for executing fault injection will only be executed when the rules are matched. 
`vars` is a list consisting of one or more [[var, operator, val]] elements, 
like this: [[[var, operator, val],[var, operator, val]], ...]. For example: 
[[["arg_name", "==", "json"]]], indicating that the current request parameter 
name is json. The var here is consistent with the naming of Nginx internal 
variables, so request_uri, host, etc. can also be used; for the operator part, 
the currently supported operators are ==, ~=, ~~, >, <, in, has and !. For 
specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 | delay.duration    | number  | required    |         |            | delay 
time (can be decimal).                     |
 | delay.percentage  | integer | optional    |         | [0, 100]   | 
percentage of requests to be delayed.            |
+| delay.vars        | array[] | optional    |         |            | Execute 
the request delay rule, and the request will be delayed only after the rule 
matches. `vars` is a list consisting of one or more [[var, operator, val]] 
elements, like this: [[[var, operator, val],[var, operator, val]], ...]. For 
example: [[["arg_name", "==", "json"]]], indicating that the current request 
parameter name is json. The var here is consistent with the naming of Nginx 
internal variables, so request_uri, host, etc. can also be used; for the 
operator part, the currently supported operators are ==, ~=, ~~, >, <, in, has 
and !. For specific usage of operators, please see the `operator-list` part of 
[lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list).  |
 
 Note: One of `abort` and `delay` must be specified.
 
+`vars` is composed of a three-level array structure, as shown below:
+
+```json
+array[

Review comment:
       Better to use a real world example. And this one is too far away from 
JSON. 

##########
File path: apisix/plugins/fault-injection.lua
##########
@@ -77,11 +151,30 @@ end
 function _M.rewrite(conf, ctx)
     core.log.info("plugin rewrite phase, conf: ", core.json.delay_encode(conf))
 
-    if conf.delay and sample_hit(conf.delay.percentage) then
+    local err
+    local abort_vars = true
+    if conf.abort and conf.abort.vars then
+        abort_vars, err = vars_match(conf.abort.vars, ctx)
+        if err then
+            return 500, err

Review comment:
       Better to log the error.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to