From ce3a7fd574b1161108c532ded41670b90dd588c8 Mon Sep 17 00:00:00 2001 From: Robert Paprocki Date: Thu, 18 Jan 2018 07:26:09 -0800 Subject: [PATCH] hotfix(migrations) fix broken upstream migrations There exists two problems with the behavior of upstream object migrations introduced in the 0.12.0 release: - First, the DDL migrations to add both healthcheck and hashing column definitions were required before executing function-level migrations to fill in default object data. This is a result of the current DAO implementation that requires that all Lua-schema definitions exist as column definitions in the underlying data store, even if the DAO update call does not reference the column in question. - Second, the functional definitions load each row directly by a directly underlying DB call (as opposed to a DAO find_all()); this resulted in "table" schema types being represented as literal JSON strings, isntead of Lua table types, by the C* driver. The Postgres implementation does not suffer this as the underlying reprentation of table data in Postgres-backed schemas is Postgres' JSON type; this is automagically deserialized to a Lua table upon retrieval. As the C* implementation offers no such behind-the-scenes transformation, a direct load of rows containing "table" schemas results in an incompatable data type when iterating over the returned rows. The fix in the commit is to use the abstract DAO to load upstream rows when leveraging C*. Fixes #3156. --- kong/dao/migrations/cassandra.lua | 56 +++++++++++++-------------- kong/dao/migrations/postgres.lua | 64 +++++++++++++++---------------- 2 files changed, 59 insertions(+), 61 deletions(-) diff --git a/kong/dao/migrations/cassandra.lua b/kong/dao/migrations/cassandra.lua index 96657cbfd1bb..524e1e8ebae1 100644 --- a/kong/dao/migrations/cassandra.lua +++ b/kong/dao/migrations/cassandra.lua @@ -481,6 +481,15 @@ return { ]], down = function(_, _, dao) end -- not implemented }, + { + name = "2017-11-07-192000_upstream_healthchecks", + up = [[ + ALTER TABLE upstreams ADD healthchecks text; + ]], + down = [[ + ALTER TABLE upstreams DROP healthchecks; + ]] + }, { name = "2017-10-27-134100_consistent_hashing_1", up = [[ @@ -497,7 +506,7 @@ return { ]] }, { - name = "2017-10-27-134100_consistent_hashing_2", + name = "2017-11-07-192100_upstream_healthchecks_2", up = function(_, _, dao) local rows, err = dao.db:query([[ SELECT * FROM upstreams; @@ -506,54 +515,43 @@ return { return err end + local upstreams = require("kong.dao.schemas.upstreams") + local default = upstreams.fields.healthchecks.default + for _, row in ipairs(rows) do - if not row.hash_on or not row.hash_fallback then - row.hash_on = "none" - row.hash_fallback = "none" --- row.created_at = nil - local _, err = dao.upstreams:update(row, { id = row.id }) + if not row.healthchecks then + + local _, err = dao.upstreams:update({ + healthchecks = default, + }, { id = row.id }) if err then return err end end end end, - down = function(_, _, dao) end -- n.a. since the columns will be dropped - }, - { - name = "2017-11-07-192000_upstream_healthchecks", - up = [[ - ALTER TABLE upstreams ADD healthchecks text; - ]], - down = [[ - ALTER TABLE upstreams DROP healthchecks; - ]] + down = function(_, _, dao) end }, { - name = "2017-11-07-192100_upstream_healthchecks_2", + name = "2017-10-27-134100_consistent_hashing_2", up = function(_, _, dao) - local rows, err = dao.db:query([[ - SELECT * FROM upstreams; - ]]) + local rows, err = dao.upstreams:find_all() if err then return err end - local upstreams = require("kong.dao.schemas.upstreams") - local default = upstreams.fields.healthchecks.default - for _, row in ipairs(rows) do - if not row.healthchecks then - - local _, err = dao.upstreams:update({ - healthchecks = default, - }, { id = row.id }) + if not row.hash_on or not row.hash_fallback then + row.hash_on = "none" + row.hash_fallback = "none" +-- row.created_at = nil + local _, err = dao.upstreams:update(row, { id = row.id }) if err then return err end end end end, - down = function(_, _, dao) end + down = function(_, _, dao) end -- n.a. since the columns will be dropped }, } diff --git a/kong/dao/migrations/postgres.lua b/kong/dao/migrations/postgres.lua index aeb43d88a652..20c2049bb794 100644 --- a/kong/dao/migrations/postgres.lua +++ b/kong/dao/migrations/postgres.lua @@ -542,6 +542,21 @@ return { ALTER TABLE apis ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP(0); ]] }, + { + name = "2017-11-07-192000_upstream_healthchecks", + up = [[ + DO $$ + BEGIN + ALTER TABLE upstreams ADD COLUMN healthchecks json; + EXCEPTION WHEN duplicate_column THEN + -- Do nothing, accept existing state + END$$; + + ]], + down = [[ + ALTER TABLE upstreams DROP COLUMN IF EXISTS healthchecks; + ]] + }, { name = "2017-10-27-134100_consistent_hashing_1", up = [[ @@ -558,7 +573,7 @@ return { ]] }, { - name = "2017-10-27-134100_consistent_hashing_2", + name = "2017-11-07-192100_upstream_healthchecks_2", up = function(_, _, dao) local rows, err = dao.db:query([[ SELECT * FROM upstreams; @@ -567,37 +582,25 @@ return { return err end + local upstreams = require("kong.dao.schemas.upstreams") + local default = upstreams.fields.healthchecks.default + for _, row in ipairs(rows) do - if not row.hash_on or not row.hash_fallback then - row.hash_on = "none" - row.hash_fallback = "none" - row.created_at = nil - local _, err = dao.upstreams:update(row, { id = row.id }) + if not row.healthchecks then + + local _, err = dao.upstreams:update({ + healthchecks = default, + }, { id = row.id }) if err then return err end end end end, - down = function(_, _, dao) end -- n.a. since the columns will be dropped - }, - { - name = "2017-11-07-192000_upstream_healthchecks", - up = [[ - DO $$ - BEGIN - ALTER TABLE upstreams ADD COLUMN healthchecks json; - EXCEPTION WHEN duplicate_column THEN - -- Do nothing, accept existing state - END$$; - - ]], - down = [[ - ALTER TABLE upstreams DROP COLUMN IF EXISTS healthchecks; - ]] + down = function(_, _, dao) end }, { - name = "2017-11-07-192100_upstream_healthchecks_2", + name = "2017-10-27-134100_consistent_hashing_2", up = function(_, _, dao) local rows, err = dao.db:query([[ SELECT * FROM upstreams; @@ -606,21 +609,18 @@ return { return err end - local upstreams = require("kong.dao.schemas.upstreams") - local default = upstreams.fields.healthchecks.default - for _, row in ipairs(rows) do - if not row.healthchecks then - - local _, err = dao.upstreams:update({ - healthchecks = default, - }, { id = row.id }) + if not row.hash_on or not row.hash_fallback then + row.hash_on = "none" + row.hash_fallback = "none" + row.created_at = nil + local _, err = dao.upstreams:update(row, { id = row.id }) if err then return err end end end end, - down = function(_, _, dao) end + down = function(_, _, dao) end -- n.a. since the columns will be dropped }, }