forked from Kong/kong
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(hybrid) control plane nodes now subscribe to cluster level `inval…
…idations` events to be notified of CRUD operations This change fixes a bug which manifested itself when Kong: * Is working at Hybrid mode. * The CP role is being executed by several Kong nodes in a cluster. * A change (any successful CRUD operation) happens in one of these nodes. The desired behaviour is that when this happens, all the CPs in the cluster would trigger a DP config push. The bug consists in that only the workers in the same Kong node as the one which received the CRUD operation executes such push. Example setup: Two Kong nodes in CP role. Node A has workers A1 and A2, and Node B has workers B1 and B2. The admins use A1's admin API to create a new Service. Before this fix, A1 would trigger the CP reload, then A2 would "see" the change (via a worker event) and refresh its DPs. But B1 and B2 would perform such refresh. This fix makes other CP nodes look for the `invalidations` cluster event generated by a CRUD operation and broadcasts a `push_config` event to all workers on the CP node, therefore when a CRUD operation happens, all CP nodes in the cluster will promptly push the updated config to DPs connected to them. Co-authored-by: Datong Sun <[email protected]>
- Loading branch information
Showing
2 changed files
with
99 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
spec/02-integration/09-hybrid_mode/04-cp_cluster_sync_spec.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
local helpers = require "spec.helpers" | ||
|
||
local function find_in_file(filepath, pat) | ||
local f = assert(io.open(filepath, "r")) | ||
|
||
local line = f:read("*l") | ||
|
||
local found = false | ||
while line and not found do | ||
if line:find(pat, 1, true) then | ||
found = true | ||
end | ||
|
||
line = f:read("*l") | ||
end | ||
|
||
f:close() | ||
|
||
return found | ||
end | ||
|
||
for _, strategy in helpers.each_strategy() do | ||
describe("CP/CP sync works with #" .. strategy .. " backend", function() | ||
lazy_setup(function() | ||
helpers.get_db_utils(strategy, { "routes", "services" }) | ||
|
||
assert(helpers.start_kong({ | ||
prefix = "servroot", | ||
admin_listen = "127.0.0.1:9000", | ||
cluster_listen = "127.0.0.1:9005", | ||
|
||
role = "control_plane", | ||
cluster_cert = "spec/fixtures/kong_clustering.crt", | ||
cluster_cert_key = "spec/fixtures/kong_clustering.key", | ||
lua_ssl_trusted_certificate = "spec/fixtures/kong_clustering.crt", | ||
database = strategy, | ||
})) | ||
|
||
assert(helpers.start_kong({ | ||
prefix = "servroot2", | ||
admin_listen = "127.0.0.1:9001", | ||
cluster_listen = "127.0.0.1:9006", | ||
|
||
role = "control_plane", | ||
cluster_cert = "spec/fixtures/kong_clustering.crt", | ||
cluster_cert_key = "spec/fixtures/kong_clustering.key", | ||
lua_ssl_trusted_certificate = "spec/fixtures/kong_clustering.crt", | ||
database = strategy, | ||
})) | ||
|
||
end) | ||
|
||
lazy_teardown(function() | ||
assert(helpers.stop_kong("servroot")) | ||
assert(helpers.stop_kong("servroot2")) | ||
end) | ||
|
||
it("syncs across other nodes in the cluster", function() | ||
local admin_client_2 = assert(helpers.http_client("127.0.0.1", 9001)) | ||
|
||
local res = admin_client_2:post("/services", { | ||
body = { name = "example", url = "http://example.dev" }, | ||
headers = { ["Content-Type"] = "application/json" } | ||
}) | ||
assert.res_status(201, res) | ||
|
||
assert(admin_client_2:close()) | ||
|
||
local cfg = helpers.test_conf | ||
local filepath = cfg.prefix .. "/" .. cfg.proxy_error_log | ||
helpers.wait_until(function() | ||
return find_in_file(filepath, | ||
-- this line is only found on the other CP (the one not receiving the Admin API call) | ||
"[cluster_events] new event (channel: 'invalidations')") and | ||
find_in_file(filepath, | ||
"worker-events: handling event; source=clustering, event=push_config") | ||
end, 10) | ||
end) | ||
end) | ||
end |