From b643741920fcad8eb3a87ec9542950c8cc12d43c Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Tue, 21 Nov 2023 20:30:21 +0100 Subject: [PATCH] feat: add a escript to help re-format older version schema dumps --- scripts/schema-dump-reformat.escript | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 scripts/schema-dump-reformat.escript diff --git a/scripts/schema-dump-reformat.escript b/scripts/schema-dump-reformat.escript new file mode 100755 index 000000000..31cfdd7d9 --- /dev/null +++ b/scripts/schema-dump-reformat.escript @@ -0,0 +1,132 @@ +#!/usr/bin/env escript + +%% This script translates the hocon_schema_json's schema dump to a new format. +%% It is used to convert older version EMQX's schema dumps to the new format +%% after all files are upgraded to the new format, this script can be removed. + +-mode(compile). + +main([Input]) -> + ok = add_libs(), + _ = atoms(), + {ok, Data} = file:read_file(Input), + Json = jsx:decode(Data), + NewJson = reformat(Json), + io:format("~s~n", [jsx:encode(NewJson)]); +main(_) -> + io:format("Usage: schema-dump-reformat.escript ~n"), + halt(1). + +reformat(Json) -> + emqx_conf:reformat_schema_dump(fix(Json)). + +%% fix old type specs to make them compatible with new type specs +fix(#{ + <<"kind">> := <<"union">>, + <<"members">> := [#{<<"name">> := <<"string()">>}, #{<<"name">> := <<"function()">>}] +}) -> + %% s3_exporter.secret_access_key + #{ + kind => primitive, + name => <<"string()">> + }; +fix(#{<<"kind">> := <<"primitive">>, <<"name">> := <<"emqx_conf_schema:log_level()">>}) -> + #{ + kind => enum, + symbols => [emergency, alert, critical, error, warning, notice, info, debug, none, all] + }; +fix(#{<<"kind">> := <<"primitive">>, <<"name">> := <<"emqx_connector_http:pool_type()">>}) -> + #{kind => enum, symbols => [random, hash]}; +fix(#{<<"kind">> := <<"primitive">>, <<"name">> := <<"emqx_bridge_http_connector:pool_type()">>}) -> + #{kind => enum, symbols => [random, hash]}; +fix(Map) when is_map(Map) -> + maps:from_list(fix(maps:to_list(Map))); +fix(List) when is_list(List) -> + lists:map(fun fix/1, List); +fix({<<"kind">>, Kind}) -> + {kind, binary_to_atom(Kind, utf8)}; +fix({<<"name">>, Type}) -> + {name, fix_type(Type)}; +fix({K, V}) -> + {binary_to_atom(K, utf8), fix(V)}; +fix(V) when is_number(V) -> + V; +fix(V) when is_atom(V) -> + V; +fix(V) when is_binary(V) -> + V. + +%% ensure below ebin dirs are added to code path: +%% _build/default/lib/*/ebin +%% _build/emqx/lib/*/ebin +%% _build/emqx-enterprise/lib/*/ebin +add_libs() -> + Profile = os:getenv("PROFILE"), + case Profile of + "emqx" -> + ok; + "emqx-enterprise" -> + ok; + _ -> + io:format("PROFILE is not set~n"), + halt(1) + end, + Dirs = + filelib:wildcard("_build/default/lib/*/ebin") ++ + filelib:wildcard("_build/" ++ Profile ++ "/lib/*/ebin"), + lists:foreach(fun add_lib/1, Dirs). + +add_lib(Dir) -> + code:add_patha(Dir), + Beams = filelib:wildcard(Dir ++ "/*.beam"), + _ = spawn(fun() -> lists:foreach(fun load_beam/1, Beams) end), + ok. + +load_beam(BeamFile) -> + ModuleName = filename:basename(BeamFile, ".beam"), + Module = list_to_atom(ModuleName), + %% load the beams to make sure the atoms are existing + code:ensure_loaded(Module), + ok. + +fix_type(<<"[{string(), string()}]">>) -> + <<"map()">>; +fix_type(<<"[{binary(), binary()}]">>) -> + <<"map()">>; +fix_type(<<"emqx_limiter_schema:rate()">>) -> + <<"string()">>; +fix_type(<<"emqx_limiter_schema:burst_rate()">>) -> + <<"string()">>; +fix_type(<<"emqx_limiter_schema:capacity()">>) -> + <<"string()">>; +fix_type(<<"emqx_limiter_schema:initial()">>) -> + <<"string()">>; +fix_type(<<"emqx_limiter_schema:failure_strategy()">>) -> + <<"string()">>; +fix_type(<<"emqx_conf_schema:file()">>) -> + <<"string()">>; +fix_type(<<"#{term() => binary()}">>) -> + <<"map()">>; +fix_type(<<"[term()]">>) -> + %% jwt claims + <<"map()">>; +fix_type(<<"emqx_ee_bridge_influxdb:write_syntax()">>) -> + <<"string()">>; +fix_type(<<"emqx_bridge_influxdb:write_syntax()">>) -> + <<"string()">>; +fix_type(<<"emqx_schema:mqtt_max_packet_size()">>) -> + <<"non_neg_integer()">>; +fix_type(<<"emqx_s3_schema:secret_access_key()">>) -> + <<"string()">>; +fix_type(Type) -> + Type. + +%% ensure atoms are loaded +%% these atoms are from older version of emqx +atoms() -> + [ + emqx_ee_connector_clickhouse, + emqx_ee_bridge_gcp_pubsub, + emqx_ee_bridge_influxdb, + emqx_connector_http + ].