Просмотр исходного кода

refactor: stop i18n support in hotconf and bridges

frontend team has decided to deal with translations all by themselves
Zaiming (Stone) Shi 2 лет назад
Родитель
Сommit
28a68a0ec7

+ 13 - 51
apps/emqx_conf/src/emqx_conf.erl

@@ -31,8 +31,9 @@
 
 %% TODO: move to emqx_dashboard when we stop building api schema at build time
 -export([
-    hotconf_schema_json/1,
-    bridge_schema_json/1
+    hotconf_schema_json/0,
+    bridge_schema_json/0,
+    hocon_schema_to_spec/2
 ]).
 
 %% for rpc
@@ -184,13 +185,13 @@ gen_api_schema_json(Dir, Lang) ->
 %% TODO: delete this function when we stop generating this JSON at build time.
 gen_api_schema_json_hotconf(Dir, Lang) ->
     File = schema_filename(Dir, "hot-config-schema-", Lang),
-    IoData = hotconf_schema_json(Lang),
+    IoData = hotconf_schema_json(),
     ok = write_api_schema_json_file(File, IoData).
 
 %% TODO: delete this function when we stop generating this JSON at build time.
 gen_api_schema_json_bridge(Dir, Lang) ->
     File = schema_filename(Dir, "bridge-api-", Lang),
-    IoData = bridge_schema_json(Lang),
+    IoData = bridge_schema_json(),
     ok = write_api_schema_json_file(File, IoData).
 
 %% TODO: delete this function when we stop generating this JSON at build time.
@@ -199,14 +200,14 @@ write_api_schema_json_file(File, IoData) ->
     file:write_file(File, IoData).
 
 %% TODO: move this function to emqx_dashboard when we stop generating this JSON at build time.
-hotconf_schema_json(Lang) ->
+hotconf_schema_json() ->
     SchemaInfo = #{title => <<"EMQX Hot Conf API Schema">>, version => <<"0.1.0">>},
-    gen_api_schema_json_iodata(emqx_mgmt_api_configs, SchemaInfo, Lang).
+    gen_api_schema_json_iodata(emqx_mgmt_api_configs, SchemaInfo).
 
 %% TODO: move this function to emqx_dashboard when we stop generating this JSON at build time.
-bridge_schema_json(Lang) ->
+bridge_schema_json() ->
     SchemaInfo = #{title => <<"EMQX Data Bridge API Schema">>, version => <<"0.1.0">>},
-    gen_api_schema_json_iodata(emqx_bridge_api, SchemaInfo, Lang).
+    gen_api_schema_json_iodata(emqx_bridge_api, SchemaInfo).
 
 schema_filename(Dir, Prefix, Lang) ->
     Filename = Prefix ++ Lang ++ ".json",
@@ -270,50 +271,11 @@ gen_example(File, SchemaModule) ->
     Example = hocon_schema_example:gen(SchemaModule, Opts),
     file:write_file(File, Example).
 
-%% TODO: move this to emqx_dashboard when we stop generating
-%% this JSON at build time.
-gen_api_schema_json_iodata(SchemaMod, SchemaInfo, Lang) ->
-    {ApiSpec0, Components0} = emqx_dashboard_swagger:spec(
+gen_api_schema_json_iodata(SchemaMod, SchemaInfo) ->
+    emqx_dashboard_swagger:gen_api_schema_json_iodata(
         SchemaMod,
-        #{
-            schema_converter => fun hocon_schema_to_spec/2,
-            i18n_lang => Lang
-        }
-    ),
-    ApiSpec = lists:foldl(
-        fun({Path, Spec, _, _}, Acc) ->
-            NewSpec = maps:fold(
-                fun(Method, #{responses := Responses}, SubAcc) ->
-                    case Responses of
-                        #{
-                            <<"200">> :=
-                                #{
-                                    <<"content">> := #{
-                                        <<"application/json">> := #{<<"schema">> := Schema}
-                                    }
-                                }
-                        } ->
-                            SubAcc#{Method => Schema};
-                        _ ->
-                            SubAcc
-                    end
-                end,
-                #{},
-                Spec
-            ),
-            Acc#{list_to_atom(Path) => NewSpec}
-        end,
-        #{},
-        ApiSpec0
-    ),
-    Components = lists:foldl(fun(M, Acc) -> maps:merge(M, Acc) end, #{}, Components0),
-    emqx_utils_json:encode(
-        #{
-            info => SchemaInfo,
-            paths => ApiSpec,
-            components => #{schemas => Components}
-        },
-        [pretty, force_utf8]
+        SchemaInfo,
+        fun ?MODULE:hocon_schema_to_spec/2
     ).
 
 -define(TO_REF(_N_, _F_), iolist_to_binary([to_bin(_N_), ".", to_bin(_F_)])).

+ 8 - 16
apps/emqx_dashboard/src/emqx_dashboard_schema_api.erl

