emqx/apps/emqx_exhook/src/emqx_exhook_app.erl
Ayodele ff99bc10ad Umbrella fix build (#7)
* fix(emqx_auth_mongo): Dialyzer warnings

* fix(emqx_auth_mnesia_api): Dialyzer warnings

* fix(emqx_exhook): Dialyzer warnings
2020-12-10 11:22:38 +01:00

118 lines
3.5 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_exhook_app).
-behaviour(application).
-include("emqx_exhook.hrl").
-emqx_plugin(extension).
-export([ start/2
, stop/1
, prep_stop/1
]).
%% Internal export
-export([ load_server/2
, unload_server/1
, load_exhooks/0
, unload_exhooks/0
]).
%%--------------------------------------------------------------------
%% Application callbacks
%%--------------------------------------------------------------------
start(_StartType, _StartArgs) ->
{ok, Sup} = emqx_exhook_sup:start_link(),
%% Load all dirvers
load_all_servers(),
%% Register all hooks
_ = load_exhooks(),
%% Register CLI
emqx_ctl:register_command(exhook, {emqx_exhook_cli, cli}, []),
{ok, Sup}.
prep_stop(State) ->
emqx_ctl:unregister_command(exhook),
_ = unload_exhooks(),
ok = unload_all_servers(),
State.
stop(_State) ->
ok.
%%--------------------------------------------------------------------
%% Internal funcs
%%--------------------------------------------------------------------
load_all_servers() ->
lists:foreach(fun({Name, Options}) ->
load_server(Name, Options)
end, application:get_env(?APP, servers, [])).
unload_all_servers() ->
emqx_exhook:disable_all().
load_server(Name, Options) ->
emqx_exhook:enable(Name, Options).
unload_server(Name) ->
emqx_exhook:disable(Name).
%%--------------------------------------------------------------------
%% Exhooks
load_exhooks() ->
[emqx:hook(Name, {M, F, A}) || {Name, {M, F, A}} <- search_exhooks()].
unload_exhooks() ->
[emqx:unhook(Name, {M, F}) || {Name, {M, F, _A}} <- search_exhooks()].
search_exhooks() ->
search_exhooks(ignore_lib_apps(application:loaded_applications())).
search_exhooks(Apps) ->
lists:flatten([ExHooks || App <- Apps, {_App, _Mod, ExHooks} <- find_attrs(App, exhooks)]).
ignore_lib_apps(Apps) ->
LibApps = [kernel, stdlib, sasl, appmon, eldap, erts,
syntax_tools, ssl, crypto, mnesia, os_mon,
inets, goldrush, gproc, runtime_tools,
snmp, otp_mibs, public_key, asn1, ssh, hipe,
common_test, observer, webtool, xmerl, tools,
test_server, compiler, debugger, eunit, et,
wx],
[AppName || {AppName, _, _} <- Apps, not lists:member(AppName, LibApps)].
find_attrs(App, Def) ->
[{App, Mod, Attr} || {ok, Modules} <- [application:get_key(App, modules)],
Mod <- Modules,
{Name, Attrs} <- module_attributes(Mod), Name =:= Def,
Attr <- Attrs].
module_attributes(Module) ->
try Module:module_info(attributes)
catch
error:undef -> [];
error:Reason -> error(Reason)
end.