Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apisix/plugins/oas-validator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ local tab_concat = table.concat
local plugin_name = "oas-validator"

local DEFAULT_SPEC_URL_TTL = 3600
-- Cache fetch/compile failures for a short window so a persistently failing
-- spec_url is not re-fetched on every request (failure amplification).
local SPEC_URL_NEG_TTL = 5

local schema = {
type = "object",
Expand Down Expand Up @@ -131,6 +134,8 @@ local function get_spec_url_lrucache()
spec_url_lrucache = core.lrucache.new({
ttl = ttl,
count = 512,
neg_ttl = SPEC_URL_NEG_TTL,
neg_count = 512,
invalid_stale = true,
refresh_stale = true,
serial_creating = true,
Expand Down
75 changes: 75 additions & 0 deletions t/plugin/oas-validator3.t
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@ add_block_preprocessor(sub {
my ($block) = @_;

my $http_config = $block->http_config // <<_EOC_;
lua_shared_dict oas_neg_count 1m;
server {
listen 1979;
location /count-fail.json {
content_by_lua_block {
ngx.shared.oas_neg_count:incr("n", 1, 0)
ngx.status = 404
ngx.print("not found")
}
}
location /spec.json {
content_by_lua_block {
local file = io.open("t/spec/spec.json", "r")
Expand Down Expand Up @@ -562,3 +570,70 @@ status: 200
}
--- response_body
passed



=== TEST 24: create route whose spec_url always fails (for negative cache)
--- config
location /t {
content_by_lua_block {
ngx.shared.oas_neg_count:set("n", 0)
local t = require("lib.test_admin")
local code, body = t.test('/apisix/admin/routes/2',
ngx.HTTP_PUT,
[[{
"uri": "/negcache",
"plugins": {
"oas-validator": {
"spec_url": "http://127.0.0.1:1979/count-fail.json"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1970": 1
}
}
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 25: failing spec_url is fetched once then negatively cached
--- config
location /t {
content_by_lua_block {
-- give the route created in the previous test time to propagate
ngx.sleep(0.3)
local http = require("resty.http")
local port = ngx.var.server_port
for i = 1, 3 do
local httpc = http.new()
local res, err = httpc:request_uri(
"http://127.0.0.1:" .. port .. "/negcache",
{ method = "POST", body = "{}",
headers = { ["Content-Type"] = "application/json" } })
if not res then
ngx.say("request failed: " .. err)
return
end
if res.status ~= 500 then
ngx.say("unexpected status: " .. res.status)
return
end
end
ngx.say("fetches=" .. (ngx.shared.oas_neg_count:get("n") or 0))
}
}
--- response_body
fetches=1
--- error_log
spec URL returned status 404
Loading