Browse Source

chore: unify `backup_tables` and `table_set_name`

Thales Macedo Garitezi 1 year ago
parent
commit
100e4077c7

+ 7 - 7
apps/emqx/src/bhvrs/emqx_db_backup.erl

@@ -16,15 +16,15 @@
 
 -module(emqx_db_backup).
 
--export([table_set_name/1]).
+-export([backup_tables/1]).
 
 -type traverse_break_reason() :: over | migrate.
 
--type opts() :: #{print_fun => fun((io:format(), [term()]) -> ok)}.
+-type table_set_name() :: binary().
 
--callback backup_tables() -> [mria:table()].
+-type opts() :: #{print_fun => fun((io:format(), [term()]) -> ok)}.
 
--callback table_set_name() -> binary().
+-callback backup_tables() -> {table_set_name(), [mria:table()]}.
 
 %% validate the backup
 %% return `ok` to traverse the next item
@@ -44,6 +44,6 @@
 
 -export_type([traverse_break_reason/0]).
 
--spec table_set_name(module()) -> binary().
-table_set_name(Mod) ->
-    Mod:table_set_name().
+-spec backup_tables(module()) -> {table_set_name(), [mria:table()]}.
+backup_tables(Mod) ->
+    Mod:backup_tables().

+ 2 - 4
apps/emqx/src/emqx_banned.erl

@@ -57,7 +57,7 @@
     code_change/3
 ]).
 
--export([backup_tables/0, table_set_name/0]).
+-export([backup_tables/0]).
 
 %% Internal exports (RPC)
 -export([
@@ -94,9 +94,7 @@ create_tables() ->
 %%--------------------------------------------------------------------
 %% Data backup
 %%--------------------------------------------------------------------
-backup_tables() -> tables().
-
-table_set_name() -> <<"banned">>.
+backup_tables() -> {<<"banned">>, tables()}.
 
 -spec tables() -> [atom()].
 tables() -> [?BANNED_RULE_TAB, ?BANNED_INDIVIDUAL_TAB].

+ 2 - 4
apps/emqx_auth_mnesia/src/emqx_authn_mnesia.erl

@@ -57,7 +57,7 @@
 
 -export([init_tables/0]).
 
--export([backup_tables/0, table_set_name/0]).
+-export([backup_tables/0]).
 
 -type user_group() :: binary().
 -type user_id() :: binary().
@@ -102,9 +102,7 @@ init_tables() ->
 %% Data backup
 %%------------------------------------------------------------------------------
 
-backup_tables() -> [?TAB].
-
-table_set_name() -> <<"builtin_authn">>.
+backup_tables() -> {<<"builtin_authn">>, [?TAB]}.
 
 %%------------------------------------------------------------------------------
 %% APIs

+ 2 - 4
apps/emqx_auth_mnesia/src/emqx_authn_scram_mnesia.erl

@@ -46,7 +46,7 @@
     group_match_spec/1
 ]).
 
--export([backup_tables/0, table_set_name/0]).
+-export([backup_tables/0]).
 
 %% Internal exports (RPC)
 -export([
@@ -102,9 +102,7 @@ init_tables() ->
 %% Data backup
 %%------------------------------------------------------------------------------
 
-backup_tables() -> [?TAB].
-
-table_set_name() -> <<"builtin_authn_scram">>.
+backup_tables() -> {<<"builtin_authn">>, [?TAB]}.
 
 %%------------------------------------------------------------------------------
 %% APIs

+ 2 - 4
apps/emqx_auth_mnesia/src/emqx_authz_mnesia.erl

@@ -68,7 +68,7 @@
     record_count/0
 ]).
 
--export([backup_tables/0, table_set_name/0]).
+-export([backup_tables/0]).
 
 -ifdef(TEST).
 -compile(export_all).
