Merge pull request #5767 from lafirest/fix/time_unit

fix(schema): fix some time unit in schema
This commit is contained in:
lafirest 2021-09-26 15:35:27 +08:00 committed by GitHub
commit acb5c693ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 55 additions and 40 deletions

View File

@ -55,7 +55,7 @@
% workaround: prevent being recognized as unused functions % workaround: prevent being recognized as unused functions
-export([to_duration/1, to_duration_s/1, to_duration_ms/1, -export([to_duration/1, to_duration_s/1, to_duration_ms/1,
to_bytesize/1, to_wordsize/1, mk_duration/2, to_bytesize/1, to_wordsize/1,
to_percent/1, to_comma_separated_list/1, to_percent/1, to_comma_separated_list/1,
to_bar_separated_list/1, to_ip_port/1, to_bar_separated_list/1, to_ip_port/1,
to_erl_cipher_suite/1, to_erl_cipher_suite/1,
@ -1191,7 +1191,7 @@ default_ciphers(psk) ->
keys(Parent, Conf) -> keys(Parent, Conf) ->
[binary_to_list(B) || B <- maps:keys(conf_get(Parent, Conf, #{}))]. [binary_to_list(B) || B <- maps:keys(conf_get(Parent, Conf, #{}))].
-spec ceiling(float()) -> integer(). -spec ceiling(number()) -> integer().
ceiling(X) -> ceiling(X) ->
T = erlang:trunc(X), T = erlang:trunc(X),
case (X - T) of case (X - T) of
@ -1210,6 +1210,15 @@ ref(Field) -> hoconsc:ref(?MODULE, Field).
ref(Module, Field) -> hoconsc:ref(Module, Field). ref(Module, Field) -> hoconsc:ref(Module, Field).
mk_duration(Desc, OverrideMeta) ->
DefaultMeta = #{desc => Desc ++ " Time span. A text string with number followed by time units:
`ms` for milli-seconds,
`s` for seconds,
`m` for minutes,
`h` for hours;
or combined representation like `1h5m0s`"},
hoconsc:mk(typerefl:alias("string", duration()), maps:merge(DefaultMeta, OverrideMeta)).
to_duration(Str) -> to_duration(Str) ->
case hocon_postprocess:duration(Str) of case hocon_postprocess:duration(Str) of
I when is_integer(I) -> {ok, I}; I when is_integer(I) -> {ok, I};
@ -1218,13 +1227,15 @@ to_duration(Str) ->
to_duration_s(Str) -> to_duration_s(Str) ->
case hocon_postprocess:duration(Str) of case hocon_postprocess:duration(Str) of
I when is_integer(I) -> {ok, ceiling(I / 1000)}; I when is_number(I) -> {ok, ceiling(I / 1000)};
_ -> {error, Str} _ -> {error, Str}
end. end.
-spec to_duration_ms(Input) -> {ok, integer()} | {error, Input}
when Input :: string() | binary().
to_duration_ms(Str) -> to_duration_ms(Str) ->
case hocon_postprocess:duration(Str) of case hocon_postprocess:duration(Str) of
I when is_integer(I) -> {ok, ceiling(I)}; I when is_number(I) -> {ok, ceiling(I)};
_ -> {error, Str} _ -> {error, Str}
end. end.

View File

@ -91,7 +91,7 @@
enable => true})). enable => true})).
-define(INSTANCE_EXAMPLE_2, maps:merge(?EXAMPLE_2, #{id => <<"password-based:http-server">>, -define(INSTANCE_EXAMPLE_2, maps:merge(?EXAMPLE_2, #{id => <<"password-based:http-server">>,
connect_timeout => 5000, connect_timeout => "5s",
enable_pipelining => true, enable_pipelining => true,
headers => #{ headers => #{
<<"accept">> => <<"application/json">>, <<"accept">> => <<"application/json">>,
@ -102,8 +102,8 @@
}, },
max_retries => 5, max_retries => 5,
pool_size => 8, pool_size => 8,
request_timeout => 5000, request_timeout => "5s",
retry_interval => 1000, retry_interval => "1s",
enable => true})). enable => true})).
-define(INSTANCE_EXAMPLE_3, maps:merge(?EXAMPLE_3, #{id => <<"jwt">>, -define(INSTANCE_EXAMPLE_3, maps:merge(?EXAMPLE_3, #{id => <<"jwt">>,
@ -1259,9 +1259,9 @@ definitions() ->
example => <<"SELECT password_hash FROM mqtt_user WHERE username = ${mqtt-username}">> example => <<"SELECT password_hash FROM mqtt_user WHERE username = ${mqtt-username}">>
}, },
query_timeout => #{ query_timeout => #{
type => integer, type => string,
description => <<"Query timeout, Unit: Milliseconds">>, description => <<"Query timeout">>,
default => 5000 default => "5s"
} }
} }
}, },
@ -1528,16 +1528,16 @@ definitions() ->
type => object type => object
}, },
connect_timeout => #{ connect_timeout => #{
type => integer, type => string,
default => 5000 default => <<"5s">>
}, },
max_retries => #{ max_retries => #{
type => integer, type => integer,
default => 5 default => 5
}, },
retry_interval => #{ retry_interval => #{
type => integer, type => string,
default => 1000 default => <<"1s">>
}, },
request_timout => #{ request_timout => #{
type => integer, type => integer,

