Merge pull request #11907 from zmstone/1108-add-type-aliases

1108 add type aliases
This commit is contained in:
Zaiming (Stone) Shi 2023-11-10 15:16:16 +01:00 committed by GitHub
commit 64b4db1104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 297 additions and 187 deletions

View File

@ -30,7 +30,7 @@
{esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.7"}}},
{ekka, {git, "https://github.com/emqx/ekka", {tag, "0.15.16"}}},
{gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.2.1"}}},
{hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.39.19"}}},
{hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.40.0"}}},
{emqx_http_lib, {git, "https://github.com/emqx/emqx_http_lib.git", {tag, "0.5.3"}}},
{pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}},
{recon, {git, "https://github.com/ferd/recon", {tag, "2.5.1"}}},

View File

@ -33,7 +33,8 @@
desc/1,
types/0,
short_paths/0,
short_paths_fields/0
short_paths_fields/0,
rate_type/0
]).
-define(KILOBYTE, 1024).
@ -129,9 +130,9 @@ fields(limiter) ->
];
fields(node_opts) ->
[
{rate, ?HOCON(rate(), #{desc => deprecated_desc(rate), default => <<"infinity">>})},
{rate, ?HOCON(rate_type(), #{desc => deprecated_desc(rate), default => <<"infinity">>})},
{burst,
?HOCON(burst_rate(), #{
?HOCON(burst_rate_type(), #{
desc => deprecated_desc(burst),
default => <<"0">>
})}
@ -142,7 +143,7 @@ fields(bucket_opts) ->
fields_of_bucket(<<"infinity">>);
fields(client_opts) ->
[
{rate, ?HOCON(rate(), #{default => <<"infinity">>, desc => deprecated_desc(rate)})},
{rate, ?HOCON(rate_type(), #{default => <<"infinity">>, desc => deprecated_desc(rate)})},
{initial,
?HOCON(initial(), #{
default => <<"0">>,
@ -164,7 +165,7 @@ fields(client_opts) ->
}
)},
{burst,
?HOCON(burst(), #{
?HOCON(burst_type(), #{
desc => deprecated_desc(burst),
default => <<"0">>,
importance => ?IMPORTANCE_HIDDEN,
@ -211,7 +212,7 @@ short_paths_fields() ->
short_paths_fields(Importance) ->
[
{Name,
?HOCON(rate(), #{
?HOCON(rate_type(), #{
desc => ?DESC(Name),
required => false,
importance => Importance,
@ -415,7 +416,7 @@ composite_bucket_fields(Types, ClientRef) ->
fields_of_bucket(Default) ->
[
{rate, ?HOCON(rate(), #{desc => deprecated_desc(rate), default => Default})},
{rate, ?HOCON(rate_type(), #{desc => deprecated_desc(rate), default => Default})},
{burst,
?HOCON(burst(), #{
desc => deprecated_desc(burst),
@ -461,3 +462,12 @@ alias_of_type(_) ->
deprecated_desc(_Field) ->
<<"Deprecated since v5.0.25">>.
rate_type() ->
typerefl:alias("string", rate()).
burst_type() ->
typerefl:alias("string", burst()).
burst_rate_type() ->
typerefl:alias("string", burst_rate()).

View File

@ -3316,7 +3316,7 @@ get_tombstone_map_value_type(Schema) ->
%% hoconsc:map_value_type(Schema)
?MAP(_Name, Union) = hocon_schema:field_schema(Schema, type),
%% TODO: violation of abstraction, fix hoconsc:union_members/1
?UNION(Members) = Union,
?UNION(Members, _) = Union,
Tombstone = tombstone(),
[Type, Tombstone] = hoconsc:union_members(Members),
Type.

View File

@ -38,7 +38,8 @@
authenticator_type_without/1,
authenticator_type_without/2,
mechanism/1,
backend/1
backend/1,
namespace/0
]).
-export([
@ -60,6 +61,7 @@
api_write
%% config: schema for config validation
| config.
-callback namespace() -> string().
-callback refs() -> [schema_ref()].
-callback refs(shema_kind()) -> [schema_ref()].
-callback select_union_member(emqx_config:raw_config()) -> [schema_ref()] | undefined | no_return().
@ -74,6 +76,8 @@
refs/1
]).
namespace() -> "authn".
roots() -> [].
injected_fields(AuthnSchemaMods) ->

View File

@ -136,7 +136,7 @@ authz_fields() ->
[
{sources,
?HOCON(
?ARRAY(?UNION(UnionMemberSelector)),
?ARRAY(hoconsc:union(UnionMemberSelector)),
#{
default => [default_authz()],
desc => ?DESC(sources),
@ -153,7 +153,7 @@ api_authz_fields() ->
[{sources, ?HOCON(?ARRAY(api_source_type()), #{desc => ?DESC(sources)})}].
api_source_type() ->
?UNION(api_authz_refs()).
hoconsc:union(api_authz_refs()).
api_authz_refs() ->
lists:concat([api_source_refs(Mod) || Mod <- source_schema_mods()]).

View File

@ -16,7 +16,6 @@
-module(emqx_authn_chains_SUITE).
-behaviour(hocon_schema).
-behaviour(emqx_authn_provider).
-compile(export_all).

View File

@ -54,7 +54,7 @@ t_check_schema(_Config) ->
?assertThrow(
#{
path := "authentication.1.password_hash_algorithm.name",
matched_type := "builtin_db/authn-hash:simple",
matched_type := "authn:builtin_db/authn-hash:simple",
reason := unable_to_convert_to_enum_symbol
},
Check(ConfigNotOk)
@ -73,7 +73,7 @@ t_check_schema(_Config) ->
#{
path := "authentication.1.password_hash_algorithm",
reason := "algorithm_name_missing",
matched_type := "builtin_db"
matched_type := "authn:builtin_db"
},
Check(ConfigMissingAlgoName)
).

View File

@ -22,6 +22,7 @@
-define(ERR(Reason), {error, Reason}).
union_member_selector_mongo_test_() ->
ok = ensure_schema_load(),
[
{"unknown", fun() ->
?assertMatch(
@ -31,25 +32,26 @@ union_member_selector_mongo_test_() ->
end},
{"single", fun() ->
?assertMatch(
?ERR(#{matched_type := "mongo_single"}),
?ERR(#{matched_type := "authn:mongo_single"}),
check("{mechanism = password_based, backend = mongodb, mongo_type = single}")
)
end},
{"replica-set", fun() ->
?assertMatch(
?ERR(#{matched_type := "mongo_rs"}),
?ERR(#{matched_type := "authn:mongo_rs"}),
check("{mechanism = password_based, backend = mongodb, mongo_type = rs}")
)
end},
{"sharded", fun() ->
?assertMatch(
?ERR(#{matched_type := "mongo_sharded"}),
?ERR(#{matched_type := "authn:mongo_sharded"}),
check("{mechanism = password_based, backend = mongodb, mongo_type = sharded}")
)
end}
].
union_member_selector_jwt_test_() ->
ok = ensure_schema_load(),
[
{"unknown", fun() ->
?assertMatch(
@ -59,25 +61,26 @@ union_member_selector_jwt_test_() ->
end},
{"jwks", fun() ->
?assertMatch(
?ERR(#{matched_type := "jwt_jwks"}),
?ERR(#{matched_type := "authn:jwt_jwks"}),
check("{mechanism = jwt, use_jwks = true}")
)
end},
{"publick-key", fun() ->
?assertMatch(
?ERR(#{matched_type := "jwt_public_key"}),
?ERR(#{matched_type := "authn:jwt_public_key"}),
check("{mechanism = jwt, use_jwks = false, public_key = 1}")
)
end},
{"hmac-based", fun() ->
?assertMatch(
?ERR(#{matched_type := "jwt_hmac"}),
?ERR(#{matched_type := "authn:jwt_hmac"}),
check("{mechanism = jwt, use_jwks = false}")
)
end}
].
union_member_selector_redis_test_() ->
ok = ensure_schema_load(),
[
{"unknown", fun() ->
?assertMatch(
@ -87,25 +90,26 @@ union_member_selector_redis_test_() ->
end},
{"single", fun() ->
?assertMatch(
?ERR(#{matched_type := "redis_single"}),
?ERR(#{matched_type := "authn:redis_single"}),
check("{mechanism = password_based, backend = redis, redis_type = single}")
)
end},
{"cluster", fun() ->
?assertMatch(
?ERR(#{matched_type := "redis_cluster"}),
?ERR(#{matched_type := "authn:redis_cluster"}),
check("{mechanism = password_based, backend = redis, redis_type = cluster}")
)
end},
{"sentinel", fun() ->
?assertMatch(
?ERR(#{matched_type := "redis_sentinel"}),
?ERR(#{matched_type := "authn:redis_sentinel"}),
check("{mechanism = password_based, backend = redis, redis_type = sentinel}")
)
end}
].
union_member_selector_http_test_() ->
ok = ensure_schema_load(),
[
{"unknown", fun() ->
?assertMatch(
@ -115,13 +119,13 @@ union_member_selector_http_test_() ->
end},
{"get", fun() ->
?assertMatch(
?ERR(#{matched_type := "http_get"}),
?ERR(#{matched_type := "authn:http_get"}),
check("{mechanism = password_based, backend = http, method = get}")
)
end},
{"post", fun() ->
?assertMatch(
?ERR(#{matched_type := "http_post"}),
?ERR(#{matched_type := "authn:http_post"}),
check("{mechanism = password_based, backend = http, method = post}")
)
end}
@ -132,3 +136,7 @@ check(HoconConf) ->
#{roots => emqx_authn_schema:global_auth_fields()},
["authentication= ", HoconConf]
).
ensure_schema_load() ->
_ = emqx_conf_schema:roots(),
ok.

View File

@ -16,10 +16,6 @@
-module(emqx_authn_http_schema).
-include("emqx_auth_http.hrl").
-include_lib("emqx_auth/include/emqx_authn.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
@ -27,9 +23,14 @@
validations/0,
desc/1,
refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
-include("emqx_auth_http.hrl").
-include_lib("emqx_auth/include/emqx_authn.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-define(NOT_EMPTY(MSG), emqx_resource_validator:not_empty(MSG)).
-define(THROW_VALIDATION_ERROR(ERROR, MESSAGE),
throw(#{
@ -38,6 +39,8 @@
})
).
namespace() -> "authn".
refs() ->
[?R_REF(http_get), ?R_REF(http_post)].
@ -97,7 +100,7 @@ common_fields() ->
{backend, emqx_authn_schema:backend(?AUTHN_BACKEND)},
{url, fun url/1},
{body,
hoconsc:mk(map([{fuzzy, term(), binary()}]), #{
hoconsc:mk(typerefl:alias("map", map([{fuzzy, term(), binary()}])), #{
required => false, desc => ?DESC(body)
})},
{request_timeout, fun request_timeout/1}

View File

@ -26,7 +26,8 @@
fields/1,
desc/1,
source_refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
-export([
@ -38,6 +39,8 @@
-import(emqx_schema, [mk_duration/2]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
source_refs() ->
@ -96,7 +99,7 @@ http_common_fields() ->
mk_duration("Request timeout", #{
required => false, default => <<"30s">>, desc => ?DESC(request_timeout)
})},
{body, ?HOCON(map(), #{required => false, desc => ?DESC(body)})}
{body, ?HOCON(hoconsc:map(name, binary()), #{required => false, desc => ?DESC(body)})}
] ++
lists:keydelete(
pool_type,
@ -105,7 +108,7 @@ http_common_fields() ->
).
headers(type) ->
list({binary(), binary()});
typerefl:alias("map", list({binary(), binary()}));
headers(desc) ->
?DESC(?FUNCTION_NAME);
headers(converter) ->
@ -118,7 +121,7 @@ headers(_) ->
undefined.
headers_no_content_type(type) ->
list({binary(), binary()});
typerefl:alias("map", list({binary(), binary()}));
headers_no_content_type(desc) ->
?DESC(?FUNCTION_NAME);
headers_no_content_type(converter) ->

View File

@ -16,18 +16,21 @@
-module(emqx_authn_jwt_schema).
-include("emqx_auth_jwt.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
-include("emqx_auth_jwt.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() ->
[
?R_REF(jwt_hmac),

View File

@ -16,18 +16,21 @@
-module(emqx_authn_ldap_bind_schema).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
fields/1,
desc/1,
refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() ->
[?R_REF(ldap_bind)].

View File

@ -16,18 +16,21 @@
-module(emqx_authn_ldap_schema).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() ->
[?R_REF(ldap)].

View File

@ -26,9 +26,12 @@
fields/1,
desc/1,
source_refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
fields(ldap) ->

View File

@ -25,9 +25,12 @@
fields/1,
desc/1,
refs/1,
select_union_member/2
select_union_member/2,
namespace/0
]).
namespace() -> "authn".
refs(api_write) ->
[?R_REF(builtin_db_api)];
refs(_) ->

View File

@ -22,12 +22,15 @@
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
namespace() -> "authn".
refs() ->
[?R_REF(scram)].

View File

@ -26,9 +26,12 @@
fields/1,
desc/1,
source_refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
fields(builtin_db) ->

View File

@ -16,18 +16,21 @@
-module(emqx_authn_mongodb_schema).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() ->
[
?R_REF(mongo_single),

View File

@ -16,17 +16,20 @@
-module(emqx_authz_mongodb_schema).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-export([
type/0,
fields/1,
desc/1,
source_refs/0,
select_union_member/1
select_union_member/1,
namespace/0
]).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
source_refs() ->

View File

@ -16,18 +16,21 @@
-module(emqx_authn_mysql_schema).
-include("emqx_auth_mysql.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
-include("emqx_auth_mysql.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() ->
[?R_REF(mysql)].

View File

@ -22,6 +22,7 @@
-behaviour(emqx_authz_schema).
-export([
namespace/0,
type/0,
fields/1,
desc/1,
@ -29,6 +30,8 @@
select_union_member/1
]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
fields(mysql) ->

View File

@ -22,12 +22,15 @@
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
namespace() -> "authn".
select_union_member(
#{
<<"mechanism">> := ?AUTHN_MECHANISM_BIN, <<"backend">> := ?AUTHN_BACKEND_BIN

View File

@ -22,6 +22,7 @@
-behaviour(emqx_authz_schema).
-export([
namespace/0,
type/0,
fields/1,
desc/1,
@ -29,6 +30,8 @@
select_union_member/1
]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
fields(postgresql) ->

View File

@ -104,7 +104,7 @@ t_update_with_invalid_config(_Config) ->
?assertMatch(
{error, #{
kind := validation_error,
matched_type := "postgresql",
matched_type := "authn:postgresql",
path := "authentication.1.server",
reason := required_field
}},

View File

@ -22,12 +22,15 @@
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
namespace() -> "authn".
refs() ->
[
?R_REF(redis_single),

View File

@ -22,6 +22,7 @@
-behaviour(emqx_authz_schema).
-export([
namespace/0,
type/0,
fields/1,
desc/1,
@ -29,6 +30,8 @@
select_union_member/1
]).
namespace() -> "authz".
type() -> ?AUTHZ_TYPE.
fields(redis_single) ->

View File

@ -170,7 +170,7 @@ test_create_invalid_config(InvalidAuthConfig, Path) ->
?assertMatch(
{error, #{
kind := validation_error,
matched_type := "redis_single",
matched_type := "authn:redis_single",
path := Path
}},
emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, InvalidAuthConfig})

View File

@ -101,7 +101,7 @@ fields(connector_config) ->
)},
{service_account_json,
sc(
service_account_json(),
typerefl:alias("map", ?MODULE:service_account_json()),
#{
required => true,
validator => fun ?MODULE:service_account_json_validator/1,

View File

@ -1,6 +1,6 @@
{application, emqx_bridge_greptimedb, [
{description, "EMQX GreptimeDB Bridge"},
{vsn, "0.1.3"},
{vsn, "0.1.4"},
{registered, []},
{applications, [
kernel,

View File

@ -126,7 +126,7 @@ desc(_) ->
undefined.
write_syntax(type) ->
emqx_bridge_influxdb:write_syntax();
emqx_bridge_influxdb:write_syntax_type();
write_syntax(required) ->
true;
write_syntax(validator) ->

View File

@ -46,14 +46,6 @@
-export([validate_method/1, join_paths/2]).
-type connect_timeout() :: emqx_schema:duration() | infinity.
-type pool_type() :: random | hash.
-reflect_type([
connect_timeout/0,
pool_type/0
]).
-define(DEFAULT_PIPELINE_SIZE, 100).
-define(DEFAULT_REQUEST_TIMEOUT_MS, 30_000).
@ -89,7 +81,7 @@ fields(config) ->
)},
{pool_type,
sc(
pool_type(),
hoconsc:enum([random, hash]),
#{
default => random,
desc => ?DESC("pool_type")

View File

@ -1,6 +1,6 @@
{application, emqx_bridge_influxdb, [
{description, "EMQX Enterprise InfluxDB Bridge"},
{vsn, "0.1.5"},
{vsn, "0.1.6"},
{registered, []},
{applications, [
kernel,

View File

@ -11,7 +11,8 @@
-import(hoconsc, [mk/2, enum/1, ref/2]).
-export([
conn_bridge_examples/1
conn_bridge_examples/1,
write_syntax_type/0
]).
-export([
@ -29,6 +30,9 @@
%% -------------------------------------------------------------------------------------------------
%% api
write_syntax_type() ->
typerefl:alias("string", write_syntax()).
conn_bridge_examples(Method) ->
[
#{
@ -154,7 +158,7 @@ desc(_) ->
undefined.
write_syntax(type) ->
?MODULE:write_syntax();
write_syntax_type();
write_syntax(required) ->
true;
write_syntax(validator) ->

View File

@ -11,7 +11,7 @@
%%===========================================================================
pulsar_producer_validations_test() ->
Name = my_producer,
Name = list_to_atom("my_producer"),
Conf0 = pulsar_producer_hocon(),
Conf1 =
Conf0 ++

View File

@ -1,6 +1,6 @@
{application, emqx_bridge_rabbitmq, [
{description, "EMQX Enterprise RabbitMQ Bridge"},
{vsn, "0.1.5"},
{vsn, "0.1.6"},
{registered, []},
{applications, [
kernel,

View File

@ -20,7 +20,7 @@
-behaviour(ecpool_worker).
%% hocon_schema callbacks
-export([roots/0, fields/1]).
-export([namespace/0, roots/0, fields/1]).
%% HTTP API callbacks
-export([values/1]).
@ -43,6 +43,8 @@
%% Internal callbacks
-export([publish_messages/3]).
namespace() -> "rabbitmq".
roots() ->
[{config, #{type => hoconsc:ref(?MODULE, config)}}].

View File

@ -292,7 +292,7 @@ hocon_schema_to_spec(?MAP(Name, Type), LocalModule) ->
},
SubRefs
};
hocon_schema_to_spec(?UNION(Types), LocalModule) ->
hocon_schema_to_spec(?UNION(Types, _DisplayName), LocalModule) ->
{OneOf, Refs} = lists:foldl(
fun(Type, {Acc, RefsAcc}) ->
{Schema, SubRefs} = hocon_schema_to_spec(Type, LocalModule),

View File

@ -28,21 +28,14 @@
-include("emqx_conf.hrl").
-type log_level() :: debug | info | notice | warning | error | critical | alert | emergency | all.
-type file() :: string().
-type cipher() :: map().
-behaviour(hocon_schema).
-reflect_type([
log_level/0,
file/0,
cipher/0
]).
-export([
namespace/0, roots/0, fields/1, translations/0, translation/1, validations/0, desc/1, tags/0
]).
-export([log_level/0]).
-export([conf_get/2, conf_get/3, keys/2, filter/1]).
-export([upgrade_raw_conf/1]).
@ -548,7 +541,7 @@ fields("node") ->
)},
{"crash_dump_file",
sc(
file(),
string(),
#{
mapping => "vm_args.-env ERL_CRASH_DUMP",
desc => ?DESC(node_crash_dump_file),
@ -839,7 +832,7 @@ fields("rpc") ->
)},
{"certfile",
sc(
file(),
string(),
#{
mapping => "gen_rpc.certfile",
converter => fun ensure_unicode_path/2,
@ -848,7 +841,7 @@ fields("rpc") ->
)},
{"keyfile",
sc(
file(),
string(),
#{
mapping => "gen_rpc.keyfile",
converter => fun ensure_unicode_path/2,
@ -857,7 +850,7 @@ fields("rpc") ->
)},
{"cacertfile",
sc(
file(),
string(),
#{
mapping => "gen_rpc.cacertfile",
converter => fun ensure_unicode_path/2,
@ -985,7 +978,7 @@ fields("log") ->
})},
{"file",
sc(
?UNION([
hoconsc:union([
?R_REF("log_file_handler"),
?MAP(handler_name, ?R_REF("log_file_handler"))
]),
@ -1004,7 +997,7 @@ fields("log_file_handler") ->
[
{"path",
sc(
file(),
string(),
#{
desc => ?DESC("log_file_handler_file"),
default => <<"${EMQX_LOG_DIR}/emqx.log">>,
@ -1538,3 +1531,6 @@ ensure_unicode_path(Path, _) when is_list(Path) ->
Path;
ensure_unicode_path(Path, _) ->
throw({"not_string", Path}).
log_level() ->
hoconsc:enum([debug, info, notice, warning, error, critical, alert, emergency, all]).

View File

@ -345,15 +345,7 @@ parse_spec_ref(Module, Path, Options) ->
erlang:apply(Module, schema, [Path])
catch
Error:Reason:Stacktrace ->
%% This error is intended to fail the build
%% hence print to standard_error
io:format(
standard_error,
"Failed to generate swagger for path ~p in module ~p~n"
"error:~p~nreason:~p~n~p~n",
[Module, Path, Error, Reason, Stacktrace]
),
error({failed_to_generate_swagger_spec, Module, Path})
failed_to_generate_swagger_spec(Module, Path, Error, Reason, Stacktrace)
end,
OperationId = maps:get('operationId', Schema),
{Specs, Refs} = maps:fold(
@ -369,6 +361,24 @@ parse_spec_ref(Module, Path, Options) ->
RouteOpts = generate_route_opts(Schema, Options),
{OperationId, Specs, Refs, RouteOpts}.
-ifdef(TEST).
-spec failed_to_generate_swagger_spec(_, _, _, _, _) -> no_return().
failed_to_generate_swagger_spec(Module, Path, _Error, _Reason, _Stacktrace) ->
error({failed_to_generate_swagger_spec, Module, Path}).
-else.
-spec failed_to_generate_swagger_spec(_, _, _, _, _) -> no_return().
failed_to_generate_swagger_spec(Module, Path, Error, Reason, Stacktrace) ->
%% This error is intended to fail the build
%% hence print to standard_error
io:format(
standard_error,
"Failed to generate swagger for path ~p in module ~p~n"
"error:~p~nreason:~p~n~p~n",
[Module, Path, Error, Reason, Stacktrace]
),
error({failed_to_generate_swagger_spec, Module, Path}).
-endif.
generate_route_opts(Schema, Options) ->
#{filter => compose_filters(filter(Options), custom_filter(Schema))}.
@ -776,7 +786,7 @@ hocon_schema_to_spec(?MAP(Name, Type), LocalModule) ->
},
SubRefs
};
hocon_schema_to_spec(?UNION(Types), LocalModule) ->
hocon_schema_to_spec(?UNION(Types, _DisplayName), LocalModule) ->
{OneOf, Refs} = lists:foldl(
fun(Type, {Acc, RefsAcc}) ->
{Schema, SubRefs} = hocon_schema_to_spec(Type, LocalModule),

View File

@ -317,68 +317,72 @@ t_sub_fields(_Config) ->
validate(Path, Object, ExpectRefs),
ok.
t_complicated_type(_Config) ->
t_complex_type(_Config) ->
Path = "/ref/complex_type",
Object = #{
<<"content">> => #{
<<"application/json">> =>
#{
<<"schema">> => #{
<<"properties">> =>
[
{<<"no_neg_integer">>, #{minimum => 0, type => integer}},
{<<"url">>, #{example => <<"http://127.0.0.1">>, type => string}},
{<<"server">>, #{example => <<"127.0.0.1:80">>, type => string}},
{<<"connect_timeout">>, #{
example => infinity,
<<"oneOf">> => [
#{example => infinity, type => string},
#{type => integer}
]
}},
{<<"pool_type">>, #{enum => [random, hash], type => string}},
{<<"timeout">>, #{
example => infinity,
<<"oneOf">> => [
#{example => infinity, type => string}, #{type => integer}
]
}},
{<<"bytesize">>, #{example => <<"32MB">>, type => string}},
{<<"wordsize">>, #{example => <<"1024KB">>, type => string}},
{<<"maps">>, #{example => #{}, type => object}},
{<<"comma_separated_list">>, #{
example => <<"item1,item2">>, type => string
}},
{<<"comma_separated_atoms">>, #{
example => <<"item1,item2">>, type => string
}},
{<<"log_level">>, #{
enum => [
debug,
info,
notice,
warning,
error,
critical,
alert,
emergency,
all
],
type => string
}},
{<<"fix_integer">>, #{
default => 100, enum => [100], type => integer
}}
],
<<"type">> => object
}
}
}
},
{OperationId, Spec, Refs, #{}} = emqx_dashboard_swagger:parse_spec_ref(?MODULE, Path, #{}),
?assertEqual(test, OperationId),
Response = maps:get(responses, maps:get(post, Spec)),
?assertEqual(Object, maps:get(<<"200">>, Response)),
ResponseBody = maps:get(<<"200">>, Response),
Content = maps:get(<<"content">>, ResponseBody),
JsonContent = maps:get(<<"application/json">>, Content),
Schema = maps:get(<<"schema">>, JsonContent),
?assertMatch(#{<<"type">> := object}, Schema),
Properties = maps:get(<<"properties">>, Schema),
?assertMatch(
[
{<<"no_neg_integer">>, #{minimum := 0, type := integer}},
{<<"url">>, #{
example := <<"http://127.0.0.1">>, type := string
}},
{<<"server">>, #{
example := <<"127.0.0.1:80">>, type := string
}},
{<<"connect_timeout">>, #{
example := _, type := string
}},
{<<"pool_type">>, #{
enum := [random, hash], type := string
}},
{<<"timeout">>, #{
example := infinity,
<<"oneOf">> := [
#{example := infinity, type := string},
#{type := integer}
]
}},
{<<"bytesize">>, #{
example := <<"32MB">>, type := string
}},
{<<"wordsize">>, #{
example := <<"1024KB">>, type := string
}},
{<<"maps">>, #{example := #{}, type := object}},
{<<"comma_separated_list">>, #{
example := <<"item1,item2">>, type := string
}},
{<<"comma_separated_atoms">>, #{
example := <<"item1,item2">>, type := string
}},
{<<"log_level">>, #{
enum := [
debug,
info,
notice,
warning,
error,
critical,
alert,
emergency,
all
],
type := string
}},
{<<"fix_integer">>, #{
default := 100, enum := [100], type := integer
}}
],
Properties
),
?assertEqual([], Refs),
ok.
@ -647,9 +651,8 @@ schema("/ref/complex_type") ->
{no_neg_integer, hoconsc:mk(non_neg_integer(), #{})},
{url, hoconsc:mk(url(), #{})},
{server, hoconsc:mk(emqx_schema:ip_port(), #{})},
{connect_timeout,
hoconsc:mk(emqx_bridge_http_connector:connect_timeout(), #{})},
{pool_type, hoconsc:mk(emqx_bridge_http_connector:pool_type(), #{})},
{connect_timeout, hoconsc:mk(emqx_schema:timeout_duration(), #{})},
{pool_type, hoconsc:mk(hoconsc:enum([random, hash]), #{})},
{timeout, hoconsc:mk(timeout(), #{})},
{bytesize, hoconsc:mk(emqx_schema:bytesize(), #{})},
{wordsize, hoconsc:mk(emqx_schema:wordsize(), #{})},

View File

@ -1,6 +1,6 @@
{application, emqx_dashboard_sso, [
{description, "EMQX Dashboard Single Sign-On"},
{vsn, "0.1.1"},
{vsn, "0.1.2"},
{registered, [emqx_dashboard_sso_sup]},
{applications, [
kernel,

View File

@ -12,6 +12,7 @@
-behaviour(emqx_dashboard_sso).
-export([
namespace/0,
fields/1,
desc/1
]).
@ -30,6 +31,9 @@
%% Hocon Schema
%%------------------------------------------------------------------------------
namespace() ->
"sso".
hocon_ref() ->
hoconsc:ref(?MODULE, ldap).

View File

@ -8,7 +8,7 @@
-include_lib("typerefl/include/types.hrl").
%% Hocon
-export([fields/1, desc/1]).
-export([namespace/0, fields/1, desc/1]).
-export([
common_backend_schema/1,
@ -21,6 +21,8 @@
%%------------------------------------------------------------------------------
%% Hocon Schema
%%------------------------------------------------------------------------------
namespace() -> "sso".
fields(sso) ->
lists:map(
fun({Type, Module}) ->

View File

@ -53,7 +53,7 @@ fields("log_audit_handler") ->
{"path",
hoconsc:mk(
emqx_conf_schema:file(),
string(),
#{
desc => ?DESC(emqx_conf_schema, "audit_file_handler_path"),
default => <<"${EMQX_LOG_DIR}/audit.log">>,

View File

@ -16,18 +16,21 @@
-module(emqx_gcp_device_authn_schema).
-include("emqx_gcp_device.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema).
-export([
namespace/0,
fields/1,
desc/1,
refs/0,
select_union_member/1
]).
-include("emqx_gcp_device.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() -> [?R_REF(gcp_device)].
select_union_member(#{<<"mechanism">> := ?AUTHN_MECHANISM_BIN}) ->

View File

@ -37,7 +37,7 @@
%% ecpool connect & reconnect
-export([connect/1]).
-export([roots/0, fields/1, desc/1]).
-export([namespace/0, roots/0, fields/1, desc/1]).
-export([do_get_status/1]).
@ -57,6 +57,9 @@
%%=====================================================================
%% Hocon schema
namespace() -> "ldap".
roots() ->
[{config, #{type => hoconsc:ref(?MODULE, config)}}].

View File

@ -13,12 +13,14 @@
-behaviour(hocon_schema).
-export([roots/0, fields/1, validations/0, desc/1, tags/0]).
-export([namespace/0, roots/0, fields/1, validations/0, desc/1, tags/0]).
-export([
default_license/0
]).
namespace() -> "license".
roots() ->
[
{license,

View File

@ -313,7 +313,7 @@ create_listener_schema(Opts) ->
],
Example = maps:remove(id, tcp_schema_example()),
emqx_dashboard_swagger:schema_with_example(
?UNION(Schemas),
hoconsc:union(Schemas),
Example#{name => <<"demo">>}
).

View File

@ -1,6 +1,6 @@
{application, emqx_mongodb, [
{description, "EMQX MongoDB Connector"},
{vsn, "0.1.2"},
{vsn, "0.1.3"},
{registered, []},
{applications, [
kernel,

View File

@ -22,6 +22,7 @@
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
-behaviour(emqx_resource).
-behaviour(hocon_schema).
%% callbacks of behaviour emqx_resource
-export([
@ -29,7 +30,8 @@
on_start/2,
on_stop/2,
on_query/3,
on_get_status/2
on_get_status/2,
namespace/0
]).
%% ecpool callback
@ -50,6 +52,9 @@
}).
%%=====================================================================
namespace() -> "mongo".
roots() ->
[
{config, #{

View File

@ -57,7 +57,7 @@ fields("prometheus") ->
)},
{headers,
?HOCON(
list({string(), string()}),
typerefl:alias("map", list({string(), string()})),
#{
default => #{},
required => false,

View File

@ -77,7 +77,7 @@ fields("retainer") ->
)},
{delivery_rate,
?HOCON(
emqx_limiter_schema:rate(),
emqx_limiter_schema:rate_type(),
#{
required => false,
desc => ?DESC(delivery_rate),

View File

@ -24,7 +24,7 @@
-export([check_params/2]).
-export([roots/0, fields/1]).
-export([namespace/0, roots/0, fields/1]).
-type tag() :: rule_creation | rule_test | rule_engine.
@ -46,6 +46,8 @@ check_params(Params, Tag) ->
%%======================================================================================
%% Hocon Schema Definitions
namespace() -> "rule_engine".
roots() ->
[
{"rule_engine", sc(ref("rule_engine"), #{desc => ?DESC("root_rule_engine")})},

View File

@ -262,7 +262,7 @@ actions() ->
end.
qos() ->
?UNION([emqx_schema:qos(), binary()]).
hoconsc:union([emqx_schema:qos(), binary()]).
rule_engine_settings() ->
[

View File

@ -37,7 +37,7 @@ fields(s3) ->
)},
{secret_access_key,
mk(
secret_access_key(),
typerefl:alias("string", secret_access_key()),
#{
desc => ?DESC("secret_access_key"),
required => false,

View File

@ -1,6 +1,6 @@
{application, emqx_telemetry, [
{description, "Report telemetry data for EMQX Opensource edition"},
{vsn, "0.1.2"},
{vsn, "0.1.3"},
{registered, [emqx_telemetry_sup, emqx_telemetry]},
{mod, {emqx_telemetry_app, []}},
{applications, [

View File

@ -22,11 +22,15 @@
-behaviour(hocon_schema).
-export([
namespace/0,
roots/0,
fields/1,
desc/1
]).
%% 'emqxtel' to distinguish open-telemetry
namespace() -> "emqxtel".
roots() -> ["telemetry"].
fields("telemetry") ->

View File

@ -72,7 +72,7 @@ defmodule EMQXUmbrella.MixProject do
# in conflict by emqtt and hocon
{:getopt, "1.0.2", override: true},
{:snabbkaffe, github: "kafka4beam/snabbkaffe", tag: "1.0.8", override: true},
{:hocon, github: "emqx/hocon", tag: "0.39.19", override: true},
{:hocon, github: "emqx/hocon", tag: "0.40.0", override: true},
{:emqx_http_lib, github: "emqx/emqx_http_lib", tag: "0.5.3", override: true},
{:esasl, github: "emqx/esasl", tag: "0.2.0"},
{:jose, github: "potatosalad/erlang-jose", tag: "1.11.2"},

View File

@ -75,7 +75,7 @@
, {system_monitor, {git, "https://github.com/ieQu1/system_monitor", {tag, "3.0.3"}}}
, {getopt, "1.0.2"}
, {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "1.0.8"}}}
, {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.39.19"}}}
, {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.40.0"}}}
, {emqx_http_lib, {git, "https://github.com/emqx/emqx_http_lib.git", {tag, "0.5.3"}}}
, {esasl, {git, "https://github.com/emqx/esasl", {tag, "0.2.0"}}}
, {jose, {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.11.2"}}}

View File

@ -4,6 +4,12 @@ set -euo pipefail
# ensure dir
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
log_red() {
local RED='\033[0;31m' # Red
local NC='\033[0m' # No Color
echo -e "${RED}${1}${NC}"
}
# match any official release tag 'e*' and 'v*'
latest_release="$(env PREV_TAG_MATCH_PATTERN='*' ./scripts/find-prev-rel-tag.sh)"
echo "Version check compare base: $latest_release"
@ -47,7 +53,7 @@ for app in ${APPS}; do
-- "$app_path/priv" \
-- "$app_path/c_src" | wc -l ) "
if [ "$changed_lines" -gt 0 ]; then
echo "ERROR: $src_file needs a vsn bump"
log_red "ERROR: $src_file needs a vsn bump"
bad_app_count=$(( bad_app_count + 1))
fi
else