Explorar o código

fix(plugins): read avsc file

JimMoen hai 1 ano
pai
achega
d06f410fd5

+ 40 - 16
apps/emqx_plugins/src/emqx_plugins.erl

@@ -81,7 +81,9 @@
 %% Defines
 -define(PLUGIN_PERSIS_CONFIG_KEY(NameVsn), {?MODULE, NameVsn}).
 
-%% Types
+-define(RAW_BIN, binary).
+-define(JSON_MAP, json_map).
+
 %% "my_plugin-0.1.0"
 -type name_vsn() :: binary() | string().
 %% the parse result of the JSON info file
@@ -590,30 +592,36 @@ do_read_plugin(NameVsn) ->
     do_read_plugin2(NameVsn, #{}).
 
 do_read_plugin2(NameVsn, Option) ->
-    do_read_plugin3(NameVsn, info_file(NameVsn), Option).
+    do_read_plugin3(NameVsn, info_file_path(NameVsn), Option).
 
 do_read_plugin3(NameVsn, InfoFilePath, Options) ->
-    {ok, PlainMap} = (read_file_fun(InfoFilePath, "bad_info_file"))(),
+    {ok, PlainMap} = (read_file_fun(InfoFilePath, "bad_info_file", #{read_mode => ?JSON_MAP}))(),
     Info0 = check_plugin(PlainMap, NameVsn, InfoFilePath),
     Info1 = plugins_readme(NameVsn, Options, Info0),
     plugin_status(NameVsn, Info1).
 
 read_plugin_avsc(NameVsn) ->
+    read_plugin_avsc(NameVsn, #{read_mode => ?JSON_MAP}).
+read_plugin_avsc(NameVsn, Options) ->
     tryit(
         atom_to_list(?FUNCTION_NAME),
-        read_file_fun(schema_file(NameVsn), "bad_avsc_file")
+        read_file_fun(avsc_file_path(NameVsn), "bad_avsc_file", Options)
     ).
 
 read_plugin_i18n(NameVsn) ->
+    read_plugin_i18n(NameVsn, #{read_mode => ?JSON_MAP}).
+read_plugin_i18n(NameVsn, Options) ->
     tryit(
         atom_to_list(?FUNCTION_NAME),
-        read_file_fun(i18n_file(NameVsn), "bad_i18n_file")
+        read_file_fun(i18n_file_path(NameVsn), "bad_i18n_file", Options)
     ).
 
 read_plugin_avro(NameVsn) ->
+    read_plugin_avro(NameVsn, #{read_mode => ?RAW_BIN}).
+read_plugin_avro(NameVsn, Options) ->
     tryit(
         atom_to_list(?FUNCTION_NAME),
-        read_file_fun(schema_file(NameVsn), "bad_avro_file")
+        read_file_fun(avro_config_file(NameVsn), "bad_avro_file", Options)
     ).
 
 ensure_exists_and_installed(NameVsn) ->
@@ -1000,15 +1008,22 @@ maybe_post_op_after_install(NameVsn) ->
     ok.
 
 maybe_load_config_schema(NameVsn) ->
-    case read_plugin_avsc(NameVsn) of
-        {ok, Avsc} ->
-            case emqx_plugins_serde:add_schema(NameVsn, Avsc) of
+    filelib:is_regular(avsc_file_path(NameVsn)) andalso
+        do_load_config_schema(NameVsn).
+
+do_load_config_schema(NameVsn) ->
+    case read_plugin_avsc(NameVsn, #{read_mode => ?RAW_BIN}) of
+        {ok, AvscBin} ->
+            case emqx_plugins_serde:add_schema(NameVsn, AvscBin) of
                 ok -> ok;
                 {error, already_exists} -> ok;
-                {error, Reason} -> {error, Reason}
+                {error, _Reason} -> ok
             end;
         {error, Reason} ->
-            ?SLOG(warning, Reason)
+            ?SLOG(warning, #{
+                msg => "failed_to_read_plugin_avsc", reason => Reason, name_vsn => NameVsn
+            }),
+            ok
     end.
 
 maybe_create_config_dir(NameVsn) ->
@@ -1020,14 +1035,23 @@ maybe_create_config_dir(NameVsn) ->
 write_avro_bin(NameVsn, AvroBin) ->
     ok = file:write_file(avro_config_file(NameVsn), AvroBin).
 
-read_file_fun(Path, ErrMsg) ->
+read_file_fun(Path, ErrMsg, #{read_mode := ?RAW_BIN}) ->
+    fun() ->
+        case file:read_file(Path) of
+            {ok, Bin} ->
+                {ok, Bin};
+            {error, Reason} ->
+                ErrMeta = #{error_msg => ErrMsg, reason => Reason},
+                throw(ErrMeta)
+        end
+    end;
+read_file_fun(Path, ErrMsg, #{read_mode := ?JSON_MAP}) ->
     fun() ->
         case hocon:load(Path, #{format => richmap}) of
             {ok, RichMap} ->
                 {ok, hocon_maps:ensure_plain(RichMap)};
             {error, Reason} ->
                 ErrMeta = #{error_msg => ErrMsg, reason => Reason},
-                ?SLOG(warning, ErrMeta),
                 throw(ErrMeta)
         end
     end.
@@ -1043,16 +1067,16 @@ plugin_config_dir(NameVsn) ->
 pkg_file(NameVsn) ->
     filename:join([install_dir(), bin([NameVsn, ".tar.gz"])]).
 
-info_file(NameVsn) ->
+info_file_path(NameVsn) ->
     filename:join([plugin_dir(NameVsn), "release.json"]).
 
-schema_file(NameVsn) ->
+avsc_file_path(NameVsn) ->
     filename:join([plugin_dir(NameVsn), "config_schema.avsc"]).
 
 avro_config_file(NameVsn) ->
     filename:join([plugin_config_dir(NameVsn), "config.avro"]).
 
-i18n_file(NameVsn) ->
+i18n_file_path(NameVsn) ->
     filename:join([plugin_dir(NameVsn), "i18n.json"]).
 
 readme_file(NameVsn) ->

+ 2 - 2
apps/emqx_plugins/src/emqx_plugins_serde.erl

@@ -79,7 +79,7 @@ add_schema(Name, Avsc) ->
     end.
 
 get_schema(NameVsn) ->
-    Path = emqx_plugins:schema_file(NameVsn),
+    Path = emqx_plugins:avsc_file_path(NameVsn),
     case read_avsc_file(Path) of
         {ok, Avsc} ->
             {ok, Avsc};
@@ -129,7 +129,7 @@ handle_continue({build_serdes, SchemasMap}, State) ->
     _ = build_serdes(SchemasMap),
     {noreply, State}.
 
-handle_call({build_serdes, {NameVsn, Avsc}}, _From, State) ->
+handle_call({build_serdes, NameVsn, Avsc}, _From, State) ->
     BuildRes = do_build_serde(NameVsn, Avsc),
     {reply, BuildRes, State};
 handle_call(_Call, _From, State) ->

+ 3 - 3
apps/emqx_plugins/test/emqx_plugins_tests.erl

@@ -49,7 +49,7 @@ read_plugin_test() ->
     with_rand_install_dir(
         fun(_Dir) ->
             NameVsn = "bar-5",
-            InfoFile = emqx_plugins:info_file(NameVsn),
+            InfoFile = emqx_plugins:info_file_path(NameVsn),
             FakeInfo =
                 "name=bar, rel_vsn=\"5\", rel_apps=[justname_no_vsn],"
                 "description=\"desc bar\"",
@@ -90,7 +90,7 @@ delete_package_test() ->
     meck_emqx(),
     with_rand_install_dir(
         fun(_Dir) ->
-            File = emqx_plugins:pkg_file("a-1"),
+            File = emqx_plugins:pkg_file_path("a-1"),
             ok = write_file(File, "a"),
             ok = emqx_plugins:delete_package("a-1"),
             %% delete again should be ok
@@ -108,7 +108,7 @@ purge_test() ->
     meck_emqx(),
     with_rand_install_dir(
         fun(_Dir) ->
-            File = emqx_plugins:info_file("a-1"),
+            File = emqx_plugins:info_file_path("a-1"),
             Dir = emqx_plugins:plugin_dir("a-1"),
             ok = filelib:ensure_dir(File),
             ?assertMatch({ok, _}, file:read_file_info(Dir)),