Merge pull request #11198 from savonarola/0705-fix-rebalance-swagger

fix(rebalance): fix rebalance swagger examples
This commit is contained in:
Ilya Averyanov 2023-07-07 15:55:16 +03:00 committed by GitHub
commit a6019a2846
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 37 deletions

View File

@ -899,15 +899,25 @@ typename_to_spec("json_binary()", _Mod) ->
typename_to_spec("port_number()", _Mod) -> typename_to_spec("port_number()", _Mod) ->
range("1..65535"); range("1..65535");
typename_to_spec(Name, Mod) -> typename_to_spec(Name, Mod) ->
Spec = range(Name), try_convert_to_spec(Name, Mod, [
Spec1 = remote_module_type(Spec, Name, Mod), fun try_remote_module_type/2,
Spec2 = typerefl_array(Spec1, Name, Mod), fun try_typerefl_array/2,
Spec3 = integer(Spec2, Name), fun try_range/2,
Spec3 =:= nomatch andalso fun try_integer/2
throw({error, #{msg => <<"Unsupported Type">>, type => Name, module => Mod}}), ]).
Spec3.
range(Name) -> range(Name) ->
#{} = try_range(Name, undefined).
try_convert_to_spec(Name, Mod, []) ->
throw({error, #{msg => <<"Unsupported Type">>, type => Name, module => Mod}});
try_convert_to_spec(Name, Mod, [Converter | Rest]) ->
case Converter(Name, Mod) of
nomatch -> try_convert_to_spec(Name, Mod, Rest);
Spec -> Spec
end.
try_range(Name, _Mod) ->
case string:split(Name, "..") of case string:split(Name, "..") of
%% 1..10 1..inf -inf..10 %% 1..10 1..inf -inf..10
[MinStr, MaxStr] -> [MinStr, MaxStr] ->
@ -919,39 +929,33 @@ range(Name) ->
end. end.
%% Module:Type %% Module:Type
remote_module_type(nomatch, Name, Mod) -> try_remote_module_type(Name, Mod) ->
case string:split(Name, ":") of case string:split(Name, ":") of
[_Module, Type] -> typename_to_spec(Type, Mod); [_Module, Type] -> typename_to_spec(Type, Mod);
_ -> nomatch _ -> nomatch
end; end.
remote_module_type(Spec, _Name, _Mod) ->
Spec.
%% [string()] or [integer()] or [xxx]. %% [string()] or [integer()] or [xxx] or [xxx,...]
typerefl_array(nomatch, Name, Mod) -> try_typerefl_array(Name, Mod) ->
case string:trim(Name, leading, "[") of case string:trim(Name, leading, "[") of
Name -> Name ->
nomatch; nomatch;
Name1 -> Name1 ->
case string:trim(Name1, trailing, "]") of case string:trim(Name1, trailing, ",.]") of
Name1 -> Name1 ->
notmatch; notmatch;
Name2 -> Name2 ->
Schema = typename_to_spec(Name2, Mod), Schema = typename_to_spec(Name2, Mod),
#{type => array, items => Schema} #{type => array, items => Schema}
end end
end; end.
typerefl_array(Spec, _Name, _Mod) ->
Spec.
%% integer(1) %% integer(1)
integer(nomatch, Name) -> try_integer(Name, _Mod) ->
case string:to_integer(Name) of case string:to_integer(Name) of
{Int, []} -> #{type => integer, enum => [Int], default => Int}; {Int, []} -> #{type => integer, enum => [Int], default => Int};
_ -> nomatch _ -> nomatch
end; end.
integer(Spec, _Name) ->
Spec.
add_integer_prop(Schema, Key, Value) -> add_integer_prop(Schema, Key, Value) ->
case string:to_integer(Value) of case string:to_integer(Value) of

View File

@ -105,6 +105,20 @@ t_deprecated(_Config) ->
emqx_dashboard_swagger:components([{?MODULE, deprecated_ref}], #{}) emqx_dashboard_swagger:components([{?MODULE, deprecated_ref}], #{})
). ).
t_nonempty_list(_Config) ->
?assertMatch(
[
#{
<<"emqx_swagger_requestBody_SUITE.nonempty_list_ref">> :=
#{
<<"properties">> :=
[{<<"list">>, #{items := #{type := string}, type := array}}]
}
}
],
emqx_dashboard_swagger:components([{?MODULE, nonempty_list_ref}], #{})
).
t_nest_object(_Config) -> t_nest_object(_Config) ->
GoodRef = <<"#/components/schemas/emqx_swagger_requestBody_SUITE.good_ref">>, GoodRef = <<"#/components/schemas/emqx_swagger_requestBody_SUITE.good_ref">>,
Spec = #{ Spec = #{
@ -829,6 +843,10 @@ fields(deprecated_ref) ->
{tag1, mk(binary(), #{desc => <<"tag1">>, deprecated => {since, "4.3.0"}})}, {tag1, mk(binary(), #{desc => <<"tag1">>, deprecated => {since, "4.3.0"}})},
{tag2, mk(binary(), #{desc => <<"tag2">>, deprecated => true})}, {tag2, mk(binary(), #{desc => <<"tag2">>, deprecated => true})},
{tag3, mk(binary(), #{desc => <<"tag3">>, deprecated => false})} {tag3, mk(binary(), #{desc => <<"tag3">>, deprecated => false})}
];
fields(nonempty_list_ref) ->
[
{list, mk(nonempty_list(binary()), #{})}
]. ].
enable(type) -> boolean(); enable(type) -> boolean();

View File

@ -709,25 +709,30 @@ fields(global_status) ->
rebalance_example() -> rebalance_example() ->
#{ #{
wait_health_check => <<"10s">>, rebalance =>
conn_evict_rate => 10, #{
sess_evict_rate => 20, wait_health_check => <<"10s">>,
abs_conn_threshold => 10, conn_evict_rate => 10,
rel_conn_threshold => 1.5, sess_evict_rate => 20,
abs_sess_threshold => 10, abs_conn_threshold => 10,
rel_sess_threshold => 1.5, rel_conn_threshold => 1.5,
wait_takeover => <<"10s">>, abs_sess_threshold => 10,
nodes => [<<"othernode@127.0.0.1">>] rel_sess_threshold => 1.5,
wait_takeover => <<"10s">>,
nodes => [<<"othernode@127.0.0.1">>]
}
}. }.
rebalance_evacuation_example() -> rebalance_evacuation_example() ->
#{ #{
wait_health_check => <<"10s">>, evacuation => #{
conn_evict_rate => 100, wait_health_check => <<"10s">>,
sess_evict_rate => 100, conn_evict_rate => 100,
redirect_to => <<"othernode:1883">>, sess_evict_rate => 100,
wait_takeover => <<"10s">>, redirect_to => <<"othernode:1883">>,
migrate_to => [<<"othernode@127.0.0.1">>] wait_takeover => <<"10s">>,
migrate_to => [<<"othernode@127.0.0.1">>]
}
}. }.
local_status_response_schema() -> local_status_response_schema() ->

View File

@ -51,7 +51,7 @@ format_local_status(Status) ->
-spec global_status() -> #{rebalances := [{node(), map()}], evacuations := [{node(), map()}]}. -spec global_status() -> #{rebalances := [{node(), map()}], evacuations := [{node(), map()}]}.
global_status() -> global_status() ->
Nodes = mria_mnesia:running_nodes(), Nodes = emqx:running_nodes(),
{RebalanceResults, _} = emqx_node_rebalance_status_proto_v1:rebalance_status(Nodes), {RebalanceResults, _} = emqx_node_rebalance_status_proto_v1:rebalance_status(Nodes),
Rebalances = [ Rebalances = [
{Node, coordinator_rebalance(Status)} {Node, coordinator_rebalance(Status)}

View File

@ -0,0 +1,65 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2023 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_node_rebalance_status_SUITE).
-compile(export_all).
-compile(nowarn_export_all).
-include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/assert.hrl").
all() -> emqx_common_test_helpers:all(?MODULE).
suite() ->
[{timetrap, {seconds, 90}}].
init_per_suite(Config) ->
WorkDir = ?config(priv_dir, Config),
Apps = [
emqx_conf,
emqx,
emqx_node_rebalance
],
Cluster = [
{emqx_node_rebalance_status_SUITE1, #{
role => core,
apps => Apps
}},
{emqx_node_rebalance_status_SUITE2, #{
role => replicant,
apps => Apps
}}
],
Nodes = emqx_cth_cluster:start(Cluster, #{work_dir => WorkDir}),
[{cluster_nodes, Nodes} | Config].
end_per_suite(Config) ->
ok = emqx_cth_cluster:stop(?config(cluster_nodes, Config)),
ok.
%%--------------------------------------------------------------------
%% Tests
%%--------------------------------------------------------------------
t_cluster_status(Config) ->
[CoreNode, ReplicantNode] = ?config(cluster_nodes, Config),
ok = emqx_node_rebalance_api_proto_v1:node_rebalance_evacuation_start(CoreNode, #{}),
?assertMatch(
#{evacuations := [_], rebalances := []},
rpc:call(ReplicantNode, emqx_node_rebalance_status, global_status, [])
).