diff --git a/.github/workflows/apps_version_check.yaml b/.github/workflows/apps_version_check.yaml index ff757d47d..37f03b332 100644 --- a/.github/workflows/apps_version_check.yaml +++ b/.github/workflows/apps_version_check.yaml @@ -38,7 +38,9 @@ jobs: if: endsWith(github.repository, 'enterprise') run: ./scripts/update-appup.sh emqx-ee --check - name: Check apps version - run: ./scripts/apps-version-check.sh + run: ./scripts/check-apps-vsn.sh + - name: Check chart versions + run: ./scripts/check-chart-vsn.sh - uses: actions/upload-artifact@v3.1.0 if: failure() with: diff --git a/CHANGES-4.3.md b/CHANGES-4.3.md index 1595ecaed..8ef71ba7f 100644 --- a/CHANGES-4.3.md +++ b/CHANGES-4.3.md @@ -16,6 +16,7 @@ File format: - Fix rule-engine update behaviour which may initialize actions for disabled rules. [#8849](https://github.com/emqx/emqx/pull/8849) - Fix JWT plugin don't support non-integer timestamp claims. [#8862](https://github.com/emqx/emqx/pull/8862) +- Fix delayed publish inaccurate caused by os time change. [#8908](https://github.com/emqx/emqx/pull/8908) - Fix a possible dead loop caused by shared subscriptions with `shared_dispatch_ack_enabled=true`. [#8918](https://github.com/emqx/emqx/pull/8918) - Fix dashboard binding IP address not working. [#8916](https://github.com/emqx/emqx/pull/8916) - Fix rule SQL topic matching to null values failed. [#8927](https://github.com/emqx/emqx/pull/8927) @@ -23,6 +24,9 @@ File format: `SELECT topic =~ 't' as r FROM "$events/client_connected"`. The topic is a null value as there's no such field in event `$events/client_connected`, so it should return false if match it to a topic. +- Added a test to prevent a last will testament message to be + published when a client is denied connection. [#8894](https://github.com/emqx/emqx/pull/8894) +- Disable authorization for `api/v4/emqx_prometheus` endpoint. [8955](https://github.com/emqx/emqx/pull/8955) ## v4.3.19 diff --git a/Makefile b/Makefile index 755ee8e88..8921a545d 100644 --- a/Makefile +++ b/Makefile @@ -116,8 +116,9 @@ $(PROFILES:%=deps-%): $(REBAR) get-dashboard @rm -f rebar.lock .PHONY: xref -xref: $(REBAR) +xref: $(REBAR) $(REL_PROFILES:%=%-rel) @$(REBAR) as check xref + @scripts/xref-check.escript .PHONY: dialyzer dialyzer: $(REBAR) diff --git a/apps/emqx_auth_jwt/src/emqx_auth_jwt_svr.erl b/apps/emqx_auth_jwt/src/emqx_auth_jwt_svr.erl index 3a5c619aa..049f07533 100644 --- a/apps/emqx_auth_jwt/src/emqx_auth_jwt_svr.erl +++ b/apps/emqx_auth_jwt/src/emqx_auth_jwt_svr.erl @@ -200,7 +200,7 @@ do_verify(JwsCompacted, [Jwk|More]) -> end. check_claims(Claims) -> - Now = os:system_time(seconds), + Now = erlang:system_time(seconds), Checker = [{<<"exp">>, with_num_value( fun(ExpireTime) -> Now < ExpireTime end)}, {<<"iat">>, with_num_value( diff --git a/apps/emqx_auth_jwt/test/emqx_auth_jwt_SUITE.erl b/apps/emqx_auth_jwt/test/emqx_auth_jwt_SUITE.erl index eb6d3c195..a0be3768f 100644 --- a/apps/emqx_auth_jwt/test/emqx_auth_jwt_SUITE.erl +++ b/apps/emqx_auth_jwt/test/emqx_auth_jwt_SUITE.erl @@ -75,7 +75,7 @@ t_check_auth(_Config) -> Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external}, Jwt = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, - {exp, os:system_time(seconds) + 2}], <<"HS256">>, <<"emqxsecret">>), + {exp, erlang:system_time(seconds) + 2}], <<"HS256">>, <<"emqxsecret">>), ct:pal("Jwt: ~p~n", [Jwt]), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), @@ -101,7 +101,7 @@ t_check_nbf(_Config) -> Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external}, Jwt = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, - {nbf, os:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), + {nbf, erlang:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), ct:pal("Jwt: ~p~n", [Jwt]), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), @@ -114,7 +114,7 @@ t_check_iat(_Config) -> Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external}, Jwt = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, - {iat, os:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), + {iat, erlang:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), ct:pal("Jwt: ~p~n", [Jwt]), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), @@ -147,7 +147,7 @@ t_check_auth_str_exp(init, _Config) -> application:unset_env(emqx_auth_jwt, verify_claims). t_check_auth_str_exp(_Config) -> Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external}, - Exp = integer_to_binary(os:system_time(seconds) + 3), + Exp = integer_to_binary(erlang:system_time(seconds) + 3), Jwt0 = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, @@ -167,7 +167,7 @@ t_check_auth_str_exp(_Config) -> ct:pal("Auth result: ~p~n", [Result1]), ?assertMatch({error, _}, Result1), - Exp2 = float_to_binary(os:system_time(seconds) + 3.5), + Exp2 = float_to_binary(erlang:system_time(seconds) + 3.5), Jwt2 = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, @@ -182,7 +182,7 @@ t_check_auth_float_exp(init, _Config) -> application:unset_env(emqx_auth_jwt, verify_claims). t_check_auth_float_exp(_Config) -> Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external}, - Exp = os:system_time(seconds) + 3.5, + Exp = erlang:system_time(seconds) + 3.5, Jwt0 = sign([{clientid, <<"client1">>}, {username, <<"plain">>}, @@ -209,7 +209,7 @@ t_check_claims(_Config) -> Jwt = sign([{client_id, <<"client1">>}, {username, <<"plain">>}, {sub, value}, - {exp, os:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), + {exp, erlang:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), ct:pal("Auth result: ~p~n", [Result0]), ?assertMatch({ok, #{auth_result := success, jwt_claims := _}}, Result0), @@ -225,7 +225,7 @@ t_check_claims_clientid(_Config) -> Plain = #{clientid => <<"client23">>, username => <<"plain">>, zone => external}, Jwt = sign([{clientid, <<"client23">>}, {username, <<"plain">>}, - {exp, os:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), + {exp, erlang:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), ct:pal("Auth result: ~p~n", [Result0]), ?assertMatch({ok, #{auth_result := success, jwt_claims := _}}, Result0), @@ -241,7 +241,7 @@ t_check_claims_username(_Config) -> Plain = #{clientid => <<"client23">>, username => <<"plain">>, zone => external}, Jwt = sign([{client_id, <<"client23">>}, {username, <<"plain">>}, - {exp, os:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), + {exp, erlang:system_time(seconds) + 3}], <<"HS256">>, <<"emqxsecret">>), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), ct:pal("Auth result: ~p~n", [Result0]), ?assertMatch({ok, #{auth_result := success, jwt_claims := _}}, Result0), @@ -257,7 +257,7 @@ t_check_claims_kid_in_header(_Config) -> Plain = #{clientid => <<"client23">>, username => <<"plain">>, zone => external}, Jwt = sign([{clientid, <<"client23">>}, {username, <<"plain">>}, - {exp, os:system_time(seconds) + 3}], + {exp, erlang:system_time(seconds) + 3}], #{<<"alg">> => <<"HS256">>, <<"kid">> => <<"a_kid_str">>}, <<"emqxsecret">>), Result0 = emqx_access_control:authenticate(Plain#{password => Jwt}), @@ -298,7 +298,7 @@ t_check_jwt_acl(_Config) -> {sub, value}, {acl, [{sub, [<<"a/b">>]}, {pub, [<<"c/d">>]}]}, - {exp, os:system_time(seconds) + 10}], + {exp, erlang:system_time(seconds) + 10}], <<"HS256">>, <<"emqxsecret">>), @@ -338,7 +338,7 @@ t_check_jwt_acl_no_recs(_Config) -> {username, <<"plain">>}, {sub, value}, {acl, []}, - {exp, os:system_time(seconds) + 10}], + {exp, erlang:system_time(seconds) + 10}], <<"HS256">>, <<"emqxsecret">>), @@ -361,7 +361,7 @@ t_check_jwt_acl_no_acl_claim(_Config) -> Jwt = sign([{client_id, <<"client1">>}, {username, <<"plain">>}, {sub, value}, - {exp, os:system_time(seconds) + 10}], + {exp, erlang:system_time(seconds) + 10}], <<"HS256">>, <<"emqxsecret">>), @@ -423,7 +423,7 @@ t_check_jwt_acl_expire(_Config) -> {username, <<"plain">>}, {sub, value}, {acl, [{sub, [<<"a/b">>]}]}, - {exp, os:system_time(seconds) + 1}], + {exp, erlang:system_time(seconds) + 1}], <<"HS256">>, <<"emqxsecret">>), diff --git a/apps/emqx_auth_mnesia/test/emqx_auth_mnesia_SUITE.erl b/apps/emqx_auth_mnesia/test/emqx_auth_mnesia_SUITE.erl index 0253110aa..f7071bc17 100644 --- a/apps/emqx_auth_mnesia/test/emqx_auth_mnesia_SUITE.erl +++ b/apps/emqx_auth_mnesia/test/emqx_auth_mnesia_SUITE.erl @@ -21,6 +21,9 @@ -include("emqx_auth_mnesia.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). + +-include_lib("emqx/include/emqx_mqtt.hrl"). -import(emqx_ct_http, [ request_api/3 , request_api/5 @@ -74,6 +77,20 @@ set_default(ClientId, UserName, Pwd, HashType) -> application:set_env(emqx_auth_mnesia, username_list, [{UserName, Pwd}]), application:set_env(emqx_auth_mnesia, password_hash, HashType), ok. + +init_per_testcase(t_will_message_connection_denied, Config) -> + emqx_zone:set_env(external, allow_anonymous, false), + Config; +init_per_testcase(_TestCase, Config) -> + Config. + +end_per_testcase(t_will_message_connection_denied, _Config) -> + emqx_zone:unset_env(external, allow_anonymous), + application:stop(emqx_auth_mnesia), + ok; +end_per_testcase(_TestCase, _Config) -> + ok. + %%------------------------------------------------------------------------------ %% Testcases %%------------------------------------------------------------------------------ @@ -390,6 +407,48 @@ t_password_hash(_) -> application:stop(emqx_auth_mnesia), ok = application:start(emqx_auth_mnesia). +t_will_message_connection_denied(Config) when is_list(Config) -> + ClientId = Username = <<"subscriber">>, + Password = <<"p">>, + application:stop(emqx_auth_mnesia), + ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia]), + ok = emqx_auth_mnesia_cli:add_user({clientid, ClientId}, Password), + + {ok, Subscriber} = emqtt:start_link([ + {clientid, ClientId}, + {password, Password} + ]), + {ok, _} = emqtt:connect(Subscriber), + {ok, _, [?RC_SUCCESS]} = emqtt:subscribe(Subscriber, <<"lwt">>), + + process_flag(trap_exit, true), + + {ok, Publisher} = emqtt:start_link([ + {clientid, <<"publisher">>}, + {will_topic, <<"lwt">>}, + {will_payload, <<"should not be published">>} + ]), + snabbkaffe:start_trace(), + ?wait_async_action( + {error, _} = emqtt:connect(Publisher), + #{?snk_kind := channel_terminated} + ), + snabbkaffe:stop(), + + timer:sleep(1000), + + receive + {publish, #{ + topic := <<"lwt">>, + payload := <<"should not be published">> + }} -> + ct:fail("should not publish will message") + after 0 -> + ok + end, + + ok. + %%------------------------------------------------------------------------------ %% Helpers %%------------------------------------------------------------------------------ diff --git a/apps/emqx_auth_pgsql/src/emqx_auth_pgsql_cli.erl b/apps/emqx_auth_pgsql/src/emqx_auth_pgsql_cli.erl index f7170e92b..4905b32bf 100644 --- a/apps/emqx_auth_pgsql/src/emqx_auth_pgsql_cli.erl +++ b/apps/emqx_auth_pgsql/src/emqx_auth_pgsql_cli.erl @@ -147,4 +147,3 @@ safe_get(K, ClientInfo) -> bin(A) when is_atom(A) -> atom_to_binary(A, utf8); bin(B) when is_binary(B) -> B; bin(X) -> X. - diff --git a/apps/emqx_exhook/src/emqx_exhook.app.src b/apps/emqx_exhook/src/emqx_exhook.app.src index 3df8f4348..1e9a01cd5 100644 --- a/apps/emqx_exhook/src/emqx_exhook.app.src +++ b/apps/emqx_exhook/src/emqx_exhook.app.src @@ -1,7 +1,7 @@ %% -*- mode: erlang -*- {application, emqx_exhook, [{description, "EMQ X Extension for Hook"}, - {vsn, "4.4.3"}, + {vsn, "4.4.4"}, {modules, []}, {registered, []}, {mod, {emqx_exhook_app, []}}, diff --git a/apps/emqx_exhook/src/emqx_exhook.appup.src b/apps/emqx_exhook/src/emqx_exhook.appup.src index 7d73e1e6e..f4ba11f92 100644 --- a/apps/emqx_exhook/src/emqx_exhook.appup.src +++ b/apps/emqx_exhook/src/emqx_exhook.appup.src @@ -1,7 +1,8 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{<<"4\\.4\\.[1-2]">>, + [{"4.4.3",[{load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}]}, + {<<"4\\.4\\.[1-2]">>, [{load_module,emqx_exhook_handler,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook,brutal_purge,soft_purge,[]}, @@ -12,9 +13,10 @@ {load_module,emqx_exhook_sup,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_handler,brutal_purge,soft_purge,[]}, - {update, emqx_exhook_mngr, {advanced, ["4.4.0"]}}]}, + {update,emqx_exhook_mngr,{advanced,["4.4.0"]}}]}, {<<".*">>,[]}], - [{<<"4\\.4\\.[1-2]">>, + [{"4.4.3",[{load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}]}, + {<<"4\\.4\\.[1-2]">>, [{load_module,emqx_exhook_handler,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook,brutal_purge,soft_purge,[]}, @@ -25,5 +27,5 @@ {load_module,emqx_exhook_sup,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_server,brutal_purge,soft_purge,[]}, {load_module,emqx_exhook_handler,brutal_purge,soft_purge,[]}, - {update, emqx_exhook_mngr, {advanced, ["4.4.0"]}}]}, + {update,emqx_exhook_mngr,{advanced,["4.4.0"]}}]}, {<<".*">>,[]}]}. diff --git a/apps/emqx_exhook/src/emqx_exhook_server.erl b/apps/emqx_exhook/src/emqx_exhook_server.erl index 477069203..22a5371af 100644 --- a/apps/emqx_exhook/src/emqx_exhook_server.erl +++ b/apps/emqx_exhook/src/emqx_exhook_server.erl @@ -46,7 +46,7 @@ channel :: pid(), %% Registered hook names and options hookspec :: #{hookpoint() => map()}, - %% Metrcis name prefix + %% Metrics name prefix prefix :: list() }). @@ -75,8 +75,6 @@ -export_type([server/0]). --dialyzer({nowarn_function, [inc_metrics/2]}). - -elvis([{elvis_style, dont_repeat_yourself, disable}]). %%-------------------------------------------------------------------- @@ -256,10 +254,6 @@ call(Hookpoint, Req, #server{name = ChannName, options = ReqOpts, end. %% @private -inc_metrics(IncFun, Name) when is_function(IncFun) -> - %% BACKW: e4.2.0-e4.2.2 - {env, [Prefix | _]} = erlang:fun_info(IncFun, env), - inc_metrics(Prefix, Name); inc_metrics(Prefix, Name) when is_list(Prefix) -> emqx_metrics:inc(list_to_atom(Prefix ++ atom_to_list(Name))). diff --git a/apps/emqx_exproto/src/emqx_exproto.appup.src b/apps/emqx_exproto/src/emqx_exproto.appup.src index fcf2fe6db..f98eb2d0e 100644 --- a/apps/emqx_exproto/src/emqx_exproto.appup.src +++ b/apps/emqx_exproto/src/emqx_exproto.appup.src @@ -1,9 +1,12 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"4.3.10",[{load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}]}, + [{"4.3.10", + [{load_module,emqx_exproto_conn,brutal_purge,soft_purge,[]}, + {load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}]}, {"4.3.9", - [{load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}, + [{load_module,emqx_exproto_conn,brutal_purge,soft_purge,[]}, + {load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_exproto_gcli,brutal_purge,soft_purge,[]}]}, {<<"4\\.3\\.[2-8]">>, [{load_module,emqx_exproto_gcli,brutal_purge,soft_purge,[]}, @@ -15,9 +18,12 @@ {load_module,emqx_exproto_conn,brutal_purge,soft_purge,[]}, {load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], - [{"4.3.10",[{load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}]}, + [{"4.3.10", + [{load_module,emqx_exproto_conn,brutal_purge,soft_purge,[]}, + {load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}]}, {"4.3.9", - [{load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}, + [{load_module,emqx_exproto_conn,brutal_purge,soft_purge,[]}, + {load_module,emqx_exproto_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_exproto_gcli,brutal_purge,soft_purge,[]}]}, {<<"4\\.3\\.[2-8]">>, [{load_module,emqx_exproto_gcli,brutal_purge,soft_purge,[]}, diff --git a/apps/emqx_exproto/src/emqx_exproto_conn.erl b/apps/emqx_exproto/src/emqx_exproto_conn.erl index 152c0edf1..7c6eb6cb3 100644 --- a/apps/emqx_exproto/src/emqx_exproto_conn.erl +++ b/apps/emqx_exproto/src/emqx_exproto_conn.erl @@ -91,14 +91,6 @@ -define(ENABLED(X), (X =/= undefined)). --dialyzer({nowarn_function, - [ system_terminate/4 - , handle_call/3 - , handle_msg/2 - , shutdown/3 - , stop/3 - ]}). - %% udp start_link(Socket = {udp, _SockPid, _Sock}, Peername, Options) -> Args = [self(), Socket, Peername, Options], @@ -501,6 +493,7 @@ terminate(Reason, State = #state{channel = Channel}) -> system_continue(Parent, _Debug, State) -> recvloop(Parent, State). +-spec system_terminate(atom(), term(), term(), state()) -> no_return(). system_terminate(Reason, _Parent, _Debug, State) -> terminate(Reason, State). diff --git a/apps/emqx_management/src/emqx_mgmt_data_backup.erl b/apps/emqx_management/src/emqx_mgmt_data_backup.erl index 9ea25c7ed..bf573a49a 100644 --- a/apps/emqx_management/src/emqx_mgmt_data_backup.erl +++ b/apps/emqx_management/src/emqx_mgmt_data_backup.erl @@ -197,7 +197,6 @@ confs_to_binary(Confs) -> -endif. --dialyzer([{nowarn_function, [import_rules/1, import_rule/1]}]). import_rule(#{<<"id">> := RuleId, <<"rawsql">> := RawSQL, <<"actions">> := Actions, @@ -562,7 +561,6 @@ do_import_acl_mnesia(Acls) -> end, Acls). -ifdef(EMQX_ENTERPRISE). --dialyzer({nowarn_function, [import_modules/1]}). import_modules(Modules) -> case ets:info(emqx_modules) of undefined -> diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src index 612ec73af..8f7ec47db 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src @@ -2,17 +2,22 @@ %% Unless you know what you are doing, DO NOT edit manually!! {VSN, [{"4.4.8", - [{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]}, {<<"4\\.4\\.[6-7]">>, - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.4.5", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, @@ -20,7 +25,8 @@ {load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, @@ -28,7 +34,8 @@ {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, @@ -86,17 +93,22 @@ {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], [{"4.4.8", - [{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]}, {<<"4\\.4\\.[6-7]">>, - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.4.5", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, @@ -104,7 +116,8 @@ {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, @@ -112,7 +125,8 @@ {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, + [{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_validator,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_utils,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}, diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.erl b/apps/emqx_rule_engine/src/emqx_rule_engine.erl index f48b8a02b..ac0ccaf4f 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.erl @@ -207,7 +207,7 @@ create_rule(Params = #{rawsql := Sql, actions := ActArgs}) -> Reason -> {error, Reason} end. --spec(update_rule(#{id := binary(), _=>_}) -> {ok, rule()} | {error, {not_found, rule_id()}}). +-spec(update_rule(#{id := binary(), _=>_}) -> {ok, rule()} | {error, {not_found, rule_id()} | term()}). update_rule(Params = #{id := RuleId}) -> case emqx_rule_registry:get_rule(RuleId) of {ok, Rule0} -> @@ -336,7 +336,6 @@ start_resource(ResId) -> {error, {resource_not_found, ResId}} end. --dialyzer([{nowarn_function, test_resource/1}]). -spec(test_resource(#{type := _, config := _, _ => _}) -> ok | {error, Reason :: term()}). test_resource(#{type := Type} = Params) -> case emqx_rule_registry:find_resource_type(Type) of diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl index 223c672e6..50fdcfe22 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl @@ -207,12 +207,6 @@ <<"Bad Arguments: ", R0/binary>> end). --dialyzer({nowarn_function, [create_rule/2, - test_rule_sql/1, - do_create_rule/1, - update_rule/2 - ]}). - %%------------------------------------------------------------------------------ %% Rules API %%------------------------------------------------------------------------------ diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl index 45a847ada..101fa54f6 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl @@ -96,7 +96,6 @@ unload() -> %%----------------------------------------------------------------------------- %% 'rules' command %%----------------------------------------------------------------------------- --dialyzer([{nowarn_function, [rules/1]}]). rules(["list"]) -> print_all(emqx_rule_registry:get_rules_ordered_by_ts()); diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index 71775f6ee..c6c3da533 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -180,7 +180,6 @@ select_and_collect([Field|More], Input, {Output, LastKV}) -> {nested_put(Key, Val, Output), LastKV}). %% Filter each item got from FOREACH --dialyzer({nowarn_function, filter_collection/4}). filter_collection(Input, InCase, DoEach, {CollKey, CollVal}) -> lists:filtermap( fun(Item) -> diff --git a/apps/emqx_rule_engine/src/emqx_rule_sqltester.erl b/apps/emqx_rule_engine/src/emqx_rule_sqltester.erl index 3d80313a0..d53f873bd 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_sqltester.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_sqltester.erl @@ -20,16 +20,6 @@ -export([ test/1 ]). -%% Dialyzer gives up on the generated code. -%% probably due to stack depth, or inlines. --dialyzer({nowarn_function, [test/1, - test_rule/4, - flatten/1, - sql_test_action/0, - fill_default_values/2, - envs_examp/1 - ]}). - -spec(test(#{}) -> {ok, map() | list()} | {error, term()}). test(#{<<"rawsql">> := Sql, <<"ctx">> := Context}) -> {ok, Select} = emqx_rule_sqlparser:parse_select(Sql), diff --git a/apps/emqx_stomp/src/emqx_stomp.app.src b/apps/emqx_stomp/src/emqx_stomp.app.src index 5883cbca5..e35e570d3 100644 --- a/apps/emqx_stomp/src/emqx_stomp.app.src +++ b/apps/emqx_stomp/src/emqx_stomp.app.src @@ -1,6 +1,6 @@ {application, emqx_stomp, [{description, "EMQ X Stomp Protocol Plugin"}, - {vsn, "4.3.5"}, % strict semver, bump manually! + {vsn, "4.3.6"}, % strict semver, bump manually! {modules, []}, {registered, [emqx_stomp_sup]}, {applications, [kernel,stdlib]}, diff --git a/apps/emqx_stomp/src/emqx_stomp.appup.src b/apps/emqx_stomp/src/emqx_stomp.appup.src index 3493ade03..69e571934 100644 --- a/apps/emqx_stomp/src/emqx_stomp.appup.src +++ b/apps/emqx_stomp/src/emqx_stomp.appup.src @@ -1,6 +1,10 @@ %% -*- mode: erlang -*- +%% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"4.3.4", + [{"4.3.5", + [{load_module,emqx_stomp_protocol,brutal_purge,soft_purge,[]}, + {load_module,emqx_stomp_connection,brutal_purge,soft_purge,[]}]}, + {"4.3.4", [{load_module,emqx_stomp_protocol,brutal_purge,soft_purge,[]}, {load_module,emqx_stomp_connection,brutal_purge,soft_purge,[]}]}, {"4.3.3", @@ -19,7 +23,10 @@ [{restart_application,emqx_stomp}, {apply,{emqx_stomp,force_clear_after_app_stoped,[]}}]}, {<<".*">>,[]}], - [{"4.3.4", + [{"4.3.5", + [{load_module,emqx_stomp_protocol,brutal_purge,soft_purge,[]}, + {load_module,emqx_stomp_connection,brutal_purge,soft_purge,[]}]}, + {"4.3.4", [{load_module,emqx_stomp_protocol,brutal_purge,soft_purge,[]}, {load_module,emqx_stomp_connection,brutal_purge,soft_purge,[]}]}, {"4.3.3", diff --git a/apps/emqx_stomp/src/emqx_stomp_connection.erl b/apps/emqx_stomp/src/emqx_stomp_connection.erl index 767ea3814..e58b242e5 100644 --- a/apps/emqx_stomp/src/emqx_stomp_connection.erl +++ b/apps/emqx_stomp/src/emqx_stomp_connection.erl @@ -91,13 +91,6 @@ -define(ENABLED(X), (X =/= undefined)). --dialyzer({nowarn_function, [ ensure_stats_timer/2 - ]}). - --dialyzer({no_return, [ init/1 - , init_state/3 - ]}). - start_link(Transport, Sock, ProtoEnv) -> {ok, proc_lib:spawn_link(?MODULE, init, [[Transport, Sock, ProtoEnv]])}. @@ -143,6 +136,7 @@ call(Pid, Req) -> call(Pid, Req, Timeout) -> gen_server:call(Pid, Req, Timeout). +-spec init([term()]) -> no_return(). init([Transport, RawSocket, ProtoEnv]) -> case Transport:wait(RawSocket) of {ok, Socket} -> @@ -152,6 +146,7 @@ init([Transport, RawSocket, ProtoEnv]) -> exit_on_sock_error(Reason) end. +-spec init_state(module(), port(), [proplists:property()]) -> no_return(). init_state(Transport, Socket, ProtoEnv) -> {ok, Peername} = Transport:ensure_ok_or_exit(peername, [Socket]), {ok, Sockname} = Transport:ensure_ok_or_exit(sockname, [Socket]), diff --git a/apps/emqx_stomp/src/emqx_stomp_protocol.erl b/apps/emqx_stomp/src/emqx_stomp_protocol.erl index 0a8a7be75..e2cc2888b 100644 --- a/apps/emqx_stomp/src/emqx_stomp_protocol.erl +++ b/apps/emqx_stomp/src/emqx_stomp_protocol.erl @@ -50,9 +50,29 @@ , handle_recv_nack_frame/2 ]). +-type stomp_conninfo() :: #{socktype := emqx_types:socktype(), + sockname := emqx_types:peername(), + peername := emqx_types:peername(), + peercert := nossl | undefined | esockd_peercert:peercert(), + conn_mod := module(), + proto_name => binary(), + proto_ver => emqx_types:ver(), + clean_start => boolean(), + clientid => emqx_types:clientid(), + username => emqx_types:username(), + conn_props => emqx_types:properties(), + connected => boolean(), + connected_at => undefined | non_neg_integer(), + disconnected_at => non_neg_integer(), + keepalive => undefined | 0..16#FFFF, + receive_maximum => non_neg_integer(), + expiry_interval => non_neg_integer(), + atom() => term() + }. + -record(pstate, { %% Stomp ConnInfo - conninfo :: emqx_types:conninfo(), + conninfo :: stomp_conninfo(), %% Stomp ClientInfo clientinfo :: emqx_types:clientinfo(), %% Stomp Heartbeats @@ -104,10 +124,6 @@ awaiting_rel_max ]). --dialyzer({nowarn_function, [ check_acl/3 - , init/2 - ]}). - -type(pstate() :: #pstate{}). %% @doc Init protocol @@ -687,12 +703,8 @@ backoff({Cx, Cy}) -> parse_topic_filters(TopicFilters) -> lists:map(fun emqx_topic:parse/1, TopicFilters). -check_acl(PubSub, Topic, State = #pstate{clientinfo = ClientInfo}) -> - case is_acl_enabled(State) andalso - emqx_access_control:check_acl(ClientInfo, PubSub, Topic) of - false -> allow; - Res -> Res - end. +check_acl(PubSub, Topic, #pstate{clientinfo = ClientInfo}) -> + emqx_access_control:check_acl(ClientInfo, PubSub, Topic). do_subscribe(TopicFilter, SubOpts, State = #pstate{clientinfo = ClientInfo, subscriptions = Subs}) -> @@ -728,10 +740,6 @@ find_sub_by_id(Id, Subs) -> [Sub | _] -> Sub end. -is_acl_enabled(_) -> - %% TODO: configs from somewhere - true. - %% automaticly fill the next sub-id and ack if sub-id is absent enrich_sub_opts(SubOpts0, Subs) -> SubOpts = maps:merge(?DEFAULT_SUBOPTS, SubOpts0), diff --git a/include/emqx.hrl b/include/emqx.hrl index 4a97f3ccb..ddfc5f19e 100644 --- a/include/emqx.hrl +++ b/include/emqx.hrl @@ -85,9 +85,13 @@ %%-------------------------------------------------------------------- -record(route, { - topic :: binary(), - dest :: node() | {binary(), node()} + topic, + dest }). +-type route() :: #route{ + topic :: binary(), + dest :: node() | {binary(), node()} + }. %%-------------------------------------------------------------------- %% Plugin @@ -132,4 +136,3 @@ }). -endif. - diff --git a/lib-ce/emqx_dashboard/src/emqx_dashboard.erl b/lib-ce/emqx_dashboard/src/emqx_dashboard.erl index c65c47c22..a4f336785 100644 --- a/lib-ce/emqx_dashboard/src/emqx_dashboard.erl +++ b/lib-ce/emqx_dashboard/src/emqx_dashboard.erl @@ -109,6 +109,8 @@ http_handlers() -> is_authorized(Req) -> is_authorized(binary_to_list(cowboy_req:path(Req)), Req). +is_authorized("/api/v4/emqx_prometheus", _Req) -> + true; is_authorized("/api/v4/auth", _Req) -> true; is_authorized(_Path, Req) -> diff --git a/lib-ce/emqx_modules/src/emqx_mod_delayed.erl b/lib-ce/emqx_modules/src/emqx_mod_delayed.erl index 4fed5e191..3525b8449 100644 --- a/lib-ce/emqx_modules/src/emqx_mod_delayed.erl +++ b/lib-ce/emqx_modules/src/emqx_mod_delayed.erl @@ -160,7 +160,7 @@ handle_cast(Msg, State) -> %% Do Publish... handle_info({timeout, TRef, do_publish}, State = #{timer := TRef}) -> - DeletedKeys = do_publish(mnesia:dirty_first(?TAB), os:system_time(seconds)), + DeletedKeys = do_publish(mnesia:dirty_first(?TAB), erlang:system_time(seconds)), lists:foreach(fun(Key) -> mnesia:dirty_delete(?TAB, Key) end, DeletedKeys), {noreply, ensure_publish_timer(State#{timer := undefined, publish_at := 0})}; @@ -203,11 +203,11 @@ ensure_publish_timer(State) -> ensure_publish_timer('$end_of_table', State) -> State#{timer := undefined, publish_at := 0}; ensure_publish_timer({Ts, _Id}, State = #{timer := undefined}) -> - ensure_publish_timer(Ts, os:system_time(seconds), State); + ensure_publish_timer(Ts, erlang:system_time(seconds), State); ensure_publish_timer({Ts, _Id}, State = #{timer := TRef, publish_at := PubAt}) when Ts < PubAt -> ok = emqx_misc:cancel_timer(TRef), - ensure_publish_timer(Ts, os:system_time(seconds), State); + ensure_publish_timer(Ts, erlang:system_time(seconds), State); ensure_publish_timer(_Key, State) -> State. diff --git a/lib-ce/emqx_modules/src/emqx_modules.app.src b/lib-ce/emqx_modules/src/emqx_modules.app.src index 7af84537b..b9c623110 100644 --- a/lib-ce/emqx_modules/src/emqx_modules.app.src +++ b/lib-ce/emqx_modules/src/emqx_modules.app.src @@ -1,6 +1,6 @@ {application, emqx_modules, [{description, "EMQ X Module Management"}, - {vsn, "4.4.6"}, + {vsn, "4.4.7"}, {modules, []}, {applications, [kernel,stdlib]}, {mod, {emqx_modules_app, []}}, diff --git a/lib-ce/emqx_modules/src/emqx_modules.appup.src b/lib-ce/emqx_modules/src/emqx_modules.appup.src index b30d2f76c..1cf968166 100644 --- a/lib-ce/emqx_modules/src/emqx_modules.appup.src +++ b/lib-ce/emqx_modules/src/emqx_modules.appup.src @@ -1,19 +1,24 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"4.4.5", - [{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, + [{"4.4.6",[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]}, + {"4.4.5", + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, - {load_module,emqx_modules,brutal_purge,soft_purge,[]}, - {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + {load_module,emqx_modules,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, {"4.4.2", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}]}, {"4.4.1", @@ -31,19 +36,24 @@ {load_module,emqx_mod_sup,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], - [{"4.4.5", - [{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, + [{"4.4.6",[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]}, + {"4.4.5", + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]}, {"4.4.2", - [{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, + [{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}, + {load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}, {load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}, {load_module,emqx_modules,brutal_purge,soft_purge,[]}]}, {"4.4.1", diff --git a/lib-ce/emqx_telemetry/src/emqx_telemetry.app.src b/lib-ce/emqx_telemetry/src/emqx_telemetry.app.src index 74f8fa63e..52bfe7b10 100644 --- a/lib-ce/emqx_telemetry/src/emqx_telemetry.app.src +++ b/lib-ce/emqx_telemetry/src/emqx_telemetry.app.src @@ -1,6 +1,6 @@ {application, emqx_telemetry, [{description, "EMQ X Telemetry"}, - {vsn, "4.3.3"}, % strict semver, bump manually! + {vsn, "4.3.4"}, % strict semver, bump manually! {modules, []}, {registered, [emqx_telemetry_sup]}, {applications, [kernel,stdlib]}, diff --git a/lib-ce/emqx_telemetry/src/emqx_telemetry.appup.src b/lib-ce/emqx_telemetry/src/emqx_telemetry.appup.src index 79e6d3d41..3d079e839 100644 --- a/lib-ce/emqx_telemetry/src/emqx_telemetry.appup.src +++ b/lib-ce/emqx_telemetry/src/emqx_telemetry.appup.src @@ -1,15 +1,11 @@ %% -*- mode: erlang -*- +%% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [ - {<<"4\\.3\\.[0-2]">>, [ - {load_module, emqx_telemetry, brutal_purge, soft_purge, []} - ]}, - {<<".*">>, []} - ], - [ - {<<"4\\.3\\.[0-2]">>, [ - {load_module, emqx_telemetry, brutal_purge, soft_purge, []} - ]}, - {<<".*">>, []} - ] -}. + [{"4.3.3",[{load_module,emqx_telemetry,brutal_purge,soft_purge,[]}]}, + {<<"4\\.3\\.[0-2]">>, + [{load_module,emqx_telemetry,brutal_purge,soft_purge,[]}]}, + {<<".*">>,[]}], + [{"4.3.3",[{load_module,emqx_telemetry,brutal_purge,soft_purge,[]}]}, + {<<"4\\.3\\.[0-2]">>, + [{load_module,emqx_telemetry,brutal_purge,soft_purge,[]}]}, + {<<".*">>,[]}]}. diff --git a/lib-ce/emqx_telemetry/src/emqx_telemetry.erl b/lib-ce/emqx_telemetry/src/emqx_telemetry.erl index b87329076..09765f3e6 100644 --- a/lib-ce/emqx_telemetry/src/emqx_telemetry.erl +++ b/lib-ce/emqx_telemetry/src/emqx_telemetry.erl @@ -133,12 +133,6 @@ get_telemetry() -> %% gen_server callbacks %%-------------------------------------------------------------------- -%% This is to suppress dialyzer warnings for mnesia:dirty_write and -%% dirty_read race condition. Given that the init function is not evaluated -%% concurrently in one node, it should be free of race condition. -%% Given the chance of having two nodes bootstraping with the write -%% is very small, it should be safe to ignore. --dialyzer([{nowarn_function, [init/1]}]). init([Opts]) -> State = #state{url = get_value(url, Opts), report_interval = timer:seconds(get_value(report_interval, Opts))}, diff --git a/rebar.config b/rebar.config index 0e01e9c2d..f1e1aa014 100644 --- a/rebar.config +++ b/rebar.config @@ -43,7 +43,7 @@ , {ehttpc, {git, "https://github.com/emqx/ehttpc", {tag, "0.2.0"}}} , {gun, {git, "https://github.com/emqx/gun", {tag, "1.3.7"}}} , {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.3"}}} - , {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.8.0"}}} + , {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.9.0"}}} , {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}} , {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.0"}}} , {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.7"}}} diff --git a/scripts/apps-version-check.sh b/scripts/check-apps-vsn.sh similarity index 100% rename from scripts/apps-version-check.sh rename to scripts/check-apps-vsn.sh diff --git a/scripts/check-chart-vsn.sh b/scripts/check-chart-vsn.sh new file mode 100755 index 000000000..633a51dc2 --- /dev/null +++ b/scripts/check-chart-vsn.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ensure dir +cd -P -- "$(dirname -- "$0")/.." + +if [ -f "EMQX_ENTERPRISE" ]; then + CHART_FILE='deploy/charts/emqx-ee/Chart.yaml' +else + CHART_FILE='deploy/charts/emqx/Chart.yaml' +fi + +if [ ! -f "$CHART_FILE" ]; then + echo "Chart file $CHART_FILE is not found" + pwd + exit 1 +fi + +CHART_VSN="$(grep -oE '^version:.*' "$CHART_FILE" | cut -d ':' -f 2 | tr -d ' ')" +APP_VSN="$(grep -oE '^appVersion:.*' "$CHART_FILE" | cut -d ':' -f 2 | tr -d ' ')" + +if [ "$CHART_VSN" != "$APP_VSN" ]; then + echo "Chart version and app version mismatch in $CHART_FILE" + exit 2 +fi + +PKG_VSN="$(./pkg-vsn.sh | cut -d '-' -f 1)" + +if [ "$CHART_VSN" != "$PKG_VSN" ]; then + echo "Chart version in $CHART_FILE is not in sync with release version." + echo "Chart version: $CHART_VSN" + echo "Release version: $PKG_VSN" + exit 3 +fi diff --git a/scripts/xref-check.escript b/scripts/xref-check.escript new file mode 100755 index 000000000..a257734d4 --- /dev/null +++ b/scripts/xref-check.escript @@ -0,0 +1,58 @@ +#!/usr/bin/env escript + +%%% @doc +%%% Unlike rebar3 xref check, this script runs the full xref checks in the EMQX release dir, +%%% meaning all the modules for release are analysed. +%%% For behavior configuration, all rebar3 related modules attributes, filters are not used in this script, +%%% instead all the filters, checks are defined in `xref_check.eterm` +main(_) -> + {ok, [Jobs]} = file:consult("scripts/xref_check.eterm"), + lists:foreach(fun(J) -> do_check(J) end, Jobs), + case get(is_warn_found) of + true -> + halt(1); + _ -> + ok + end. + +do_check(#{ name := Name + , analysis := Analysis + , excl_apps := ExclApps + , excl_mods := ExclMods + , filters := Filters + }) -> + xref:start(Name), + %% Build a table for later printing more informative warnings. + %% The table is currently not in use. + Tid = ets:new(Name, [ordered_set, named_table]), + xref:set_default(Name, [{verbose,false}, {warnings,false}]), + Profile = case filelib:is_file("EMQX_ENTERPRISE") of + true -> 'emqx-ee'; + false -> emqx + end, + Dir = filename:join(["_build/", Profile, "rel/emqx/lib/"]), + xref:add_release(Name, Dir), + xref:add_application(Name, code:lib_dir(erts)), + [ case xref:remove_application(Name, App) of + ok -> ok; + {error, xref_base, {no_such_application, _}} -> ok + end || App <- ExclApps + ], + + [case xref:remove_module(Name, M) of + ok -> ok; + %% but in doc it should return '{error, module(), Reason}` + {error, xref_base, {no_such_module, M}} -> ok + end || M <- ExclMods + ], + ModuleInfos = xref:info(Name, modules), + LibInfos = xref:info(Name, libraries), + true = ets:insert(Tid, ModuleInfos ++ LibInfos), + {ok, Res0} = xref:analyse(Name, Analysis), + Res = Res0 -- Filters, + Res =/= [] andalso + begin + put(is_warn_found, true), + io:format("** Warnings for ~p~n : ~p~n", [Name, Res]) + end, + xref:stop(Name). diff --git a/scripts/xref_check.eterm b/scripts/xref_check.eterm new file mode 100644 index 000000000..3a6e20835 --- /dev/null +++ b/scripts/xref_check.eterm @@ -0,0 +1,540 @@ +%% -*- mode: erlang; -*- +[ %% Check undefined_function_calls + #{ name => undefined_function_calls + , analysis => undefined_function_calls + , excl_apps => + [ observer + , redbug + ] + , excl_mods => + [ hipe_unified_loader + , systools_make + , systools + , systools_relup + , basho_bench_driver_erldis + , release_handler + , cuttlefish_rebar_plugin + ] + , filters => + [{{coap_client,channel_apply,3},{coap_dtls_socket,close,1}}, + {{coap_client,channel_apply,3},{coap_dtls_socket,connect,2}}, + {{coap_client,channel_apply,3},{coap_udp_socket,close,1}}, + {{coap_client,channel_apply,3},{coap_udp_socket,get_channel,2}}, + {{coap_client,channel_apply,3},{coap_udp_socket,start_link,0}}, + {{coap_client,test,0},{eunit,test,1}}, + {{coap_core_link,test,0},{eunit,test,1}}, + {{coap_message_parser,test,0},{eunit,test,1}}, + {{coap_observer,init,1},{coap_dtls_socket,connect,2}}, + {{coap_observer,init,1},{coap_udp_socket,get_channel,2}}, + {{coap_observer,init,1},{coap_udp_socket,start_link,0}}, + {{coap_observer,terminate,2},{coap_dtls_socket,close,1}}, + {{coap_observer,terminate,2},{coap_udp_socket,close,1}}, + + %% Exclude hipe which is disabled + {{code,beam_file_native_md5,2},{hipe_unified_loader,chunk_name,1}}, + {{code,get_native_fun,0},{hipe_unified_loader,chunk_name,1}}, + {{code,load_native_code_for_all_loaded,1}, + {hipe_unified_loader,chunk_name,1}}, + {{code_server,handle_call,3},{hipe_unified_loader,load,3}}, + {{code_server,handle_call,3},{hipe_unified_loader,load_module,4}}, + {{code_server,try_load_module_2,6}, + {hipe_unified_loader,load_native_code,3}}, + {{compile,embed_native_code,2},{hipe_unified_loader,chunk_name,1}}, + {{compile,native_compile_1,2},{hipe,compile,4}}, + + + {{core_link,test,0},{eunit,test,1}}, + {{emqx_misc,ipv6_probe,1},{gen_tcp,ipv6_probe,0}}, + {{eredis_parser,test,0},{eunit,test,1}}, + {{gen_rpc_driver_ssl,authenticate_client,3}, + {ssl_verify_hostname,verify_cert_hostname,2}}, + {{gen_rpc_driver_ssl,merge_ssl_options,2}, + {ssl_verify_hostname,verify_fun,3}}, + {{gproc_dist,from_leader,3},{gen_leader,leader_cast,2}}, + {{gproc_dist,handle_call,4},{gen_leader,leader_node,1}}, + {{gproc_dist,handle_leader_cast,3},{gen_leader,alive,1}}, + {{gproc_dist,handle_leader_cast,3},{gen_leader,broadcast,3}}, + {{gproc_dist,initiate_sync,3},{gen_leader,alive,1}}, + {{gproc_dist,initiate_sync,3},{gen_leader,broadcast,3}}, + {{gproc_dist,leader_call,1},{gen_leader,leader_call,2}}, + {{gproc_dist,leader_cast,1},{gen_leader,leader_cast,2}}, + {{gproc_dist,send_sync_complete,3},{gen_leader,broadcast,3}}, + {{gproc_dist,start_link,1},{gen_leader,start_link,6}}, + {{inets_ftp_wrapper,start_service,1},{ftp,start_service,1}}, + {{inets_ftp_wrapper,start_standalone,1},{ftp,start_standalone,1}}, + {{inets_ftp_wrapper,stop_service,1},{ftp,stop_service,1}}, + {{inets_tftp_wrapper,start_service,1},{tftp,start_service,1}}, + {{inets_tftp_wrapper,start_standalone,1},{tftp,start_standalone,1}}, + {{inets_tftp_wrapper,stop_service,1},{tftp,stop_service,1}}, + {{jose_chacha20_poly1305_libsodium,authenticate,3}, + {libsodium_crypto_onetimeauth_poly1305,crypto_onetimeauth_poly1305,2}}, + {{jose_chacha20_poly1305_libsodium,decrypt,5}, + {libsodium_crypto_aead_chacha20poly1305,ietf_decrypt_detached,5}}, + {{jose_chacha20_poly1305_libsodium,encrypt,4}, + {libsodium_crypto_aead_chacha20poly1305,ietf_encrypt_detached,4}}, + {{jose_chacha20_poly1305_libsodium,one_time_key,2}, + {libsodium_crypto_stream_chacha20,ietf_xor_ic,4}}, + {{jose_chacha20_poly1305_libsodium,verify,4}, + {libsodium_crypto_onetimeauth_poly1305,verify,3}}, + {{jose_curve25519_libdecaf,ed25519_sign,2}, + {libdecaf_curve25519,ed25519_sign,2}}, + {{jose_curve25519_libdecaf,ed25519_verify,3}, + {libdecaf_curve25519,ed25519_verify,3}}, + {{jose_curve25519_libdecaf,ed25519ph_sign,2}, + {libdecaf_curve25519,ed25519ph_sign,2}}, + {{jose_curve25519_libdecaf,ed25519ph_verify,3}, + {libdecaf_curve25519,ed25519ph_verify,3}}, + {{jose_curve25519_libdecaf,eddsa_keypair,0}, + {libdecaf_curve25519,eddsa_keypair,0}}, + {{jose_curve25519_libdecaf,eddsa_keypair,1}, + {libdecaf_curve25519,eddsa_keypair,1}}, + {{jose_curve25519_libdecaf,eddsa_secret_to_public,1}, + {libdecaf_curve25519,eddsa_secret_to_pk,1}}, + {{jose_curve25519_libdecaf,x25519_keypair,0}, + {libdecaf_curve25519,x25519_keypair,0}}, + {{jose_curve25519_libdecaf,x25519_keypair,1}, + {libdecaf_curve25519,x25519_keypair,1}}, + {{jose_curve25519_libdecaf,x25519_secret_to_public,1}, + {libdecaf_curve25519,x25519,1}}, + {{jose_curve25519_libdecaf,x25519_shared_secret,2}, + {libdecaf_curve25519,x25519,2}}, + {{jose_curve25519_libsodium,ed25519_sign,2}, + {libsodium_crypto_sign_ed25519,detached,2}}, + {{jose_curve25519_libsodium,ed25519_verify,3}, + {libsodium_crypto_sign_ed25519,verify_detached,3}}, + {{jose_curve25519_libsodium,ed25519ph_sign,2}, + {libsodium_crypto_hash_sha512,crypto_hash_sha512,1}}, + {{jose_curve25519_libsodium,ed25519ph_verify,3}, + {libsodium_crypto_hash_sha512,crypto_hash_sha512,1}}, + {{jose_curve25519_libsodium,eddsa_keypair,0}, + {libsodium_crypto_sign_ed25519,keypair,0}}, + {{jose_curve25519_libsodium,eddsa_keypair,1}, + {libsodium_crypto_sign_ed25519,seed_keypair,1}}, + {{jose_curve25519_libsodium,eddsa_secret_to_public,1}, + {libsodium_crypto_sign_ed25519,seed_keypair,1}}, + {{jose_curve25519_libsodium,x25519_keypair,0}, + {libsodium_crypto_box_curve25519xsalsa20poly1305,keypair,0}}, + {{jose_curve25519_libsodium,x25519_secret_to_public,1}, + {libsodium_crypto_scalarmult_curve25519,base,1}}, + {{jose_curve25519_libsodium,x25519_shared_secret,2}, + {libsodium_crypto_scalarmult_curve25519,crypto_scalarmult_curve25519,2}}, + {{jose_curve448_libdecaf,ed448_sign,2},{libdecaf_curve448,ed448_sign,2}}, + {{jose_curve448_libdecaf,ed448_sign,3},{libdecaf_curve448,ed448_sign,3}}, + {{jose_curve448_libdecaf,ed448_verify,3}, + {libdecaf_curve448,ed448_verify,3}}, + {{jose_curve448_libdecaf,ed448_verify,4}, + {libdecaf_curve448,ed448_verify,4}}, + {{jose_curve448_libdecaf,ed448ph_sign,2}, + {libdecaf_curve448,ed448ph_sign,2}}, + {{jose_curve448_libdecaf,ed448ph_sign,3}, + {libdecaf_curve448,ed448ph_sign,3}}, + {{jose_curve448_libdecaf,ed448ph_verify,3}, + {libdecaf_curve448,ed448ph_verify,3}}, + {{jose_curve448_libdecaf,ed448ph_verify,4}, + {libdecaf_curve448,ed448ph_verify,4}}, + {{jose_curve448_libdecaf,eddsa_keypair,0}, + {libdecaf_curve448,eddsa_keypair,0}}, + {{jose_curve448_libdecaf,eddsa_keypair,1}, + {libdecaf_curve448,eddsa_keypair,1}}, + {{jose_curve448_libdecaf,eddsa_secret_to_public,1}, + {libdecaf_curve448,eddsa_secret_to_pk,1}}, + {{jose_curve448_libdecaf,x448_keypair,0}, + {libdecaf_curve448,x448_keypair,0}}, + {{jose_curve448_libdecaf,x448_keypair,1}, + {libdecaf_curve448,x448_keypair,1}}, + {{jose_curve448_libdecaf,x448_secret_to_public,1}, + {libdecaf_curve448,x448,1}}, + {{jose_curve448_libdecaf,x448_shared_secret,2},{libdecaf_curve448,x448,2}}, + {{jose_json_jason,decode,1},{'Elixir.Jason','decode!',1}}, + {{jose_json_jason,encode,1},{'Elixir.Jason','encode!',1}}, + {{jose_json_jsone,decode,1},{jsone,decode,1}}, + {{jose_json_jsone,encode,1},{jsone,encode,2}}, + {{jose_json_jsx,decode,1},{jsx,decode,2}}, + {{jose_json_jsx,encode,1},{jsx,encode,1}}, + {{jose_json_ojson,decode,1},{ojson,'decode!',1}}, + {{jose_json_ojson,encode,1},{ojson,'encode!',1}}, + {{jose_json_poison,decode,1},{'Elixir.Poison','decode!',1}}, + {{jose_json_poison,encode,1},{'Elixir.Poison','encode!',1}}, + {{jose_json_poison_compat_encoder,decode,1},{'Elixir.Poison','decode!',1}}, + {{jose_json_poison_compat_encoder,encode,1}, + {'Elixir.IO',iodata_to_binary,1}}, + {{jose_json_poison_compat_encoder,lexical_encode,1}, + {'Elixir.Poison.EncodeError',exception,1}}, + {{jose_json_poison_compat_encoder,lexical_encode,1}, + {'Elixir.Poison.Encoder.Atom',encode,2}}, + {{jose_json_poison_compat_encoder,lexical_encode,1}, + {'Elixir.Poison.Encoder.BitString',encode,2}}, + {{jose_json_poison_compat_encoder,lexical_encode,1}, + {'Elixir.Poison.Encoder.Float',encode,2}}, + {{jose_json_poison_compat_encoder,lexical_encode,1}, + {'Elixir.Poison.Encoder.Integer',encode,2}}, + {{jose_json_poison_compat_encoder,lexical_encode_map,1}, + {'Elixir.Poison.Encoder.BitString',encode,2}}, + {{jose_json_poison_compat_encoder,lexical_encode_name,1}, + {'Elixir.Atom',to_string,1}}, + {{jose_json_poison_compat_encoder,lexical_encode_name,1}, + {'Elixir.Kernel',inspect,1}}, + {{jose_json_poison_compat_encoder,lexical_encode_name,1}, + {'Elixir.Poison.EncodeError',exception,1}}, + {{jose_json_poison_compat_encoder,lexical_encode_struct,2}, + {'Elixir.Enum',flat_map,2}}, + {{jose_json_poison_compat_encoder,lexical_encode_struct,2}, + {'Elixir.HashDict',size,1}}, + {{jose_json_poison_compat_encoder,lexical_encode_struct,2}, + {'Elixir.Map',from_struct,1}}, + {{jose_json_poison_compat_encoder,lexical_encode_struct,2}, + {'Elixir.Poison.Encoder.BitString',encode,2}}, + {{jose_json_poison_lexical_encoder,decode,1}, + {'Elixir.Poison','decode!',1}}, + {{jose_json_poison_lexical_encoder,encode,1}, + {'Elixir.JOSE.Poison','lexical_encode!',1}}, + {{jose_jwk_kty_rsa,try_generate_key,3},{cutkey,rsa,3}}, + {{jose_sha3_keccakf1600_driver,sha3_224,1}, + {keccakf1600_fips202,sha3_224,1}}, + {{jose_sha3_keccakf1600_driver,sha3_256,1}, + {keccakf1600_fips202,sha3_256,1}}, + {{jose_sha3_keccakf1600_driver,sha3_384,1}, + {keccakf1600_fips202,sha3_384,1}}, + {{jose_sha3_keccakf1600_driver,sha3_512,1}, + {keccakf1600_fips202,sha3_512,1}}, + {{jose_sha3_keccakf1600_driver,shake128,2}, + {keccakf1600_fips202,shake128,2}}, + {{jose_sha3_keccakf1600_driver,shake256,2}, + {keccakf1600_fips202,shake256,2}}, + {{jose_sha3_keccakf1600_nif,sha3_224,1},{keccakf1600,hash,2}}, + {{jose_sha3_keccakf1600_nif,sha3_256,1},{keccakf1600,hash,2}}, + {{jose_sha3_keccakf1600_nif,sha3_384,1},{keccakf1600,hash,2}}, + {{jose_sha3_keccakf1600_nif,sha3_512,1},{keccakf1600,hash,2}}, + {{jose_sha3_keccakf1600_nif,shake128,2},{keccakf1600,hash,3}}, + {{jose_sha3_keccakf1600_nif,shake256,2},{keccakf1600,hash,3}}, + {{jose_sha3_libdecaf,sha3_224,1},{libdecaf_sha3,hash,2}}, + {{jose_sha3_libdecaf,sha3_256,1},{libdecaf_sha3,hash,2}}, + {{jose_sha3_libdecaf,sha3_384,1},{libdecaf_sha3,hash,2}}, + {{jose_sha3_libdecaf,sha3_512,1},{libdecaf_sha3,hash,2}}, + {{jose_sha3_libdecaf,shake128,2},{libdecaf_sha3,hash,3}}, + {{jose_sha3_libdecaf,shake256,2},{libdecaf_sha3,hash,3}}, + {{lwm2m_coap_client,channel_apply,3},{lwm2m_coap_dtls_socket,close,1}}, + {{lwm2m_coap_client,channel_apply,3},{lwm2m_coap_dtls_socket,connect,2}}, + {{lwm2m_coap_client,channel_apply,3},{lwm2m_coap_udp_socket,close,1}}, + {{lwm2m_coap_client,channel_apply,3}, + {lwm2m_coap_udp_socket,get_channel,2}}, + {{lwm2m_coap_client,channel_apply,3},{lwm2m_coap_udp_socket,start_link,0}}, + {{lwm2m_coap_client,test,0},{eunit,test,1}}, + {{lwm2m_coap_message_parser,test,0},{eunit,test,1}}, + {{lwm2m_coap_observer,init,1},{lwm2m_coap_dtls_socket,connect,2}}, + {{lwm2m_coap_observer,init,1},{lwm2m_coap_udp_socket,get_channel,2}}, + {{lwm2m_coap_observer,init,1},{lwm2m_coap_udp_socket,start_link,0}}, + {{lwm2m_coap_observer,terminate,2},{lwm2m_coap_dtls_socket,close,1}}, + {{lwm2m_coap_observer,terminate,2},{lwm2m_coap_udp_socket,close,1}}, + {{ranch_app,consider_profiling,0},{eprof,start,0}}, + {{ranch_app,consider_profiling,0},{eprof,start_profiling,1}}, + {{ranch_app,profile_output,0},{eprof,analyze,1}}, + {{ranch_app,profile_output,0},{eprof,log,1}}, + {{ranch_app,profile_output,0},{eprof,stop_profiling,0}} + ] + } + + %% Check undefined_functions +, #{ name => undefined_functions + , analysis => undefined_functions + , excl_apps => + [ observer + ] + , excl_mods => + [ systools + , systools_make + , release_handler + , systools_relup + , cuttlefish_rebar_plugin + ] + , filters => + [{'Elixir.Atom',to_string,1}, + {'Elixir.Enum',flat_map,2}, + {'Elixir.HashDict',size,1}, + {'Elixir.IO',iodata_to_binary,1}, + {'Elixir.JOSE.Poison','lexical_encode!',1}, + {'Elixir.Jason','decode!',1}, + {'Elixir.Jason','encode!',1}, + {'Elixir.Kernel',inspect,1}, + {'Elixir.Map',from_struct,1}, + {'Elixir.Poison','decode!',1}, + {'Elixir.Poison','encode!',1}, + {'Elixir.Poison.EncodeError',exception,1}, + {'Elixir.Poison.Encoder.Atom',encode,2}, + {'Elixir.Poison.Encoder.BitString',encode,2}, + {'Elixir.Poison.Encoder.Float',encode,2}, + {'Elixir.Poison.Encoder.Integer',encode,2}, + {coap_dtls_socket,close,1}, + {coap_dtls_socket,connect,2}, + {coap_udp_socket,close,1}, + {coap_udp_socket,get_channel,2}, + {coap_udp_socket,start_link,0}, + {ct_slave,start,2}, + {ct_slave,stop,1}, + {cutkey,rsa,3}, + {eprof,analyze,1}, + {eprof,log,1}, + {eprof,start,0}, + {eprof,start_profiling,1}, + {eprof,stop_profiling,0}, + {erldis,mget,2}, + {erldis,set,3}, + {erldis_client,connect,0}, + {et_collector,iterate,5}, + {et_collector,report,2}, + {et_selector,parse_event,2}, + {et_viewer,get_collector_pid,1}, + {et_viewer,start_link,1}, + {eunit,test,1}, + {ftp,start_service,1}, + {ftp,start_standalone,1}, + {ftp,stop_service,1}, + {gen_leader,alive,1}, + {gen_leader,broadcast,3}, + {gen_leader,leader_call,2}, + {gen_leader,leader_cast,2}, + {gen_leader,leader_node,1}, + {gen_leader,start_link,6}, + {gen_tcp,ipv6_probe,0}, + + %% We dont use hipes + {hipe,compile,4}, + {hipe_bifs,add_ref,2}, + {hipe_bifs,alloc_data,3}, + {hipe_bifs,alloc_loader_state,1}, + {hipe_bifs,atom_to_word,1}, + {hipe_bifs,bif_address,3}, + {hipe_bifs,check_crc,1}, + {hipe_bifs,commit_patch_load,1}, + {hipe_bifs,enter_code,3}, + {hipe_bifs,enter_sdesc,2}, + {hipe_bifs,find_na_or_make_stub,1}, + {hipe_bifs,fun_to_address,1}, + {hipe_bifs,get_fe,2}, + {hipe_bifs,merge_term,1}, + {hipe_bifs,patch_call,3}, + {hipe_bifs,patch_insn,3}, + {hipe_bifs,primop_address,1}, + {hipe_bifs,set_funinfo_native_address,3}, + {hipe_bifs,set_native_address,3}, + {hipe_bifs,set_native_address_in_fe,2}, + {hipe_bifs,term_to_word,1}, + {hipe_bifs,write_u32,2}, + {hipe_bifs,write_u64,2}, + {hipe_bifs,write_u8,2}, + + + {jsone,decode,1}, + {jsone,encode,2}, + {jsx,decode,2}, + {jsx,encode,1}, + {keccakf1600,hash,2}, + {keccakf1600,hash,3}, + {keccakf1600_fips202,sha3_224,1}, + {keccakf1600_fips202,sha3_256,1}, + {keccakf1600_fips202,sha3_384,1}, + {keccakf1600_fips202,sha3_512,1}, + {keccakf1600_fips202,shake128,2}, + {keccakf1600_fips202,shake256,2}, + {libdecaf_curve25519,ed25519_sign,2}, + {libdecaf_curve25519,ed25519_verify,3}, + {libdecaf_curve25519,ed25519ph_sign,2}, + {libdecaf_curve25519,ed25519ph_verify,3}, + {libdecaf_curve25519,eddsa_keypair,0}, + {libdecaf_curve25519,eddsa_keypair,1}, + {libdecaf_curve25519,eddsa_secret_to_pk,1}, + {libdecaf_curve25519,x25519,1}, + {libdecaf_curve25519,x25519,2}, + {libdecaf_curve25519,x25519_keypair,0}, + {libdecaf_curve25519,x25519_keypair,1}, + {libdecaf_curve448,ed448_sign,2}, + {libdecaf_curve448,ed448_sign,3}, + {libdecaf_curve448,ed448_verify,3}, + {libdecaf_curve448,ed448_verify,4}, + {libdecaf_curve448,ed448ph_sign,2}, + {libdecaf_curve448,ed448ph_sign,3}, + {libdecaf_curve448,ed448ph_verify,3}, + {libdecaf_curve448,ed448ph_verify,4}, + {libdecaf_curve448,eddsa_keypair,0}, + {libdecaf_curve448,eddsa_keypair,1}, + {libdecaf_curve448,eddsa_secret_to_pk,1}, + {libdecaf_curve448,x448,1}, + {libdecaf_curve448,x448,2}, + {libdecaf_curve448,x448_keypair,0}, + {libdecaf_curve448,x448_keypair,1}, + {libdecaf_sha3,hash,2}, + {libdecaf_sha3,hash,3}, + {libsodium_crypto_aead_chacha20poly1305,ietf_decrypt_detached,5}, + {libsodium_crypto_aead_chacha20poly1305,ietf_encrypt_detached,4}, + {libsodium_crypto_box_curve25519xsalsa20poly1305,keypair,0}, + {libsodium_crypto_hash_sha512,crypto_hash_sha512,1}, + {libsodium_crypto_onetimeauth_poly1305,crypto_onetimeauth_poly1305,2}, + {libsodium_crypto_onetimeauth_poly1305,verify,3}, + {libsodium_crypto_scalarmult_curve25519,base,1}, + {libsodium_crypto_scalarmult_curve25519,crypto_scalarmult_curve25519,2}, + {libsodium_crypto_sign_ed25519,detached,2}, + {libsodium_crypto_sign_ed25519,keypair,0}, + {libsodium_crypto_sign_ed25519,seed_keypair,1}, + {libsodium_crypto_sign_ed25519,verify_detached,3}, + {libsodium_crypto_stream_chacha20,ietf_xor_ic,4}, + {lwm2m_coap_dtls_socket,close,1}, + {lwm2m_coap_dtls_socket,connect,2}, + {lwm2m_coap_udp_socket,close,1}, + {lwm2m_coap_udp_socket,get_channel,2}, + {lwm2m_coap_udp_socket,start_link,0}, + {ojson,'decode!',1}, + {ojson,'encode!',1}, + {ssl_verify_hostname,verify_cert_hostname,2}, + {ssl_verify_hostname,verify_fun,3}, + {tftp,start_service,1}, + {tftp,start_standalone,1}, + {tftp,stop_service,1}, + + %% Xref could not check itself + {xref,add_application,3}, + {xref,analyze,2}, + {xref,set_default,3}, + {xref,set_library_path,2}, + {xref,start,2}, + {xref,stop,1} + ] + } + +, #{ name => locals_not_used + , analysis => locals_not_used + , excl_apps => + [ + ] + , excl_mods => + [ + ] + , filters => + [{coap_core_link_parser,return_error,2}, + {core_link_parser,return_error,2}, + {emqx_exhook_pb,e_type_double,3}, + {emqx_exhook_pb,e_type_fixed32,3}, + {emqx_exhook_pb,e_type_fixed64,3}, + {emqx_exhook_pb,e_type_float,3}, + {emqx_exhook_pb,e_type_int32,3}, + {emqx_exhook_pb,e_type_int64,3}, + {emqx_exhook_pb,e_type_sfixed32,3}, + {emqx_exhook_pb,e_type_sfixed64,3}, + {emqx_exhook_pb,e_type_sint,3}, + {emqx_exhook_pb,m_overwrite,3}, + {emqx_exhook_pb,v_ok,3}, + {emqx_exproto_pb,e_type_bool,3}, + {emqx_exproto_pb,e_type_double,3}, + {emqx_exproto_pb,e_type_fixed32,3}, + {emqx_exproto_pb,e_type_fixed64,3}, + {emqx_exproto_pb,e_type_float,3}, + {emqx_exproto_pb,e_type_int32,3}, + {emqx_exproto_pb,e_type_int64,3}, + {emqx_exproto_pb,e_type_sfixed32,3}, + {emqx_exproto_pb,e_type_sfixed64,3}, + {emqx_exproto_pb,e_type_sint,3}, + {emqx_exproto_pb,m_overwrite,3}, + {emqx_exproto_pb,v_ok,3}, + {grpc_health_pb,cons,3}, + {grpc_health_pb,e_type_bool,3}, + {grpc_health_pb,e_type_bytes,3}, + {grpc_health_pb,e_type_double,3}, + {grpc_health_pb,e_type_fixed32,3}, + {grpc_health_pb,e_type_fixed64,3}, + {grpc_health_pb,e_type_float,3}, + {grpc_health_pb,e_type_int32,3}, + {grpc_health_pb,e_type_int64,3}, + {grpc_health_pb,e_type_sfixed32,3}, + {grpc_health_pb,e_type_sfixed64,3}, + {grpc_health_pb,e_type_sint,3}, + {grpc_health_pb,e_varint,3}, + {grpc_health_pb,'erlang_++',3}, + {grpc_health_pb,lists_reverse,2}, + {grpc_health_pb,m_overwrite,3}, + {grpc_health_pb,v_ok,3}, + {grpc_reflection_pb,e_type_bool,3}, + {grpc_reflection_pb,e_type_double,3}, + {grpc_reflection_pb,e_type_fixed32,3}, + {grpc_reflection_pb,e_type_fixed64,3}, + {grpc_reflection_pb,e_type_float,3}, + {grpc_reflection_pb,e_type_int64,3}, + {grpc_reflection_pb,e_type_sfixed32,3}, + {grpc_reflection_pb,e_type_sfixed64,3}, + {grpc_reflection_pb,e_type_sint,3}, + {grpc_reflection_pb,e_varint,3}, + {grpc_reflection_pb,m_overwrite,3}, + {grpc_reflection_pb,v_ok,3}, + {prometheus_text_format,escape_metric_help,1}, + + %% + %% To be used in grammar files to throw an error message to the parser + %% toplevel. Doesn't have to be exported! + %% + {redbug_parser,return_error,2}, + {rulesql,return_error,2}, + {xmerl_b64Bin,return_error,2}, + {xmerl_xpath_parse,return_error,2}] + } + +, #{ name => deprecated_function_calls + , analysis => deprecated_function_calls + , excl_apps => + [ + ] + , excl_mods => + [ + ] + , filters => + [{{coap_core_link,join_uri,1},{http_uri,encode,1}}, + {{disk_log_server,dist_pids,1},{pg2,get_members,1}}, + {{disk_log_server,do_accessible_logs,0},{pg2,which_groups,0}}, + {{disk_log_server,do_get_log_pids,1},{pg2,get_members,1}}, + {{disk_log_server,do_open,3},{pg2,create,1}}, + {{disk_log_server,erase_log,2},{pg2,leave,2}}, + {{disk_log_server,handle_info,2},{pg2,join,2}}, + {{gen_fsm,error_info,7},{gen_fsm,format_log,1}}, + {{gen_fsm,error_info,7},{gen_fsm,format_log,2}}, + {{gen_fsm,handle_msg,8},{gen_fsm,format_log,1}}, + {{gen_fsm,handle_msg,8},{gen_fsm,format_log,2}}, + {{httpd_util,decode_hex,1},{http_uri,decode,1}}, + {{httpd_util,encode_hex,1},{http_uri,encode,1}}, + {{igor,tidy,2},{erl_tidy,module,2}}, + {{jose_public_key,pseudo_random_function,1},{crypto,hmac,4}}, + {{lwm2m_coap_client,make_segment,1},{http_uri,decode,1}}, + {{lwm2m_coap_client,resolve_uri,1},{http_uri,parse,2}}, + {{lwm2m_coap_responder,cancel_observer,2},{pg2,delete,1}}, + {{lwm2m_coap_responder,cancel_observer,2},{pg2,get_members,1}}, + {{lwm2m_coap_responder,cancel_observer,2},{pg2,leave,2}}, + {{lwm2m_coap_responder,handle_observe,4},{pg2,create,1}}, + {{lwm2m_coap_responder,handle_observe,4},{pg2,join,2}}, + {{lwm2m_coap_responder,notify,2},{pg2,get_members,1}}, + {{public_key,ssh_hostkey_fingerprint,1},{public_key,ssh_encode,2}}, + {{public_key,ssh_hostkey_fingerprint,2},{public_key,ssh_encode,2}}, + {{ranch_ssl,handshake,3},{ssl,ssl_accept,3}}] + } + +, #{ name => deprecated_functions + , analysis => deprecated_functions + , excl_apps => + [ + ] + , excl_mods => + [ + ] + , filters => + [{crypto,hmac,4}, + {erl_tidy,module,2}, + {gen_fsm,format_log,1}, + {gen_fsm,format_log,2}, + {http_uri,decode,1}, + {http_uri,encode,1}, + {http_uri,parse,2}, + {pg2,create,1}, + {pg2,delete,1}, + {pg2,get_members,1}, + {pg2,join,2}, + {pg2,leave,2}, + {pg2,which_groups,0}, + {public_key,ssh_encode,2}, + {ssl,ssl_accept,3}] + } +]. diff --git a/src/emqx.appup.src b/src/emqx.appup.src index 690acc648..5f35836be 100644 --- a/src/emqx.appup.src +++ b/src/emqx.appup.src @@ -2,14 +2,25 @@ %% Unless you know what you are doing, DO NOT edit manually!! {VSN, [{"4.4.8", - [{load_module,emqx_relup,brutal_purge,soft_purge,[]}, + [{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, + {load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}]}, {"4.4.7", - [{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, @@ -19,7 +30,12 @@ {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}]}, {"4.4.6", - [{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, @@ -29,7 +45,12 @@ {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}]}, {"4.4.5", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_misc,brutal_purge,soft_purge,[]}, @@ -42,7 +63,12 @@ {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, @@ -63,7 +89,11 @@ {load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {add_module,emqx_calendar}, {update,emqx_broker_sup,supervisor}, @@ -92,7 +122,11 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_relup}]}, {"4.4.2", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {add_module,emqx_calendar}, {update,emqx_broker_sup,supervisor}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, @@ -123,7 +157,10 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_relup}]}, {"4.4.1", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_packet,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, @@ -161,7 +198,9 @@ {load_module,emqx_connection,brutal_purge,soft_purge,[]}, {add_module,emqx_relup}]}, {"4.4.0", - [{load_module,emqx_packet,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_packet,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, {add_module,emqx_calendar}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, @@ -203,14 +242,25 @@ {load_module,emqx_limiter,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], [{"4.4.8", - [{load_module,emqx_relup,brutal_purge,soft_purge,[]}, + [{load_module,emqx_plugins,brutal_purge,soft_purge,[]}, + {load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}]}, {"4.4.7", - [{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, @@ -220,7 +270,12 @@ {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}]}, {"4.4.6", - [{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, @@ -230,7 +285,12 @@ {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}]}, {"4.4.5", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, @@ -243,7 +303,12 @@ {load_module,emqx_shared_sub,brutal_purge,soft_purge,[]}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}]}, {"4.4.4", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_alarm,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_access_control,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]}, @@ -264,7 +329,11 @@ {load_module,emqx_plugins,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]}]}, {"4.4.3", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx,brutal_purge,soft_purge,[]}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, @@ -292,7 +361,11 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_relup}]}, {"4.4.2", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, {load_module,emqx_ctl,brutal_purge,soft_purge,[]}, @@ -322,7 +395,10 @@ {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_relup}]}, {"4.4.1", - [{load_module,emqx_message,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_ws_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_message,brutal_purge,soft_purge,[]}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, {load_module,emqx_mqtt_caps,brutal_purge,soft_purge,[]}, @@ -359,7 +435,9 @@ {load_module,emqx_connection,brutal_purge,soft_purge,[]}, {delete_module,emqx_relup}]}, {"4.4.0", - [{load_module,emqx_broker,brutal_purge,soft_purge,[]}, + [{load_module,emqx_router_helper,brutal_purge,soft_purge,[]}, + {load_module,emqx_router,brutal_purge,soft_purge,[]}, + {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {load_module,emqx_message,brutal_purge,soft_purge,[]}, {update,emqx_broker_sup,supervisor}, {load_module,emqx_mqtt_caps,brutal_purge,soft_purge,[]}, diff --git a/src/emqx_alarm.erl b/src/emqx_alarm.erl index e3b45e295..d838e139e 100644 --- a/src/emqx_alarm.erl +++ b/src/emqx_alarm.erl @@ -191,10 +191,8 @@ init([Opts]) -> size_limit = SizeLimit, validity_period = ValidityPeriod})}. -%% suppress dialyzer warning due to dirty read/write race condition. %% TODO: change from dirty_read/write to transactional. %% TODO: handle mnesia write errors. --dialyzer([{nowarn_function, [handle_call/3]}]). handle_call({activate_alarm, Name, Details}, _From, State = #state{actions = Actions}) -> case mnesia:dirty_read(?ACTIVATED_ALARM, Name) of [#activated_alarm{name = Name}] -> diff --git a/src/emqx_channel.erl b/src/emqx_channel.erl index 881a0f3f9..64b235917 100644 --- a/src/emqx_channel.erl +++ b/src/emqx_channel.erl @@ -87,7 +87,7 @@ %% Quota checkers quota :: maybe(emqx_limiter:limiter()), %% Timers - timers :: #{atom() => disabled | maybe(reference())}, + timers :: #{channel_timer() => disabled | maybe(reference())}, %% Conn State conn_state :: conn_state(), %% Takeover @@ -109,6 +109,13 @@ -type(replies() :: emqx_types:packet() | reply() | [reply()]). +-type(channel_timer() :: alive_timer + | retry_timer + | await_timer + | expire_timer + | will_timer + | quota_timer). + -define(IS_MQTT_V5, #channel{conninfo = #{proto_ver := ?MQTT_PROTO_V5}}). -define(TIMER_TABLE, #{ @@ -147,8 +154,6 @@ , 'send_msg.dropped.too_large' ]). --dialyzer({no_match, [shutdown/4, ensure_timer/2, interval/2]}). - %%-------------------------------------------------------------------- %% Info, Attrs and Caps %%-------------------------------------------------------------------- @@ -268,7 +273,6 @@ setting_peercert_infos(Peercert, ClientInfo, Options) -> ClientId = peer_cert_as(peer_cert_as_clientid, Options, Peercert, DN, CN), ClientInfo#{username => Username, clientid => ClientId, dn => DN, cn => CN}. --dialyzer([{nowarn_function, [peer_cert_as/5]}]). % esockd_peercert:peercert is opaque % https://github.com/emqx/esockd/blob/master/src/esockd_peercert.erl peer_cert_as(Key, Options, Peercert, DN, CN) -> @@ -1151,12 +1155,8 @@ handle_timeout(_TRef, Msg, Channel) -> %% Ensure timers %%-------------------------------------------------------------------- -ensure_timer([Name], Channel) -> - ensure_timer(Name, Channel); -ensure_timer([Name | Rest], Channel) -> - ensure_timer(Rest, ensure_timer(Name, Channel)); - -ensure_timer(Name, Channel = #channel{timers = Timers}) -> +-spec ensure_timer(channel_timer(), channel()) -> channel(). +ensure_timer(Name, Channel = #channel{timers = Timers}) when is_atom(Name) -> TRef = maps:get(Name, Timers, undefined), Time = interval(Name, Channel), case TRef == undefined andalso Time > 0 of @@ -1164,6 +1164,7 @@ ensure_timer(Name, Channel = #channel{timers = Timers}) -> false -> Channel %% Timer disabled or exists end. +-spec ensure_timer(channel_timer(), timeout(), channel()) -> channel(). ensure_timer(Name, Time, Channel = #channel{timers = Timers}) -> Msg = maps:get(Name, ?TIMER_TABLE), TRef = emqx_misc:start_timer(Time, Msg), @@ -1178,36 +1179,47 @@ reset_timer(Name, Time, Channel) -> clean_timer(Name, Channel = #channel{timers = Timers}) -> Channel#channel{timers = maps:remove(Name, Timers)}. +-spec interval(channel_timer(), channel()) -> timeout(). interval(alive_timer, #channel{keepalive = KeepAlive}) -> emqx_keepalive:info(interval, KeepAlive); interval(retry_timer, #channel{session = Session}) -> timer:seconds(emqx_session:info(retry_interval, Session)); interval(await_timer, #channel{session = Session}) -> - timer:seconds(emqx_session:info(await_rel_timeout, Session)); -interval(expire_timer, #channel{conninfo = ConnInfo}) -> - timer:seconds(maps:get(expiry_interval, ConnInfo)); -interval(will_timer, #channel{will_msg = WillMsg}) -> - timer:seconds(will_delay_interval(WillMsg)). + timer:seconds(emqx_session:info(await_rel_timeout, Session)). %%-------------------------------------------------------------------- %% Terminate %%-------------------------------------------------------------------- -spec(terminate(any(), channel()) -> ok). -terminate(_, #channel{conn_state = idle}) -> ok; +terminate(_Reason, #channel{conn_state = idle} = _Channel) -> + ?tp(channel_terminated, #{channel => _Channel, reason => _Reason}), + ok; terminate(normal, Channel) -> run_terminate_hook(normal, Channel); -terminate({shutdown, Reason}, Channel) - when Reason =:= kicked; Reason =:= discarded; Reason =:= takeovered -> - run_terminate_hook(Reason, Channel); terminate(Reason, Channel = #channel{will_msg = WillMsg}) -> - (WillMsg =/= undefined) andalso publish_will_msg(WillMsg), + should_publish_will_message(Reason, Channel) + andalso publish_will_msg(WillMsg), run_terminate_hook(Reason, Channel). -run_terminate_hook(_Reason, #channel{session = undefined}) -> ok; -run_terminate_hook(Reason, #channel{clientinfo = ClientInfo, session = Session}) -> +run_terminate_hook(_Reason, #channel{session = undefined} = _Channel) -> + ?tp(channel_terminated, #{channel => _Channel, reason => _Reason}), + ok; +run_terminate_hook(Reason, #channel{clientinfo = ClientInfo, session = Session} = _Channel) -> + ?tp(channel_terminated, #{channel => _Channel, reason => Reason}), emqx_session:terminate(ClientInfo, Reason, Session). +should_publish_will_message(TerminateReason, Channel) -> + not lists:member(TerminateReason, [ {shutdown, kicked} + , {shutdown, discarded} + , {shutdown, takeovered} + , {shutdown, not_authorized} + ]) + andalso not lists:member(info(conn_state, Channel), [ idle + , connecting + ]) + andalso info(will_msg, Channel) =/= undefined. + %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- @@ -1797,8 +1809,6 @@ shutdown(success, Reply, Channel) -> shutdown(Reason, Reply, Channel) -> {shutdown, Reason, Reply, Channel}. -shutdown(success, Reply, Packet, Channel) -> - shutdown(normal, Reply, Packet, Channel); shutdown(Reason, Reply, Packet, Channel) -> {shutdown, Reason, Reply, Packet, Channel}. diff --git a/src/emqx_connection.erl b/src/emqx_connection.erl index 44f3f9301..c994ecc3d 100644 --- a/src/emqx_connection.erl +++ b/src/emqx_connection.erl @@ -158,12 +158,6 @@ ]). -dialyzer({no_match, [info/2]}). --dialyzer({nowarn_function, [ init/4 - , init_state/3 - , run_loop/2 - , system_terminate/4 - , system_code_change/4 - ]}). -spec(start_link(esockd:transport(), esockd:socket(), proplists:proplist()) -> {ok, pid()}). @@ -318,8 +312,8 @@ run_loop(Parent, State = #state{transport = Transport, peername = Peername, channel = Channel}) -> emqx_logger:set_metadata_peername(esockd:format(Peername)), - emqx_misc:tune_heap_size(emqx_zone:oom_policy( - emqx_channel:info(zone, Channel))), + _ = emqx_misc:tune_heap_size(emqx_zone:oom_policy( + emqx_channel:info(zone, Channel))), case activate_socket(State) of {ok, NState} -> hibernate(Parent, NState); {error, Reason} -> diff --git a/src/emqx_frame.erl b/src/emqx_frame.erl index 5eb971f8a..d32bd6888 100644 --- a/src/emqx_frame.erl +++ b/src/emqx_frame.erl @@ -78,8 +78,6 @@ %% 16#0D,16#0A, 16#0D,16#0A,16#00,16#0D,16#0A,16#51,16#55,16#49,16#54,16#0A -define(PPV2_HEADER_SIG, "\r\n\r\n\0\r\nQUIT\n"). --dialyzer({no_match, [serialize_utf8_string/2]}). - -ifdef(TEST). -export([parse_variable_byte_integer/1]). -endif. @@ -788,8 +786,6 @@ serialize_utf8_pair({Name, Value}) -> serialize_binary_data(Bin) -> [<<(byte_size(Bin)):16/big-unsigned-integer>>, Bin]. -serialize_utf8_string(undefined, false) -> - error(utf8_string_undefined); serialize_utf8_string(undefined, true) -> <<>>; serialize_utf8_string(String, _AllowNull) -> diff --git a/src/emqx_limiter.erl b/src/emqx_limiter.erl index 8e194ed39..0275cb0e5 100644 --- a/src/emqx_limiter.erl +++ b/src/emqx_limiter.erl @@ -55,8 +55,6 @@ -type(limiter() :: #limiter{}). --dialyzer({nowarn_function, [consume/3]}). - %%-------------------------------------------------------------------- %% APIs %%-------------------------------------------------------------------- diff --git a/src/emqx_plugins.erl b/src/emqx_plugins.erl index ca103520d..a01dc2a5b 100644 --- a/src/emqx_plugins.erl +++ b/src/emqx_plugins.erl @@ -41,10 +41,6 @@ -compile(nowarn_export_all). -endif. --dialyzer({no_match, [ plugin_loaded/2 - , plugin_unloaded/2 - ]}). - %%-------------------------------------------------------------------- %% APIs %%-------------------------------------------------------------------- @@ -105,7 +101,7 @@ unload(PluginName) when is_atom(PluginName) -> ?LOG(error, "Plugin ~s is not started", [PluginName]), {error, not_started}; {_, _} -> - unload_plugin(PluginName, true) + unload_plugin(PluginName) end. reload(PluginName) when is_atom(PluginName)-> @@ -384,10 +380,11 @@ start_app(App, SuccFun) -> {error, {ErrApp, Reason}} end. -unload_plugin(App, Persistent) -> +unload_plugin(App) -> case stop_app(App) of ok -> - _ = plugin_unloaded(App, Persistent), ok; + _ = plugin_unloaded(App), + ok; {error, Reason} -> {error, Reason} end. @@ -428,9 +425,7 @@ plugin_loaded(Name, true) -> ?LOG(error, "Cannot read loaded plugins: ~p", [Error]) end. -plugin_unloaded(_Name, false) -> - ok; -plugin_unloaded(Name, true) -> +plugin_unloaded(Name) -> case read_loaded() of {ok, Names0} -> Names = filter_plugins(Names0), diff --git a/src/emqx_router.erl b/src/emqx_router.erl index 760c48d43..2c93d759c 100644 --- a/src/emqx_router.erl +++ b/src/emqx_router.erl @@ -266,9 +266,6 @@ maybe_trans(Fun, Args) -> end, []) end. -%% The created fun only terminates with explicit exception --dialyzer({nowarn_function, [trans/2]}). - -spec(trans(function(), list(any())) -> ok | {error, term()}). trans(Fun, Args) -> {WPid, RefMon} = @@ -277,13 +274,7 @@ trans(Fun, Args) -> %% are caught by mnesia:transaction/2. %% Future changes should keep in mind that this process %% always exit with database write result. - fun() -> - Res = case mnesia:transaction(Fun, Args) of - {atomic, Ok} -> Ok; - {aborted, Reason} -> {error, Reason} - end, - exit({shutdown, Res}) - end), + make_trans(Fun, Args)), %% Receive a 'shutdown' exit to pass result from the short-lived process. %% so the receive below can be receive-mark optimized by the compiler. %% @@ -300,6 +291,16 @@ trans(Fun, Args) -> end end. +-spec make_trans(fun((...) -> term()), [term()]) -> fun(() -> no_return()). +make_trans(Fun, Args) -> + fun() -> + Res = case mnesia:transaction(Fun, Args) of + {atomic, Ok} -> Ok; + {aborted, Reason} -> {error, Reason} + end, + exit({shutdown, Res}) + end. + lock_router() -> %% if Retry is not 0, global:set_lock could sleep a random time up to 8s. %% Considering we have a limited number of brokers, it is safe to use sleep 1 ms. diff --git a/src/emqx_router_helper.erl b/src/emqx_router_helper.erl index 67a706975..fb72ad9c6 100644 --- a/src/emqx_router_helper.erl +++ b/src/emqx_router_helper.erl @@ -53,8 +53,6 @@ -define(ROUTING_NODE, emqx_routing_node). -define(LOCK, {?MODULE, cleanup_routes}). --dialyzer({nowarn_function, [cleanup_routes/1]}). - %%-------------------------------------------------------------------- %% Mnesia bootstrap %%-------------------------------------------------------------------- @@ -176,4 +174,3 @@ cleanup_routes(Node) -> #route{_ = '_', dest = {'_', Node}}], [mnesia:delete_object(?ROUTE, Route, write) || Pat <- Patterns, Route <- mnesia:match_object(?ROUTE, Pat, write)]. - diff --git a/src/emqx_types.erl b/src/emqx_types.erl index aa1fe3b0b..dfabe0ed2 100644 --- a/src/emqx_types.erl +++ b/src/emqx_types.erl @@ -202,7 +202,6 @@ -type(deliver_result() :: ok | {ok, non_neg_integer()} | {error, term()}). -type(publish_result() :: [{node(), topic(), deliver_result()} | {share, topic(), deliver_result()}]). --type(route() :: #route{}). -type(sub_group() :: tuple() | binary()). -type(route_entry() :: {topic(), node()} | {topic, sub_group()}). -type(plugin() :: #plugin{}). @@ -216,4 +215,3 @@ -type(oom_policy() :: #{message_queue_len => non_neg_integer(), max_heap_size => non_neg_integer() }). - diff --git a/src/emqx_ws_connection.erl b/src/emqx_ws_connection.erl index cd1abc781..44b2b9a17 100644 --- a/src/emqx_ws_connection.erl +++ b/src/emqx_ws_connection.erl @@ -112,7 +112,6 @@ -define(ENABLED(X), (X =/= undefined)). -dialyzer({no_match, [info/2]}). --dialyzer({nowarn_function, [websocket_init/1]}). %%-------------------------------------------------------------------- %% Info, Stats @@ -315,7 +314,7 @@ websocket_init([Req, Opts]) -> %% MQTT Idle Timeout IdleTimeout = emqx_zone:idle_timeout(Zone), IdleTimer = start_timer(IdleTimeout, idle_timeout), - emqx_misc:tune_heap_size(emqx_zone:oom_policy(Zone)), + _ = emqx_misc:tune_heap_size(emqx_zone:oom_policy(Zone)), emqx_logger:set_metadata_peername(esockd:format(Peername)), {ok, #state{peername = Peername, sockname = Sockname, @@ -812,4 +811,3 @@ get_peer(Req, Opts) -> set_field(Name, Value, State) -> Pos = emqx_misc:index_of(Name, record_info(fields, state)), setelement(Pos+1, State, Value). - diff --git a/test/emqx_plugins_SUITE.erl b/test/emqx_plugins_SUITE.erl index 57f10f2f0..b26e90743 100644 --- a/test/emqx_plugins_SUITE.erl +++ b/test/emqx_plugins_SUITE.erl @@ -160,8 +160,8 @@ t_plugin_loaded(_) -> ?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_mini_plugin, true)). t_plugin_unloaded(_) -> - ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, false)), - ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, true)). + ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin)), + ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin)). t_plugin(_) -> try @@ -199,8 +199,8 @@ t_unload_plugin(_) -> (error_app) -> {error, error}; (_) -> ok end), - ?assertEqual(ok, emqx_plugins:unload_plugin(not_started_app, true)), - ?assertEqual(ok, emqx_plugins:unload_plugin(normal, true)), - ?assertEqual({error,error}, emqx_plugins:unload_plugin(error_app, true)), + ?assertEqual(ok, emqx_plugins:unload_plugin(not_started_app)), + ?assertEqual(ok, emqx_plugins:unload_plugin(normal)), + ?assertEqual({error,error}, emqx_plugins:unload_plugin(error_app)), ok = meck:unload(application).