Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert mod_mam to gen_hook #3841

Merged
merged 6 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion big_tests/tests/amp_big_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ setup_meck(suite) ->
ok = rpc(mim(), meck, new, [ejabberd_socket, [passthrough, no_link]]),
ok = rpc(mim(), amp_test_helper, setup_meck, []);
setup_meck(mam_failure) ->
ok = rpc(mim(), meck, expect, [mod_mam_rdbms_arch, archive_message, 3, {error, simulated}]);
ok = rpc(mim(), meck, expect, [mod_mam_rdbms_arch, archive_message, 3, {ok, {error, simulated}}]);
setup_meck(offline_failure) ->
ok = rpc(mim(), meck, expect, [mod_offline_mnesia, write_messages, 4, {error, simulated}]);
setup_meck(_) -> ok.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,28 @@


start(HostType, _Opts) ->
ejabberd_hooks:add(hooks(HostType)).
gen_hook:add_handlers(hooks(HostType)).

stop(HostType) ->
ejabberd_hooks:delete(hooks(HostType)).
gen_hook:delete_handlers(hooks(HostType)).

supported_features() ->
[dynamic_domains].

hooks(HostType) ->
[{mam_lookup_messages, HostType, ?MODULE, lookup_messages, 60},
{mam_muc_lookup_messages, HostType, ?MODULE, lookup_messages, 60}].
[{mam_lookup_messages, HostType, fun ?MODULE:lookup_messages/3, #{}, 60},
{mam_muc_lookup_messages, HostType, fun ?MODULE:lookup_messages/3, #{}, 60}].

%% caller_jid could be used for privacy checking or per-user customization
lookup_messages({error, _Reason} = Result, _Host, _Params) ->
Result;
lookup_messages({error, _Reason} = Result, _Params, _Extra) ->
{ok, Result};
lookup_messages({ok, {TotalCount, Offset, MessageRows}},
Host, _Params = #{owner_jid := ArcJID, caller_jid := _CallerJID}) ->
MessageRows2 = [extend_message(Host, ArcJID, Row) || Row <- MessageRows],
{ok, {TotalCount, Offset, MessageRows2}}.
#{owner_jid := ArcJID, caller_jid := _CallerJID} = _Params,
#{host_type := HostType}) ->
MessageRows2 = [extend_message(HostType, ArcJID, Row) || Row <- MessageRows],
{ok, {ok, {TotalCount, Offset, MessageRows2}}}.

extend_message(_Host, _ArcJID, Row = #{}) ->
extend_message(_HostType, _ArcJID, Row = #{}) ->
%% Extend a message with a new field
%% Usually extracted from a DB
Row#{some_hash => erlang:phash2(Row, 32)}.
Expand Down
8 changes: 4 additions & 4 deletions src/event_pusher/mod_event_pusher_hook_translator.erl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ filter_local_packet({From, To, Acc0, Packet}, _, _) ->
-spec user_send_packet(Acc, Args, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Args :: map(),
Extra :: map().
Extra :: gen_hook:extra().
user_send_packet(Acc, _, _) ->
Packet = mongoose_acc:packet(Acc),
ChatType = chat_type(Acc),
Expand All @@ -72,7 +72,7 @@ user_send_packet(Acc, _, _) ->
-spec user_present(Acc, Args, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Args :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
user_present(Acc, #{jid := UserJID = #jid{}}, _) ->
Event = #user_status_event{jid = UserJID, status = online},
NewAcc = mod_event_pusher:push_event(Acc, Event),
Expand All @@ -81,7 +81,7 @@ user_present(Acc, #{jid := UserJID = #jid{}}, _) ->
-spec user_not_present(Acc, Args, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Args :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
user_not_present(Acc, #{jid := UserJID}, _) ->
Event = #user_status_event{jid = UserJID, status = offline},
NewAcc = mod_event_pusher:push_event(Acc, Event),
Expand All @@ -90,7 +90,7 @@ user_not_present(Acc, #{jid := UserJID}, _) ->
-spec unacknowledged_message(Acc, Args, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Args :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
unacknowledged_message(Acc, #{jid := Jid}, _) ->
Event = #unack_msg_event{to = Jid},
NewAcc = mod_event_pusher:push_event(Acc, Event),
Expand Down
13 changes: 7 additions & 6 deletions src/gen_hook.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@
host_type => mongooseim:host_type(),
_ => _}.

-type hook_fn_ret_value() :: {ok | stop, NewAccumulator :: hook_acc()}.
-type hook_fn_ret() :: hook_fn_ret(hook_acc()).
-type hook_fn_ret(Acc) :: {ok | stop, Acc}.
-type hook_fn() :: %% see run_fold/4 documentation
fun((Accumulator :: hook_acc(),
ExecutionParameters :: hook_params(),
ExtraParameters :: extra()) -> hook_fn_ret_value()).
ExtraParameters :: extra()) -> hook_fn_ret()).

-type key() :: {HookName :: atom(),
Tag :: any()}.
Expand All @@ -54,7 +55,7 @@

-type hook_list() :: [hook_tuple()].

-export_type([hook_fn/0, hook_list/0]).
-export_type([hook_fn/0, hook_list/0, hook_fn_ret/0, hook_fn_ret/1]).

-record(hook_handler, {prio :: pos_integer(),
hook_fn :: hook_fn(),
Expand Down Expand Up @@ -122,7 +123,7 @@ delete_handler({HookName, Tag, _, _, _} = HookTuple) ->
-spec run_fold(HookName :: hook_name(),
Tag :: hook_tag(),
Acc :: hook_acc(),
Params :: hook_params()) -> hook_fn_ret_value().
Params :: hook_params()) -> hook_fn_ret().
run_fold(HookName, Tag, Acc, Params) ->
Key = hook_key(HookName, Tag),
case ets:lookup(?TABLE, Key) of
Expand Down Expand Up @@ -200,7 +201,7 @@ code_change(_OldVsn, State, _Extra) ->
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
-spec run_hook([#hook_handler{}], hook_acc(), hook_params(), key()) -> hook_fn_ret_value().
-spec run_hook([#hook_handler{}], hook_acc(), hook_params(), key()) -> hook_fn_ret().
run_hook([], Acc, _Params, _Key) ->
{ok, Acc};
run_hook([Handler | Ls], Acc, Params, Key) ->
Expand All @@ -215,7 +216,7 @@ run_hook([Handler | Ls], Acc, Params, Key) ->
end.

-spec apply_hook_function(#hook_handler{}, hook_acc(), hook_params()) ->
hook_fn_ret_value() | {'EXIT', Reason :: any()}.
hook_fn_ret() | {'EXIT', Reason :: any()}.
apply_hook_function(#hook_handler{hook_fn = HookFn, extra = Extra},
Acc, Params) ->
safely:apply(HookFn, [Acc, Params, Extra]).
Expand Down
10 changes: 5 additions & 5 deletions src/global_distrib/mod_global_distrib_mapping.erl
Original file line number Diff line number Diff line change
Expand Up @@ -172,31 +172,31 @@ deps(_HostType, Opts) ->
-spec session_opened(Acc, Params, Extra) -> {ok, Acc} when
Acc :: any(),
Params :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
session_opened(Acc, #{jid := UserJid}, _) ->
insert_for_jid(UserJid),
{ok, Acc}.

-spec session_closed(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
session_closed(Acc, #{jid := UserJid}, _) ->
delete_for_jid(UserJid),
{ok, Acc}.

-spec packet_to_component(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: #{from := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
packet_to_component(Acc, #{from := From}, _) ->
mod_global_distrib_utils:maybe_update_mapping(From, Acc),
{ok, Acc}.

-spec register_subhost(Acc, Params, Extra) -> {ok, ok} when
Acc :: any(),
Params :: #{ldomain := binary(), is_hidden := boolean()},
Extra :: map().
Extra :: gen_hook:extra().
register_subhost(_, #{ldomain := SubHost, is_hidden := IsHidden}, _) ->
IsSubhostOf =
fun(Host) ->
Expand All @@ -216,7 +216,7 @@ register_subhost(_, #{ldomain := SubHost, is_hidden := IsHidden}, _) ->
-spec unregister_subhost(Acc, Params, Extra) -> {ok, ok} when
Acc :: any(),
Params :: #{ldomain := binary()},
Extra :: map().
Extra :: gen_hook:extra().
unregister_subhost(_, #{ldomain := SubHost}, _) ->
{ok, delete_for_domain(SubHost)}.

Expand Down
2 changes: 1 addition & 1 deletion src/http_upload/mod_http_upload.erl
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ process_disco_iq(Acc, _From, _To, #iq{type = get, lang = Lang, sub_el = SubEl} =
-spec disco_local_items(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_disco:item_acc(),
Params :: map(),
Extra :: map().
Extra :: gen_hook:extra().
disco_local_items(Acc = #{host_type := HostType, to_jid := #jid{lserver = Domain}, node := <<>>, lang := Lang}, _, _) ->
{ok, mongoose_disco:add_items([#{jid => subdomain(HostType, Domain), name => my_disco_name(Lang)}], Acc)};
disco_local_items(Acc, _, _) ->
Expand Down
12 changes: 6 additions & 6 deletions src/inbox/mod_inbox.erl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ stop_cleaner(HostType) ->
From :: jid:jid(),
To :: jid:jid(),
IQ :: jlib:iq(),
Extra :: map()) -> {stop, mongoose_acc:t()} | {mongoose_acc:t(), jlib:iq()}.
Extra :: gen_hook:extra()) -> {stop, mongoose_acc:t()} | {mongoose_acc:t(), jlib:iq()}.
process_iq(Acc, _From, _To, #iq{type = get, sub_el = SubEl} = IQ, #{host_type := HostType}) ->
Form = build_inbox_form(HostType),
SubElWithForm = SubEl#xmlel{ children = [Form] },
Expand Down Expand Up @@ -232,7 +232,7 @@ send_message(Acc, To = #jid{lserver = LServer}, Msg) ->
-spec user_send_packet(Acc, Args, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Args :: #{from := jid:jid(), to := jid:jid(), packet := exml:element()},
Extra :: map().
Extra :: gen_hook:extra().
user_send_packet(Acc, _, _) ->
{From, To, Msg} = mongoose_acc:packet(Acc),
NewAcc = case Msg of
Expand All @@ -244,7 +244,7 @@ user_send_packet(Acc, _, _) ->
-spec inbox_unread_count(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: #{user := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
inbox_unread_count(Acc, #{user := User}, _) ->
Res = mongoose_acc:get(inbox, unread_count, undefined, Acc),
NewAcc = get_inbox_unread(Res, Acc, User),
Expand All @@ -254,7 +254,7 @@ inbox_unread_count(Acc, #{user := User}, _) ->
(FPacketAcc, Params, Extra) -> {ok, FPacketAcc} when
FPacketAcc :: mongoose_hooks:filter_packet_acc(),
Params :: map(),
Extra :: map().
Extra :: gen_hook:extra().
filter_local_packet({From, To, Acc, Msg = #xmlel{name = <<"message">>}}, _, _) ->
Acc0 = maybe_process_message(Acc, From, To, Msg, incoming),
{ok, {From, To, Acc0, Msg}};
Expand All @@ -264,7 +264,7 @@ filter_local_packet(FPacketAcc, _, _) ->
-spec remove_user(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: #{jid := jid:jid()},
Extra :: map().
Extra :: gen_hook:extra().
remove_user(Acc, #{jid := #jid{luser = User, lserver = Server}}, _) ->
HostType = mongoose_acc:host_type(Acc),
mod_inbox_utils:clear_inbox(HostType, User, Server),
Expand All @@ -284,7 +284,7 @@ remove_domain(Acc, #{domain := Domain}, #{host_type := HostType}) ->
-spec disco_local_features(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_disco:feature_acc(),
Params :: map(),
Extra :: map().
Extra :: gen_hook:extra().
disco_local_features(Acc = #{node := <<>>}, _, _) ->
{ok, mongoose_disco:add_features([?NS_ESL_INBOX], Acc)};
disco_local_features(Acc, _, _) ->
Expand Down
2 changes: 1 addition & 1 deletion src/inbox/mod_inbox_muc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ hooks(HostType) ->
-spec update_inbox_for_muc(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mod_muc_room:update_inbox_for_muc_payload(),
Params :: map(),
Extra :: map().
Extra :: gen_hook:extra().
update_inbox_for_muc(
#{host_type := HostType,
room_jid := Room,
Expand Down
2 changes: 1 addition & 1 deletion src/jingle_sip/mod_jingle_sip.erl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ hooks(Host) ->
-spec intercept_jingle_stanza(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mongoose_acc:t(),
Params :: map(),
Extra :: map().
Extra :: gen_hook:extra().
intercept_jingle_stanza(Acc, _, _) ->
NewAcc = case mongoose_acc:get(hook, result, undefined, Acc) of
drop ->
Expand Down
50 changes: 30 additions & 20 deletions src/mam/ejabberd_gen_mam_archive.erl
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
-module(ejabberd_gen_mam_archive).

-ignore_xref([behaviour_info/1]).

-callback archive_size(Size :: integer(), Host :: jid:server(),
ArchiveID :: mod_mam:archive_id(), ArchiveJID :: jid:jid())
-> integer().

-callback archive_message(Result :: any(), Host :: jid:server(),
Params :: mod_mam:archive_message_params()) -> ok | {error, timeout}.

-callback lookup_messages(Result :: any(), Host :: jid:server(),
Params :: map()) -> Result when
Result :: {ok, mod_mam:lookup_result()} | {error, 'policy-violation'}.

-callback get_mam_pm_gdpr_data(mam_pm_gdpr_data(), mongooseim:host_type(), jid:jid()) -> mam_pm_gdpr_data().

-callback get_mam_muc_gdpr_data(mam_muc_gdpr_data(), mongooseim:host_type(), jid:jid()) -> mam_muc_gdpr_data().
-callback archive_size(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: integer(),
Params :: #{archive_id := mod_mam:archive_id() | undefined, owner => jid:jid(), room => jid:jid()},
Extra :: gen_hook:extra().

-callback archive_message(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: ok | {error, term()},
Params :: mod_mam:archive_message_params(),
Extra :: gen_hook:extra().

-callback lookup_messages(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: {ok, mod_mam:lookup_result()} | {error, term()},
Params :: mam_iq:lookup_params(),
Extra :: gen_hook:extra().

-callback get_mam_pm_gdpr_data(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: mam_pm_gdpr_data(),
Params :: #{jid := jid:jid()},
Extra :: gen_hook:extra().

-callback get_mam_muc_gdpr_data(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: mam_muc_gdpr_data(),
Params :: #{jid := jid:jid()},
Extra :: gen_hook:extra().

-optional_callbacks([get_mam_pm_gdpr_data/3,
get_mam_muc_gdpr_data/3,
archive_size/4,
archive_size/3,
lookup_messages/3]).

-type mam_pm_gdpr_data() :: [{MessageID :: bitstring(), FromJID :: bitstring(), Message :: bitstring()}].
-type mam_pm_gdpr_data() :: [{MessageID :: bitstring(),
FromJID :: bitstring(),
Message :: bitstring()}].

-type mam_muc_gdpr_data() :: [{MessageID :: bitstring(), Message :: bitstring()}].
-type mam_muc_gdpr_data() :: [{MessageID :: bitstring(),
Message :: bitstring()}].

-export_type([mam_pm_gdpr_data/0, mam_muc_gdpr_data/0]).

38 changes: 26 additions & 12 deletions src/mam/ejabberd_gen_mam_prefs.erl
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
-module(ejabberd_gen_mam_prefs).

-ignore_xref([behaviour_info/1]).
-type set_prefs_params() :: #{archive_id := undefined | mod_mam:archive_id(),
owner := jid:jid(),
default_mode := mod_mam:archive_behaviour(),
always_jids := [jid:literal_jid()],
never_jids := [jid:literal_jid()]}.

-callback get_behaviour(Default :: mod_mam:archive_behaviour(),
Host :: jid:server(), ArcID :: mod_mam:archive_id(),
LocJID :: jid:jid(), RemJID :: jid:jid()) -> any().
-type get_prefs_params() :: #{archive_id := undefined | mod_mam:archive_id(),
owner := jid:jid()}.

-callback set_prefs(Result :: any(), Host :: jid:server(),
ArcID :: mod_mam:archive_id(), ArcJID :: jid:jid(),
DefaultMode :: mod_mam:archive_behaviour(),
AlwaysJIDs :: [jid:literal_jid()],
NeverJIDs :: [jid:literal_jid()]) -> any().
-type get_behaviour_params() :: #{archive_id := undefined | mod_mam:archive_id(),
owner => jid:jid(),
room => jid:jid(),
remote := jid:jid()}.

-callback get_prefs(mod_mam:preference(), _Host :: jid:server(),
ArcId :: mod_mam:archive_id(), ArcJID :: jid:jid())
-> mod_mam:preference().
-export_type([set_prefs_params/0, get_prefs_params/0, get_behaviour_params/0]).

-callback get_behaviour(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: mod_mam:archive_behaviour(),
Params :: get_behaviour_params(),
Extra :: map().

-callback set_prefs(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: term(),
Params :: set_prefs_params(),
Extra :: map().

-callback get_prefs(Acc, Params, Extra) -> gen_hook:hook_fn_ret(Acc) when
Acc :: mod_mam:preference() | {error, Reason :: term()},
Params :: get_prefs_params(),
Extra :: map().
Loading