Skip to content

Commit

Permalink
api: add API to get applied migrations list
Browse files Browse the repository at this point in the history
Add new API to get migrations list.

Closes #65
  • Loading branch information
psergee committed Mar 28, 2024
1 parent a7b7658 commit 47809f1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added:
- An API for moving existing migration names from the cluster configuration to
a space.
- API for getting applied migrations list for the cluster.

## [0.7.0]
### Added:
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ IMPORTANT: code snippets below should be embedded to `init.lua`, so they would t
end
```

* To get a list of applied migrations make a POST request to
`http://<your_tarantool_ip>:<http_port>/migrations/applied` or a call
`require('migrator').get_applied()`on any cluster instance. This method will return a list of
applied migrations grouped by a leader node.

## Upgrade from 0.* versions.

Applied migrations names storage method has been changed in `1.*` version: applied migrations list
Expand Down
36 changes: 36 additions & 0 deletions migrator/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,34 @@ local function get_applied_local()
return result
end

--- Get list of applied migration names in cluster.
-- Throws an exception in case of any problems
-- @function get_applied
-- @return table of applied migrations in cluster grouped by leader aliases.
local function get_applied()
local leaders = rpc.get_candidates('migrator',{leader_only = true })
log.info('Preparing getting applied migrations from %s', json.encode(leaders))
local result, errmap = pool.map_call('_G.__cluster_rpc_call_local',
{'migrator', 'get_applied_local'}, {
uri_list = leaders,
timeout = get_storage_timeout()
})
if errmap ~= nil then
for uri, err in pairs(errmap) do
log.error('Cannot get migrations state from %s: %s',
uri, json.encode(err))
end
error("Failed to get migrations state: " .. json.encode(errmap))
end

local migrations_by_alias = {}
for uri, migrations in pairs(result) do
migrations_by_alias[get_server_alias(uri)] = migrations
end

return migrations_by_alias
end

-- Append migration names to the _migrations space.
local function append_migrations_to_local_space(migrations)
local copied_migrations = {}
Expand Down Expand Up @@ -299,6 +327,12 @@ local function init(opts)
resp.status = 200
return resp
end)

httpd:route({ path = '/migrations/applied', method = 'POST' }, function(req)
local resp = req:render({ json = { applied = get_applied() }})
resp.status = 200
return resp
end)
end

local function upgrade()
Expand Down Expand Up @@ -363,6 +397,8 @@ return {
get_schema = get_schema,

move_migrations_state = move_migrations_state,
get_applied = get_applied,
get_applied_local = get_applied_local,

_VERSION = require('migrator.version'),
}
94 changes: 94 additions & 0 deletions test/integration/get_applied_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
local t = require('luatest')
local g = t.group('get_migrations_state')

local fio = require('fio')

local cartridge_helpers = require('cartridge.test-helpers')
local shared = require('test.helper.integration').shared
local utils = require("test.helper.utils")
local datadir = fio.pathjoin(shared.datadir, 'get_migrations_state')

g.cluster = cartridge_helpers.Cluster:new({
server_command = shared.server_command,
datadir = datadir,
use_vshard = true,
base_advertise_port = 10500,
replicasets = {
{
alias = 'router',
uuid = cartridge_helpers.uuid('a'),
roles = { 'vshard-router', 'migrator' },
servers = { {
alias = 'router',
instance_uuid = cartridge_helpers.uuid('a', 1)
} },
},
{
alias = 'storage-1',
uuid = cartridge_helpers.uuid('b'),
roles = { 'vshard-storage', 'migrator' },
servers = {
{
alias = 'storage-1-master',
instance_uuid = cartridge_helpers.uuid('b', 1),
env = {TARANTOOL_HTTP_ENABLED = 'false'},
},
{
alias = 'storage-1-replica',
instance_uuid = cartridge_helpers.uuid('b', 2),
env = {TARANTOOL_HTTP_ENABLED = 'false'},
},
},
},
{
alias = 'storage-2',
uuid = cartridge_helpers.uuid('c'),
roles = { 'vshard-storage', 'migrator' },
servers = {
{
alias = 'storage-2-master',
instance_uuid = cartridge_helpers.uuid('c', 1),
env = {TARANTOOL_HTTP_ENABLED = 'false'},
},
{
alias = 'storage-2-replica',
instance_uuid = cartridge_helpers.uuid('c', 2),
env = {TARANTOOL_HTTP_ENABLED = 'false'},
},
},
},
},
})

g.before_all(function() g.cluster:start() end)
g.after_all(function() g.cluster:stop() end)
g.after_each(function() utils.cleanup(g) end)

g.test_get_migrations_state = function(cg)
local main = cg.cluster.main_server

local status, resp = main:eval("return pcall(require('migrator').up)")
t.assert(status, tostring(resp))
t.assert_equals(resp, {
['router'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-1-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-2-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
})

status, resp = main:eval("return pcall(require('migrator').get_applied)")
t.assert(status, tostring(resp))
t.assert_equals(resp, {
['router'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-1-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-2-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
})

-- Check the same result is returned by http.
local result = main:http_request('post', '/migrations/applied', { json = {} })
local expected_applied = {
['router'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-1-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
['storage-2-master'] = { '01_first.lua', '02_second.lua', '03_sharded.lua' },
}
t.assert_equals(result.json, { applied = expected_applied })
end

0 comments on commit 47809f1

Please sign in to comment.