]> granicus.if.org Git - ejabberd/commitdiff
Keep info about carbons inside session table
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 1 Dec 2018 10:33:44 +0000 (13:33 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 1 Dec 2018 10:33:44 +0000 (13:33 +0300)
Accordingly, Mnesia/SQL/Riak table 'carboncopy' is not used anymore
and can be safely removed.

As a consequence, the commit deprecates the following options of
mod_carboncopy:
- ram_db_type
- use_cache
- cache_size
- cache_missed
- cache_life_time

Fixes #2663

14 files changed:
include/mod_carboncopy.hrl [deleted file]
sql/lite.new.sql
sql/lite.sql
sql/mssql.sql
sql/mysql.new.sql
sql/mysql.sql
sql/pg.new.sql
sql/pg.sql
src/ejabberd_sm.erl
src/mod_carboncopy.erl
src/mod_carboncopy_mnesia.erl [deleted file]
src/mod_carboncopy_redis.erl [deleted file]
src/mod_carboncopy_riak.erl [deleted file]
src/mod_carboncopy_sql.erl [deleted file]

diff --git a/include/mod_carboncopy.hrl b/include/mod_carboncopy.hrl
deleted file mode 100644 (file)
index f02f3e8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-%%%----------------------------------------------------------------------
-%%%
-%%% ejabberd, Copyright (C) 2002-2018   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--type matchspec_atom() :: '_' | '$1' | '$2' | '$3' | '$4'.
--record(carboncopy, {us       :: {binary(), binary()} | matchspec_atom(), 
-                    resource :: binary() | matchspec_atom(),
-                    version  :: binary() | matchspec_atom(),
-                    node = node() :: node() | matchspec_atom()}).
-
--define(CARBONCOPY_CACHE, carboncopy_cache).
index d58d04c7717abb579c8ef21d2cff018cdc0c15e5..de62cd1694ac5f32a0a8f6ac155327471653c92c 100644 (file)
@@ -387,17 +387,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh(sid);
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    server_host text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL,
-    PRIMARY KEY (server_host, username, resource)
-);
-
-CREATE INDEX i_carboncopy_sh_user ON carboncopy (server_host, username);
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index abb25d5b4d304c970f7ef51653f74d1b4167e476..50bfec3bda1fc9179cc1b03fc6d135c8caeba89f 100644 (file)
@@ -357,16 +357,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh(sid);
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL
-);
-
-CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy (username, resource);
-CREATE INDEX i_carboncopy_user ON carboncopy (username);
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index 04798ee51e0387c3f8b9d05a7d5043a12aacc3dc..9393a19c1a5039bb696d005a67a684f6272f9775 100644 (file)
@@ -531,19 +531,6 @@ CREATE TABLE [dbo].[bosh] (
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)\r
 );\r
 \r
-CREATE TABLE [dbo].[carboncopy] (\r
-    [username] [varchar] (255) NOT NULL,\r
-    [resource] [varchar] (255) NOT NULL,\r
-    [namespace] [varchar] (255) NOT NULL,\r
-    [node] [varchar] (255) NOT NULL\r
-);\r
-\r
-CREATE UNIQUE CLUSTERED INDEX [carboncopy_ur] ON [carboncopy] (username, resource)\r
-WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);\r
-\r
-CREATE INDEX [carboncopy_user] ON [carboncopy] (username)\r
-WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);\r
-\r
 CREATE TABLE [dbo].[push_session] (\r
     [username] [varchar] (255) NOT NULL,\r
     [timestamp] [bigint] NOT NULL,\r
index 0f564f08fd46a5e6e5bda8d7d36f10ca86661797..88769ddaea8569c32da4144e75df7ea52899d7d8 100644 (file)
@@ -403,17 +403,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh(sid(75));
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    server_host text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL,
-    PRIMARY KEY (server_host(191), username(191), resource(191))
-) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
-CREATE INDEX i_carboncopy_sh_user ON carboncopy (server_host(191), username(75));
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index d731f89dfb29e113dd1ee66edf76144f1eeb5d3c..2fcea38f58cadbbc670d981f78994088482b8ac1 100644 (file)
@@ -373,16 +373,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh(sid(75));
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL
-) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
-CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy (username(75), resource(75));
-CREATE INDEX i_carboncopy_user ON carboncopy (username(75));
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index 928d74db096e410ae9a43f12d0a2d9b1164efb0f..6244eeea98daa45096757f1c345508da9fcf5173 100644 (file)
 -- CREATE INDEX i_sm_sh_username ON sm USING btree (server_host, username);
 -- ALTER TABLE sm ALTER COLUMN server_host DROP DEFAULT;
 
