diff --git a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl index 47acee58b..f829c8b08 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl @@ -897,15 +897,25 @@ typename_to_spec("json_binary()", _Mod) -> typename_to_spec("port_number()", _Mod) -> range("1..65535"); typename_to_spec(Name, Mod) -> - Spec = range(Name), - Spec1 = remote_module_type(Spec, Name, Mod), - Spec2 = typerefl_array(Spec1, Name, Mod), - Spec3 = integer(Spec2, Name), - Spec3 =:= nomatch andalso - throw({error, #{msg => <<"Unsupported Type">>, type => Name, module => Mod}}), - Spec3. + try_convert_to_spec(Name, Mod, [ + fun try_remote_module_type/2, + fun try_typerefl_array/2, + fun try_range/2, + fun try_integer/2 + ]). 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 %% 1..10 1..inf -inf..10 [MinStr, MaxStr] -> @@ -917,39 +927,33 @@ range(Name) -> end. %% Module:Type -remote_module_type(nomatch, Name, Mod) -> +try_remote_module_type(Name, Mod) -> case string:split(Name, ":") of [_Module, Type] -> typename_to_spec(Type, Mod); _ -> nomatch - end; -remote_module_type(Spec, _Name, _Mod) -> - Spec. + end. -%% [string()] or [integer()] or [xxx]. -typerefl_array(nomatch, Name, Mod) -> +%% [string()] or [integer()] or [xxx] or [xxx,...] +try_typerefl_array(Name, Mod) -> case string:trim(Name, leading, "[") of Name -> nomatch; Name1 -> - case string:trim(Name1, trailing, "]") of + case string:trim(Name1, trailing, ",.]") of Name1 -> notmatch; Name2 -> Schema = typename_to_spec(Name2, Mod), #{type => array, items => Schema} end - end; -typerefl_array(Spec, _Name, _Mod) -> - Spec. + end. %% integer(1) -integer(nomatch, Name) -> +try_integer(Name, _Mod) -> case string:to_integer(Name) of {Int, []} -> #{type => integer, enum => [Int], default => Int}; _ -> nomatch - end; -integer(Spec, _Name) -> - Spec. + end. add_integer_prop(Schema, Key, Value) -> case string:to_integer(Value) of diff --git a/apps/emqx_dashboard/test/emqx_swagger_requestBody_SUITE.erl b/apps/emqx_dashboard/test/emqx_swagger_requestBody_SUITE.erl index e8c79c57c..4bc0f4a7c 100644 --- a/apps/emqx_dashboard/test/emqx_swagger_requestBody_SUITE.erl +++ b/apps/emqx_dashboard/test/emqx_swagger_requestBody_SUITE.erl @@ -105,6 +105,20 @@ t_deprecated(_Config) -> 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) -> GoodRef = <<"#/components/schemas/emqx_swagger_requestBody_SUITE.good_ref">>, Spec = #{ @@ -829,6 +843,10 @@ fields(deprecated_ref) -> {tag1, mk(binary(), #{desc => <<"tag1">>, deprecated => {since, "4.3.0"}})}, {tag2, mk(binary(), #{desc => <<"tag2">>, deprecated => true})}, {tag3, mk(binary(), #{desc => <<"tag3">>, deprecated => false})} + ]; +fields(nonempty_list_ref) -> + [ + {list, mk(nonempty_list(binary()), #{})} ]. enable(type) -> boolean(); diff --git a/apps/emqx_node_rebalance/src/emqx_node_rebalance_api.erl b/apps/emqx_node_rebalance/src/emqx_node_rebalance_api.erl index 1d25bfb33..fb27c0a30 100644 --- a/apps/emqx_node_rebalance/src/emqx_node_rebalance_api.erl +++ b/apps/emqx_node_rebalance/src/emqx_node_rebalance_api.erl @@ -709,25 +709,30 @@ fields(global_status) -> rebalance_example() -> #{ - wait_health_check => <<"10s">>, - conn_evict_rate => 10, - sess_evict_rate => 20, - abs_conn_threshold => 10, - rel_conn_threshold => 1.5, - abs_sess_threshold => 10, - rel_sess_threshold => 1.5, - wait_takeover => <<"10s">>, - nodes => [<<"othernode@127.0.0.1">>] + rebalance => + #{ + wait_health_check => <<"10s">>, + conn_evict_rate => 10, + sess_evict_rate => 20, + abs_conn_threshold => 10, + rel_conn_threshold => 1.5, + abs_sess_threshold => 10, + rel_sess_threshold => 1.5, + wait_takeover => <<"10s">>, + nodes => [<<"othernode@127.0.0.1">>] + } }. rebalance_evacuation_example() -> #{ - wait_health_check => <<"10s">>, - conn_evict_rate => 100, - sess_evict_rate => 100, - redirect_to => <<"othernode:1883">>, - wait_takeover => <<"10s">>, - migrate_to => [<<"othernode@127.0.0.1">>] + evacuation => #{ + wait_health_check => <<"10s">>, + conn_evict_rate => 100, + sess_evict_rate => 100, + redirect_to => <<"othernode:1883">>, + wait_takeover => <<"10s">>, + migrate_to => [<<"othernode@127.0.0.1">>] + } }. local_status_response_schema() ->