Skip to content

Commit f7d76f6

Browse files
andreyaksenovp7novlenkis
authored
Document the 'experimental.config.utils.schema' module (#4469)
Resolves #4279. Co-authored-by: Pavel Semyonov <[email protected]> Co-authored-by: Elena Shebunyaeva <[email protected]>
1 parent f0695d1 commit f7d76f6

File tree

33 files changed

+1831
-29
lines changed

33 files changed

+1831
-29
lines changed

doc/code_snippets/snippets/config/instances.enabled/application_role_cfg/greeter.lua

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
-- greeter.lua --
22
local log = require('log').new("greeter")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local greeter_schema = schema.new('greeter', schema.record({
6+
greeting = schema.scalar({
7+
type = 'string',
8+
allowed_values = { 'Hi', 'Hello' }
9+
})
10+
}))
311

412
local function validate(cfg)
5-
if cfg.greeting then
6-
assert(type(cfg.greeting) == "string", "'greeting' should be a string")
7-
assert(cfg.greeting == "Hi" or cfg.greeting == "Hello", "'greeting' should be 'Hi' or 'Hello'")
8-
end
13+
greeter_schema:validate(cfg)
914
end
1015

1116
local function apply(cfg)
12-
log.info("%s from the 'greeter' role!", cfg.greeting)
17+
log.info("%s from the 'greeter' role!", greeter_schema:get(cfg, 'greeting'))
1318
end
1419

1520
local function stop()

doc/code_snippets/snippets/config/instances.enabled/application_role_http_api/http-api.lua

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,46 @@
11
-- http-api.lua --
22
local httpd
33
local json = require('json')
4+
local schema = require('experimental.config.utils.schema')
45

5-
local function validate(cfg)
6-
if cfg.host then
7-
assert(type(cfg.host) == "string", "'host' should be a string containing a valid IP address")
6+
local function validate_host(host, w)
7+
local host_pattern = "^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
8+
if not host:match(host_pattern) then
9+
w.error("'host' should be a string containing a valid IP address, got %q", host)
810
end
9-
if cfg.port then
10-
assert(type(cfg.port) == "number", "'port' should be a number")
11-
assert(cfg.port >= 1 and cfg.port <= 65535, "'port' should be between 1 and 65535")
11+
end
12+
13+
local function validate_port(port, w)
14+
if port <= 1 or port >= 65535 then
15+
w.error("'port' should be between 1 and 65535, got %d", port)
1216
end
1317
end
1418

19+
local listen_address_schema = schema.new('listen_address', schema.record({
20+
host = schema.scalar({
21+
type = 'string',
22+
validate = validate_host,
23+
default = '127.0.0.1',
24+
}),
25+
port = schema.scalar({
26+
type = 'integer',
27+
validate = validate_port,
28+
default = 8080,
29+
}),
30+
}))
31+
32+
local function validate(cfg)
33+
listen_address_schema:validate(cfg)
34+
end
35+
1536
local function apply(cfg)
1637
if httpd then
1738
httpd:stop()
1839
end
19-
httpd = require('http.server').new(cfg.host, cfg.port)
40+
local cfg_with_defaults = listen_address_schema:apply_default(cfg)
41+
local host = listen_address_schema:get(cfg_with_defaults, 'host')
42+
local port = listen_address_schema:get(cfg_with_defaults, 'port')
43+
httpd = require('http.server').new(host, port)
2044
local response_headers = { ['content-type'] = 'application/json' }
2145
httpd:route({ path = '/band/:id', method = 'GET' }, function(req)
2246
local id = req:stash('id')
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
groups:
2+
group001:
3+
replicasets:
4+
replicaset001:
5+
instances:
6+
instance001:
7+
roles: [ http_api ]
8+
roles_cfg:
9+
http_api:
10+
host: '127.0.0.1'
11+
port: 8080
12+
scheme: 'http'
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
-- http_api.lua --
2+
local log = require('log').new("http_api")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local function validate_host(host, w)
6+
local host_pattern = "^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
7+
if not host:match(host_pattern) then
8+
w.error("'host' should be a string containing a valid IP address, got %q", host)
9+
end
10+
end
11+
12+
local function validate_port(port, w)
13+
if port <= 1 or port >= 65535 then
14+
w.error("'port' should be between 1 and 65535, got %d", port)
15+
end
16+
end
17+
18+
local listen_address_schema = schema.new('listen_address', schema.record({
19+
scheme = schema.scalar({
20+
type = 'string',
21+
allowed_values = { 'http', 'https' },
22+
default = 'http',
23+
}),
24+
host = schema.scalar({
25+
type = 'string',
26+
validate = validate_host,
27+
default = '127.0.0.1',
28+
}),
29+
port = schema.scalar({
30+
type = 'integer',
31+
validate = validate_port,
32+
default = 8080,
33+
}),
34+
}))
35+
36+
local function validate(cfg)
37+
listen_address_schema:validate(cfg)
38+
end
39+
40+
local function apply(cfg)
41+
local cfg_with_defaults = listen_address_schema:apply_default(cfg)
42+
local scheme = listen_address_schema:get(cfg_with_defaults, 'scheme')
43+
local host = listen_address_schema:get(cfg_with_defaults, 'host')
44+
local port = listen_address_schema:get(cfg_with_defaults, 'port')
45+
log.info("HTTP API endpoint: %s://%s:%d", scheme, host, port)
46+
end
47+
48+
local function stop()
49+
log.info("The 'http_api' role is stopped")
50+
end
51+
52+
return {
53+
validate = validate,
54+
apply = apply,
55+
stop = stop,
56+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instance001:
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-- api.lua --
2+
local log = require('log').new("api")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local listen_address = schema.record({
6+
scheme = schema.enum({ 'http', 'https' }),
7+
host = schema.scalar({ type = 'string' }),
8+
port = schema.scalar({ type = 'integer' })
9+
}, {
10+
validate = function(data, w)
11+
local protocol = w.schema.computed.annotations.protocol
12+
if protocol == 'iproto' and data.scheme ~= nil then
13+
w.error("iproto doesn't support 'scheme'")
14+
end
15+
end,
16+
})
17+
18+
local http_listen_address_schema = schema.new('http_listen_address', schema.record({
19+
name = schema.scalar({ type = 'string' }),
20+
listen_address = listen_address,
21+
}, {
22+
protocol = 'http',
23+
}))
24+
25+
local iproto_listen_address_schema = schema.new('iproto_listen_address', schema.record({
26+
name = schema.scalar({ type = 'string' }),
27+
listen_address = listen_address,
28+
}, {
29+
protocol = 'iproto',
30+
}))
31+
32+
local function validate(cfg)
33+
http_listen_address_schema:validate(cfg)
34+
end
35+
36+
local function apply(cfg)
37+
local scheme = http_listen_address_schema:get(cfg, 'listen_address.scheme')
38+
local host = http_listen_address_schema:get(cfg, 'listen_address.host')
39+
local port = http_listen_address_schema:get(cfg, 'listen_address.port')
40+
log.info("API endpoint: %s://%s:%d", scheme, host, port)
41+
end
42+
43+
local function stop()
44+
log.info("The 'api' role is stopped")
45+
end
46+
47+
return {
48+
validate = validate,
49+
apply = apply,
50+
stop = stop,
51+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
groups:
2+
group001:
3+
replicasets:
4+
replicaset001:
5+
instances:
6+
instance001:
7+
roles: [ api ]
8+
roles_cfg:
9+
api:
10+
name: 'HTTP listen address'
11+
listen_address:
12+
host: '127.0.0.1'
13+
port: 8080
14+
scheme: 'http'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instance001:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
groups:
2+
group001:
3+
replicasets:
4+
replicaset001:
5+
instances:
6+
instance001:
7+
roles: [ http_api ]
8+
roles_cfg:
9+
http_api:
10+
host: '127.0.0.1'
11+
port: 8080
12+
scheme: 'http'
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
-- http_api.lua --
2+
local log = require('log').new("http_api")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local listen_address_schema = schema.new('listen_address', schema.record({
6+
scheme = schema.enum({ 'http', 'https' }, { env = 'HTTP_SCHEME' }),
7+
host = schema.scalar({ type = 'string', env = 'HTTP_HOST' }),
8+
port = schema.scalar({ type = 'integer', env = 'HTTP_PORT' })
9+
}))
10+
11+
local function collect_env_cfg()
12+
local res = {}
13+
for _, w in listen_address_schema:pairs() do
14+
local env_var = w.schema.env
15+
if env_var ~= nil then
16+
local value = schema.fromenv(env_var, os.getenv(env_var), w.schema)
17+
listen_address_schema:set(res, w.path, value)
18+
end
19+
end
20+
return res
21+
end
22+
23+
local function validate(cfg)
24+
local env_cfg = collect_env_cfg()
25+
local result_cfg = listen_address_schema:merge(cfg, env_cfg)
26+
listen_address_schema:validate(result_cfg)
27+
end
28+
29+
local function apply(cfg)
30+
local env_cfg = collect_env_cfg()
31+
local result_cfg = listen_address_schema:merge(cfg, env_cfg)
32+
log.info("HTTP API endpoint: %s://%s:%d", result_cfg.scheme, result_cfg.host, result_cfg.port)
33+
end
34+
35+
local function stop()
36+
log.info("The 'http_api' role is stopped")
37+
end
38+
39+
return {
40+
validate = validate,
41+
apply = apply,
42+
stop = stop,
43+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instance001:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
groups:
2+
group001:
3+
replicasets:
4+
replicaset001:
5+
instances:
6+
instance001:
7+
roles: [ http_api ]
8+
roles_cfg:
9+
http_api:
10+
host: '127.0.0.1'
11+
port: 8080
12+
scheme: 'http'
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
-- http_api.lua --
2+
local log = require('log').new("http_api")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local listen_address_schema = schema.new(
6+
"listen_address",
7+
schema.record(
8+
{
9+
scheme = schema.enum({ "http", "https" }),
10+
host = schema.scalar({ type = "string" }),
11+
port = schema.scalar({ type = "integer" })
12+
}
13+
),
14+
{
15+
methods = {
16+
format = function(_self, url)
17+
return string.format("%s://%s:%d", url.scheme, url.host, url.port)
18+
end
19+
}
20+
}
21+
)
22+
23+
local function validate(cfg)
24+
listen_address_schema:validate(cfg)
25+
end
26+
27+
local function apply(cfg)
28+
local url_string = listen_address_schema:format(cfg)
29+
log.info("HTTP API endpoint: %s", url_string)
30+
end
31+
32+
local function stop()
33+
log.info("The 'http_api' role is stopped")
34+
end
35+
36+
return {
37+
validate = validate,
38+
apply = apply,
39+
stop = stop,
40+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instance001:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
groups:
2+
group001:
3+
replicasets:
4+
replicaset001:
5+
instances:
6+
instance001:
7+
roles: [ http-api ]
8+
roles_cfg:
9+
http-api:
10+
- host: '127.0.0.1'
11+
port: 8080
12+
scheme: 'http'
13+
- host: '127.0.0.1'
14+
port: 8443
15+
scheme: 'https'
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
-- http_api.lua --
2+
local log = require('log').new("http_api")
3+
local schema = require('experimental.config.utils.schema')
4+
5+
local listen_address_schema = schema.new('listen_address', schema.array({
6+
items = schema.record({
7+
scheme = schema.enum({ 'http', 'https' }),
8+
host = schema.scalar({ type = 'string' }),
9+
port = schema.scalar({ type = 'integer' })
10+
})
11+
}))
12+
13+
local function validate(cfg)
14+
listen_address_schema:validate(cfg)
15+
end
16+
17+
local function apply(cfg)
18+
for _, uri in ipairs(cfg) do
19+
local scheme = uri.scheme
20+
local host = uri.host
21+
local port = uri.port
22+
log.info("HTTP API endpoint: %s://%s:%d", scheme, host, port)
23+
end
24+
end
25+
26+
local function stop()
27+
log.info("The 'http_api' role is stopped")
28+
end
29+
30+
return {
31+
validate = validate,
32+
apply = apply,
33+
stop = stop,
34+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instance001:

0 commit comments

Comments
 (0)