--- ALTER TABLE carboncopy ADD COLUMN server_host text NOT NULL DEFAULT '<HOST>';
--- DROP INDEX i_carboncopy_ur;
--- DROP INDEX i_carboncopy_user;
--- ALTER TABLE carboncopy ADD PRIMARY KEY (server_host, username, resource);
--- CREATE INDEX i_carboncopy_sh_user ON carboncopy USING btree (server_host, username);
--- ALTER TABLE carboncopy ALTER COLUMN server_host DROP DEFAULT;
-
 
 CREATE TABLE users (
     username text NOT NULL,
@@ -555,17 +548,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh USING btree (sid);
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    server_host text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL,
-    PRIMARY KEY (server_host, username, resource)
-);
-
-CREATE INDEX i_carboncopy_sh_user ON carboncopy USING btree (server_host, username);
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index a0cfe0ea62d2ce097b0ea18d4ddfe670c2fafbdd..ad1e4b9c28772856d8c12943e2b816da5a95d69c 100644 (file)
@@ -377,16 +377,6 @@ CREATE TABLE bosh (
 
 CREATE UNIQUE INDEX i_bosh_sid ON bosh USING btree (sid);
 
-CREATE TABLE carboncopy (
-    username text NOT NULL,
-    resource text NOT NULL,
-    namespace text NOT NULL,
-    node text NOT NULL
-);
-
-CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy USING btree (username, resource);
-CREATE INDEX i_carboncopy_user ON carboncopy USING btree (username);
-
 CREATE TABLE proxy65 (
     sid text NOT NULL,
     pid_t text NOT NULL,
index de871a11c5d139faba3923445d89fa658e0c9a8f..ab125171578644a82a51f4622c0e743adb6e675b 100644 (file)
@@ -66,6 +66,8 @@
         get_session_sids/2,
         get_user_info/2,
         get_user_info/3,
+        set_user_info/5,
+        del_user_info/4,
         get_user_ip/3,
         get_max_user_sessions/2,
         get_all_pids/0,
@@ -266,6 +268,44 @@ get_user_info(User, Server, Resource) ->
             |Session#session.info]
     end.
 
+-spec set_user_info(binary(), binary(), binary(), atom(), term()) -> ok | {error, any()}.
+set_user_info(User, Server, Resource, Key, Val) ->
+    LUser = jid:nodeprep(User),
+    LServer = jid:nameprep(Server),
+    LResource = jid:resourceprep(Resource),
+    Mod = get_sm_backend(LServer),
+    case get_sessions(Mod, LUser, LServer, LResource) of
+       [] -> {error, notfound};
+       Ss ->
+           lists:foldl(
+             fun(#session{sid = {_, Pid},
+                          info = Info} = Session, _) when Pid == self() ->
+                     Info1 = lists:keystore(Key, 1, Info, {Key, Val}),
+                     set_session(Session#session{info = Info1});
+                (_, Acc) ->
+                     Acc
+             end, {error, not_owner}, Ss)
+    end.
+
+-spec del_user_info(binary(), binary(), binary(), atom()) -> ok | {error, any()}.
+del_user_info(User, Server, Resource, Key) ->
+    LUser = jid:nodeprep(User),
+    LServer = jid:nameprep(Server),
+    LResource = jid:resourceprep(Resource),
+    Mod = get_sm_backend(LServer),
+    case get_sessions(Mod, LUser, LServer, LResource) of
+       [] -> {error, notfound};
+       Ss ->
+           lists:foldl(
+             fun(#session{sid = {_, Pid},
+                          info = Info} = Session, _) when Pid == self() ->
+                     Info1 = lists:keydelete(Key, 1, Info),
+                     set_session(Session#session{info = Info1});
+                (_, Acc) ->
+                     Acc
+             end, {error, not_owner}, Ss)
+    end.
+
 -spec set_presence(sid(), binary(), binary(), binary(),
                    prio(), presence(), info()) -> ok.
 
@@ -483,9 +523,13 @@ set_session(SID, User, Server, Resource, Priority, Info) ->
     LResource = jid:resourceprep(Resource),
     US = {LUser, LServer},
     USR = {LUser, LServer, LResource},
+    set_session(#session{sid = SID, usr = USR, us = US,
+                        priority = Priority, info = Info}).
+
+-spec set_session(#session{}) -> ok | {error, any()}.
+set_session(#session{us = {LUser, LServer}} = Session) ->
     Mod = get_sm_backend(LServer),
-    case Mod:set_session(#session{sid = SID, usr = USR, us = US,
-                                 priority = Priority, info = Info}) of
+    case Mod:set_session(Session) of
        ok ->
            case use_cache(Mod, LServer) of
                true ->
index 73034ec3fbb9dc6f2c5bdfb5591a2710d22bb295..4c05f84c32810307d3cdec031f0c67648c011839 100644 (file)
 -export([start/2, stop/1, reload/3]).
 
 -export([user_send_packet/1, user_receive_packet/1,
-        iq_handler/1, remove_connection/4, disco_features/5,
-        is_carbon_copy/1, mod_opt_type/1, depends/2, clean_cache/1,
+        iq_handler/1, disco_features/5,
+        is_carbon_copy/1, mod_opt_type/1, depends/2,
         mod_options/1]).
+%% For debugging purposes
+-export([list/2]).
 
 -include("logger.hrl").
 -include("xmpp.hrl").
--include("mod_carboncopy.hrl").
 
 -type direction() :: sent | received.
 
--callback init(binary(), gen_mod:opts()) -> any().
--callback enable(binary(), binary(), binary(), binary()) -> ok | {error, any()}.
--callback disable(binary(), binary(), binary()) -> ok | {error, any()}.
--callback list(binary(), binary()) -> [{binary(), binary(), node()}].
--callback use_cache(binary()) -> boolean().
--callback cache_nodes(binary()) -> [node()].
-
--optional_callbacks([use_cache/1, cache_nodes/1]).
-
 -spec is_carbon_copy(stanza()) -> boolean().
 is_carbon_copy(#message{meta = #{carbon_copy := true}}) ->
     true;
 is_carbon_copy(_) ->
     false.
 
-start(Host, Opts) ->
+start(Host, _Opts) ->
     ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
-    Mod = gen_mod:ram_db_mod(Host, ?MODULE),
-    init_cache(Mod, Host, Opts),
-    Mod:init(Host, Opts),
-    clean_cache(),
-    ejabberd_hooks:add(unset_presence_hook,Host, ?MODULE, remove_connection, 10),
     %% why priority 89: to define clearly that we must run BEFORE mod_logdb hook (90)
     ejabberd_hooks:add(user_send_packet,Host, ?MODULE, user_send_packet, 89),
     ejabberd_hooks:add(user_receive_packet,Host, ?MODULE, user_receive_packet, 89),
@@ -77,23 +64,10 @@ stop(Host) ->
     ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
     %% why priority 89: to define clearly that we must run BEFORE mod_logdb hook (90)
     ejabberd_hooks:delete(user_send_packet,Host, ?MODULE, user_send_packet, 89),
-    ejabberd_hooks:delete(user_receive_packet,Host, ?MODULE, user_receive_packet, 89),
-    ejabberd_hooks:delete(unset_presence_hook,Host, ?MODULE, remove_connection, 10).
+    ejabberd_hooks:delete(user_receive_packet,Host, ?MODULE, user_receive_packet, 89).
 
-reload(Host, NewOpts, OldOpts) ->
-    NewMod = gen_mod:ram_db_mod(Host, NewOpts, ?MODULE),
-    OldMod = gen_mod:ram_db_mod(Host, OldOpts, ?MODULE),
-    if NewMod /= OldMod ->
-           NewMod:init(Host, NewOpts);
-       true ->
-           ok
-    end,
-    case use_cache(NewMod, Host) of
-       true ->
-           ets_cache:new(?CARBONCOPY_CACHE, cache_opts(NewOpts));
-       false ->
-           ok
-    end.
+reload(_Host, _NewOpts, _OldOpts) ->
+    ok.
 
 -spec disco_features({error, stanza_error()} | {result, [binary()]} | empty,
                     jid(), jid(), binary(), binary()) ->
@@ -113,19 +87,13 @@ iq_handler(#iq{type = set, lang = Lang, from = From,
                                          is_record(El, carbons_disable) ->
     {U, S, R} = jid:tolower(From),
     Result = case El of
-                #carbons_enable{} ->
-                    ?DEBUG("Carbons enabled for user ~s@~s/~s", [U,S,R]),
-                    enable(S, U, R, ?NS_CARBONS_2);
-                #carbons_disable{} ->
-                    ?DEBUG("Carbons disabled for user ~s@~s/~s", [U,S,R]),
-                    disable(S, U, R)
+                #carbons_enable{} -> enable(S, U, R, ?NS_CARBONS_2);
+                #carbons_disable{} -> disable(S, U, R)
             end,
     case Result of
        ok ->
-           ?DEBUG("carbons IQ result: ok", []),
            xmpp:make_iq_result(IQ);
-       {error,_Error} ->
-           ?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]),
+       {error, _} ->
            Txt = <<"Database failure">>,
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end;
@@ -180,12 +148,6 @@ check_and_forward(JID, To, Packet, Direction)->
            Packet
     end.
 
--spec remove_connection(binary(), binary(), binary(), binary()) -> ok.
-remove_connection(User, Server, Resource, _Status)->
-    disable(Server, User, Resource),
-    ok.
-
-
 %%% Internal
 %% Direction = received | sent <received xmlns='urn:xmpp:carbons:1'/>
 -spec send_copies(jid(), jid(), message(), direction()) -> ok.
@@ -248,22 +210,26 @@ build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) ->
 
 -spec enable(binary(), binary(), binary(), binary()) -> ok | {error, any()}.
 enable(Host, U, R, CC)->
-    ?DEBUG("enabling for ~p", [U]),
-    Mod = gen_mod:ram_db_mod(Host, ?MODULE),
-    case Mod:enable(U, Host, R, CC) of
-       ok ->
-           delete_cache(Mod, U, Host);
-       {error, _} = Err ->
+    ?DEBUG("Enabling carbons for ~s@~s/~s", [U, Host, R]),
+    case ejabberd_sm:set_user_info(U, Host, R, carboncopy, CC) of
+       ok -> ok;
+       {error, Reason} = Err ->
+           ?ERROR_MSG("Failed to disable carbons for ~s@~s/~s: ~p",
+                      [U, Host, R, Reason]),
            Err
     end.
 
 -spec disable(binary(), binary(), binary()) -> ok | {error, any()}.
 disable(Host, U, R)->
-    ?DEBUG("disabling for ~p", [U]),
-    Mod = gen_mod:ram_db_mod(Host, ?MODULE),
-    Res = Mod:disable(U, Host, R),
-    delete_cache(Mod, U, Host),
-    Res.
+    ?DEBUG("Disabling carbons for ~s@~s/~s", [U, Host, R]),
+    case ejabberd_sm:del_user_info(U, Host, R, carboncopy) of
+       ok -> ok;
+       {error, notfound} -> ok;
+       {error, Reason} = Err ->
+           ?ERROR_MSG("Failed to disable carbons for ~s@~s/~s: ~p",
+                      [U, Host, R, Reason]),
+           Err
+    end.
 
 -spec complete_packet(jid(), message(), direction()) -> message().
 complete_packet(From, #message{from = undefined} = Msg, sent) ->
@@ -291,99 +257,30 @@ is_received_muc_pm(_To, Packet, received) ->
 
 -spec list(binary(), binary()) -> [{Resource :: binary(), Namespace :: binary()}].
 list(User, Server) ->
-    Mod = gen_mod:ram_db_mod(Server, ?MODULE),
-    case use_cache(Mod, Server) of
-       true ->
-           case ets_cache:lookup(
-                  ?CARBONCOPY_CACHE, {User, Server},
-                  fun() ->
-                          case Mod:list(User, Server) of
-                              {ok, L} when L /= [] -> {ok, L};
-                              _ -> error
-                          end
-                  end) of
-               {ok, L} -> [{Resource, NS} || {Resource, NS, _} <- L];
-               error -> []
-           end;
-       false ->
-           case Mod:list(User, Server) of
-               {ok, L} -> [{Resource, NS} || {Resource, NS, _} <- L];
-               error -> []
-           end
-    end.
-
--spec init_cache(module(), binary(), gen_mod:opts()) -> ok.
-init_cache(Mod, Host, Opts) ->
-    case use_cache(Mod, Host) of
-       true ->
-           ets_cache:new(?CARBONCOPY_CACHE, cache_opts(Opts));
-       false ->
-           ets_cache:delete(?CARBONCOPY_CACHE)
-    end.
-
--spec cache_opts(gen_mod:opts()) -> [proplists:property()].
-cache_opts(Opts) ->
-    MaxSize = gen_mod:get_opt(cache_size, Opts),
-    CacheMissed = gen_mod:get_opt(cache_missed, Opts),
-    LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of
-                  infinity -> infinity;
-                  I -> timer:seconds(I)
-              end,
-    [{max_size, MaxSize}, {cache_missed, CacheMissed}, {life_time, LifeTime}].
-
--spec use_cache(module(), binary()) -> boolean().
-use_cache(Mod, Host) ->
-    case erlang:function_exported(Mod, use_cache, 1) of
-       true -> Mod:use_cache(Host);
-       false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache)
-    end.
-
--spec cache_nodes(module(), binary()) -> [node()].
-cache_nodes(Mod, Host) ->
-    case erlang:function_exported(Mod, cache_nodes, 1) of
-       true -> Mod:cache_nodes(Host);
-       false -> ejabberd_cluster:get_nodes()
-    end.
-
--spec clean_cache(node()) -> non_neg_integer().
-clean_cache(Node) ->
-    ets_cache:filter(
-      ?CARBONCOPY_CACHE,
-      fun(_, error) ->
-             false;
-        (_, {ok, L}) ->
-             not lists:any(fun({_, _, N}) -> N == Node end, L)
-      end).
-
--spec clean_cache() -> ok.
-clean_cache() ->
-    ejabberd_cluster:eval_everywhere(?MODULE, clean_cache, [node()]).
-
--spec delete_cache(module(), binary(), binary()) -> ok.
-delete_cache(Mod, User, Server) ->
-    case use_cache(Mod, Server) of
-       true ->
-           ets_cache:delete(?CARBONCOPY_CACHE, {User, Server},
-                            cache_nodes(Mod, Server));
-       false ->
-           ok
-    end.
+    lists:filtermap(
+      fun({Resource, Info}) ->
+             case lists:keyfind(carboncopy, 1, Info) of
+                 {_, NS} -> {true, {Resource, NS}};
+                 false -> false
+             end
+      end, ejabberd_sm:get_user_info(User, Server)).
 
 depends(_Host, _Opts) ->
     [].
 
-mod_opt_type(ram_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
-mod_opt_type(O) when O == use_cache; O == cache_missed ->
-    fun(B) when is_boolean(B) -> B end;
-mod_opt_type(O) when O == cache_size; O == cache_life_time ->
-    fun(I) when is_integer(I), I>0 -> I;
-       (unlimited) -> infinity;
-       (infinity) -> infinity
+mod_opt_type(O) when O == cache_size; O == cache_life_time;
+                    O == use_cache; O == cache_missed;
+                    O == ram_db_type ->
+    fun(deprecated) -> deprecated;
+       (_) ->
+           ?WARNING_MSG("Option ~s of ~s has no effect anymore "
+                        "and will be ingored", [O, ?MODULE]),
+           deprecated
     end.
 
-mod_options(Host) ->
-    [{ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)},
-     {use_cache, ejabberd_config:use_cache(Host)},
-     {cache_size, ejabberd_config:cache_size(Host)},
-     {cache_missed, ejabberd_config:cache_missed(Host)},
-     {cache_life_time, ejabberd_config:cache_life_time(Host)}].
+mod_options(_) ->
+    [{ram_db_type, deprecated},
+     {use_cache, deprecated},
+     {cache_size, deprecated},
+     {cache_missed, deprecated},
+     {cache_life_time, deprecated}].
diff --git a/src/mod_carboncopy_mnesia.erl b/src/mod_carboncopy_mnesia.erl
deleted file mode 100644 (file)
index 03bde98..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : mod_carboncopy_mnesia.erl
-%%% Author  : Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2018   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--module(mod_carboncopy_mnesia).
-
--behaviour(mod_carboncopy).
-
-%% API
--export([init/2, enable/4, disable/3, list/2, use_cache/1]).
-
--include("mod_carboncopy.hrl").
-
-%%%===================================================================
-%%% API
-%%%===================================================================
-init(_Host, _Opts) ->
-    Fields = record_info(fields, carboncopy),
-    try mnesia:table_info(carboncopy, attributes) of
-       Fields ->
-           ok;
-       _ ->
-           %% recreate..
-           mnesia:delete_table(carboncopy)
-    catch _:_Error ->
-           %% probably table don't exist
-           ok
-    end,
-    ejabberd_mnesia:create(?MODULE, carboncopy,
-                       [{ram_copies, [node()]}, 
-                        {attributes, record_info(fields, carboncopy)}, 
-                        {type, bag}]).
-
-enable(LUser, LServer, LResource, NS) ->
-    mnesia:dirty_write(
-      #carboncopy{us = {LUser, LServer},
-                 resource = LResource,
-                 version = NS}).
-
-disable(LUser, LServer, LResource) ->
-    ToDelete = mnesia:dirty_match_object(
-                #carboncopy{us = {LUser, LServer},
-                            resource = LResource,
-                            _ = '_'}),
-    lists:foreach(fun mnesia:dirty_delete_object/1, ToDelete).
-
-list(LUser, LServer) ->
-    {ok, mnesia:dirty_select(
-          carboncopy,
-          [{#carboncopy{us = {LUser, LServer}, resource = '$2',
-                        version = '$3', node = '$4'},
-            [], [{{'$2','$3','$4'}}]}])}.
-
-use_cache(_LServer) ->
-    false.
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
diff --git a/src/mod_carboncopy_redis.erl b/src/mod_carboncopy_redis.erl
deleted file mode 100644 (file)
index 90b5516..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% Created : 30 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2018   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%-------------------------------------------------------------------
--module(mod_carboncopy_redis).
--behaviour(mod_carboncopy).
--behaviour(gen_server).
-
-%% API
--export([init/2, enable/4, disable/3, list/2, cache_nodes/1]).
-%% gen_server callbacks
--export([init/1, handle_cast/2, handle_call/3, handle_info/2,
-        terminate/2, code_change/3, start_link/0]).
-
--include("logger.hrl").
--include("mod_carboncopy.hrl").
-
--define(CARBONCOPY_KEY, <<"ejabberd:carboncopy">>).
-
--record(state, {}).
-
-%%%===================================================================
-%%% API
-%%%===================================================================
-init(_Host, _Opts) ->
-    Spec = {?MODULE, {?MODULE, start_link, []},
-           transient, 5000, worker, [?MODULE]},
-    case supervisor:start_child(ejabberd_backend_sup, Spec) of
-       {ok, _Pid} -> ok;
-       Err -> Err
-    end.
-
--spec start_link() -> {ok, pid()} | {error, any()}.
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-cache_nodes(_LServer) ->
-    [node()].
-
-enable(LUser, LServer, LResource, NS) ->
-    USKey = us_key(LUser, LServer),
-    NodeKey = node_key(),
-    JID = jid:encode({LUser, LServer, LResource}),
-    Data = term_to_binary({NS, node()}),
-    case ejabberd_redis:multi(
-          fun() ->
-                  ejabberd_redis:hset(USKey, LResource, Data),
-                  ejabberd_redis:sadd(NodeKey, [JID]),
-                  ejabberd_redis:publish(
-                    ?CARBONCOPY_KEY,
-                    term_to_binary({delete, {LUser, LServer}}))
-          end) of
-       {ok, _} ->
-           ok;
-       {error, _} ->
-           {error, db_failure}
-    end.
-
-disable(LUser, LServer, LResource) ->
-    USKey = us_key(LUser, LServer),
-    NodeKey = node_key(),
-    JID = jid:encode({LUser, LServer, LResource}),
-    case ejabberd_redis:multi(
-          fun() ->
-                  ejabberd_redis:hdel(USKey, [LResource]),
-                  ejabberd_redis:srem(NodeKey, [JID]),
-                  ejabberd_redis:publish(
-                    ?CARBONCOPY_KEY,
-                    term_to_binary({delete, {LUser, LServer}}))
-          end) of
-       {ok, _} ->
-           ok;
-       {error, _} ->
-           {error, db_failure}
-    end.
-
-list(LUser, LServer) ->
-    USKey = us_key(LUser, LServer),
-    case ejabberd_redis:hgetall(USKey) of
-       {ok, Pairs} ->
-           {ok, lists:flatmap(
-                  fun({Resource, Data}) ->
-                          try
-                              {NS, Node} = binary_to_term(Data),
-                              [{Resource, NS, Node}]
-                          catch _:_ ->
-                                  ?ERROR_MSG("invalid term stored in Redis "
-                                             "(key = ~s): ~p",
-                                             [USKey, Data]),
-                                  []
-                          end
-                  end, Pairs)};
-       {error, _} ->
-           {error, db_failure}
-    end.
-
-%%%===================================================================
-%%% gen_server callbacks
-%%%===================================================================
-init([]) ->
-    ejabberd_redis:subscribe([?CARBONCOPY_KEY]),
-    clean_table(),
-    {ok, #state{}}.
-
-handle_call(_Request, _From, State) ->
-    Reply = ok,
-    {reply, Reply, State}.
-
-handle_cast(_Msg, State) ->
-    {noreply, State}.
-
-handle_info({redis_message, ?CARBONCOPY_KEY, Data}, State) ->
-    case binary_to_term(Data) of
-       {delete, Key} ->
-           ets_cache:delete(?CARBONCOPY_CACHE, Key);
-       Msg ->
-           ?WARNING_MSG("unexpected redis message: ~p", [Msg])
-    end,
-    {noreply, State};
-handle_info(Info, State) ->
-    ?ERROR_MSG("unexpected info: ~p", [Info]),
-    {noreply, State}.
-
-terminate(_Reason, _State) ->
-    ok.
-
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
-clean_table() ->
-    ?DEBUG("Cleaning Redis 'carboncopy' table...", []),
-    NodeKey = node_key(),
-    case ejabberd_redis:smembers(NodeKey) of
-       {ok, JIDs} ->
-           ejabberd_redis:multi(
-             fun() ->
-                     lists:foreach(
-                       fun(JID) ->
-                               {U, S, R} = jid:split(jid:decode(JID)),
-                               USKey = us_key(U, S),
-                               ejabberd_redis:hdel(USKey, [R])
-                       end, JIDs)
-             end);
-       {error, _} ->
-           ok
-    end,
-    ejabberd_redis:del([NodeKey]),
-    ok.
-
-us_key(LUser, LServer) ->
-    <<"ejabberd:carboncopy:users:", LUser/binary, $@, LServer/binary>>.
-
-node_key() ->
-    Node = erlang:atom_to_binary(node(), latin1),
-    <<"ejabberd:carboncopy:nodes:", Node/binary>>.
diff --git a/src/mod_carboncopy_riak.erl b/src/mod_carboncopy_riak.erl
deleted file mode 100644 (file)
index d6df300..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2018   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%-------------------------------------------------------------------
--module(mod_carboncopy_riak).
--behaviour(mod_carboncopy).
-
-%% API
--export([init/2, enable/4, disable/3, list/2]).
-
--include("logger.hrl").
--include("mod_carboncopy.hrl").
-
-%%%===================================================================
-%%% API
-%%%===================================================================
-init(_Host, _Opts) ->
-    clean_table().
-
-enable(LUser, LServer, LResource, NS) ->
-    ejabberd_riak:put(#carboncopy{us = {LUser, LServer},
-                                 resource = LResource,
-                                 version = NS},
-                     carboncopy_schema(),
-                     [{i, {LUser, LServer, LResource}},
-                      {'2i', [{<<"us">>, {LUser, LServer}}]}]).
-
-disable(LUser, LServer, LResource) ->
-    ejabberd_riak:delete(carboncopy, {LUser, LServer, LResource}).
-
-list(LUser, LServer) ->
-    case ejabberd_riak:get_by_index(
-          carboncopy, carboncopy_schema(),
-          <<"us">>, {LUser, LServer}) of
-       {ok, Rs} ->
-           {ok, [{Resource, NS, Node}
-                 || #carboncopy{resource = Resource,
-                                version = NS,
-                                node = Node} <- Rs]};
-       {error, _} = Err ->
-           Err
-    end.
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
-carboncopy_schema() ->
-    {record_info(fields, carboncopy), #carboncopy{}}.
-
-clean_table() ->
-    ?DEBUG("Cleaning Riak 'carboncopy' table...", []),
-    case ejabberd_riak:get(carboncopy, carboncopy_schema()) of
-       {ok, Rs} ->
-           lists:foreach(
-             fun(#carboncopy{us = {U, S}, resource = R, node = Node})
-                   when Node == node() ->
-                     ejabberd_riak:delete(carboncopy, {U, S, R});
-                (_) ->
-                     ok
-             end, Rs);
-       {error, Reason} = Err ->
-           ?ERROR_MSG("Failed to clean Riak 'carboncopy' table: ~p", [Reason]),
-           Err
-    end.
diff --git a/src/mod_carboncopy_sql.erl b/src/mod_carboncopy_sql.erl
deleted file mode 100644 (file)
index 46b6ea8..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% Created : 29 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2018   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%-------------------------------------------------------------------
--module(mod_carboncopy_sql).
--behaviour(mod_carboncopy).
-
--compile([{parse_transform, ejabberd_sql_pt}]).
-
-%% API
--export([init/2, enable/4, disable/3, list/2]).
-
--include("logger.hrl").
--include("ejabberd_sql_pt.hrl").
-
-%%%===================================================================
-%%% API
-%%%===================================================================
-init(Host, _Opts) ->
-    clean_table(Host).
-
-enable(LUser, LServer, LResource, NS) ->
-    NodeS = erlang:atom_to_binary(node(), latin1),
-    case ?SQL_UPSERT(LServer, "carboncopy",
-                    ["!username=%(LUser)s",
-                      "!server_host=%(LServer)s",
-                     "!resource=%(LResource)s",
-                     "namespace=%(NS)s",
-                     "node=%(NodeS)s"]) of
-       ok ->
-           ok;
-       _Err ->
-           {error, db_failure}
-    end.
-
-disable(LUser, LServer, LResource) ->
-    case ejabberd_sql:sql_query(
-          LServer,
-          ?SQL("delete from carboncopy where username=%(LUser)s "
-               "and %(LServer)H and resource=%(LResource)s")) of
-       {updated, _} ->
-           ok;
-       _Err ->
-           {error, db_failure}
-    end.
-
-list(LUser, LServer) ->
-    case ejabberd_sql:sql_query(
-          LServer,
-          ?SQL("select @(resource)s, @(namespace)s, @(node)s from carboncopy "
-               "where username=%(LUser)s and %(LServer)H")) of
-       {selected, Rows} ->
-           {ok, [{Resource, NS, binary_to_atom(Node, latin1)}
-                 || {Resource, NS, Node} <- Rows]};
-       _Err ->
-           {error, db_failure}
-    end.
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
-clean_table(LServer) ->
-    NodeS = erlang:atom_to_binary(node(), latin1),
-    ?DEBUG("Cleaning SQL 'carboncopy' table...", []),
-    case ejabberd_sql:sql_query(
-          LServer,
-          ?SQL("delete from carboncopy where node=%(NodeS)s")) of
-       {updated, _} ->
-           ok;
-       Err ->
-           ?ERROR_MSG("failed to clean 'carboncopy' table: ~p", [Err]),
-           {error, db_failure}
-    end.