@@ -129,9 +129,7 @@ authorize(
 %% Data backup
 %%--------------------------------------------------------------------
 
-backup_tables() -> [?ACL_TABLE].
-
-table_set_name() -> <<"builtin_authz">>.
+backup_tables() -> {<<"builtin_authz">>, [?ACL_TABLE]}.
 
 %%--------------------------------------------------------------------
 %% Management API

+ 2 - 4
apps/emqx_dashboard/src/emqx_dashboard_admin.erl

@@ -55,7 +55,7 @@
 
 -export([role/1]).
 
--export([backup_tables/0, table_set_name/0]).
+-export([backup_tables/0]).
 
 -if(?EMQX_RELEASE_EDITION == ee).
 -export([add_sso_user/4, lookup_user/2]).
@@ -89,9 +89,7 @@ create_tables() ->
 %% Data backup
 %%--------------------------------------------------------------------
 
-backup_tables() -> [?ADMIN].
-
-table_set_name() -> <<"dashboard_users">>.
+backup_tables() -> {<<"dashboard_users">>, [?ADMIN]}.
 
 %%--------------------------------------------------------------------
 %% bootstrap API

+ 2 - 4
apps/emqx_management/src/emqx_mgmt_auth.erl

@@ -39,7 +39,7 @@
 -export([authorize/4]).
 -export([post_config_update/5]).
 
--export([backup_tables/0, table_set_name/0, validate_mnesia_backup/1]).
+-export([backup_tables/0, validate_mnesia_backup/1]).
 
 %% Internal exports (RPC)
 -export([
@@ -86,9 +86,7 @@ create_tables() ->
 %% Data backup
 %%--------------------------------------------------------------------
 
-backup_tables() -> [?APP].
-
-table_set_name() -> <<"api_keys">>.
+backup_tables() -> {<<"api_keys">>, [?APP]}.
 
 validate_mnesia_backup({schema, _Tab, CreateList} = Schema) ->
     case emqx_mgmt_data_backup:default_validate_mnesia_backup(Schema) of

+ 23 - 44
apps/emqx_management/src/emqx_mgmt_data_backup.erl

@@ -132,15 +132,13 @@ export() ->
 
 -spec compile_mnesia_table_filter([binary()]) -> {ok, mnesia_table_filter()} | {error, any()}.
 compile_mnesia_table_filter(TableSets) ->
-    Mapping = table_set_to_module_mapping(),
+    Mapping = table_set_to_tables_mapping(),
     {TableNames, Errors} =
         lists:foldl(
             fun(TableSetName, {TableAcc, ErrorAcc}) ->
-                maybe
-                    {ok, Mod} ?= maps:find(TableSetName, Mapping),
-                    Tables = Mod:backup_tables(),
-                    {lists:usort(Tables ++ TableAcc), ErrorAcc}
-                else
+                case maps:find(TableSetName, Mapping) of
+                    {ok, Tables} ->
+                        {lists:usort(Tables ++ TableAcc), ErrorAcc};
                     error ->
                         {TableAcc, [TableSetName | ErrorAcc]}
                 end
@@ -190,9 +188,12 @@ all_table_set_names() ->
 
 build_all_table_set_names() ->
     Mods = modules_with_mnesia_tabs_to_backup(),
-    lists:sort(
+    lists:usort(
         lists:map(
-            fun emqx_db_backup:table_set_name/1,
+            fun(Mod) ->
+                {TableSetName, _Tabs} = emqx_db_backup:backup_tables(Mod),
+                TableSetName
+            end,
             Mods
         )
     ).
@@ -449,7 +450,7 @@ export_mnesia_tabs(TarDescriptor, BackupName, BackupBaseName, Opts) ->
     FilterFn = maps:get(mnesia_table_filter, Opts, fun(_TableName) -> true end),
     lists:foreach(
         fun(Mod) ->
-            Tabs = Mod:backup_tables(),
+            {_Name, Tabs} = emqx_db_backup:backup_tables(Mod),
             lists:foreach(
                 fun(Tab) ->
                     export_mnesia_tab(TarDescriptor, Tab, BackupName, BackupBaseName, Opts)
@@ -602,7 +603,7 @@ import_mnesia_tabs(BackupDir, Opts) ->
     filter_errors(
         lists:foldr(
             fun(Mod, Acc) ->
-                Tabs = Mod:backup_tables(),
+                {_Name, Tabs} = emqx_db_backup:backup_tables(Mod),
                 lists:foldr(
                     fun(Tab, InAcc) ->
                         InAcc#{Tab => import_mnesia_tab(BackupDir, Mod, Tab, Opts)}
@@ -1057,52 +1058,30 @@ apps() ->
         end
     ].
 
--spec table_set_to_module_mapping() -> #{binary() => module()}.
-table_set_to_module_mapping() ->
-    Key = {?MODULE, table_set_to_module_mapping},
+-spec table_set_to_tables_mapping() -> #{binary() => module()}.
+table_set_to_tables_mapping() ->
+    Key = {?MODULE, table_set_to_tables_mapping},
     case persistent_term:get(Key, undefined) of
         undefined ->
-            Mapping = build_table_set_to_module_mapping(),
+            Mapping = build_table_set_to_tables_mapping(),
             persistent_term:put(Key, Mapping),
             Mapping;
         Mapping ->
             Mapping
     end.
 
-build_table_set_to_module_mapping() ->
+build_table_set_to_tables_mapping() ->
     Mods = modules_with_mnesia_tabs_to_backup(),
     lists:foldl(
         fun(Mod, Acc) ->
-            Name = emqx_db_backup:table_set_name(Mod),
-            Acc#{Name => Mod}
+            {Name, Tabs} = emqx_db_backup:backup_tables(Mod),
+            maps:update_with(
+                Name,
+                fun(PrevTabs) -> Tabs ++ PrevTabs end,
+                Tabs,
+                Acc
+            )
         end,
         #{},
         Mods
     ).
-
--ifdef(TEST).
--include_lib("eunit/include/eunit.hrl").
-
-%% Different implementations of `emqx_db_backup' behaviour should have distinct names.
-ensure_no_table_set_name_clash_test() ->
-    UmbrellaApps = emqx_machine_boot:reboot_apps(),
-    lists:foreach(fun(App) -> application:load(App) end, UmbrellaApps),
-    Mods = modules_with_mnesia_tabs_to_backup(),
-    Names = lists:sort(
-        lists:map(
-            fun(Mod) ->
-                try
-                    emqx_db_backup:table_set_name(Mod)
-                catch
-                    error:undef ->
-                        ct:fail("module ~s is missing an implementation of `table_set_name'", [Mod])
-                end
-            end,
-            Mods
-        )
-    ),
-    UniqueNames = lists:usort(Names),
-    Duplicates = Names -- UniqueNames,
-    ?assertEqual([], Duplicates),
-    ok.
--endif.

+ 0 - 1
apps/emqx_management/test/emqx_mgmt_api_data_backup_SUITE.erl

@@ -263,7 +263,6 @@ export_cloud_backup(NodeApiPort, Auth) ->
         <<"table_sets">> => [
             <<"banned">>,
             <<"builtin_authn">>,
-            <<"builtin_authn_scram">>,
             <<"builtin_authz">>
         ],
         <<"root_keys">> => [

+ 2 - 2
apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl

@@ -542,7 +542,7 @@ t_verify_imported_mnesia_tab_on_cluster(Config) ->
         rpc:call(CoreNode1, emqx_mgmt_data_backup, import, [AbsFilePath])
     ),
 
-    [Tab] = emqx_dashboard_admin:backup_tables(),
+    {_Name, [Tab]} = emqx_dashboard_admin:backup_tables(),
     AllUsers = lists:sort(mnesia:dirty_all_keys(Tab) ++ UsersBeforeImport),
     [
         ?assertEqual(
@@ -557,7 +557,7 @@ t_verify_imported_mnesia_tab_on_cluster(Config) ->
     ?assertEqual(AllUsers, lists:sort(rpc:call(ReplicantNode, mnesia, dirty_all_keys, [Tab]))).
 
 backup_tables() ->
-    [data_backup_test].
+    {<<"mocked_test">>, [data_backup_test]}.
 
 t_mnesia_bad_tab_schema(_Config) ->
     OldAttributes = [id, name, description],

+ 2 - 5
apps/emqx_psk/src/emqx_psk.erl

@@ -55,8 +55,7 @@
 %% Data backup
 -export([
     import_config/1,
-    backup_tables/0,
-    table_set_name/0
+    backup_tables/0
 ]).
 
 -record(psk_entry, {
@@ -95,9 +94,7 @@ create_tables() ->
 %% Data backup
 %%------------------------------------------------------------------------------
 
-backup_tables() -> [?TAB].
-
-table_set_name() -> <<"psk">>.
+backup_tables() -> {<<"psk">>, [?TAB]}.
 
 %%------------------------------------------------------------------------------
 %% APIs

+ 11 - 4
apps/emqx_retainer/src/emqx_retainer_mnesia.erl

@@ -60,7 +60,6 @@
 
 -export([
     backup_tables/0,
-    table_set_name/0,
     on_backup_table_imported/2
 ]).
 
@@ -89,9 +88,17 @@ topics() ->
 %%--------------------------------------------------------------------
 
 backup_tables() ->
-    [?TAB_MESSAGE || is_enabled()].
-
-table_set_name() -> <<"builtin_retainer">>.
+    {<<"builtin_retainer">>, tables_to_backup()}.
+
+tables_to_backup() ->
+    %% `backup_tables' is inspected to construct API docs (available table sets), and such
+    %% docs are built in `emqx_conf:dump_schema', while there's no started node.
+    try
+        [?TAB_MESSAGE || is_enabled()]
+    catch
+        exit:{noproc, _} ->
+            []
+    end.
 
 on_backup_table_imported(?TAB_MESSAGE, Opts) ->
     case is_enabled() of