Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api-breaker plugin returns default response body #6949

Merged
merged 11 commits into from
May 10, 2022
33 changes: 26 additions & 7 deletions apisix/plugins/api-breaker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ local plugin_name = "api-breaker"
local ngx = ngx
local math = math
local error = error
local ipairs = ipairs


local shared_buffer = ngx.shared["plugin-".. plugin_name]
if not shared_buffer then
Expand All @@ -38,9 +40,19 @@ local schema = {
break_response_body = {
type = "string"
},
break_response_content_type = {
type = "string",
default = "application/json"
headers = {
qihaiyan marked this conversation as resolved.
Show resolved Hide resolved
type = "array",
items = {
type = "object",
properties = {
key = {
type = "string"
qihaiyan marked this conversation as resolved.
Show resolved Hide resolved
},
value = {
type = "string"
qihaiyan marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
},
max_breaker_sec = {
type = "integer",
Expand Down Expand Up @@ -120,7 +132,12 @@ local _M = {


function _M.check_schema(conf)
return core.schema.check(schema, conf)
local ok, err = core.schema.check(schema, conf)
qihaiyan marked this conversation as resolved.
Show resolved Hide resolved
if not ok then
return false, err
end

return true
end


Expand Down Expand Up @@ -166,9 +183,11 @@ function _M.access(conf, ctx)
-- breaker
if lasttime + breaker_time >= ngx.time() then
if conf.break_response_body then
core.response.clear_header_as_body_modified()
if conf.break_response_content_type then
core.response.set_header("Content-Type", conf.break_response_content_type)
if conf.headers then
for _, value in ipairs(conf.headers) do
local val = core.utils.resolve_var(value.value, ctx.var)
core.response.add_header(value.key, val)
end
end
return conf.break_response_code, conf.break_response_body
end
Expand Down
2 changes: 1 addition & 1 deletion docs/en/latest/plugins/api-breaker.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ In an unhealthy state, when a request is forwarded to an upstream service and th
| ----------------------- | ------------- | ----------- | -------- | --------------- | --------------------------------------------------------------------------- |
| break_response_code | integer | required | | [200, ..., 599] | Return error code when unhealthy |
| break_response_body | string | optional | | | Return response body when unhealthy |
| break_response_content_type | string | optional | application/json | | Return body's content type when unhealthy. This field is in effective only if `break_response_body` is configured. |
| headers | array[object] | optional | | | New headers for the response. The values in the header can contain Nginx variables like `$remote_addr` and `$balancer_ip`. This field is in effective only if `break_response_body` is configured. |
| max_breaker_sec | integer | optional | 300 | >=3 | Maximum breaker time(seconds) |
| unhealthy.http_statuses | array[integer] | optional | {500} | [500, ..., 599] | Status codes when unhealthy |
| unhealthy.failures | integer | optional | 3 | >=1 | Number of consecutive error requests that triggered an unhealthy state |
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/latest/plugins/api-breaker.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ title: api-breaker
| ----------------------- | -------------- | ------ | ---------- | --------------- | -------------------------------- |
| break_response_code | integer | 必须 | 无 | [200, ..., 599] | 不健康返回错误码 |
| break_response_body | string | 可选 | 无 | | 不健康返回报文 |
| break_response_content_type | string | 可选 | application/json | | 不健康返回报文的内容类型,该字段仅在 `break_response_body` 被配置时生效 |
| headers | array[object] | 可选 | | | 不健康返回报文头,这里可以设置多个。这个值能够以 `$var` 的格式包含 Nginx 变量,比如 `$remote_addr $balancer_ip`。该字段仅在 `break_response_body` 被配置时生效 |
| max_breaker_sec | integer | 可选 | 300 | >=3 | 最大熔断持续时间 |
| unhealthy.http_statuses | array[integer] | 可选 | {500} | [500, ..., 599] | 不健康时候的状态码 |
| unhealthy.failures | integer | 可选 | 3 | >=1 | 触发不健康状态的连续错误请求次数 |
Expand Down
8 changes: 4 additions & 4 deletions t/plugin/api-breaker.t
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ done
--- request
GET /t
--- response_body
{"break_response_code":502,"break_response_content_type":"application/json","healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
{"break_response_code":502,"healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
--- no_error_log
[error]

Expand All @@ -104,7 +104,7 @@ GET /t
--- request
GET /t
--- response_body
{"break_response_code":502,"break_response_content_type":"application/json","healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
{"break_response_code":502,"healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
--- no_error_log
[error]

Expand All @@ -131,7 +131,7 @@ GET /t
--- request
GET /t
--- response_body
{"break_response_code":502,"break_response_content_type":"application/json","healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
{"break_response_code":502,"healthy":{"http_statuses":[200],"successes":3},"max_breaker_sec":300,"unhealthy":{"failures":3,"http_statuses":[500]}}
--- no_error_log
[error]

Expand Down Expand Up @@ -459,7 +459,7 @@ breaker_time: 2
"api-breaker": {
"break_response_code": 502,
"break_response_body": "{\"message\":\"breaker opened.\"}",
"break_response_content_type": "application/json+v1",
"headers": [{"key":"Content-Type","value":"application/json"},{"key":"Content-Type","value":"application/json+v1"}],
"unhealthy": {
"failures": 3
},
Expand Down