View File

@ -100,8 +100,8 @@ body(type) -> map();
body(validator) -> [fun check_body/1]; body(validator) -> [fun check_body/1];
body(_) -> undefined. body(_) -> undefined.
request_timeout(type) -> non_neg_integer(); request_timeout(type) -> emqx_schema:duration_ms();
request_timeout(default) -> 5000; request_timeout(default) -> "5s";
request_timeout(_) -> undefined. request_timeout(_) -> undefined.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

View File

@ -65,8 +65,8 @@ salt_position(_) -> undefined.
query(type) -> string(); query(type) -> string();
query(_) -> undefined. query(_) -> undefined.
query_timeout(type) -> integer(); query_timeout(type) -> emqx_schema:duration_ms();
query_timeout(default) -> 5000; query_timeout(default) -> "5s";
query_timeout(_) -> undefined. query_timeout(_) -> undefined.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

View File

@ -79,9 +79,9 @@ definitions() ->
}, },
headers => #{type => object}, headers => #{type => object},
body => #{type => object}, body => #{type => object},
connect_timeout => #{type => integer}, connect_timeout => #{type => string},
max_retries => #{type => integer}, max_retries => #{type => integer},
retry_interval => #{type => integer}, retry_interval => #{type => string},
pool_type => #{ pool_type => #{
type => string, type => string,
enum => [<<"random">>, <<"hash">>], enum => [<<"random">>, <<"hash">>],
@ -133,8 +133,8 @@ definitions() ->
properties => #{ properties => #{
pool_size => #{type => integer}, pool_size => #{type => integer},
max_overflow => #{type => integer}, max_overflow => #{type => integer},
overflow_ttl => #{type => integer}, overflow_ttl => #{type => string},
overflow_check_period => #{type => integer}, overflow_check_period => #{type => string},
local_threshold_ms => #{type => integer}, local_threshold_ms => #{type => integer},
connect_timeout_ms => #{type => integer}, connect_timeout_ms => #{type => integer},
socket_timeout_ms => #{type => integer}, socket_timeout_ms => #{type => integer},
@ -191,8 +191,8 @@ definitions() ->
properties => #{ properties => #{
pool_size => #{type => integer}, pool_size => #{type => integer},
max_overflow => #{type => integer}, max_overflow => #{type => integer},
overflow_ttl => #{type => integer}, overflow_ttl => #{type => string},
overflow_check_period => #{type => integer}, overflow_check_period => #{type => string},
local_threshold_ms => #{type => integer}, local_threshold_ms => #{type => integer},
connect_timeout_ms => #{type => integer}, connect_timeout_ms => #{type => integer},
socket_timeout_ms => #{type => integer}, socket_timeout_ms => #{type => integer},
@ -247,8 +247,8 @@ definitions() ->
properties => #{ properties => #{
pool_size => #{type => integer}, pool_size => #{type => integer},
max_overflow => #{type => integer}, max_overflow => #{type => integer},
overflow_ttl => #{type => integer}, overflow_ttl => #{type => string},
overflow_check_period => #{type => integer}, overflow_check_period => #{type => string},
local_threshold_ms => #{type => integer}, local_threshold_ms => #{type => integer},
connect_timeout_ms => #{type => integer}, connect_timeout_ms => #{type => integer},
socket_timeout_ms => #{type => integer}, socket_timeout_ms => #{type => integer},

