Skip to content

Commit

Permalink
Convert mod_mam to gen_hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Waz committed Nov 8, 2022
1 parent 7c74198 commit 3351768
Show file tree
Hide file tree
Showing 23 changed files with 1,002 additions and 799 deletions.
7 changes: 5 additions & 2 deletions big_tests/tests/amp_big_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ 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}]);
ok = rpc(mim(), meck, expect, [mod_offline_mnesia, write_messages, 4, {error, simulated}]);
setup_meck(_) -> ok.

save_offline_status(mam_success, Config) -> [{offline_storage, mam} | Config];
Expand Down Expand Up @@ -371,6 +371,7 @@ notify_deliver_to_offline_user_test(Config) ->
false -> none
end, notify},
Rules = rules(Config, [Rule]),
io:format("~p~n", [Rules]),
BobJid = escalus_users:get_jid(FreshConfig, bob),
Msg = amp_message_to(BobJid, Rules, <<"A message in a bottle...">>),

Expand All @@ -382,12 +383,14 @@ notify_deliver_to_offline_user_test(Config) ->
true -> client_receives_notification(Alice, BobJid, Rule);
false -> ok
end,
io:format("~p~n", [?config(offline_storage, Config)]),
case ?config(offline_storage, Config) of
offline_failure -> client_receives_generic_error(Alice, <<"500">>, <<"wait">>);
_ -> client_receives_nothing(Alice)
end
end),
wait_until_no_session(FreshConfig, alice),
io:format("no session~n"),
case is_offline_storage_working(Config) of
true -> user_has_incoming_offline_message(FreshConfig, bob, <<"A message in a bottle...">>);
false -> user_has_no_incoming_offline_messages(FreshConfig, bob)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,26 @@


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}) ->
#{params := #{owner_jid := ArcJID, caller_jid := _CallerJID} = _Params},
#{host_type := Host}) ->
MessageRows2 = [extend_message(Host, ArcJID, Row) || Row <- MessageRows],
{ok, {TotalCount, Offset, MessageRows2}}.
{ok, {ok, {TotalCount, Offset, MessageRows2}}}.

extend_message(_Host, _ArcJID, Row = #{}) ->
%% Extend a message with a new field
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) -> {ok | stop, Acc} when
Acc :: integer(),
Params :: map(),
Extra :: map().

-callback archive_message(Acc, Params, Extra) -> {ok | stop, Acc} when
Acc :: ok | {error, term()},
Params :: map(),
Extra :: map().

-callback lookup_messages(Acc, Params, Extra) -> {ok | stop, Acc} when
Acc :: {ok, mod_mam:lookup_result()} | {error, term()},
Params :: map(),
Extra :: map().

-callback get_mam_pm_gdpr_data(Acc, Params, Extra) -> {ok | stop, Acc} when
Acc :: mam_pm_gdpr_data(),
Params :: map(),
Extra :: map().

-callback get_mam_muc_gdpr_data(Acc, Params, Extra) -> {ok | stop, Acc} when
Acc :: mam_muc_gdpr_data(),
Params :: map(),
Extra :: map().

-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]).

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

-ignore_xref([behaviour_info/1]).
-callback get_behaviour(Acc, Params, Extra) -> {ok | stop, Acc} when
Acc :: mod_mam:archive_behaviour(),
Params :: map(),
Extra :: map().

-callback get_behaviour(Default :: mod_mam:archive_behaviour(),
Host :: jid:server(), ArcID :: mod_mam:archive_id(),
LocJID :: jid:jid(), RemJID :: jid:jid()) -> any().

-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().

-callback get_prefs(mod_mam:preference(), _Host :: jid:server(),
ArcId :: mod_mam:archive_id(), ArcJID :: jid:jid())
-> mod_mam:preference().
-callback set_prefs(Acc, Params, Extra) -> {ok, Acc} when
Acc :: term(),
Params :: map(),
Extra :: map().

-callback get_prefs(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mod_mam:preference() | {error, Reason :: term()},
Params :: map(),
Extra :: map().
59 changes: 32 additions & 27 deletions src/mam/mod_mam_cache_user.erl
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@
-module(mod_mam_cache_user).

-behaviour(mongoose_module_metrics).
-behaviour(gen_mod).

%% gen_mod handlers
-export([start/2, stop/1, supported_features/0]).

%% ejabberd handlers
-export([cached_archive_id/3,
store_archive_id/3,
remove_archive/4]).

-ignore_xref([start/2, stop/1, supported_features/0,
cached_archive_id/3, store_archive_id/3, remove_archive/4]).
remove_archive/3]).

