diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 8f12abf47..79703bd4a 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -38,7 +38,9 @@ -type ip_port() :: tuple(). -type cipher() :: map(). -type rfc3339_system_time() :: integer(). +-type qos():: integer(). +-typerefl_from_string({qos/0, emqx_schema, to_qos}). -typerefl_from_string({duration/0, emqx_schema, to_duration}). -typerefl_from_string({duration_s/0, emqx_schema, to_duration_s}). -typerefl_from_string({duration_ms/0, emqx_schema, to_duration_ms}). @@ -62,7 +64,7 @@ mk_duration/2, to_bytesize/1, to_wordsize/1, to_percent/1, to_comma_separated_list/1, to_bar_separated_list/1, to_ip_port/1, - to_erl_cipher_suite/1, + to_erl_cipher_suite/1, to_qos/1, to_comma_separated_atoms/1, rfc3339_to_system_time/1]). @@ -71,7 +73,7 @@ -reflect_type([ duration/0, duration_s/0, duration_ms/0, bytesize/0, wordsize/0, percent/0, file/0, comma_separated_list/0, bar_separated_list/0, ip_port/0, - cipher/0, + cipher/0, qos/0, comma_separated_atoms/0, rfc3339_system_time/0]). @@ -312,7 +314,7 @@ message within this interval.""" desc => "Maximum topic levels allowed." })} , {"max_qos_allowed", - sc(range(0, 2), + sc(qos(), #{ default => 2, desc => "Maximum QoS allowed." })} @@ -1529,6 +1531,12 @@ rfc3339_to_system_time(DateTime) -> to_bar_separated_list(Str) -> {ok, string:tokens(Str, "| ")}. +to_qos(Str) -> + case string:to_integer(Str) of + {Num, []} when Num >= 0 andalso Num =< 2 -> {ok, Num}; + _ -> {error, Str} + end. + to_ip_port(Str) -> case string:tokens(Str, ": ") of [Ip, Port] -> diff --git a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl index 37d586d8f..2649093bf 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl @@ -453,6 +453,7 @@ typename_to_spec("timeout()", _Mod) -> #{<<"oneOf">> => [#{type => string, examp typename_to_spec("bytesize()", _Mod) -> #{type => string, example => <<"32MB">>}; typename_to_spec("wordsize()", _Mod) -> #{type => string, example => <<"1024KB">>}; typename_to_spec("map()", _Mod) -> #{type => object, example => #{}}; +typename_to_spec("qos()", _Mod) -> #{type => string, enum => [0, 1, 2], example => 0}; typename_to_spec("{binary(), binary()}", _Mod) -> #{type => object, example => #{}}; typename_to_spec("comma_separated_list()", _Mod) -> #{type => string, example => <<"item1,item2">>}; diff --git a/apps/emqx_dashboard/test/emqx_swagger_parameter_SUITE.erl b/apps/emqx_dashboard/test/emqx_swagger_parameter_SUITE.erl index 3c70cfe65..c47c91d9c 100644 --- a/apps/emqx_dashboard/test/emqx_swagger_parameter_SUITE.erl +++ b/apps/emqx_dashboard/test/emqx_swagger_parameter_SUITE.erl @@ -40,7 +40,9 @@ t_in_query(_Config) -> Expect = [#{description => <<"results per page (max 100)">>, example => 1, in => query, name => per_page, - schema => #{example => 1, maximum => 100, minimum => 1, type => integer}}], + schema => #{example => 1, maximum => 100, minimum => 1, type => integer}}, + #{description => <<"QOS">>, in => query, name => qos, + schema => #{enum => [0, 1, 2], example => 0, type => string}}], validate("/test/in/query", Expect), ok. @@ -148,8 +150,8 @@ t_in_path_trans(_Config) -> t_in_query_trans(_Config) -> Path = "/test/in/query", Expect = {ok, #{bindings => #{},body => #{}, - query_string => #{<<"per_page">> => 100}}}, - ?assertEqual(Expect, trans_parameters(Path, #{}, #{<<"per_page">> => 100})), + query_string => #{<<"per_page">> => 100, <<"qos">> => 1}}}, + ?assertEqual(Expect, trans_parameters(Path, #{}, #{<<"per_page">> => 100, <<"qos">> => 1})), ok. t_ref_trans(_Config) -> @@ -286,7 +288,8 @@ schema("/test/in/query") -> parameters => [ {per_page, mk(range(1, 100), - #{in => query, desc => <<"results per page (max 100)">>, example => 1})} + #{in => query, desc => <<"results per page (max 100)">>, example => 1})}, + {qos, mk(emqx_schema:qos(), #{in => query, desc => <<"QOS">>})} ], responses => #{200 => <<"ok">>} }