View File

@ -18,6 +18,8 @@
, fields/1 , fields/1
]). ]).
-import(emqx_schema, [mk_duration/2]).
namespace() -> authz. namespace() -> authz.
%% @doc authorization schema is not exported %% @doc authorization schema is not exported
@ -77,7 +79,7 @@ fields(http_get) ->
end end
} }
} }
, {request_timeout, #{type => timeout(), default => 30000 }} , {request_timeout, mk_duration("request timeout", #{default => "30s"})}
] ++ proplists:delete(base_url, emqx_connector_http:fields(config)); ] ++ proplists:delete(base_url, emqx_connector_http:fields(config));
fields(http_post) -> fields(http_post) ->
[ {type, #{type => http}} [ {type, #{type => http}}
@ -107,7 +109,7 @@ fields(http_post) ->
end end
} }
} }
, {request_timeout, #{type => timeout(), default => 30000 }} , {request_timeout, mk_duration("request timeout", #{default => "30s"})}
, {body, #{type => map(), , {body, #{type => map(),
nullable => true nullable => true
} }

View File

@ -42,7 +42,7 @@
<<"url">> => <<"https://fake.com:443/">>, <<"url">> => <<"https://fake.com:443/">>,
<<"headers">> => #{}, <<"headers">> => #{},
<<"method">> => <<"get">>, <<"method">> => <<"get">>,
<<"request_timeout">> => 5000 <<"request_timeout">> => <<"5s">>
}). }).
-define(SOURCE2, #{<<"type">> => <<"mongodb">>, -define(SOURCE2, #{<<"type">> => <<"mongodb">>,
<<"enable">> => true, <<"enable">> => true,

View File

@ -71,16 +71,16 @@ base_url(validator) -> fun(#{query := _Query}) ->
end; end;
base_url(_) -> undefined. base_url(_) -> undefined.
connect_timeout(type) -> connect_timeout(); connect_timeout(type) -> emqx_schema:duration_ms();
connect_timeout(default) -> 5000; connect_timeout(default) -> "5s";
connect_timeout(_) -> undefined. connect_timeout(_) -> undefined.
max_retries(type) -> non_neg_integer(); max_retries(type) -> non_neg_integer();
max_retries(default) -> 5; max_retries(default) -> 5;
max_retries(_) -> undefined. max_retries(_) -> undefined.
retry_interval(type) -> non_neg_integer(); retry_interval(type) -> emqx_schema:duration_ms();
retry_interval(default) -> 1000; retry_interval(default) -> "1s";
retry_interval(_) -> undefined. retry_interval(_) -> undefined.
pool_type(type) -> pool_type(); pool_type(type) -> pool_type();

View File

@ -23,19 +23,21 @@
-export([ roots/0 -export([ roots/0
, fields/1]). , fields/1]).
-import(emqx_schema, [mk_duration/2]).
roots() -> roots() ->
[{config, #{type => hoconsc:ref(?MODULE, "config")}}]. [{config, #{type => hoconsc:ref(?MODULE, "config")}}].
fields("config") -> fields("config") ->
[ {server, hoconsc:mk(emqx_schema:ip_port(), #{default => "127.0.0.1:1883"})} [ {server, hoconsc:mk(emqx_schema:ip_port(), #{default => "127.0.0.1:1883"})}
, {reconnect_interval, hoconsc:mk(emqx_schema:duration_ms(), #{default => "30s"})} , {reconnect_interval, mk_duration("reconnect interval", #{default => "30s"})}
, {proto_ver, fun proto_ver/1} , {proto_ver, fun proto_ver/1}
, {bridge_mode, hoconsc:mk(boolean(), #{default => true})} , {bridge_mode, hoconsc:mk(boolean(), #{default => true})}
, {username, hoconsc:mk(string())} , {username, hoconsc:mk(string())}
, {password, hoconsc:mk(string())} , {password, hoconsc:mk(string())}
, {clean_start, hoconsc:mk(boolean(), #{default => true})} , {clean_start, hoconsc:mk(boolean(), #{default => true})}
, {keepalive, hoconsc:mk(integer(), #{default => 300})} , {keepalive, mk_duration("keepalive", #{default => "300s"})}
, {retry_interval, hoconsc:mk(emqx_schema:duration_ms(), #{default => "30s"})} , {retry_interval, mk_duration("retry interval", #{default => "30s"})}
, {max_inflight, hoconsc:mk(integer(), #{default => 32})} , {max_inflight, hoconsc:mk(integer(), #{default => 32})}
, {replayq, hoconsc:mk(hoconsc:ref(?MODULE, "replayq"))} , {replayq, hoconsc:mk(hoconsc:ref(?MODULE, "replayq"))}
, {ingress_channels, hoconsc:mk(hoconsc:map(id, hoconsc:ref(?MODULE, "ingress_channels")), #{default => []})} , {ingress_channels, hoconsc:mk(hoconsc:map(id, hoconsc:ref(?MODULE, "ingress_channels")), #{default => []})}

View File

@ -52,8 +52,8 @@ request(post, #{body := Body, bindings := Bindings}) ->
CT = maps:get(<<"content_type">>, Body, <<"text/plain">>), CT = maps:get(<<"content_type">>, Body, <<"text/plain">>),
Token = maps:get(<<"token">>, Body, <<>>), Token = maps:get(<<"token">>, Body, <<>>),
Payload = maps:get(<<"payload">>, Body, <<>>), Payload = maps:get(<<"payload">>, Body, <<>>),
WaitTime = maps:get(<<"timeout">>, Body, ?DEF_WAIT_TIME), BinWaitTime = maps:get(<<"timeout">>, Body, <<"10s">>),
{ok, WaitTime} = emqx_schema:to_duration_ms(BinWaitTime),
Payload2 = parse_payload(CT, Payload), Payload2 = parse_payload(CT, Payload),
ReqType = erlang:binary_to_atom(Method), ReqType = erlang:binary_to_atom(Method),
@ -83,7 +83,7 @@ request_parameters() ->
request_properties() -> request_properties() ->
properties([ {token, string, "message token, can be empty"} properties([ {token, string, "message token, can be empty"}
, {method, string, "request method type", ["get", "put", "post", "delete"]} , {method, string, "request method type", ["get", "put", "post", "delete"]}
, {timeout, integer, "timespan for response"} , {timeout, string, "timespan for response", "10s"}
, {content_type, string, "payload type", , {content_type, string, "payload type",
[<<"text/plain">>, <<"application/json">>, <<"application/octet-stream">>]} [<<"text/plain">>, <<"application/json">>, <<"application/octet-stream">>]}
, {payload, string, "payload"}]). , {payload, string, "payload"}]).

View File

@ -71,7 +71,7 @@ t_send_request_api(_) ->
Payload = <<"simple echo this">>, Payload = <<"simple echo this">>,
Req = #{token => Token, Req = #{token => Token,
payload => Payload, payload => Payload,
timeout => 10, timeout => <<"10s">>,
content_type => <<"text/plain">>, content_type => <<"text/plain">>,
method => <<"get">>}, method => <<"get">>},
Auth = emqx_mgmt_api_test_util:auth_header_(), Auth = emqx_mgmt_api_test_util:auth_header_(),