Skip to content

Commit

Permalink
hotfix(db-miss) porting #1914 fix into 0.9.x (#1984)
Browse files Browse the repository at this point in the history
* hotfix(db-miss) porting #1914 fix
  • Loading branch information
subnetmarco authored and Tieske committed Jan 18, 2017
1 parent 1fe629f commit 3f19aaf
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 4 deletions.
5 changes: 2 additions & 3 deletions kong/core/plugins_iterator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ local function load_plugin_configuration(api_id, consumer_id, plugin_name)
return row
end
end
else
-- insert a cached value to not trigger too many DB queries.
return {null = true}
end
-- insert a cached value to not trigger too many DB queries.
return {null = true}
end)

if plugin ~= nil and plugin.enabled then
Expand Down
109 changes: 108 additions & 1 deletion spec/02-integration/04-core/02-hooks_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ local pl_path = require "pl.path"
local pl_file = require "pl.file"
local pl_stringx = require "pl.stringx"

-- cache entry inserted as a sentinel whenever a db lookup returns nothing
local db_miss_sentinel = { null = true }

describe("Core Hooks", function()
describe("Global", function()
describe("Global Plugin entity invalidation on API", function()
describe("Plugin entity invalidation on API", function()
local client, api_client
local plugin
local db_miss_api

before_each(function()
helpers.start_kong()
Expand All @@ -22,11 +26,30 @@ describe("Core Hooks", function()
request_host = "hooks1.com",
upstream_url = "http://mockbin.com"
})
assert(helpers.dao.apis:insert {
request_host = "hooks2.com",
upstream_url = "http://mockbin.com"
})

plugin = assert(helpers.dao.plugins:insert {
name = "rate-limiting",
config = { minute = 10 }
})

assert(helpers.dao.apis:insert {
request_host = "db-miss.org",
upstream_url = "http://mockbin.com"
})

db_miss_api = assert(helpers.dao.apis:insert {
request_host = "db-miss-you-too.org",
upstream_url = "http://mockbin.com"
})
assert(helpers.dao.plugins:insert {
name = "correlation-id",
api_id = db_miss_api.id
})

end)
after_each(function()
if client and api_client then
Expand All @@ -36,6 +59,90 @@ describe("Core Hooks", function()
helpers.stop_kong()
end)

it("inserts sentinel values for db-miss", function()
-- test case specific for https://github.com/Mashape/kong/pull/1841
-- make a request, to populate cache with sentinel values
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "db-miss.org"
}
})
assert.response(res).has.status(200)

-- check sentinel value for global plugin; pluginname, nil, nil
local cache_path = "/cache/"..cache.plugin_key("correlation-id", nil, nil)
local res = assert(api_client:send {
method = "GET",
path = cache_path
})
assert.response(res).has.status(200)
assert.same(db_miss_sentinel, assert.response(res).has.jsonbody())
end)

it("should invalidate a global plugin when adding", function()
-- Making a request to populate the cache
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "hooks2.com"
}
})
assert.response(res).has.status(200)

-- Make sure the cache is not populated
local res = assert(api_client:send {
method = "GET",
path = "/cache/"..cache.plugin_key("basic-auth", nil, nil)
})
local entry = cjson.decode(assert.res_status(200, res))
assert.same(db_miss_sentinel, entry) -- db-miss sentinel value

-- Add plugin
local res = assert(api_client:send {
method = "POST",
path = "/plugins/",
headers = {
["Content-Type"] = "application/json"
},
body = cjson.encode({
name = "basic-auth"
})
})
assert.response(res).has.status(201)

-- Wait for cache to be invalidated
helpers.wait_until(function()
local res = assert(api_client:send {
method = "GET",
path = "/cache/"..cache.plugin_key("basic-auth", nil, nil)
})
res:read_body()
return res.status == 404
end, 3)

-- Making a request: replacing the db-miss sentinel value in cache
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "hooks2.com"
}
})
assert.response(res).has.status(401) -- in effect plugin, so failure

-- Make sure the cache is populated
local res = assert(api_client:send {
method = "GET",
path = "/cache/"..cache.plugin_key("basic-auth", nil, nil)
})
local entry = cjson.decode(assert.res_status(200, res))
assert.is_true(entry.enabled)
assert.is.same("basic-auth", entry.name)
end)

it("should invalidate a global plugin when deleting", function()
-- Making a request to populate the cache
local res = assert(client:send {
Expand Down

0 comments on commit 3f19aaf

Please sign in to comment.