diff --git a/apps/emqx/rebar.config b/apps/emqx/rebar.config index 0ee94328b..271558f6d 100644 --- a/apps/emqx/rebar.config +++ b/apps/emqx/rebar.config @@ -28,7 +28,7 @@ [{deps, [ meck , {bbmustache,"1.10.0"} - , {emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers.git", {branch,"hocon"}}} + , {emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers.git", {tag,"2.1.0"}}} , {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.4.3"}}} ]}, {extra_src_dirs, [{"test",[recursive]}]} diff --git a/apps/emqx/src/emqx_config.erl b/apps/emqx/src/emqx_config.erl index e995f1d74..2f5bc9551 100644 --- a/apps/emqx/src/emqx_config.erl +++ b/apps/emqx/src/emqx_config.erl @@ -298,10 +298,11 @@ read_override_conf() -> -spec save_schema_mod_and_names(module()) -> ok. save_schema_mod_and_names(SchemaMod) -> - RootNames = SchemaMod:structs(), + RootNames = hocon_schema:root_names(SchemaMod), OldMods = get_schema_mod(), OldNames = get_root_names(), - NewMods = maps:from_list([{root_bin(Name), SchemaMod} || Name <- RootNames]), + %% map from root name to schema module name + NewMods = maps:from_list([{Name, SchemaMod} || Name <- RootNames]), persistent_term:put(?PERSIS_SCHEMA_MODS, #{ mods => maps:merge(OldMods, NewMods), names => lists:usort(OldNames ++ RootNames) @@ -442,6 +443,3 @@ conf_key(?CONF, RootName) -> atom(RootName); conf_key(?RAW_CONF, RootName) -> bin(RootName). - -root_bin({array, Bin}) -> bin(Bin); -root_bin(Bin) -> bin(Bin). diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 34a63534d..7d1e39510 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -65,14 +65,15 @@ cipher/0, comma_separated_atoms/0]). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -export([t/1, t/3, t/4, ref/1]). -export([conf_get/2, conf_get/3, keys/2, filter/1]). -export([ssl/1]). -structs() -> ["zones", "mqtt", "flapping_detect", "force_shutdown", "force_gc", - "conn_congestion", "rate_limit", "quota", "listeners", "broker", "plugins", - "stats", "sysmon", "alarm", "authorization"]. +roots() -> + ["zones", "mqtt", "flapping_detect", "force_shutdown", "force_gc", + "conn_congestion", "rate_limit", "quota", "listeners", "broker", "plugins", + "stats", "sysmon", "alarm", "authorization"]. fields("stats") -> [ {"enable", t(boolean(), undefined, true)} diff --git a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl b/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl index fab74b5e8..8e333a3e0 100644 --- a/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl +++ b/apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/src/emqx_hocon_plugin_schema.erl @@ -2,11 +2,11 @@ -include_lib("typerefl/include/types.hrl"). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -behaviour(hocon_schema). -structs() -> ["emqx_hocon_plugin"]. +roots() -> ["emqx_hocon_plugin"]. fields("emqx_hocon_plugin") -> [{name, fun name/1}]. diff --git a/apps/emqx_authn/src/emqx_authn_schema.erl b/apps/emqx_authn/src/emqx_authn_schema.erl index 6a834df1f..de0de9fcc 100644 --- a/apps/emqx_authn/src/emqx_authn_schema.erl +++ b/apps/emqx_authn/src/emqx_authn_schema.erl @@ -21,7 +21,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -32,7 +32,7 @@ -export([ authenticators/1 ]). -structs() -> [ "authentication" ]. +roots() -> [ "authentication" ]. fields("authentication") -> [ {enable, fun enable/1} diff --git a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl b/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl index f4fede9f5..0ca281aa0 100644 --- a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl +++ b/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl @@ -21,7 +21,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -74,7 +74,7 @@ mnesia(copy) -> %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [config]. +roots() -> [config]. fields(config) -> [ {name, fun emqx_authn_schema:authenticator_name/1} diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl index 43af1d9b4..c5cbc0f02 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl @@ -22,7 +22,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 , validations/0 ]). @@ -37,13 +37,11 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [""]. - -fields("") -> +roots() -> [ {config, {union, [ hoconsc:t(get) , hoconsc:t(post) ]}} - ]; + ]. fields(get) -> [ {method, #{type => get, diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl index 74aa9e8f6..bc26bf70e 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl @@ -20,7 +20,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -34,14 +34,12 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [""]. - -fields("") -> +roots() -> [ {config, {union, [ hoconsc:t('hmac-based') , hoconsc:t('public-key') , hoconsc:t('jwks') ]}} - ]; + ]. fields('hmac-based') -> [ {use_jwks, {enum, [false]}} diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl index 9bbf3239c..c525efbf1 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl @@ -21,7 +21,7 @@ -behaviour(hocon_schema). --export([ structs/0, fields/1 ]). +-export([ roots/0, fields/1 ]). -export([ create/1 , update/2 @@ -79,7 +79,7 @@ mnesia(copy) -> %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [config]. +roots() -> [config]. fields(config) -> [ {name, fun emqx_authn_schema:authenticator_name/1} @@ -391,4 +391,4 @@ to_binary(L) when is_list(L) -> iolist_to_binary(L). serialize_user_info(#user_info{user_id = {_, UserID}, superuser = Superuser}) -> - #{user_id => UserID, superuser => Superuser}. \ No newline at end of file + #{user_id => UserID, superuser => Superuser}. diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl index 1ce145f35..11411b70f 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl @@ -22,7 +22,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -36,14 +36,12 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [""]. - -fields("") -> +roots() -> [ {config, {union, [ hoconsc:t(standalone) , hoconsc:t('replica-set') , hoconsc:t('sharded-cluster') ]}} - ]; + ]. fields(standalone) -> common_fields() ++ emqx_connector_mongo:fields(single); diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl index 59afa9671..3cafdb94e 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl @@ -22,7 +22,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -36,7 +36,7 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [config]. +roots() -> [config]. fields(config) -> [ {name, fun emqx_authn_schema:authenticator_name/1} diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl index cce9ebd6f..5c21d3d6c 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl @@ -23,7 +23,7 @@ -behaviour(hocon_schema). --export([ structs/0, fields/1 ]). +-export([ roots/0, fields/1 ]). -export([ create/1 , update/2 @@ -35,7 +35,7 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [config]. +roots() -> [config]. fields(config) -> [ {name, fun emqx_authn_schema:authenticator_name/1} diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl index 6eff345ed..1b090b007 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl @@ -22,7 +22,7 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1 ]). @@ -36,14 +36,12 @@ %% Hocon Schema %%------------------------------------------------------------------------------ -structs() -> [""]. - -fields("") -> +roots() -> [ {config, {union, [ hoconsc:t(standalone) , hoconsc:t(cluster) , hoconsc:t(sentinel) ]}} - ]; + ]. fields(standalone) -> common_fields() ++ emqx_connector_redis:fields(single); diff --git a/apps/emqx_authz/src/emqx_authz_schema.erl b/apps/emqx_authz/src/emqx_authz_schema.erl index 64ef09601..7fb60bae2 100644 --- a/apps/emqx_authz/src/emqx_authz_schema.erl +++ b/apps/emqx_authz/src/emqx_authz_schema.erl @@ -13,11 +13,11 @@ -type permission() :: allow | deny. -type url() :: emqx_http_lib:uri_map(). --export([ structs/0 +-export([ roots/0 , fields/1 ]). -structs() -> ["authorization"]. +roots() -> ["authorization"]. fields("authorization") -> [ {sources, sources()} @@ -180,4 +180,4 @@ connector_fields(DB) -> [ {type, #{type => DB}} , {enable, #{type => boolean(), default => true}} - ] ++ Mod:fields(""). + ] ++ Mod:roots(). diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl index c3621f3a4..73ae262a1 100644 --- a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl @@ -19,10 +19,10 @@ -include_lib("typerefl/include/types.hrl"). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> +roots() -> ["auto_subscribe"]. fields("auto_subscribe") -> diff --git a/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_schema.erl b/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_schema.erl index 02078fac0..925bfa403 100644 --- a/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_schema.erl +++ b/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_schema.erl @@ -20,10 +20,12 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> [{array, "bridge_mqtt"}]. +roots() -> [array("bridge_mqtt")]. + +array(Name) -> {Name, hoconsc:array(hoconsc:ref(Name))}. fields("bridge_mqtt") -> [ {name, emqx_schema:t(string(), undefined, true)} diff --git a/apps/emqx_connector/src/emqx_connector_http.erl b/apps/emqx_connector/src/emqx_connector_http.erl index 11860f32d..572b2a4e8 100644 --- a/apps/emqx_connector/src/emqx_connector_http.erl +++ b/apps/emqx_connector/src/emqx_connector_http.erl @@ -32,7 +32,7 @@ -reflect_type([url/0]). -typerefl_from_string({url/0, emqx_http_lib, uri_parse}). --export([ structs/0 +-export([ roots/0 , fields/1 , validations/0]). @@ -47,10 +47,8 @@ %%===================================================================== %% Hocon schema -structs() -> [""]. - -fields("") -> - [{config, #{type => hoconsc:ref(?MODULE, config)}}]; +roots() -> + [{config, #{type => hoconsc:ref(?MODULE, config)}}]. fields(config) -> [ {base_url, fun base_url/1} diff --git a/apps/emqx_connector/src/emqx_connector_ldap.erl b/apps/emqx_connector/src/emqx_connector_ldap.erl index 8c0504d53..fadf7f56f 100644 --- a/apps/emqx_connector/src/emqx_connector_ldap.erl +++ b/apps/emqx_connector/src/emqx_connector_ldap.erl @@ -19,7 +19,7 @@ -include_lib("typerefl/include/types.hrl"). -include_lib("emqx_resource/include/emqx_resource_behaviour.hrl"). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). %% callbacks of behaviour emqx_resource -export([ on_start/2 @@ -35,11 +35,11 @@ -export([search/4]). %%===================================================================== -structs() -> [""]. +roots() -> + ldap_fields() ++ emqx_connector_schema_lib:ssl_fields(). -fields("") -> - ldap_fields() ++ - emqx_connector_schema_lib:ssl_fields(). +%% this schema has no sub-structs +fields(_) -> []. on_jsonify(Config) -> Config. diff --git a/apps/emqx_connector/src/emqx_connector_mongo.erl b/apps/emqx_connector/src/emqx_connector_mongo.erl index c4953c3fb..88dfb2b72 100644 --- a/apps/emqx_connector/src/emqx_connector_mongo.erl +++ b/apps/emqx_connector/src/emqx_connector_mongo.erl @@ -33,19 +33,18 @@ -export([connect/1]). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -export([mongo_query/5]). %%===================================================================== -structs() -> [""]. - -fields("") -> +roots() -> [ {config, #{type => hoconsc:union( [ hoconsc:ref(?MODULE, single) , hoconsc:ref(?MODULE, rs) , hoconsc:ref(?MODULE, sharded) ])}} - ]; + ]. + fields(single) -> [ {mongo_type, #{type => single, default => single}} diff --git a/apps/emqx_connector/src/emqx_connector_mysql.erl b/apps/emqx_connector/src/emqx_connector_mysql.erl index 6a5d93ca2..9dc194c55 100644 --- a/apps/emqx_connector/src/emqx_connector_mysql.erl +++ b/apps/emqx_connector/src/emqx_connector_mysql.erl @@ -28,16 +28,14 @@ -export([connect/1]). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -export([do_health_check/1]). %%===================================================================== %% Hocon schema -structs() -> [""]. - -fields("") -> - [{config, #{type => hoconsc:ref(?MODULE, config)}}]; +roots() -> + [{config, #{type => hoconsc:ref(?MODULE, config)}}]. fields(config) -> emqx_connector_schema_lib:relational_db_fields() ++ diff --git a/apps/emqx_connector/src/emqx_connector_pgsql.erl b/apps/emqx_connector/src/emqx_connector_pgsql.erl index e89ab7401..8472c661e 100644 --- a/apps/emqx_connector/src/emqx_connector_pgsql.erl +++ b/apps/emqx_connector/src/emqx_connector_pgsql.erl @@ -18,7 +18,7 @@ -include_lib("typerefl/include/types.hrl"). -include_lib("emqx_resource/include/emqx_resource_behaviour.hrl"). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). %% callbacks of behaviour emqx_resource -export([ on_start/2 @@ -35,10 +35,9 @@ -export([do_health_check/1]). %%===================================================================== -structs() -> [""]. -fields("") -> - [{config, #{type => hoconsc:ref(?MODULE, config)}}]; +roots() -> + [{config, #{type => hoconsc:ref(?MODULE, config)}}]. fields(config) -> emqx_connector_schema_lib:relational_db_fields() ++ diff --git a/apps/emqx_connector/src/emqx_connector_redis.erl b/apps/emqx_connector/src/emqx_connector_redis.erl index 60087188f..4fe26381e 100644 --- a/apps/emqx_connector/src/emqx_connector_redis.erl +++ b/apps/emqx_connector/src/emqx_connector_redis.erl @@ -23,7 +23,7 @@ -reflect_type([server/0]). -typerefl_from_string({server/0, emqx_connector_schema_lib, to_ip_port}). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). %% callbacks of behaviour emqx_resource -export([ on_start/2 @@ -40,16 +40,15 @@ -export([cmd/3]). %%===================================================================== -structs() -> [""]. - -fields("") -> +roots() -> [ {config, #{type => hoconsc:union( [ hoconsc:ref(?MODULE, cluster) , hoconsc:ref(?MODULE, single) , hoconsc:ref(?MODULE, sentinel) ])} } - ]; + ]. + fields(single) -> [ {server, #{type => server()}} , {redis_type, #{type => hoconsc:enum([single]), diff --git a/apps/emqx_connector/src/emqx_connector_schema_lib.erl b/apps/emqx_connector/src/emqx_connector_schema_lib.erl index d0b314077..5f9472cca 100644 --- a/apps/emqx_connector/src/emqx_connector_schema_lib.erl +++ b/apps/emqx_connector/src/emqx_connector_schema_lib.erl @@ -51,9 +51,9 @@ , servers/0 ]). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -structs() -> [ssl_on, ssl_off]. +roots() -> [ssl_on, ssl_off]. fields(ssl_on) -> [ {enable, #{type => true}} diff --git a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl index 018061ff6..e0ff21ada 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl @@ -17,10 +17,10 @@ -include_lib("typerefl/include/types.hrl"). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> ["emqx_dashboard"]. +roots() -> ["emqx_dashboard"]. fields("emqx_dashboard") -> [ {listeners, hoconsc:array(hoconsc:union([hoconsc:ref(?MODULE, "http"), diff --git a/apps/emqx_data_bridge/src/emqx_data_bridge_schema.erl b/apps/emqx_data_bridge/src/emqx_data_bridge_schema.erl index 066d72096..69f53d6c1 100644 --- a/apps/emqx_data_bridge/src/emqx_data_bridge_schema.erl +++ b/apps/emqx_data_bridge/src/emqx_data_bridge_schema.erl @@ -1,6 +1,6 @@ -module(emqx_data_bridge_schema). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). %%====================================================================================== %% Hocon Schema Definitions @@ -8,7 +8,7 @@ -define(TYPES, [mysql, pgsql, mongo, redis, ldap]). -define(BRIDGES, [hoconsc:ref(?MODULE, T) || T <- ?TYPES]). -structs() -> ["emqx_data_bridge"]. +roots() -> ["emqx_data_bridge"]. fields("emqx_data_bridge") -> [{bridges, #{type => hoconsc:array(hoconsc:union(?BRIDGES)), @@ -23,4 +23,4 @@ fields(ldap) -> connector_fields(ldap). connector_fields(DB) -> Mod = list_to_existing_atom(io_lib:format("~s_~s",[emqx_connector, DB])), [{name, hoconsc:t(typerefl:binary())}, - {type, #{type => DB}}] ++ Mod:fields(""). + {type, #{type => DB}}] ++ Mod:roots(). diff --git a/apps/emqx_exhook/src/emqx_exhook_schema.erl b/apps/emqx_exhook/src/emqx_exhook_schema.erl index 852a210fe..16fd93fa0 100644 --- a/apps/emqx_exhook/src/emqx_exhook_schema.erl +++ b/apps/emqx_exhook/src/emqx_exhook_schema.erl @@ -32,11 +32,11 @@ -reflect_type([duration/0]). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -export([t/1, t/3, t/4, ref/1]). -structs() -> [exhook]. +roots() -> [exhook]. fields(exhook) -> [ {request_failed_action, t(union([deny, ignore]), undefined, deny)} diff --git a/apps/emqx_gateway/src/emqx_gateway_schema.erl b/apps/emqx_gateway/src/emqx_gateway_schema.erl index 8db75e504..9371f8c6b 100644 --- a/apps/emqx_gateway/src/emqx_gateway_schema.erl +++ b/apps/emqx_gateway/src/emqx_gateway_schema.erl @@ -43,14 +43,10 @@ , ip_port/0 ]). --export([structs/0 , fields/1]). - +-export([roots/0 , fields/1]). -export([t/1, t/3, t/4, ref/1]). -%%-------------------------------------------------------------------- -%% Structs - -structs() -> [gateway]. +roots() -> [gateway]. fields(gateway) -> [{stomp, t(ref(stomp_structs))}, diff --git a/apps/emqx_machine/src/emqx_machine_schema.erl b/apps/emqx_machine/src/emqx_machine_schema.erl index ee8cc4978..c25ab8139 100644 --- a/apps/emqx_machine/src/emqx_machine_schema.erl +++ b/apps/emqx_machine/src/emqx_machine_schema.erl @@ -34,7 +34,7 @@ file/0, cipher/0]). --export([structs/0, fields/1, translations/0, translation/1]). +-export([roots/0, fields/1, translations/0, translation/1]). -export([t/1, t/3, t/4, ref/1]). -export([conf_get/2, conf_get/3, keys/2, filter/1]). @@ -59,9 +59,9 @@ ]). %% TODO: add a test case to ensure the list elements are unique -structs() -> +roots() -> ["cluster", "node", "rpc", "log"] - ++ lists:flatmap(fun(Mod) -> Mod:structs() end, ?MERGED_CONFIGS). + ++ lists:flatmap(fun(Mod) -> Mod:roots() end, ?MERGED_CONFIGS). fields("cluster") -> [ {"name", t(atom(), "ekka.cluster_name", emqxcl)} @@ -215,8 +215,7 @@ fields(Name) -> find_field(Name, []) -> error({unknown_config_struct_field, Name}); find_field(Name, [SchemaModule | Rest]) -> - case lists:member(Name, SchemaModule:structs()) orelse - lists:keymember(Name, 2, SchemaModule:structs()) of + case lists:member(bin(Name), hocon_schema:root_names(SchemaModule)) of true -> SchemaModule:fields(Name); false -> find_field(Name, Rest) end. @@ -475,3 +474,7 @@ to_atom(Str) when is_list(Str) -> list_to_atom(Str); to_atom(Bin) when is_binary(Bin) -> binary_to_atom(Bin, utf8). + +bin(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8); +bin(Bin) when is_binary(Bin) -> Bin; +bin(L) when is_list(L) -> iolist_to_binary(L). diff --git a/apps/emqx_management/src/emqx_management_schema.erl b/apps/emqx_management/src/emqx_management_schema.erl index a0da91d86..d21f0e106 100644 --- a/apps/emqx_management/src/emqx_management_schema.erl +++ b/apps/emqx_management/src/emqx_management_schema.erl @@ -19,9 +19,9 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> []. +roots() -> []. fields(_) -> []. diff --git a/apps/emqx_modules/src/emqx_modules_schema.erl b/apps/emqx_modules/src/emqx_modules_schema.erl index 695db972f..7a6b72a8a 100644 --- a/apps/emqx_modules/src/emqx_modules_schema.erl +++ b/apps/emqx_modules/src/emqx_modules_schema.erl @@ -20,16 +20,16 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> +roots() -> ["delayed", "recon", "telemetry", "event_message", - {array, "rewrite"}, - {array, "topic_metrics"}]. + array("rewrite"), + array("topic_metrics")]. fields(Name) when Name =:= "recon"; Name =:= "telemetry" -> @@ -61,3 +61,4 @@ fields("event_message") -> fields("topic_metrics") -> [{topic, emqx_schema:t(binary())}]. +array(Name) -> {Name, hoconsc:array(hoconsc:ref(Name))}. diff --git a/apps/emqx_prometheus/src/emqx_prometheus_schema.erl b/apps/emqx_prometheus/src/emqx_prometheus_schema.erl index fa41154d3..47630b58d 100644 --- a/apps/emqx_prometheus/src/emqx_prometheus_schema.erl +++ b/apps/emqx_prometheus/src/emqx_prometheus_schema.erl @@ -19,10 +19,10 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> ["prometheus"]. +roots() -> ["prometheus"]. fields("prometheus") -> [ {push_gateway_server, emqx_schema:t(string())} diff --git a/apps/emqx_retainer/src/emqx_retainer_schema.erl b/apps/emqx_retainer/src/emqx_retainer_schema.erl index df31f647f..e2acc7fe7 100644 --- a/apps/emqx_retainer/src/emqx_retainer_schema.erl +++ b/apps/emqx_retainer/src/emqx_retainer_schema.erl @@ -2,11 +2,11 @@ -include_lib("typerefl/include/types.hrl"). --export([structs/0, fields/1]). +-export([roots/0, fields/1]). -define(TYPE(Type), hoconsc:t(Type)). -structs() -> ["emqx_retainer"]. +roots() -> ["emqx_retainer"]. fields("emqx_retainer") -> [ {enable, t(boolean(), false)} diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl index f7658c208..a9646ae1e 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl @@ -20,10 +20,10 @@ -behaviour(hocon_schema). --export([ structs/0 +-export([ roots/0 , fields/1]). -structs() -> ["emqx_rule_engine"]. +roots() -> ["emqx_rule_engine"]. fields("emqx_rule_engine") -> [{ignore_sys_message, emqx_schema:t(boolean(), undefined, true)}]. diff --git a/apps/emqx_statsd/src/emqx_statsd_schema.erl b/apps/emqx_statsd/src/emqx_statsd_schema.erl index 0e96c37d0..906f55a4c 100644 --- a/apps/emqx_statsd/src/emqx_statsd_schema.erl +++ b/apps/emqx_statsd/src/emqx_statsd_schema.erl @@ -6,12 +6,12 @@ -export([to_ip_port/1]). --export([ structs/0 +-export([ roots/0 , fields/1]). -typerefl_from_string({ip_port/0, emqx_statsd_schema, to_ip_port}). -structs() -> ["statsd"]. +roots() -> ["statsd"]. fields("statsd") -> [ {enable, emqx_schema:t(boolean(), undefined, false)} diff --git a/rebar.config.erl b/rebar.config.erl index ad24e6479..aac6e0085 100644 --- a/rebar.config.erl +++ b/rebar.config.erl @@ -127,8 +127,7 @@ test_plugins() -> test_deps() -> [ {bbmustache, "1.10.0"} - %, {emqx_ct_helpers, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "2.0.0"}}} - , {emqx_ct_helpers, {git, "https://github.com/emqx/emqx-ct-helpers", {branch, "hocon"}}} + , {emqx_ct_helpers, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "2.1.0"}}} , meck ].