Merge pull request #8027 from thalesmg/telemetry-uuid-file

feat(telemetry): save uuids to files
This commit is contained in:
Thales Macedo Garitezi 2022-05-24 16:55:09 -03:00 committed by GitHub
commit 0333e6f860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 127 additions and 4 deletions

View File

@ -93,6 +93,9 @@
-define(TELEMETRY_SHARD, emqx_telemetry_shard).
-define(NODE_UUID_FILENAME, "node.uuid").
-define(CLUSTER_UUID_FILENAME, "cluster.uuid").
%%--------------------------------------------------------------------
%% API
%%--------------------------------------------------------------------
@ -531,7 +534,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{
@ -547,7 +554,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{
@ -562,8 +573,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{

View File

@ -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"),