feat(telemetry): save uuids to files
In order for the node and cluster UUIDs used by telemetry to survive database purges, we'll save the generated UUIDs to files in EMQX's data directory as well.
This commit is contained in:
parent
866810cea6
commit
4afb4d9dd8
|
@ -93,6 +93,9 @@
|
|||
|
||||
-define(TELEMETRY_SHARD, emqx_telemetry_shard).
|
||||
|
||||
-define(NODE_UUID_FILENAME, "node.uuid").
|
||||
-define(CLUSTER_UUID_FILENAME, "cluster.uuid").
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% API
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -535,7 +538,11 @@ ensure_uuids() ->
|
|||
NodeUUID =
|
||||
case mnesia:wread({?TELEMETRY, node()}) of
|
||||
[] ->
|
||||
NodeUUID0 = generate_uuid(),
|
||||
NodeUUID0 =
|
||||
case get_uuid_from_file(node) of
|
||||
{ok, NUUID} -> NUUID;
|
||||
undefined -> generate_uuid()
|
||||
end,
|
||||
mnesia:write(
|
||||
?TELEMETRY,
|
||||
#telemetry{
|
||||
|
@ -551,7 +558,11 @@ ensure_uuids() ->
|
|||
ClusterUUID =
|
||||
case mnesia:wread({?TELEMETRY, ?CLUSTER_UUID_KEY}) of
|
||||
[] ->
|
||||
ClusterUUID0 = generate_uuid(),
|
||||
ClusterUUID0 =
|
||||
case get_uuid_from_file(cluster) of
|
||||
{ok, CUUID} -> CUUID;
|
||||
undefined -> generate_uuid()
|
||||
end,
|
||||
mnesia:write(
|
||||
?TELEMETRY,
|
||||
#telemetry{
|
||||
|
@ -566,8 +577,35 @@ ensure_uuids() ->
|
|||
end,
|
||||
{NodeUUID, ClusterUUID}
|
||||
end,
|
||||
{atomic, UUIDs} = mria:transaction(?TELEMETRY_SHARD, Txn),
|
||||
UUIDs.
|
||||
{atomic, {NodeUUID, ClusterUUID}} = mria:transaction(?TELEMETRY_SHARD, Txn),
|
||||
save_uuid_to_file(NodeUUID, node),
|
||||
save_uuid_to_file(ClusterUUID, cluster),
|
||||
{NodeUUID, ClusterUUID}.
|
||||
|
||||
get_uuid_from_file(Type) ->
|
||||
Path = uuid_file_path(Type),
|
||||
case file:read_file(Path) of
|
||||
{ok,
|
||||
UUID =
|
||||
<<_:8/binary, "-", _:4/binary, "-", _:4/binary, "-", _:4/binary, "-", _:12/binary>>} ->
|
||||
{ok, UUID};
|
||||
_ ->
|
||||
undefined
|
||||
end.
|
||||
|
||||
save_uuid_to_file(UUID, Type) when is_binary(UUID) ->
|
||||
Path = uuid_file_path(Type),
|
||||
ok = filelib:ensure_dir(Path),
|
||||
ok = file:write_file(Path, UUID).
|
||||
|
||||
uuid_file_path(Type) ->
|
||||
DataDir = emqx:data_dir(),
|
||||
Filename =
|
||||
case Type of
|
||||
node -> ?NODE_UUID_FILENAME;
|
||||
cluster -> ?CLUSTER_UUID_FILENAME
|
||||
end,
|
||||
filename:join(DataDir, Filename).
|
||||
|
||||
empty_state() ->
|
||||
#state{
|
||||
|
|
|
@ -151,6 +151,41 @@ init_per_testcase(t_cluster_uuid, Config) ->
|
|||
Node = start_slave(n1),
|
||||
ok = setup_slave(Node),
|
||||
[{n1, Node} | Config];
|
||||
init_per_testcase(t_uuid_restored_from_file, Config) ->
|
||||
mock_httpc(),
|
||||
NodeUUID = <<"AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE">>,
|
||||
ClusterUUID = <<"FFFFFFFF-GGGG-HHHH-IIII-JJJJJJJJJJJJ">>,
|
||||
DataDir = emqx:data_dir(),
|
||||
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
|
||||
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
|
||||
file:delete(NodeUUIDFile),
|
||||
file:delete(ClusterUUIDFile),
|
||||
ok = file:write_file(NodeUUIDFile, NodeUUID),
|
||||
ok = file:write_file(ClusterUUIDFile, ClusterUUID),
|
||||
|
||||
%% clear the UUIDs in the DB
|
||||
{atomic, ok} = mria:clear_table(emqx_telemetry),
|
||||
emqx_common_test_helpers:stop_apps([emqx_conf, emqx_authn, emqx_authz, emqx_modules]),
|
||||
emqx_common_test_helpers:start_apps(
|
||||
[emqx_conf, emqx_authn, emqx_authz, emqx_modules],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
Node = start_slave(n1),
|
||||
ok = setup_slave(Node),
|
||||
[
|
||||
{n1, Node},
|
||||
{node_uuid, NodeUUID},
|
||||
{cluster_uuid, ClusterUUID}
|
||||
| Config
|
||||
];
|
||||
init_per_testcase(t_uuid_saved_to_file, Config) ->
|
||||
mock_httpc(),
|
||||
DataDir = emqx:data_dir(),
|
||||
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
|
||||
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
|
||||
file:delete(NodeUUIDFile),
|
||||
file:delete(ClusterUUIDFile),
|
||||
Config;
|
||||
init_per_testcase(t_num_clients, Config) ->
|
||||
mock_httpc(),
|
||||
ok = snabbkaffe:start_trace(),
|
||||
|
@ -213,6 +248,14 @@ end_per_testcase(t_num_clients, Config) ->
|
|||
meck:unload([httpc]),
|
||||
ok = snabbkaffe:stop(),
|
||||
Config;
|
||||
end_per_testcase(t_uuid_restored_from_file, _Config) ->
|
||||
DataDir = emqx:data_dir(),
|
||||
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
|
||||
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
|
||||
ok = file:delete(NodeUUIDFile),
|
||||
ok = file:delete(ClusterUUIDFile),
|
||||
meck:unload([httpc]),
|
||||
ok;
|
||||
end_per_testcase(_Testcase, _Config) ->
|
||||
meck:unload([httpc]),
|
||||
ok.
|
||||
|
@ -248,6 +291,48 @@ t_cluster_uuid(Config) ->
|
|||
?assertNotEqual(NodeUUID0, NodeUUID1),
|
||||
ok.
|
||||
|
||||
%% should attempt read UUID from file in data dir to keep UUIDs
|
||||
%% unique, in the event of a database purge.
|
||||
t_uuid_restored_from_file(Config) ->
|
||||
ExpectedNodeUUID = ?config(node_uuid, Config),
|
||||
ExpectedClusterUUID = ?config(cluster_uuid, Config),
|
||||
?assertEqual(
|
||||
{ok, ExpectedNodeUUID},
|
||||
emqx_telemetry:get_node_uuid()
|
||||
),
|
||||
?assertEqual(
|
||||
{ok, ExpectedClusterUUID},
|
||||
emqx_telemetry:get_cluster_uuid()
|
||||
),
|
||||
ok.
|
||||
|
||||
t_uuid_saved_to_file(_Config) ->
|
||||
DataDir = emqx:data_dir(),
|
||||
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
|
||||
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
|
||||
%% preconditions
|
||||
?assertEqual({error, enoent}, file:read_file(NodeUUIDFile)),
|
||||
?assertEqual({error, enoent}, file:read_file(ClusterUUIDFile)),
|
||||
|
||||
%% clear the UUIDs in the DB
|
||||
{atomic, ok} = mria:clear_table(emqx_telemetry),
|
||||
emqx_common_test_helpers:stop_apps([emqx_conf, emqx_authn, emqx_authz, emqx_modules]),
|
||||
emqx_common_test_helpers:start_apps(
|
||||
[emqx_conf, emqx_authn, emqx_authz, emqx_modules],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
{ok, NodeUUID} = emqx_telemetry:get_node_uuid(),
|
||||
{ok, ClusterUUID} = emqx_telemetry:get_cluster_uuid(),
|
||||
?assertEqual(
|
||||
{ok, NodeUUID},
|
||||
file:read_file(NodeUUIDFile)
|
||||
),
|
||||
?assertEqual(
|
||||
{ok, ClusterUUID},
|
||||
file:read_file(ClusterUUIDFile)
|
||||
),
|
||||
ok.
|
||||
|
||||
t_official_version(_) ->
|
||||
true = emqx_telemetry:official_version("0.0.0"),
|
||||
true = emqx_telemetry:official_version("1.1.1"),
|
||||
|
|
Loading…
Reference in New Issue