@@ -45,18 +45,11 @@ schema("/schemas/:name") ->
         'operationId' => get_schema,
         get => #{
             parameters => [
-                {name, hoconsc:mk(hoconsc:enum([hotconf, bridges]), #{in => path})},
-                {lang,
-                    hoconsc:mk(typerefl:string(), #{
-                        in => query,
-                        default => <<"en">>,
-                        desc => <<"The language of the schema.">>
-                    })}
+                {name, hoconsc:mk(hoconsc:enum([hotconf, bridges]), #{in => path})}
             ],
             desc => <<
                 "Get the schema JSON of the specified name. "
-                "NOTE: you should never need to make use of this API "
-                "unless you are building a multi-lang dashboaard."
+                "NOTE: only intended for EMQX Dashboard."
             >>,
             tags => ?TAGS,
             security => [],
@@ -71,14 +64,13 @@ schema("/schemas/:name") ->
 %%--------------------------------------------------------------------
 
 get_schema(get, #{
-    bindings := #{name := Name},
-    query_string := #{<<"lang">> := Lang}
+    bindings := #{name := Name}
 }) ->
-    {200, gen_schema(Name, iolist_to_binary(Lang))};
+    {200, gen_schema(Name)};
 get_schema(get, _) ->
     {400, ?BAD_REQUEST, <<"unknown">>}.
 
-gen_schema(hotconf, Lang) ->
-    emqx_conf:hotconf_schema_json(Lang);
-gen_schema(bridges, Lang) ->
-    emqx_conf:bridge_schema_json(Lang).
+gen_schema(hotconf) ->
+    emqx_conf:hotconf_schema_json();
+gen_schema(bridges) ->
+    emqx_conf:bridge_schema_json().

+ 67 - 1
apps/emqx_dashboard/src/emqx_dashboard_swagger.erl

@@ -26,7 +26,11 @@
 -export([error_codes/1, error_codes/2]).
 -export([file_schema/1]).
 
--export([filter_check_request/2, filter_check_request_and_translate_body/2]).
+-export([
+    filter_check_request/2,
+    filter_check_request_and_translate_body/2,
+    gen_api_schema_json_iodata/3
+]).
 
 -ifdef(TEST).
 -export([
@@ -72,6 +76,8 @@
     ])
 ).
 
+-define(SPECIAL_LANG_MSGID, <<"$msgid">>).
+
 -define(MAX_ROW_LIMIT, 1000).
 -define(DEFAULT_ROW, 100).
 
@@ -192,6 +198,50 @@ file_schema(FileName) ->
         }
     }.
 
+gen_api_schema_json_iodata(SchemaMod, SchemaInfo, Converter) ->
+    {ApiSpec0, Components0} = emqx_dashboard_swagger:spec(
+        SchemaMod,
+        #{
+            schema_converter => Converter,
+            i18n_lang => ?SPECIAL_LANG_MSGID
+        }
+    ),
+    ApiSpec = lists:foldl(
+        fun({Path, Spec, _, _}, Acc) ->
+            NewSpec = maps:fold(
+                fun(Method, #{responses := Responses}, SubAcc) ->
+                    case Responses of
+                        #{
+                            <<"200">> :=
+                                #{
+                                    <<"content">> := #{
+                                        <<"application/json">> := #{<<"schema">> := Schema}
+                                    }
+                                }
+                        } ->
+                            SubAcc#{Method => Schema};
+                        _ ->
+                            SubAcc
+                    end
+                end,
+                #{},
+                Spec
+            ),
+            Acc#{list_to_atom(Path) => NewSpec}
+        end,
+        #{},
+        ApiSpec0
+    ),
+    Components = lists:foldl(fun(M, Acc) -> maps:merge(M, Acc) end, #{}, Components0),
+    emqx_utils_json:encode(
+        #{
+            info => SchemaInfo,
+            paths => ApiSpec,
+            components => #{schemas => Components}
+        },
+        [pretty, force_utf8]
+    ).
+
 %%------------------------------------------------------------------------------
 %% Private functions
 %%------------------------------------------------------------------------------
@@ -482,6 +532,14 @@ maybe_add_summary_from_label(Spec, Hocon, Options) ->
 
 get_i18n(Tag, ?DESC(Namespace, Id), Default, Options) ->
     Lang = get_lang(Options),
+    case Lang of
+        ?SPECIAL_LANG_MSGID ->
+            make_msgid(Namespace, Id, Tag);
+        _ ->
+            get_i18n_text(Lang, Namespace, Id, Tag, Default)
+    end.
+
+get_i18n_text(Lang, Namespace, Id, Tag, Default) ->
     case emqx_dashboard_desc_cache:lookup(Lang, Namespace, Id, Tag) of
         undefined ->
             Default;
@@ -489,6 +547,14 @@ get_i18n(Tag, ?DESC(Namespace, Id), Default, Options) ->
             Text
     end.
 
+%% Format:$msgid:Namespace.Id.Tag
+%% e.g. $msgid:emqx_schema.key.desc
+%%      $msgid:emqx_schema.key.label
+%% if needed, the consumer of this schema JSON can use this msgid to
+%% resolve the text in the i18n database.
+make_msgid(Namespace, Id, Tag) ->
+    iolist_to_binary(["$msgid:", to_bin(Namespace), ".", to_bin(Id), ".", Tag]).
+
 %% So far i18n_lang in options is only used at build time.
 %% At runtime, it's still the global config which controls the language.
 get_lang(#{i18n_lang := Lang}) -> Lang;