fix(emqx_mgmt): clients api query params supports epoch(milliseconds).
This commit is contained in:
parent
8cbec2ec6e
commit
294c1a5f69
|
@ -46,8 +46,8 @@
|
||||||
%% for test suite
|
%% for test suite
|
||||||
-export([ unix_ts_to_rfc3339_bin/1
|
-export([ unix_ts_to_rfc3339_bin/1
|
||||||
, unix_ts_to_rfc3339_bin/2
|
, unix_ts_to_rfc3339_bin/2
|
||||||
, rfc3339_to_unix_ts_int/1
|
, time_string_to_unix_ts_int/1
|
||||||
, rfc3339_to_unix_ts_int/2
|
, time_string_to_unix_ts_int/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,9 +106,9 @@ properties(client) ->
|
||||||
{clean_start, boolean, <<"Indicate whether the client is using a brand new session">>},
|
{clean_start, boolean, <<"Indicate whether the client is using a brand new session">>},
|
||||||
{clientid, string , <<"Client identifier">>},
|
{clientid, string , <<"Client identifier">>},
|
||||||
{connected, boolean, <<"Whether the client is connected">>},
|
{connected, boolean, <<"Whether the client is connected">>},
|
||||||
{connected_at, string , <<"Client connection time">>},
|
{connected_at, string , <<"Client connection time, rfc3339">>},
|
||||||
{created_at, string , <<"Session creation time">>},
|
{created_at, string , <<"Session creation time, rfc3339">>},
|
||||||
{disconnected_at, string , <<"Client offline time, This field is only valid and returned when connected is false">>},
|
{disconnected_at, string , <<"Client offline time, This field is only valid and returned when connected is false, rfc3339">>},
|
||||||
{expiry_interval, integer, <<"Session expiration interval, with the unit of second">>},
|
{expiry_interval, integer, <<"Session expiration interval, with the unit of second">>},
|
||||||
{heap_size, integer, <<"Process heap size with the unit of byte">>},
|
{heap_size, integer, <<"Process heap size with the unit of byte">>},
|
||||||
{inflight_cnt, integer, <<"Current length of inflight">>},
|
{inflight_cnt, integer, <<"Current length of inflight">>},
|
||||||
|
@ -238,28 +238,28 @@ clients_api() ->
|
||||||
name => gte_created_at,
|
name => gte_created_at,
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
description => <<"Search client session creation time by greater than or equal method, rfc3339">>,
|
description => <<"Search client session creation time by greater than or equal method, rfc3339 or timestamp(millisecond)">>,
|
||||||
schema => #{type => string}
|
schema => #{type => string}
|
||||||
},
|
},
|
||||||
#{
|
#{
|
||||||
name => lte_created_at,
|
name => lte_created_at,
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
description => <<"Search client session creation time by less than or equal method, rfc3339">>,
|
description => <<"Search client session creation time by less than or equal method, rfc3339 or timestamp(millisecond)">>,
|
||||||
schema => #{type => string}
|
schema => #{type => string}
|
||||||
},
|
},
|
||||||
#{
|
#{
|
||||||
name => gte_connected_at,
|
name => gte_connected_at,
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
description => <<"Search client connection creation time by greater than or equal method, rfc3339">>,
|
description => <<"Search client connection creation time by greater than or equal method, rfc3339 or timestamp(millisecond)">>,
|
||||||
schema => #{type => string}
|
schema => #{type => string}
|
||||||
},
|
},
|
||||||
#{
|
#{
|
||||||
name => lte_connected_at,
|
name => lte_connected_at,
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
description => <<"Search client connection creation time by less than or equal method, rfc3339">>,
|
description => <<"Search client connection creation time by less than or equal method, rfc3339 or timestamp(millisecond) ">>,
|
||||||
schema => #{type => string}
|
schema => #{type => string}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -532,22 +532,25 @@ do_unsubscribe(ClientID, Topic) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% QueryString Generation (rfc3339 to timestamp)
|
%% QueryString Generation (try rfc3339 to timestamp or keep timestamp)
|
||||||
|
|
||||||
|
time_keys() ->
|
||||||
|
[ <<"gte_created_at">>
|
||||||
|
, <<"lte_created_at">>
|
||||||
|
, <<"gte_connected_at">>
|
||||||
|
, <<"lte_connected_at">>].
|
||||||
|
|
||||||
generate_qs(Qs) ->
|
generate_qs(Qs) ->
|
||||||
TimeKeys = [ <<"gte_created_at">>
|
|
||||||
, <<"lte_created_at">>
|
|
||||||
, <<"gte_connected_at">>
|
|
||||||
, <<"lte_connected_at">>],
|
|
||||||
Fun =
|
Fun =
|
||||||
fun
|
fun (Key, NQs) ->
|
||||||
(Key, NQs) ->
|
|
||||||
case NQs of
|
case NQs of
|
||||||
#{Key := Rfc3339Time} -> NQs#{Key => rfc3339_to_unix_ts_int(Rfc3339Time)};
|
%% TimeString likes "2021-01-01T00:00:00.000+08:00" (in rfc3339)
|
||||||
#{} -> NQs
|
%% or "1609430400000" (in millisecond)
|
||||||
|
#{Key := TimeString} -> NQs#{Key => time_string_to_unix_ts_int(TimeString)};
|
||||||
|
#{} -> NQs
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
lists:foldl(Fun, Qs, TimeKeys).
|
lists:foldl(Fun, Qs, time_keys()).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Query Functions
|
%% Query Functions
|
||||||
|
@ -717,8 +720,13 @@ unix_ts_to_rfc3339_bin(TimeStamp) ->
|
||||||
unix_ts_to_rfc3339_bin(TimeStamp, Unit) when is_integer(TimeStamp) ->
|
unix_ts_to_rfc3339_bin(TimeStamp, Unit) when is_integer(TimeStamp) ->
|
||||||
list_to_binary(calendar:system_time_to_rfc3339(TimeStamp, [{unit, Unit}])).
|
list_to_binary(calendar:system_time_to_rfc3339(TimeStamp, [{unit, Unit}])).
|
||||||
|
|
||||||
rfc3339_to_unix_ts_int(DateTime) ->
|
time_string_to_unix_ts_int(DateTime) ->
|
||||||
rfc3339_to_unix_ts_int(DateTime, millisecond).
|
time_string_to_unix_ts_int(DateTime, millisecond).
|
||||||
|
|
||||||
rfc3339_to_unix_ts_int(DateTime, Unit) when is_binary(DateTime) ->
|
time_string_to_unix_ts_int(DateTime, Unit) when is_binary(DateTime) ->
|
||||||
calendar:rfc3339_to_system_time(binary_to_list(DateTime), [{unit, Unit}]).
|
try binary_to_integer(DateTime) of
|
||||||
|
TimeStamp when is_integer(TimeStamp) -> TimeStamp
|
||||||
|
catch
|
||||||
|
error:badarg ->
|
||||||
|
calendar:rfc3339_to_system_time(binary_to_list(DateTime), [{unit, Unit}])
|
||||||
|
end.
|
||||||
|
|
|
@ -104,6 +104,7 @@ t_clients(_) ->
|
||||||
|
|
||||||
t_query_clients_with_time(_) ->
|
t_query_clients_with_time(_) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
|
|
||||||
Username1 = <<"user1">>,
|
Username1 = <<"user1">>,
|
||||||
ClientId1 = <<"client1">>,
|
ClientId1 = <<"client1">>,
|
||||||
|
|
||||||
|
@ -122,22 +123,26 @@ t_query_clients_with_time(_) ->
|
||||||
%% get /clients with time(rfc3339)
|
%% get /clients with time(rfc3339)
|
||||||
NowTimeStampInt = erlang:system_time(millisecond),
|
NowTimeStampInt = erlang:system_time(millisecond),
|
||||||
%% Do not uri_encode `=` to `%3D`
|
%% Do not uri_encode `=` to `%3D`
|
||||||
NowTimeString = emqx_http_lib:uri_encode(binary:bin_to_list(emqx_mgmt_api_clients:unix_ts_to_rfc3339_bin(NowTimeStampInt))),
|
Rfc3339String = emqx_http_lib:uri_encode(binary:bin_to_list(emqx_mgmt_api_clients:unix_ts_to_rfc3339_bin(NowTimeStampInt))),
|
||||||
Parameters = [Param ++ NowTimeString
|
TimeStampString = emqx_http_lib:uri_encode(integer_to_list(NowTimeStampInt)),
|
||||||
|| Param <- [ "lte_created_at="
|
|
||||||
, "lte_connected_at="
|
LteKeys = ["lte_created_at=", "lte_connected_at="],
|
||||||
, "gte_created_at="
|
GteKeys = ["gte_created_at=", "gte_connected_at="],
|
||||||
, "gte_connected_at="]],
|
LteParamRfc3339 = [Param ++ Rfc3339String || Param <- LteKeys],
|
||||||
|
LteParamStamp = [Param ++ TimeStampString || Param <- LteKeys],
|
||||||
|
GteParamRfc3339 = [Param ++ Rfc3339String || Param <- GteKeys],
|
||||||
|
GteParamStamp = [Param ++ TimeStampString || Param <- GteKeys],
|
||||||
|
|
||||||
RequestResults = [emqx_mgmt_api_test_util:request_api(get, ClientsPath, Param, AuthHeader)
|
RequestResults = [emqx_mgmt_api_test_util:request_api(get, ClientsPath, Param, AuthHeader)
|
||||||
|| Param <- Parameters],
|
|| Param <- LteParamRfc3339 ++ LteParamStamp ++ GteParamRfc3339 ++ GteParamStamp],
|
||||||
DecodedResults = [emqx_json:decode(Response, [return_maps])
|
DecodedResults = [emqx_json:decode(Response, [return_maps])
|
||||||
|| {ok, Response} <- RequestResults],
|
|| {ok, Response} <- RequestResults],
|
||||||
{LteResponseDecodeds, GteResponseDecodeds} = lists:split(2, DecodedResults),
|
{LteResponseDecodeds, GteResponseDecodeds} = lists:split(4, DecodedResults),
|
||||||
%% EachData :: list()
|
%% EachData :: list()
|
||||||
[?assert( emqx_mgmt_api_clients:rfc3339_to_unix_ts_int(CreatedAt) < NowTimeStampInt)
|
[?assert( emqx_mgmt_api_clients:time_string_to_unix_ts_int(CreatedAt) < NowTimeStampInt)
|
||||||
|| #{<<"data">> := EachData} <- LteResponseDecodeds,
|
|| #{<<"data">> := EachData} <- LteResponseDecodeds,
|
||||||
#{<<"created_at">> := CreatedAt} <- EachData],
|
#{<<"created_at">> := CreatedAt} <- EachData],
|
||||||
[?assert(emqx_mgmt_api_clients:rfc3339_to_unix_ts_int(ConnectedAt) < NowTimeStampInt)
|
[?assert(emqx_mgmt_api_clients:time_string_to_unix_ts_int(ConnectedAt) < NowTimeStampInt)
|
||||||
|| #{<<"data">> := EachData} <- LteResponseDecodeds,
|
|| #{<<"data">> := EachData} <- LteResponseDecodeds,
|
||||||
#{<<"connected_at">> := ConnectedAt} <- EachData],
|
#{<<"connected_at">> := ConnectedAt} <- EachData],
|
||||||
[?assertEqual(EachData, [])
|
[?assertEqual(EachData, [])
|
||||||
|
|
Loading…
Reference in New Issue