%%====================================================================
%% gen_mod callbacks
Expand All @@ -31,20 +29,20 @@
-spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok.
start(HostType, Opts) ->
start_cache(HostType, Opts),
ejabberd_hooks:add(hooks(HostType, Opts)),
gen_hook:add_handlers(hooks(HostType, Opts)),
ok.

-spec stop(HostType :: mongooseim:host_type()) -> ok.
stop(HostType) ->
ejabberd_hooks:delete(hooks(HostType)),
gen_hook:delete_handlers(hooks(HostType)),
stop_cache(HostType),
ok.

-spec supported_features() -> [atom()].
supported_features() ->
[dynamic_domains].

-spec hooks(mongooseim:host_type()) -> [ejabberd_hooks:hook()].
-spec hooks(mongooseim:host_type()) -> gen_hook:hook_list().
hooks(HostType) ->
Opts = gen_mod:get_module_opts(HostType, ?MODULE),
hooks(HostType, Opts).
Expand All @@ -62,44 +60,51 @@ maybe_muc_hooks(true, HostType) -> muc_hooks(HostType);
maybe_muc_hooks(false, _HostType) -> [].

pm_hooks(HostType) ->
[{mam_archive_id, HostType, ?MODULE, cached_archive_id, 30},
{mam_archive_id, HostType, ?MODULE, store_archive_id, 70},
{mam_remove_archive, HostType, ?MODULE, remove_archive, 100}].
[{mam_archive_id, HostType, fun ?MODULE:cached_archive_id/3, #{}, 30},
{mam_archive_id, HostType, fun ?MODULE:store_archive_id/3, #{}, 70},
{mam_remove_archive, HostType, fun ?MODULE:remove_archive/3, #{}, 100}].

muc_hooks(HostType) ->
[{mam_muc_archive_id, HostType, ?MODULE, cached_archive_id, 30},
{mam_muc_archive_id, HostType, ?MODULE, store_archive_id, 70},
{mam_muc_remove_archive, HostType, ?MODULE, remove_archive, 100}].
[{mam_muc_archive_id, HostType, fun ?MODULE:cached_archive_id/3, #{}, 30},
{mam_muc_archive_id, HostType, fun ?MODULE:store_archive_id/3, #{}, 70},
{mam_muc_remove_archive, HostType, fun ?MODULE:remove_archive/3, #{}, 100}].

%%====================================================================
%% API
%%====================================================================
-spec cached_archive_id(undefined, mongooseim:host_type(), jid:jid()) ->
mod_mam:archive_id().
cached_archive_id(undefined, HostType, ArcJid) ->
-spec cached_archive_id(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mod_mam:archive_id() | undefined,
Params :: map(),
Extra :: map().
cached_archive_id(undefined, #{owner := ArcJid}, #{host_type := HostType}) ->
case mongoose_user_cache:get_entry(HostType, ?MODULE, ArcJid) of
#{id := ArchId} -> ArchId;
#{id := ArchId} ->
{ok, ArchId};
_ ->
put(mam_not_cached_flag, true),
undefined
{ok, undefined}
end.

-spec store_archive_id(mod_mam:archive_id(), mongooseim:host_type(), jid:jid())
-> mod_mam:archive_id().
store_archive_id(ArchId, HostType, ArcJid) ->
-spec store_archive_id(Acc, Params, Extra) -> {ok, Acc} when
Acc :: mod_mam:archive_id() | undefined,
Params :: map(),
Extra :: map().
store_archive_id(ArchId, #{owner := ArcJid}, #{host_type := HostType}) ->
case erase(mam_not_cached_flag) of
undefined ->
ArchId;
{ok, ArchId};
true ->
mongoose_user_cache:merge_entry(HostType, ?MODULE, ArcJid, #{id => ArchId}),
ArchId
{ok, ArchId}
end.

-spec remove_archive(Acc :: map(), HostType :: mongooseim:host_type(),
ArchId :: mod_mam:archive_id(), ArcJid :: jid:jid()) -> map().
remove_archive(Acc, HostType, _UserID, ArcJid) ->
-spec remove_archive(Acc, Params, Extra) -> {ok, Acc} when
Acc :: term(),
Params :: map(),
Extra :: map().
remove_archive(Acc, #{owner := ArcJid}, #{host_type := HostType}) ->
mongoose_user_cache:delete_user(HostType, ?MODULE, ArcJid),
Acc.
{ok, Acc}.

%%====================================================================
%% internal
Expand Down
Loading

0 comments on commit 3351768

Please sign in to comment.