mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-20 17:27:00 +01:00
Remove Riak support
Reasons: - Riak DB development is almost halted after Basho - riak-erlang-client is abandoned and doesn't work correctly with OTP22 - Riak is slow in comparison to other databases - Missing key ordering makes it impossible to implement range queries efficiently (e.g. MAM queries)
This commit is contained in:
parent
11e4b9d882
commit
3f7d9e3ad6
@ -44,7 +44,7 @@ before_script:
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --prefix=/tmp/ejabberd --enable-all --disable-odbc --disable-riak --disable-elixir
|
||||
- ./configure --prefix=/tmp/ejabberd --enable-all --disable-odbc --disable-elixir
|
||||
- make
|
||||
- make install -s
|
||||
- make xref
|
||||
|
17
configure.ac
17
configure.ac
@ -109,10 +109,10 @@ AC_ARG_ENABLE(mssql,
|
||||
esac],[db_type=generic])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-riak --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true stun=true sip=true debug=true tools=true ;;
|
||||
no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false riak=false redis=false elixir=false stun=false sip=false debug=false tools=false ;;
|
||||
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true tools=true ;;
|
||||
no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
@ -172,14 +172,6 @@ AC_ARG_ENABLE(zlib,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
|
||||
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(riak,
|
||||
[AC_HELP_STRING([--enable-riak], [enable Riak support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) riak=true ;;
|
||||
no) riak=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-riak) ;;
|
||||
esac],[if test "x$riak" = "x"; then riak=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(redis,
|
||||
[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
@ -275,7 +267,7 @@ if test "$sqlite" = "true"; then
|
||||
fi
|
||||
|
||||
enabled_backends=""
|
||||
for backend in odbc mysql pgsql sqlite riak redis; do
|
||||
for backend in odbc mysql pgsql sqlite redis; do
|
||||
if eval test x\${$backend} = xtrue; then
|
||||
if test "x$enabled_backends" = "x"; then
|
||||
enabled_backends=$backend
|
||||
@ -296,7 +288,6 @@ AC_SUBST(pgsql)
|
||||
AC_SUBST(sqlite)
|
||||
AC_SUBST(pam)
|
||||
AC_SUBST(zlib)
|
||||
AC_SUBST(riak)
|
||||
AC_SUBST(redis)
|
||||
AC_SUBST(elixir)
|
||||
AC_SUBST(stun)
|
||||
|
1
mix.exs
1
mix.exs
@ -107,7 +107,6 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
defp cond_deps do
|
||||
for {:true, dep} <- [{config(:sqlite), {:sqlite3, "~> 1.1"}},
|
||||
{config(:riak), {:riakc, "~> 2.4"}},
|
||||
{config(:redis), {:eredis, "~> 1.0"}},
|
||||
{config(:zlib), {:ezlib, "~> 1.0"}},
|
||||
{config(:pam), {:epam, "~> 1.0"}},
|
||||
|
2
mix.lock
2
mix.lock
@ -28,8 +28,6 @@
|
||||
"p1_pgsql": {:hex, :p1_pgsql, "1.1.7", "ef64d34adbbe08258cc10b1532649446d8c086ff8663d44f430d837ec31a89f8", [:rebar3], [], "hexpm"},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.15", "731f76ae1f31f4554afb2ae629cb5589d53bd13efc72b11f5a7c3b1242f91046", [:rebar3], [], "hexpm"},
|
||||
"pkix": {:hex, :pkix, "1.0.2", "f618455c4edbcc7ebf8be5e655b269876fa36e890b806d18d8b2b708dfb1e583", [:rebar3], [], "hexpm"},
|
||||
"riak_pb": {:hex, :riak_pb, "2.3.2", "48ffbf66dbb3f136ab9a7134bac4e496754baa5ef58c4f50a61326736d996390", [:make, :mix, :rebar3], [{:hamcrest, "~> 0.4.1", [hex: :basho_hamcrest, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"riakc": {:hex, :riakc, "2.5.3", "6132d9e687a0dfd314b2b24c4594302ca8b55568a5d733c491d8fb6cd4004763", [:make, :mix, :rebar3], [{:riak_pb, "~> 2.3", [hex: :riak_pb, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlite3": {:hex, :sqlite3, "1.1.6", "4ea71af0b45908b5f02c9b09e4c87177039ef404f20accb35049cd8924cc417c", [:rebar3], [], "hexpm"},
|
||||
"stringprep": {:hex, :stringprep, "1.0.16", "5a7e617cabba5791aed45b394307d46b9f22ac2eef3bbcf6a4b639637079c84d", [:rebar3], [{:p1_utils, "1.0.15", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"stun": {:hex, :stun, "1.0.28", "ee81bc075f955f529679213157f76c3d3355a1dec4625108a62872006c3db8a0", [:rebar3], [{:fast_tls, "1.1.1", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.15", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -45,8 +45,6 @@
|
||||
{tag, "1.0.6"}}}},
|
||||
{if_var_true, zlib, {ezlib, ".*", {git, "https://github.com/processone/ezlib",
|
||||
{tag, "1.0.6"}}}},
|
||||
{if_var_true, riak, {riakc, ".*", {git, "https://github.com/processone/riak-erlang-client",
|
||||
{tag, {if_version_above, "19", "develop", "2.5.3"}}}}},
|
||||
%% Elixir support, needed to run tests
|
||||
{if_var_true, elixir, {elixir, ".*", {git, "https://github.com/elixir-lang/elixir",
|
||||
{tag, {if_version_above, "17", "v1.4.4", "v1.1.1"}}}}},
|
||||
@ -129,8 +127,6 @@
|
||||
{if_var_false, mysql, "(\".*mysql.*\":_/_)"},
|
||||
{if_var_false, pgsql, "(\".*pgsql.*\":_/_)"},
|
||||
{if_var_false, pam, "(\"epam\":_/_)"},
|
||||
{if_var_false, riak, "(\"riak.*\":_/_)"},
|
||||
{if_var_true, riak, "(\"riak_object\":_/_)"},
|
||||
{if_var_false, zlib, "(\"ezlib\":_/_)"},
|
||||
{if_var_false, http, "(\"lhttpc\":_/_)"},
|
||||
{if_var_false, odbc, "(\"odbc\":_/_)"},
|
||||
|
@ -278,7 +278,7 @@ get_commands_spec() ->
|
||||
args_example = ["example.com"],
|
||||
args = [{host, binary}], result = {res, rescode}},
|
||||
|
||||
#ejabberd_commands{name = import_prosody, tags = [mnesia, sql, riak],
|
||||
#ejabberd_commands{name = import_prosody, tags = [mnesia, sql],
|
||||
desc = "Import data from Prosody",
|
||||
longdesc = "Note: this method requires ejabberd compiled with optional tools support "
|
||||
"and package must provide optional luerl dependency.",
|
||||
|
@ -901,7 +901,5 @@ import_start(_LServer, _) ->
|
||||
|
||||
import(Server, {sql, _}, mnesia, <<"users">>, Fields) ->
|
||||
ejabberd_auth_mnesia:import(Server, Fields);
|
||||
import(Server, {sql, _}, riak, <<"users">>, Fields) ->
|
||||
ejabberd_auth_riak:import(Server, Fields);
|
||||
import(_LServer, {sql, _}, sql, <<"users">>, _) ->
|
||||
ok.
|
||||
|
@ -1,127 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_auth_riak.erl
|
||||
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Purpose : Authentication via Riak
|
||||
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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(ejabberd_auth_riak).
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, stop/1, set_password/3, try_register/3,
|
||||
get_users/2, count_users/2,
|
||||
get_password/2, remove_user/2, store_type/1, export/1, import/2,
|
||||
plain_password_required/1]).
|
||||
-export([passwd_schema/0]).
|
||||
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
-include("scram.hrl").
|
||||
-include("ejabberd_auth.hrl").
|
||||
|
||||
start(_Host) ->
|
||||
ok.
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
plain_password_required(Server) ->
|
||||
store_type(Server) == scram.
|
||||
|
||||
store_type(Server) ->
|
||||
ejabberd_auth:password_format(Server).
|
||||
|
||||
passwd_schema() ->
|
||||
{record_info(fields, passwd), #passwd{}}.
|
||||
|
||||
set_password(User, Server, Password) ->
|
||||
case ejabberd_riak:put(#passwd{us = {User, Server}, password = Password},
|
||||
passwd_schema(),
|
||||
[{'2i', [{<<"host">>, Server}]}]) of
|
||||
ok -> {cache, {ok, Password}};
|
||||
{error, _} -> {nocache, {error, db_failure}}
|
||||
end.
|
||||
|
||||
try_register(User, Server, Password) ->
|
||||
US = {User, Server},
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), US) of
|
||||
{error, notfound} ->
|
||||
case ejabberd_riak:put(#passwd{us = US, password = Password},
|
||||
passwd_schema(),
|
||||
[{'2i', [{<<"host">>, Server}]}]) of
|
||||
ok -> {cache, {ok, Password}};
|
||||
{error, _} -> {nocache, {error, db_failure}}
|
||||
end;
|
||||
{ok, _} ->
|
||||
{cache, {error, exists}};
|
||||
{error, _} ->
|
||||
{nocache, {error, db_failure}}
|
||||
end.
|
||||
|
||||
get_users(Server, _) ->
|
||||
case ejabberd_riak:get_keys_by_index(passwd, <<"host">>, Server) of
|
||||
{ok, Users} ->
|
||||
Users;
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
count_users(Server, _) ->
|
||||
case ejabberd_riak:count_by_index(passwd, <<"host">>, Server) of
|
||||
{ok, N} ->
|
||||
N;
|
||||
_ ->
|
||||
0
|
||||
end.
|
||||
|
||||
get_password(User, Server) ->
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {User, Server}) of
|
||||
{ok, Password} ->
|
||||
{cache, {ok, Password}};
|
||||
{error, notfound} ->
|
||||
{cache, error};
|
||||
{error, _} ->
|
||||
{nocache, error}
|
||||
end.
|
||||
|
||||
remove_user(User, Server) ->
|
||||
ejabberd_riak:delete(passwd, {User, Server}).
|
||||
|
||||
export(_Server) ->
|
||||
[{passwd,
|
||||
fun(Host, #passwd{us = {LUser, LServer}, password = Password})
|
||||
when LServer == Host ->
|
||||
[?SQL("delete from users where username=%(LUser)s and %(LServer)H;"),
|
||||
?SQL_INSERT(
|
||||
"users",
|
||||
["username=%(LUser)s",
|
||||
"server_host=%(LServer)s",
|
||||
"password=%(Password)s"])];
|
||||
(_Host, _R) ->
|
||||
[]
|
||||
end}].
|
||||
|
||||
import(LServer, [LUser, Password, _TimeStamp]) ->
|
||||
Passwd = #passwd{us = {LUser, LServer}, password = Password},
|
||||
ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]).
|
@ -60,8 +60,7 @@ transform(Opts) ->
|
||||
Opts1 = transform_register(Opts),
|
||||
Opts2 = transform_s2s(Opts1),
|
||||
Opts3 = transform_listeners(Opts2),
|
||||
Opts4 = transform_sql(Opts3),
|
||||
Opts5 = transform_riak(Opts4),
|
||||
Opts5 = transform_sql(Opts3),
|
||||
Opts6 = transform_shaper(Opts5),
|
||||
Opts7 = transform_s2s_out(Opts6),
|
||||
Opts8 = transform_acl(Opts7),
|
||||
@ -412,17 +411,6 @@ transform_sql({odbc_pool_size, N}, Opts) ->
|
||||
transform_sql(Opt, Opts) ->
|
||||
[Opt|Opts].
|
||||
|
||||
%%%===================================================================
|
||||
%%% Riak
|
||||
%%%===================================================================
|
||||
transform_riak(Opts) ->
|
||||
lists:foldl(fun transform_riak/2, [], Opts).
|
||||
|
||||
transform_riak({riak_server, {S, P}}, Opts) ->
|
||||
[{riak_server, S}, {riak_port, P}|Opts];
|
||||
transform_riak(Opt, Opts) ->
|
||||
[Opt|Opts].
|
||||
|
||||
%%%===================================================================
|
||||
%%% modules
|
||||
%%%===================================================================
|
||||
|
@ -105,13 +105,6 @@
|
||||
-export([redis_server/0]).
|
||||
-export([registration_timeout/0]).
|
||||
-export([resource_conflict/0, resource_conflict/1]).
|
||||
-export([riak_cacertfile/0]).
|
||||
-export([riak_password/0]).
|
||||
-export([riak_pool_size/0]).
|
||||
-export([riak_port/0]).
|
||||
-export([riak_server/0]).
|
||||
-export([riak_start_interval/0]).
|
||||
-export([riak_username/0]).
|
||||
-export([router_cache_life_time/0]).
|
||||
-export([router_cache_missed/0]).
|
||||
-export([router_cache_size/0]).
|
||||
@ -327,17 +320,17 @@ cluster_backend() ->
|
||||
cluster_nodes() ->
|
||||
ejabberd_config:get_option({cluster_nodes, global}).
|
||||
|
||||
-spec default_db() -> 'mnesia' | 'riak' | 'sql'.
|
||||
-spec default_db() -> 'mnesia' | 'sql'.
|
||||
default_db() ->
|
||||
default_db(global).
|
||||
-spec default_db(global | binary()) -> 'mnesia' | 'riak' | 'sql'.
|
||||
-spec default_db(global | binary()) -> 'mnesia' | 'sql'.
|
||||
default_db(Host) ->
|
||||
ejabberd_config:get_option({default_db, Host}).
|
||||
|
||||
-spec default_ram_db() -> 'mnesia' | 'redis' | 'riak' | 'sql'.
|
||||
-spec default_ram_db() -> 'mnesia' | 'redis' | 'sql'.
|
||||
default_ram_db() ->
|
||||
default_ram_db(global).
|
||||
-spec default_ram_db(global | binary()) -> 'mnesia' | 'redis' | 'riak' | 'sql'.
|
||||
-spec default_ram_db(global | binary()) -> 'mnesia' | 'redis' | 'sql'.
|
||||
default_ram_db(Host) ->
|
||||
ejabberd_config:get_option({default_ram_db, Host}).
|
||||
|
||||
@ -735,34 +728,6 @@ resource_conflict() ->
|
||||
resource_conflict(Host) ->
|
||||
ejabberd_config:get_option({resource_conflict, Host}).
|
||||
|
||||
-spec riak_cacertfile() -> 'nil' | string().
|
||||
riak_cacertfile() ->
|
||||
ejabberd_config:get_option({riak_cacertfile, global}).
|
||||
|
||||
-spec riak_password() -> 'nil' | string().
|
||||
riak_password() ->
|
||||
ejabberd_config:get_option({riak_password, global}).
|
||||
|
||||
-spec riak_pool_size() -> pos_integer().
|
||||
riak_pool_size() ->
|
||||
ejabberd_config:get_option({riak_pool_size, global}).
|
||||
|
||||
-spec riak_port() -> 1..1114111.
|
||||
riak_port() ->
|
||||
ejabberd_config:get_option({riak_port, global}).
|
||||
|
||||
-spec riak_server() -> string().
|
||||
riak_server() ->
|
||||
ejabberd_config:get_option({riak_server, global}).
|
||||
|
||||
-spec riak_start_interval() -> pos_integer().
|
||||
riak_start_interval() ->
|
||||
ejabberd_config:get_option({riak_start_interval, global}).
|
||||
|
||||
-spec riak_username() -> 'nil' | string().
|
||||
riak_username() ->
|
||||
ejabberd_config:get_option({riak_username, global}).
|
||||
|
||||
-spec router_cache_life_time() -> 'infinity' | pos_integer().
|
||||
router_cache_life_time() ->
|
||||
ejabberd_config:get_option({router_cache_life_time, global}).
|
||||
|
@ -104,9 +104,9 @@ opt_type(cluster_backend) ->
|
||||
opt_type(cluster_nodes) ->
|
||||
econf:list(econf:atom(), [unique]);
|
||||
opt_type(default_db) ->
|
||||
econf:enum([mnesia, riak, sql]);
|
||||
econf:enum([mnesia, sql]);
|
||||
opt_type(default_ram_db) ->
|
||||
econf:enum([mnesia, riak, sql, redis]);
|
||||
econf:enum([mnesia, sql, redis]);
|
||||
opt_type(define_macro) ->
|
||||
econf:any();
|
||||
opt_type(disable_sasl_mechanisms) ->
|
||||
@ -280,20 +280,6 @@ opt_type(registration_timeout) ->
|
||||
econf:timeout(second, infinity);
|
||||
opt_type(resource_conflict) ->
|
||||
econf:enum([setresource, closeold, closenew, acceptnew]);
|
||||
opt_type(riak_cacertfile) ->
|
||||
econf:and_then(econf:pem(), econf:string());
|
||||
opt_type(riak_password) ->
|
||||
econf:string();
|
||||
opt_type(riak_pool_size) ->
|
||||
econf:pos_int();
|
||||
opt_type(riak_port) ->
|
||||
econf:port();
|
||||
opt_type(riak_server) ->
|
||||
econf:string();
|
||||
opt_type(riak_start_interval) ->
|
||||
econf:timeout(second);
|
||||
opt_type(riak_username) ->
|
||||
econf:string();
|
||||
opt_type(router_cache_life_time) ->
|
||||
econf:timeout(second, infinity);
|
||||
opt_type(router_cache_missed) ->
|
||||
@ -570,13 +556,6 @@ options() ->
|
||||
{redis_server, "localhost"},
|
||||
{registration_timeout, timer:seconds(600)},
|
||||
{resource_conflict, acceptnew},
|
||||
{riak_cacertfile, nil},
|
||||
{riak_password, nil},
|
||||
{riak_pool_size, 10},
|
||||
{riak_port, 8087},
|
||||
{riak_server, "127.0.0.1"},
|
||||
{riak_start_interval, timer:seconds(30)},
|
||||
{riak_username, nil},
|
||||
{router_cache_life_time,
|
||||
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
|
||||
{router_cache_missed,
|
||||
@ -702,13 +681,6 @@ globals() ->
|
||||
redis_queue_type,
|
||||
redis_server,
|
||||
registration_timeout,
|
||||
riak_cacertfile,
|
||||
riak_password,
|
||||
riak_pool_size,
|
||||
riak_port,
|
||||
riak_server,
|
||||
riak_start_interval,
|
||||
riak_username,
|
||||
router_cache_life_time,
|
||||
router_cache_missed,
|
||||
router_cache_size,
|
||||
|
@ -1,568 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : ejabberd_riak.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : Interface for Riak database
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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(ejabberd_riak).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/5, get_proc/1, make_bucket/1, put/2, put/3,
|
||||
get/2, get/3, get_by_index/4, delete/1, delete/2,
|
||||
count_by_index/3, get_by_index_range/5,
|
||||
get_keys/1, get_keys_by_index/3, is_connected/0,
|
||||
count/1, delete_by_index/3]).
|
||||
%% For debugging
|
||||
-export([get_tables/0]).
|
||||
%% map/reduce exports
|
||||
-export([map_key/3]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-record(state, {pid = self() :: pid()}).
|
||||
|
||||
-type index() :: {binary(), any()}.
|
||||
|
||||
-type index_info() :: [{i, any()} | {'2i', [index()]}].
|
||||
|
||||
%% The `record_schema()' is just a tuple:
|
||||
%% {record_info(fields, some_record), #some_record{}}
|
||||
|
||||
-type record_schema() :: {[atom()], tuple()}.
|
||||
|
||||
%% The `index_info()' is used in put/delete functions:
|
||||
%% `i' defines a primary index, `` '2i' '' defines secondary indexes.
|
||||
%% There must be only one primary index. If `i' is not specified,
|
||||
%% the first element of the record is assumed as a primary index,
|
||||
%% i.e. `i' = element(2, Record).
|
||||
|
||||
-export_type([index_info/0]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
start_link(Num, Server, Port, _StartInterval, Options) ->
|
||||
gen_server:start_link({local, get_proc(Num)}, ?MODULE, [Server, Port, Options], []).
|
||||
|
||||
%% @private
|
||||
is_connected() ->
|
||||
lists:all(
|
||||
fun({_Id, Pid, _Type, _Modules}) when is_pid(Pid) ->
|
||||
case catch riakc_pb_socket:is_connected(get_riak_pid(Pid)) of
|
||||
true -> true;
|
||||
_ -> false
|
||||
end;
|
||||
(_) ->
|
||||
false
|
||||
end, supervisor:which_children(ejabberd_riak_sup)).
|
||||
|
||||
%% @private
|
||||
get_proc(I) ->
|
||||
misc:binary_to_atom(
|
||||
iolist_to_binary(
|
||||
[atom_to_list(?MODULE), $_, integer_to_list(I)])).
|
||||
|
||||
-spec make_bucket(atom()) -> binary().
|
||||
%% @doc Makes a bucket from a table name
|
||||
%% @private
|
||||
make_bucket(Table) ->
|
||||
erlang:atom_to_binary(Table, utf8).
|
||||
|
||||
-spec put(tuple(), record_schema()) -> ok | {error, any()}.
|
||||
%% @equiv put(Record, [])
|
||||
put(Record, RecFields) ->
|
||||
?MODULE:put(Record, RecFields, []).
|
||||
|
||||
-spec put(tuple(), record_schema(), index_info()) -> ok | {error, any()}.
|
||||
%% @doc Stores a record `Rec' with indexes described in ``IndexInfo''
|
||||
put(Rec, RecSchema, IndexInfo) ->
|
||||
Key = encode_key(proplists:get_value(i, IndexInfo, element(2, Rec))),
|
||||
SecIdxs = [encode_index_key(K, V) ||
|
||||
{K, V} <- proplists:get_value('2i', IndexInfo, [])],
|
||||
Table = element(1, Rec),
|
||||
Value = encode_record(Rec, RecSchema),
|
||||
case put_raw(Table, Key, Value, SecIdxs) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _} = Error ->
|
||||
log_error(Error, put, [{record, Rec},
|
||||
{index_info, IndexInfo}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
put_raw(Table, Key, Value, Indexes) ->
|
||||
Bucket = make_bucket(Table),
|
||||
Obj = riakc_obj:new(Bucket, Key, Value, "application/x-erlang-term"),
|
||||
Obj1 = if Indexes /= [] ->
|
||||
MetaData = dict:store(<<"index">>, Indexes, dict:new()),
|
||||
riakc_obj:update_metadata(Obj, MetaData);
|
||||
true ->
|
||||
Obj
|
||||
end,
|
||||
catch riakc_pb_socket:put(get_random_pid(), Obj1).
|
||||
|
||||
get_object_raw(Table, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
catch riakc_pb_socket:get(get_random_pid(), Bucket, Key).
|
||||
|
||||
-spec get(atom(), record_schema()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns all objects from table `Table'
|
||||
get(Table, RecSchema) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Obj) ->
|
||||
case catch decode_record(Obj, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Obj)},
|
||||
log_error(Error, get,
|
||||
[{table, Table}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Objs)};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get(atom(), record_schema(), any()) -> {ok, any()} | {error, any()}.
|
||||
%% @doc Reads record by `Key' from table `Table'
|
||||
get(Table, RecSchema, Key) ->
|
||||
case get_raw(Table, encode_key(Key)) of
|
||||
{ok, Val} ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get, [{table, Table}, {key, Key}]),
|
||||
{error, notfound};
|
||||
Term ->
|
||||
{ok, Term}
|
||||
end;
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get, [{table, Table},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_by_index(atom(), record_schema(), binary(), any()) ->
|
||||
{ok, [any()]} | {error, any()}.
|
||||
%% @doc Reads records by `Index' and value `Key' from `Table'
|
||||
get_by_index(Table, RecSchema, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
case get_by_index_raw(Table, NewIndex, NewKey) of
|
||||
{ok, Vals} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Val) ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get_by_index,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Vals)};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_by_index,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_by_index_range(atom(), record_schema(), binary(), any(), any()) ->
|
||||
{ok, [any()]} | {error, any()}.
|
||||
%% @doc Reads records by `Index' in the range `FromKey'..`ToKey' from `Table'
|
||||
get_by_index_range(Table, RecSchema, Index, FromKey, ToKey) ->
|
||||
{NewIndex, NewFromKey} = encode_index_key(Index, FromKey),
|
||||
{NewIndex, NewToKey} = encode_index_key(Index, ToKey),
|
||||
case get_by_index_range_raw(Table, NewIndex, NewFromKey, NewToKey) of
|
||||
{ok, Vals} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Val) ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get_by_index_range,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{start_key, FromKey},
|
||||
{end_key, ToKey}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Vals)};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_by_index_range,
|
||||
[{table, Table}, {index, Index},
|
||||
{start_key, FromKey}, {end_key, ToKey}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
get_raw(Table, Key) ->
|
||||
case get_object_raw(Table, Key) of
|
||||
{ok, Obj} ->
|
||||
{ok, riakc_obj:get_value(Obj)};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_keys(atom()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns a list of index values
|
||||
get_keys(Table) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
|
||||
{ok, [{_, Keys}]} ->
|
||||
{ok, Keys};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_keys, [{table, Table}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_keys_by_index(atom(), binary(),
|
||||
any()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns a list of primary keys of objects indexed by `Key'.
|
||||
get_keys_by_index(Table, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, NewIndex, NewKey},
|
||||
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
|
||||
{ok, [{_, Keys}]} ->
|
||||
{ok, Keys};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_keys_by_index, [{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
%% @hidden
|
||||
get_tables() ->
|
||||
catch riakc_pb_socket:list_buckets(get_random_pid()).
|
||||
|
||||
get_by_index_raw(Table, Index, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, Key},
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, Objs};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
get_by_index_range_raw(Table, Index, FromKey, ToKey) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, FromKey, ToKey},
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, Objs};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec count(atom()) -> {ok, non_neg_integer()} | {error, any()}.
|
||||
%% @doc Returns the number of objects in the `Table'
|
||||
count(Table) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
|
||||
none, true}]) of
|
||||
{ok, [{_, [Cnt]}]} ->
|
||||
{ok, Cnt};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, count, [{table, Table}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec count_by_index(atom(), binary(), any()) ->
|
||||
{ok, non_neg_integer()} | {error, any()}.
|
||||
%% @doc Returns the number of objects in the `Table' by index
|
||||
count_by_index(Tab, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
case count_by_index_raw(Tab, NewIndex, NewKey) of
|
||||
{ok, Cnt} ->
|
||||
{ok, Cnt};
|
||||
{error, notfound} ->
|
||||
{ok, 0};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, count_by_index,
|
||||
[{table, Tab},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
count_by_index_raw(Table, Index, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, Key},
|
||||
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
|
||||
none, true}]) of
|
||||
{ok, [{_, [Cnt]}]} ->
|
||||
{ok, Cnt};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec delete(tuple() | atom()) -> ok | {error, any()}.
|
||||
%% @doc Same as delete(T, []) when T is record.
|
||||
%% Or deletes all elements from table if T is atom.
|
||||
delete(Rec) when is_tuple(Rec) ->
|
||||
delete(Rec, []);
|
||||
delete(Table) when is_atom(Table) ->
|
||||
try
|
||||
{ok, Keys} = ?MODULE:get_keys(Table),
|
||||
lists:foreach(
|
||||
fun(K) ->
|
||||
ok = delete(Table, K)
|
||||
end, Keys)
|
||||
catch _:{badmatch, Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
-spec delete(tuple() | atom(), index_info() | any()) -> ok | {error, any()}.
|
||||
%% @doc Delete an object
|
||||
delete(Rec, Opts) when is_tuple(Rec) ->
|
||||
Table = element(1, Rec),
|
||||
Key = proplists:get_value(i, Opts, element(2, Rec)),
|
||||
delete(Table, Key);
|
||||
delete(Table, Key) when is_atom(Table) ->
|
||||
case delete_raw(Table, encode_key(Key)) of
|
||||
ok ->
|
||||
ok;
|
||||
Err ->
|
||||
log_error(Err, delete, [{table, Table}, {key, Key}]),
|
||||
Err
|
||||
end.
|
||||
|
||||
delete_raw(Table, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
catch riakc_pb_socket:delete(get_random_pid(), Bucket, Key).
|
||||
|
||||
-spec delete_by_index(atom(), binary(), any()) -> ok | {error, any()}.
|
||||
%% @doc Deletes objects by index
|
||||
delete_by_index(Table, Index, Key) ->
|
||||
try
|
||||
{ok, Keys} = get_keys_by_index(Table, Index, Key),
|
||||
lists:foreach(
|
||||
fun(K) ->
|
||||
ok = delete(Table, K)
|
||||
end, Keys)
|
||||
catch _:{badmatch, Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% map/reduce functions
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
map_key(Obj, _, _) ->
|
||||
[case riak_object:key(Obj) of
|
||||
<<"b_", B/binary>> ->
|
||||
B;
|
||||
<<"i_", B/binary>> ->
|
||||
(binary_to_integer(B));
|
||||
B ->
|
||||
erlang:binary_to_term(B)
|
||||
end].
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server API
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
init([Server, Port, Options]) ->
|
||||
case riakc_pb_socket:start(Server, Port, Options) of
|
||||
{ok, Pid} ->
|
||||
erlang:monitor(process, Pid),
|
||||
{ok, #state{pid = Pid}};
|
||||
Err ->
|
||||
{stop, Err}
|
||||
end.
|
||||
|
||||
%% @private
|
||||
handle_call(get_pid, _From, #state{pid = Pid} = State) ->
|
||||
{reply, {ok, Pid}, State};
|
||||
handle_call(Request, From, State) ->
|
||||
?WARNING_MSG("Unexpected call from ~p: ~p", [From, Request]),
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
handle_cast(Msg, State) ->
|
||||
?WARNING_MSG("Unexpected cast: ~p", [Msg]),
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
handle_info({'DOWN', _MonitorRef, _Type, _Object, _Info}, State) ->
|
||||
{stop, normal, State};
|
||||
handle_info(Info, State) ->
|
||||
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
encode_index_key(Idx, Key) when is_integer(Key) ->
|
||||
{<<Idx/binary, "_int">>, Key};
|
||||
encode_index_key(Idx, Key) ->
|
||||
{<<Idx/binary, "_bin">>, encode_key(Key)}.
|
||||
|
||||
encode_key(Bin) when is_binary(Bin) ->
|
||||
<<"b_", Bin/binary>>;
|
||||
encode_key(Int) when is_integer(Int) ->
|
||||
<<"i_", ((integer_to_binary(Int)))/binary>>;
|
||||
encode_key(Term) ->
|
||||
erlang:term_to_binary(Term).
|
||||
|
||||
log_error({error, notfound}, _, _) ->
|
||||
ok;
|
||||
log_error({error, Why} = Err, Function, Opts) ->
|
||||
Txt = lists:map(
|
||||
fun({table, Table}) ->
|
||||
io_lib:fwrite("** Table: ~p~n", [Table]);
|
||||
({key, Key}) ->
|
||||
io_lib:fwrite("** Key: ~p~n", [Key]);
|
||||
({index, Index}) ->
|
||||
io_lib:fwrite("** Index = ~p~n", [Index]);
|
||||
({start_key, Key}) ->
|
||||
io_lib:fwrite("** Start Key: ~p~n", [Key]);
|
||||
({end_key, Key}) ->
|
||||
io_lib:fwrite("** End Key: ~p~n", [Key]);
|
||||
({record, Rec}) ->
|
||||
io_lib:fwrite("** Record = ~p~n", [Rec]);
|
||||
({index_info, IdxInfo}) ->
|
||||
io_lib:fwrite("** Index info = ~p~n", [IdxInfo]);
|
||||
(_) ->
|
||||
""
|
||||
end, Opts),
|
||||
ErrTxt = if is_binary(Why) ->
|
||||
io_lib:fwrite("** Error: ~s", [Why]);
|
||||
true ->
|
||||
io_lib:fwrite("** Error: ~p", [Err])
|
||||
end,
|
||||
?ERROR_MSG("Database error:~n** Function: ~p~n~s~s",
|
||||
[Function, Txt, ErrTxt]);
|
||||
log_error(_, _, _) ->
|
||||
ok.
|
||||
|
||||
make_invalid_object(Val) ->
|
||||
(str:format("Invalid object: ~p", [Val])).
|
||||
|
||||
get_random_pid() ->
|
||||
case ejabberd_riak_sup:start() of
|
||||
ok ->
|
||||
PoolPid = ejabberd_riak_sup:get_random_pid(),
|
||||
get_riak_pid(PoolPid);
|
||||
{error, _} = Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
get_riak_pid(PoolPid) ->
|
||||
case catch gen_server:call(PoolPid, get_pid) of
|
||||
{ok, Pid} ->
|
||||
Pid;
|
||||
{'EXIT', {timeout, _}} ->
|
||||
throw({error, timeout});
|
||||
{'EXIT', Err} ->
|
||||
throw({error, Err})
|
||||
end.
|
||||
|
||||
encode_record(Rec, {Fields, DefRec}) ->
|
||||
term_to_binary(encode_record(Rec, Fields, DefRec, 2)).
|
||||
|
||||
encode_record(Rec, [FieldName|Fields], DefRec, Pos) ->
|
||||
Value = element(Pos, Rec),
|
||||
DefValue = element(Pos, DefRec),
|
||||
if Value == DefValue ->
|
||||
encode_record(Rec, Fields, DefRec, Pos+1);
|
||||
true ->
|
||||
[{FieldName, Value}|encode_record(Rec, Fields, DefRec, Pos+1)]
|
||||
end;
|
||||
encode_record(_, [], _, _) ->
|
||||
[].
|
||||
|
||||
decode_record(Bin, {Fields, DefRec}) ->
|
||||
decode_record(binary_to_term(Bin), Fields, DefRec, 2).
|
||||
|
||||
decode_record(KeyVals, [FieldName|Fields], Rec, Pos) ->
|
||||
case lists:keyfind(FieldName, 1, KeyVals) of
|
||||
{_, Value} ->
|
||||
NewRec = setelement(Pos, Rec, Value),
|
||||
decode_record(KeyVals, Fields, NewRec, Pos+1);
|
||||
false ->
|
||||
decode_record(KeyVals, Fields, Rec, Pos+1)
|
||||
end;
|
||||
decode_record(_, [], Rec, _) ->
|
||||
Rec.
|
@ -1,142 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_riak_sup.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : Riak connections supervisor
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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(ejabberd_riak_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/0, start_link/0, init/1, get_pids/0,
|
||||
get_random_pid/0, config_reloaded/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
% time to wait for the supervisor to start its child before returning
|
||||
% a timeout error to the request
|
||||
-define(CONNECT_TIMEOUT, 500). % milliseconds
|
||||
|
||||
start() ->
|
||||
case is_started() of
|
||||
true -> ok;
|
||||
false ->
|
||||
ejabberd:start_app(riakc),
|
||||
Spec = {?MODULE, {?MODULE, start_link, []},
|
||||
permanent, infinity, supervisor, [?MODULE]},
|
||||
case supervisor:start_child(ejabberd_db_sup, Spec) of
|
||||
{ok, _} -> ok;
|
||||
{error, {already_started, _}} -> ok;
|
||||
{error, Why} = Err ->
|
||||
?ERROR_MSG("Failed to start ~s: ~p",
|
||||
[?MODULE, Why]),
|
||||
Err
|
||||
end
|
||||
end.
|
||||
|
||||
config_reloaded() ->
|
||||
case is_started() of
|
||||
true ->
|
||||
lists:foreach(
|
||||
fun(Spec) ->
|
||||
supervisor:start_child(?MODULE, Spec)
|
||||
end, get_specs()),
|
||||
PoolSize = get_pool_size(),
|
||||
lists:foreach(
|
||||
fun({Id, _, _, _}) when Id > PoolSize ->
|
||||
case supervisor:terminate_child(?MODULE, Id) of
|
||||
ok -> supervisor:delete_child(?MODULE, Id);
|
||||
_ -> ok
|
||||
end;
|
||||
(_) ->
|
||||
ok
|
||||
end, supervisor:which_children(?MODULE));
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
init([]) ->
|
||||
ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 20),
|
||||
{ok, {{one_for_one, 500, 1}, get_specs()}}.
|
||||
|
||||
is_started() ->
|
||||
whereis(?MODULE) /= undefined.
|
||||
|
||||
-spec get_specs() -> [supervisor:child_spec()].
|
||||
get_specs() ->
|
||||
PoolSize = get_pool_size(),
|
||||
StartInterval = get_start_interval(),
|
||||
Server = get_riak_server(),
|
||||
Port = get_riak_port(),
|
||||
CACertFile = get_riak_cacertfile(),
|
||||
Username = get_riak_username(),
|
||||
Password = get_riak_password(),
|
||||
Options = lists:filter(
|
||||
fun(X) -> X /= nil end,
|
||||
[auto_reconnect,
|
||||
{keepalive, true},
|
||||
if CACertFile /= nil -> {cacertfile ,CACertFile};
|
||||
true -> nil
|
||||
end,
|
||||
if (Username /= nil) and (Password /= nil) ->
|
||||
{credentials, Username, Password};
|
||||
true -> nil
|
||||
end]),
|
||||
lists:map(
|
||||
fun(I) ->
|
||||
{ejabberd_riak:get_proc(I),
|
||||
{ejabberd_riak, start_link,
|
||||
[I, Server, Port, StartInterval, Options]},
|
||||
transient, 2000, worker, [?MODULE]}
|
||||
end, lists:seq(1, PoolSize)).
|
||||
|
||||
get_start_interval() ->
|
||||
ejabberd_option:riak_start_interval().
|
||||
|
||||
get_pool_size() ->
|
||||
ejabberd_option:riak_pool_size().
|
||||
|
||||
get_riak_server() ->
|
||||
ejabberd_option:riak_server().
|
||||
|
||||
get_riak_cacertfile() ->
|
||||
ejabberd_option:riak_cacertfile().
|
||||
|
||||
get_riak_username() ->
|
||||
ejabberd_option:riak_username().
|
||||
|
||||
get_riak_password() ->
|
||||
ejabberd_option:riak_password().
|
||||
|
||||
get_riak_port() ->
|
||||
ejabberd_option:riak_port().
|
||||
|
||||
get_pids() ->
|
||||
[ejabberd_riak:get_proc(I) || I <- lists:seq(1, get_pool_size())].
|
||||
|
||||
get_random_pid() ->
|
||||
I = p1_rand:round_robin(get_pool_size()) + 1,
|
||||
ejabberd_riak:get_proc(I).
|
@ -1,83 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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(ejabberd_router_riak).
|
||||
-behaviour(ejabberd_router).
|
||||
|
||||
%% API
|
||||
-export([init/0, register_route/5, unregister_route/3, find_routes/1,
|
||||
get_all_routes/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_router.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init() ->
|
||||
clean_table().
|
||||
|
||||
register_route(Domain, ServerHost, LocalHint, _, Pid) ->
|
||||
ejabberd_riak:put(#route{domain = Domain,
|
||||
server_host = ServerHost,
|
||||
local_hint = LocalHint,
|
||||
pid = Pid},
|
||||
route_schema(),
|
||||
[{i, {Domain, Pid}}, {'2i', [{<<"route">>, Domain}]}]).
|
||||
|
||||
unregister_route(Domain, _, Pid) ->
|
||||
ejabberd_riak:delete(route, {Domain, Pid}).
|
||||
|
||||
find_routes(Domain) ->
|
||||
ejabberd_riak:get_by_index(route, route_schema(), <<"route">>, Domain).
|
||||
|
||||
get_all_routes() ->
|
||||
case ejabberd_riak:get(route, route_schema()) of
|
||||
{ok, Routes} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(#route{domain = D, server_host = S}) when D /= S ->
|
||||
[D];
|
||||
(_) ->
|
||||
[]
|
||||
end, Routes)};
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
route_schema() ->
|
||||
{record_info(fields, route), #route{domain = <<>>, server_host = <<>>}}.
|
||||
|
||||
clean_table() ->
|
||||
?DEBUG("Cleaning Riak 'route' table...", []),
|
||||
case ejabberd_riak:get(route, route_schema()) of
|
||||
{ok, Routes} ->
|
||||
lists:foreach(
|
||||
fun(#route{domain = Domain, pid = Pid}) ->
|
||||
ejabberd_riak:delete(route, {Domain, Pid})
|
||||
end, Routes);
|
||||
{error, Err} ->
|
||||
?ERROR_MSG("Failed to clean Riak 'route' table: ~p", [Err]),
|
||||
Err
|
||||
end.
|
@ -1,72 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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(ejabberd_sm_riak).
|
||||
-behaviour(ejabberd_sm).
|
||||
|
||||
%% API
|
||||
-export([init/0, set_session/1, delete_session/1, get_sessions/0,
|
||||
get_sessions/1, get_sessions/2]).
|
||||
|
||||
-include("ejabberd_sm.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init() ->
|
||||
clean_table().
|
||||
|
||||
set_session(Session) ->
|
||||
ejabberd_riak:put(Session, session_schema(),
|
||||
[{'2i', [{<<"us">>, Session#session.us}]}]).
|
||||
|
||||
delete_session(Session) ->
|
||||
ejabberd_riak:delete(session, Session#session.sid).
|
||||
|
||||
get_sessions() ->
|
||||
case ejabberd_riak:get(session, session_schema()) of
|
||||
{ok, Ss} -> Ss;
|
||||
{error, _} -> []
|
||||
end.
|
||||
|
||||
get_sessions(LServer) ->
|
||||
[S || S <- get_sessions(), element(2, S#session.us) == LServer].
|
||||
|
||||
get_sessions(U, S) ->
|
||||
ejabberd_riak:get_by_index(session, session_schema(), <<"us">>, {U, S}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
session_schema() ->
|
||||
{record_info(fields, session), #session{}}.
|
||||
|
||||
clean_table() ->
|
||||
%% TODO: not very efficient, rewrite using map-reduce or something
|
||||
?DEBUG("Cleaning Riak 'sm' table...", []),
|
||||
lists:foreach(
|
||||
fun(#session{sid = {_, Pid} = SID}) when node(Pid) == node() ->
|
||||
ejabberd_riak:delete(session, SID);
|
||||
(_) ->
|
||||
ok
|
||||
end, get_sessions()).
|
@ -1,107 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_announce_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_announce_riak).
|
||||
|
||||
-behaviour(mod_announce).
|
||||
|
||||
%% API
|
||||
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_announce.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
set_motd_users(_LServer, USRs) ->
|
||||
try
|
||||
lists:foreach(
|
||||
fun({U, S, _R}) ->
|
||||
ok = ejabberd_riak:put(#motd_users{us = {U, S}},
|
||||
motd_users_schema(),
|
||||
[{'2i', [{<<"server">>, S}]}])
|
||||
end, USRs)
|
||||
catch _:{badmatch, {error, _} = Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
set_motd(LServer, Packet) ->
|
||||
ejabberd_riak:put(#motd{server = LServer,
|
||||
packet = Packet},
|
||||
motd_schema()).
|
||||
|
||||
delete_motd(LServer) ->
|
||||
try
|
||||
ok = ejabberd_riak:delete(motd, LServer),
|
||||
ok = ejabberd_riak:delete_by_index(motd_users,
|
||||
<<"server">>,
|
||||
LServer)
|
||||
catch _:{badmatch, {error, _} = Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
get_motd(LServer) ->
|
||||
case ejabberd_riak:get(motd, motd_schema(), LServer) of
|
||||
{ok, #motd{packet = Packet}} ->
|
||||
{ok, Packet};
|
||||
{error, notfound} ->
|
||||
error;
|
||||
{error, _} = Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
is_motd_user(LUser, LServer) ->
|
||||
case ejabberd_riak:get(motd_users, motd_users_schema(),
|
||||
{LUser, LServer}) of
|
||||
{ok, #motd_users{}} -> {ok, true};
|
||||
{error, notfound} -> {ok, false};
|
||||
{error, _} = Err -> Err
|
||||
end.
|
||||
|
||||
set_motd_user(LUser, LServer) ->
|
||||
ejabberd_riak:put(
|
||||
#motd_users{us = {LUser, LServer}}, motd_users_schema(),
|
||||
[{'2i', [{<<"server">>, LServer}]}]).
|
||||
|
||||
import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) ->
|
||||
El = fxml_stream:parse_element(XML),
|
||||
ejabberd_riak:put(#motd{server = LServer, packet = El}, motd_schema());
|
||||
import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) ->
|
||||
Users = #motd_users{us = {LUser, LServer}},
|
||||
ejabberd_riak:put(Users, motd_users_schema(),
|
||||
[{'2i', [{<<"server">>, LServer}]}]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
motd_schema() ->
|
||||
{record_info(fields, motd), #motd{}}.
|
||||
|
||||
motd_users_schema() ->
|
||||
{record_info(fields, motd_users), #motd_users{}}.
|
@ -1,71 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_bosh_riak).
|
||||
-behaviour(mod_bosh).
|
||||
|
||||
%% API
|
||||
-export([init/0, open_session/2, close_session/1, find_session/1]).
|
||||
|
||||
-record(bosh, {sid :: binary(),
|
||||
pid :: pid()}).
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init() ->
|
||||
clean_table().
|
||||
|
||||
open_session(SID, Pid) ->
|
||||
ejabberd_riak:put(#bosh{sid = SID, pid = Pid}, bosh_schema()).
|
||||
|
||||
close_session(SID) ->
|
||||
ejabberd_riak:delete(bosh, SID).
|
||||
|
||||
find_session(SID) ->
|
||||
case ejabberd_riak:get(bosh, bosh_schema(), SID) of
|
||||
{ok, #bosh{pid = Pid}} -> {ok, Pid};
|
||||
{error, _} = Err -> Err
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
bosh_schema() ->
|
||||
{record_info(fields, bosh), #bosh{sid = <<>>, pid = self()}}.
|
||||
|
||||
clean_table() ->
|
||||
?DEBUG("Cleaning Riak 'bosh' table...", []),
|
||||
case ejabberd_riak:get(bosh, bosh_schema()) of
|
||||
{ok, Rs} ->
|
||||
lists:foreach(
|
||||
fun(#bosh{sid = SID, pid = Pid}) when node(Pid) == node() ->
|
||||
ejabberd_riak:delete(bosh, SID);
|
||||
(_) ->
|
||||
ok
|
||||
end, Rs);
|
||||
{error, Reason} = Err ->
|
||||
?ERROR_MSG("Failed to clean Riak 'bosh' table: ~p", [Reason]),
|
||||
Err
|
||||
end.
|
@ -1,64 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_caps_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_caps_riak).
|
||||
|
||||
-behaviour(mod_caps).
|
||||
|
||||
%% API
|
||||
-export([init/2, caps_read/2, caps_write/3, import/3]).
|
||||
|
||||
-include("mod_caps.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
caps_read(_LServer, Node) ->
|
||||
case ejabberd_riak:get(caps_features, caps_features_schema(), Node) of
|
||||
{ok, #caps_features{features = Features}} -> {ok, Features};
|
||||
_ -> error
|
||||
end.
|
||||
|
||||
caps_write(_LServer, Node, Features) ->
|
||||
ejabberd_riak:put(#caps_features{node_pair = Node,
|
||||
features = Features},
|
||||
caps_features_schema()).
|
||||
|
||||
import(_LServer, NodePair, [I]) when is_integer(I) ->
|
||||
ejabberd_riak:put(
|
||||
#caps_features{node_pair = NodePair, features = I},
|
||||
caps_features_schema());
|
||||
import(_LServer, NodePair, Features) ->
|
||||
ejabberd_riak:put(
|
||||
#caps_features{node_pair = NodePair, features = Features},
|
||||
caps_features_schema()).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
caps_features_schema() ->
|
||||
{record_info(fields, caps_features), #caps_features{}}.
|
@ -1,71 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_last_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_last_riak).
|
||||
|
||||
-behaviour(mod_last).
|
||||
|
||||
%% API
|
||||
-export([init/2, import/2, get_last/2, store_last_info/4, remove_user/2]).
|
||||
|
||||
-include("mod_last.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
get_last(LUser, LServer) ->
|
||||
case ejabberd_riak:get(last_activity, last_activity_schema(),
|
||||
{LUser, LServer}) of
|
||||
{ok, #last_activity{timestamp = TimeStamp,
|
||||
status = Status}} ->
|
||||
{ok, {TimeStamp, Status}};
|
||||
{error, notfound} ->
|
||||
error;
|
||||
_Err ->
|
||||
%% TODO: log error
|
||||
{error, db_failure}
|
||||
end.
|
||||
|
||||
store_last_info(LUser, LServer, TimeStamp, Status) ->
|
||||
US = {LUser, LServer},
|
||||
ejabberd_riak:put(#last_activity{us = US,
|
||||
timestamp = TimeStamp,
|
||||
status = Status},
|
||||
last_activity_schema()).
|
||||
|
||||
remove_user(LUser, LServer) ->
|
||||
{atomic, ejabberd_riak:delete(last_activity, {LUser, LServer})}.
|
||||
|
||||
import(_LServer, #last_activity{} = LA) ->
|
||||
ejabberd_riak:put(LA, last_activity_schema()).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
last_activity_schema() ->
|
||||
{record_info(fields, last_activity), #last_activity{}}.
|
@ -1,193 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_muc_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_muc_riak).
|
||||
|
||||
-behaviour(mod_muc).
|
||||
-behaviour(mod_muc_room).
|
||||
|
||||
%% API
|
||||
-export([init/2, import/3, store_room/5, restore_room/3, forget_room/3,
|
||||
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]).
|
||||
-export([register_online_room/4, unregister_online_room/4, find_online_room/3,
|
||||
get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
|
||||
register_online_user/4, unregister_online_user/4,
|
||||
count_online_rooms_by_user/3, get_online_rooms_by_user/3]).
|
||||
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||
get_affiliations/3, search_affiliation/4]).
|
||||
|
||||
-include("jid.hrl").
|
||||
-include("mod_muc.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
store_room(_LServer, Host, Name, Opts, _) ->
|
||||
{atomic, ejabberd_riak:put(#muc_room{name_host = {Name, Host},
|
||||
opts = Opts},
|
||||
muc_room_schema())}.
|
||||
|
||||
restore_room(_LServer, Host, Name) ->
|
||||
case ejabberd_riak:get(muc_room, muc_room_schema(), {Name, Host}) of
|
||||
{ok, #muc_room{opts = Opts}} -> Opts;
|
||||
_ -> error
|
||||
end.
|
||||
|
||||
forget_room(_LServer, Host, Name) ->
|
||||
{atomic, ejabberd_riak:delete(muc_room, {Name, Host})}.
|
||||
|
||||
can_use_nick(_LServer, Host, JID, Nick) ->
|
||||
{LUser, LServer, _} = jid:tolower(JID),
|
||||
LUS = {LUser, LServer},
|
||||
case ejabberd_riak:get_by_index(muc_registered,
|
||||
muc_registered_schema(),
|
||||
<<"nick_host">>, {Nick, Host}) of
|
||||
{ok, []} ->
|
||||
true;
|
||||
{ok, [#muc_registered{us_host = {U, _Host}}]} ->
|
||||
U == LUS;
|
||||
{error, _} ->
|
||||
true
|
||||
end.
|
||||
|
||||
get_rooms(_LServer, Host) ->
|
||||
case ejabberd_riak:get(muc_room, muc_room_schema()) of
|
||||
{ok, Rs} ->
|
||||
lists:filter(
|
||||
fun(#muc_room{name_host = {_, H}}) ->
|
||||
Host == H
|
||||
end, Rs);
|
||||
_Err ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_nick(LServer, Host, From) ->
|
||||
{LUser, LServer, _} = jid:tolower(From),
|
||||
US = {LUser, LServer},
|
||||
case ejabberd_riak:get(muc_registered,
|
||||
muc_registered_schema(),
|
||||
{US, Host}) of
|
||||
{ok, #muc_registered{nick = Nick}} -> Nick;
|
||||
{error, _} -> error
|
||||
end.
|
||||
|
||||
set_nick(LServer, Host, From, Nick) ->
|
||||
{LUser, LServer, _} = jid:tolower(From),
|
||||
LUS = {LUser, LServer},
|
||||
{atomic,
|
||||
case Nick of
|
||||
<<"">> ->
|
||||
ejabberd_riak:delete(muc_registered, {LUS, Host});
|
||||
_ ->
|
||||
Allow = case ejabberd_riak:get_by_index(
|
||||
muc_registered,
|
||||
muc_registered_schema(),
|
||||
<<"nick_host">>, {Nick, Host}) of
|
||||
{ok, []} ->
|
||||
true;
|
||||
{ok, [#muc_registered{us_host = {U, _Host}}]} ->
|
||||
U == LUS;
|
||||
{error, _} ->
|
||||
false
|
||||
end,
|
||||
if Allow ->
|
||||
ejabberd_riak:put(#muc_registered{us_host = {LUS, Host},
|
||||
nick = Nick},
|
||||
muc_registered_schema(),
|
||||
[{'2i', [{<<"nick_host">>,
|
||||
{Nick, Host}}]}]);
|
||||
true ->
|
||||
false
|
||||
end
|
||||
end}.
|
||||
|
||||
set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
|
||||
{error, not_implemented}.
|
||||
|
||||
set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
|
||||
{error, not_implemented}.
|
||||
|
||||
get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
|
||||
{error, not_implemented}.
|
||||
|
||||
get_affiliations(_ServerHost, _Room, _Host) ->
|
||||
{error, not_implemented}.
|
||||
|
||||
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
|
||||
{error, not_implemented}.
|
||||
|
||||
register_online_room(_, _, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
unregister_online_room(_, _, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
find_online_room(_, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
count_online_rooms(_, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
get_online_rooms(_, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
rsm_supported() ->
|
||||
false.
|
||||
|
||||
register_online_user(_, _, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
unregister_online_user(_, _, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
count_online_rooms_by_user(_, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
get_online_rooms_by_user(_, _, _) ->
|
||||
erlang:error(not_implemented).
|
||||
|
||||
import(_LServer, <<"muc_room">>,
|
||||
[Name, RoomHost, SOpts, _TimeStamp]) ->
|
||||
Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
|
||||
ejabberd_riak:put(
|
||||
#muc_room{name_host = {Name, RoomHost}, opts = Opts},
|
||||
muc_room_schema());
|
||||
import(_LServer, <<"muc_registered">>,
|
||||
[J, RoomHost, Nick, _TimeStamp]) ->
|
||||
#jid{user = U, server = S} = jid:decode(J),
|
||||
R = #muc_registered{us_host = {{U, S}, RoomHost}, nick = Nick},
|
||||
ejabberd_riak:put(R, muc_registered_schema(),
|
||||
[{'2i', [{<<"nick_host">>, {Nick, RoomHost}}]}]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
muc_room_schema() ->
|
||||
{record_info(fields, muc_room), #muc_room{}}.
|
||||
|
||||
muc_registered_schema() ->
|
||||
{record_info(fields, muc_registered), #muc_registered{}}.
|
@ -1,150 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_offline_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_offline_riak).
|
||||
|
||||
-behaviour(mod_offline).
|
||||
|
||||
-export([init/2, store_message/1, pop_messages/2, remove_expired_messages/1,
|
||||
remove_old_messages/2, remove_user/2, read_message_headers/2,
|
||||
read_message/3, remove_message/3, read_all_messages/2,
|
||||
remove_all_messages/2, count_messages/2, import/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_offline.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
store_message(#offline_msg{us = US, packet = Pkt, timestamp = TS} = M) ->
|
||||
El = xmpp:encode(Pkt),
|
||||
ejabberd_riak:put(M#offline_msg{packet = El},
|
||||
offline_msg_schema(),
|
||||
[{i, TS}, {'2i', [{<<"us">>, US}]}]).
|
||||
|
||||
pop_messages(LUser, LServer) ->
|
||||
case ejabberd_riak:get_by_index(offline_msg, offline_msg_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, Rs} ->
|
||||
try
|
||||
lists:foreach(
|
||||
fun(#offline_msg{timestamp = T}) ->
|
||||
ok = ejabberd_riak:delete(offline_msg, T)
|
||||
end, Rs),
|
||||
{ok, lists:keysort(#offline_msg.timestamp, Rs)}
|
||||
catch _:{badmatch, Err} ->
|
||||
Err
|
||||
end;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
remove_expired_messages(_LServer) ->
|
||||
%% TODO
|
||||
{atomic, ok}.
|
||||
|
||||
remove_old_messages(_Days, _LServer) ->
|
||||
%% TODO
|
||||
{atomic, ok}.
|
||||
|
||||
remove_user(LUser, LServer) ->
|
||||
{atomic, ejabberd_riak:delete_by_index(offline_msg,
|
||||
<<"us">>, {LUser, LServer})}.
|
||||
|
||||
read_message_headers(LUser, LServer) ->
|
||||
case ejabberd_riak:get_by_index(
|
||||
offline_msg, offline_msg_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, Rs} ->
|
||||
Hdrs = lists:map(
|
||||
fun(#offline_msg{from = From, to = To, packet = Pkt,
|
||||
timestamp = TS}) ->
|
||||
Seq = now_to_integer(TS),
|
||||
{Seq, From, To, TS, Pkt}
|
||||
end, Rs),
|
||||
lists:keysort(1, Hdrs);
|
||||
_Err ->
|
||||
error
|
||||
end.
|
||||
|
||||
read_message(_LUser, _LServer, I) ->
|
||||
TS = integer_to_now(I),
|
||||
case ejabberd_riak:get(offline_msg, offline_msg_schema(), TS) of
|
||||
{ok, Msg} ->
|
||||
{ok, Msg};
|
||||
_ ->
|
||||
error
|
||||
end.
|
||||
|
||||
remove_message(_LUser, _LServer, I) ->
|
||||
TS = integer_to_now(I),
|
||||
ejabberd_riak:delete(offline_msg, TS),
|
||||
ok.
|
||||
|
||||
read_all_messages(LUser, LServer) ->
|
||||
case ejabberd_riak:get_by_index(
|
||||
offline_msg, offline_msg_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, Rs} ->
|
||||
lists:keysort(#offline_msg.timestamp, Rs);
|
||||
_Err ->
|
||||
[]
|
||||
end.
|
||||
|
||||
remove_all_messages(LUser, LServer) ->
|
||||
Res = ejabberd_riak:delete_by_index(offline_msg,
|
||||
<<"us">>, {LUser, LServer}),
|
||||
{atomic, Res}.
|
||||
|
||||
count_messages(LUser, LServer) ->
|
||||
case ejabberd_riak:count_by_index(
|
||||
offline_msg, <<"us">>, {LUser, LServer}) of
|
||||
{ok, Res} ->
|
||||
{cache, Res};
|
||||
_ ->
|
||||
{nocache, 0}
|
||||
end.
|
||||
|
||||
import(#offline_msg{us = US, timestamp = TS} = M) ->
|
||||
ejabberd_riak:put(M, offline_msg_schema(),
|
||||
[{i, TS}, {'2i', [{<<"us">>, US}]}]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
offline_msg_schema() ->
|
||||
{record_info(fields, offline_msg), #offline_msg{}}.
|
||||
|
||||
now_to_integer({MS, S, US}) ->
|
||||
(MS * 1000000 + S) * 1000000 + US.
|
||||
|
||||
integer_to_now(Int) ->
|
||||
Secs = Int div 1000000,
|
||||
USec = Int rem 1000000,
|
||||
MSec = Secs div 1000000,
|
||||
Sec = Secs rem 1000000,
|
||||
{MSec, Sec, USec}.
|
@ -1,140 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_privacy_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_privacy_riak).
|
||||
|
||||
-behaviour(mod_privacy).
|
||||
|
||||
%% API
|
||||
-export([init/2, set_default/3, unset_default/2, set_lists/1,
|
||||
set_list/4, get_lists/2, get_list/3, remove_lists/2,
|
||||
remove_list/3, import/1]).
|
||||
|
||||
-export([privacy_schema/0]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
unset_default(LUser, LServer) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, R} ->
|
||||
ejabberd_riak:put(R#privacy{default = none}, privacy_schema());
|
||||
{error, notfound} ->
|
||||
ok;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
set_default(LUser, LServer, Name) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{lists = Lists} = P} ->
|
||||
case lists:keymember(Name, 1, Lists) of
|
||||
true ->
|
||||
ejabberd_riak:put(P#privacy{default = Name,
|
||||
lists = Lists},
|
||||
privacy_schema());
|
||||
false ->
|
||||
{error, notfound}
|
||||
end;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
remove_list(LUser, LServer, Name) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{default = Default, lists = Lists} = P} ->
|
||||
if Name == Default ->
|
||||
{error, conflict};
|
||||
true ->
|
||||
NewLists = lists:keydelete(Name, 1, Lists),
|
||||
ejabberd_riak:put(P#privacy{lists = NewLists},
|
||||
privacy_schema())
|
||||
end;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
set_lists(Privacy) ->
|
||||
ejabberd_riak:put(Privacy, privacy_schema()).
|
||||
|
||||
set_list(LUser, LServer, Name, List) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{lists = Lists} = P} ->
|
||||
NewLists1 = lists:keydelete(Name, 1, Lists),
|
||||
NewLists = [{Name, List} | NewLists1],
|
||||
ejabberd_riak:put(P#privacy{lists = NewLists}, privacy_schema());
|
||||
{error, notfound} ->
|
||||
NewLists = [{Name, List}],
|
||||
ejabberd_riak:put(#privacy{us = {LUser, LServer},
|
||||
lists = NewLists},
|
||||
privacy_schema());
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
get_list(LUser, LServer, Name) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{default = Default, lists = Lists}} when Name == default ->
|
||||
case lists:keyfind(Default, 1, Lists) of
|
||||
{_, List} -> {ok, {Default, List}};
|
||||
false -> error
|
||||
end;
|
||||
{ok, #privacy{lists = Lists}} ->
|
||||
case lists:keyfind(Name, 1, Lists) of
|
||||
{_, List} -> {ok, {Name, List}};
|
||||
false -> error
|
||||
end;
|
||||
{error, notfound} ->
|
||||
error;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
get_lists(LUser, LServer) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{} = P} ->
|
||||
{ok, P};
|
||||
{error, notfound} ->
|
||||
error;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
remove_lists(LUser, LServer) ->
|
||||
ejabberd_riak:delete(privacy, {LUser, LServer}).
|
||||
|
||||
import(#privacy{} = P) ->
|
||||
ejabberd_riak:put(P, privacy_schema()).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
privacy_schema() ->
|
||||
{record_info(fields, privacy), #privacy{}}.
|
@ -1,91 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_private_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_private_riak).
|
||||
|
||||
-behaviour(mod_private).
|
||||
|
||||
%% API
|
||||
-export([init/2, set_data/3, get_data/3, get_all_data/2, del_data/2,
|
||||
import/3]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_private.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
set_data(LUser, LServer, Data) ->
|
||||
lists:foldl(
|
||||
fun(_, {error, _} = Err) ->
|
||||
Err;
|
||||
({XMLNS, El}, _) ->
|
||||
ejabberd_riak:put(#private_storage{usns = {LUser, LServer, XMLNS},
|
||||
xml = El},
|
||||
private_storage_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}])
|
||||
end, ok, Data).
|
||||
|
||||
get_data(LUser, LServer, XMLNS) ->
|
||||
case ejabberd_riak:get(private_storage, private_storage_schema(),
|
||||
{LUser, LServer, XMLNS}) of
|
||||
{ok, #private_storage{xml = El}} ->
|
||||
{ok, El};
|
||||
{error, notfound} ->
|
||||
error;
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
get_all_data(LUser, LServer) ->
|
||||
case ejabberd_riak:get_by_index(
|
||||
private_storage, private_storage_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, []} ->
|
||||
error;
|
||||
{ok, Res} ->
|
||||
{ok, [El || #private_storage{xml = El} <- Res]};
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
del_data(LUser, LServer) ->
|
||||
ejabberd_riak:delete_by_index(private_storage,
|
||||
<<"us">>, {LUser, LServer}).
|
||||
|
||||
import(LServer, <<"private_storage">>,
|
||||
[LUser, XMLNS, XML, _TimeStamp]) ->
|
||||
El = #xmlel{} = fxml_stream:parse_element(XML),
|
||||
PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El},
|
||||
ejabberd_riak:put(PS, private_storage_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
private_storage_schema() ->
|
||||
{record_info(fields, private_storage), #private_storage{}}.
|
@ -1,111 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_proxy65_riak).
|
||||
-behaviour(mod_proxy65).
|
||||
|
||||
%% API
|
||||
-export([init/0, register_stream/2, unregister_stream/1, activate_stream/4]).
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-record(proxy65, {sid :: binary(),
|
||||
pid_t :: pid(),
|
||||
pid_i :: pid() | undefined,
|
||||
jid_i :: binary() | undefined}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init() ->
|
||||
clean_table().
|
||||
|
||||
register_stream(SID, Pid) ->
|
||||
case ejabberd_riak:get(proxy65, proxy65_schema(), SID) of
|
||||
{error, notfound} ->
|
||||
ejabberd_riak:put(#proxy65{sid = SID, pid_t = Pid},
|
||||
proxy65_schema());
|
||||
{ok, #proxy65{pid_i = undefined} = R} ->
|
||||
ejabberd_riak:put(R#proxy65{pid_i = Pid},
|
||||
proxy65_schema());
|
||||
{ok, _} ->
|
||||
{error, conflict};
|
||||
{error, _} ->
|
||||
{error, db_failure}
|
||||
end.
|
||||
|
||||
unregister_stream(SID) ->
|
||||
case ejabberd_riak:delete(proxy65, SID) of
|
||||
ok -> ok;
|
||||
{error, _} -> {error, db_failure}
|
||||
end.
|
||||
|
||||
activate_stream(SID, IJID, MaxConnections, _Node) ->
|
||||
try
|
||||
case ejabberd_riak:get(proxy65, proxy65_schema(), SID) of
|
||||
{ok, #proxy65{pid_t = TPid, pid_i = IPid,
|
||||
jid_i = undefined} = R} when is_pid(IPid) ->
|
||||
{ok, Num} = ejabberd_riak:count_by_index(
|
||||
proxy65, <<"jid_i">>, IJID),
|
||||
if Num >= MaxConnections ->
|
||||
{error, {limit, IPid, TPid}};
|
||||
true ->
|
||||
ok = ejabberd_riak:put(
|
||||
R#proxy65{jid_i = IJID},
|
||||
proxy65_schema(),
|
||||
[{'2i', [{<<"jid_i">>, IJID}]}]),
|
||||
{ok, IPid, TPid}
|
||||
end;
|
||||
{ok, #proxy65{jid_i = JID}} ->
|
||||
if is_binary(JID) -> {error, conflict};
|
||||
true -> {error, notfound}
|
||||
end;
|
||||
{error, _} = Err ->
|
||||
Err
|
||||
end
|
||||
catch _:{badmatch, {error, _}} ->
|
||||
{error, db_failure}
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
proxy65_schema() ->
|
||||
{record_info(fields, proxy65), #proxy65{sid = <<>>, pid_t = self()}}.
|
||||
|
||||
clean_table() ->
|
||||
?DEBUG("Cleaning Riak 'proxy65' table...", []),
|
||||
case ejabberd_riak:get(proxy65, proxy65_schema()) of
|
||||
{ok, Rs} ->
|
||||
lists:foreach(
|
||||
fun(#proxy65{sid = SID, pid_t = TPid, pid_i = IPid}) ->
|
||||
if node(TPid) == node() orelse
|
||||
(is_pid(IPid) andalso node(IPid) == node()) ->
|
||||
ejabberd_riak:delete(proxy65, SID);
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
end, Rs);
|
||||
{error, Reason} = Err ->
|
||||
?ERROR_MSG("Failed to clean Riak 'proxy65' table: ~p", [Reason]),
|
||||
Err
|
||||
end.
|
@ -1,32 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_pubsub_riak).
|
||||
|
||||
%% API
|
||||
-export([init/3]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _ServerHost, _Opts) ->
|
||||
ok.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
@ -1,118 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_roster_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_roster_riak).
|
||||
|
||||
-behaviour(mod_roster).
|
||||
|
||||
%% API
|
||||
-export([init/2, read_roster_version/2, write_roster_version/4,
|
||||
get_roster/2, get_roster_item/3, create_roster/1,
|
||||
roster_subscribe/4, remove_user/2, update_roster/4,
|
||||
del_roster/3, read_subscription_and_groups/3, transaction/2,
|
||||
import/3]).
|
||||
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
read_roster_version(LUser, LServer) ->
|
||||
case ejabberd_riak:get(roster_version, roster_version_schema(),
|
||||
{LUser, LServer}) of
|
||||
{ok, #roster_version{version = V}} -> {ok, V};
|
||||
_Err -> error
|
||||
end.
|
||||
|
||||
write_roster_version(LUser, LServer, _InTransaction, Ver) ->
|
||||
US = {LUser, LServer},
|
||||
ejabberd_riak:put(#roster_version{us = US, version = Ver},
|
||||
roster_version_schema()).
|
||||
|
||||
get_roster(LUser, LServer) ->
|
||||
case ejabberd_riak:get_by_index(roster, roster_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, Items} -> {ok, Items};
|
||||
_Err -> error
|
||||
end.
|
||||
|
||||
roster_subscribe(LUser, LServer, _LJID, Item) ->
|
||||
ejabberd_riak:put(Item, roster_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||
|
||||
transaction(_LServer, F) ->
|
||||
{atomic, F()}.
|
||||
|
||||
get_roster_item(LUser, LServer, LJID) ->
|
||||
case ejabberd_riak:get(roster, roster_schema(), {LUser, LServer, LJID}) of
|
||||
{ok, I} ->
|
||||
{ok, I};
|
||||
{error, _} ->
|
||||
error
|
||||
end.
|
||||
|
||||
remove_user(LUser, LServer) ->
|
||||
ejabberd_riak:delete_by_index(roster, <<"us">>, {LUser, LServer}).
|
||||
|
||||
update_roster(LUser, LServer, _LJID, Item) ->
|
||||
ejabberd_riak:put(Item, roster_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||
|
||||
del_roster(LUser, LServer, LJID) ->
|
||||
ejabberd_riak:delete(roster, {LUser, LServer, LJID}).
|
||||
|
||||
read_subscription_and_groups(LUser, LServer, LJID) ->
|
||||
case ejabberd_riak:get(roster, roster_schema(), {LUser, LServer, LJID}) of
|
||||
{ok, #roster{subscription = Subscription,
|
||||
ask = Ask,
|
||||
groups = Groups}} ->
|
||||
{ok, {Subscription, Ask, Groups}};
|
||||
_ ->
|
||||
error
|
||||
end.
|
||||
|
||||
create_roster(#roster{us = {LUser, LServer}} = RItem) ->
|
||||
ejabberd_riak:put(
|
||||
RItem, roster_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||
|
||||
import(_LServer, <<"rosterusers">>, RosterItem) ->
|
||||
{LUser, LServer} = RosterItem#roster.us,
|
||||
ejabberd_riak:put(RosterItem, roster_schema(),
|
||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]);
|
||||
import(LServer, <<"roster_version">>, [LUser, Ver]) ->
|
||||
RV = #roster_version{us = {LUser, LServer}, version = Ver},
|
||||
ejabberd_riak:put(RV, roster_version_schema()).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
roster_schema() ->
|
||||
{record_info(fields, roster), #roster{}}.
|
||||
|
||||
roster_version_schema() ->
|
||||
{record_info(fields, roster_version), #roster_version{}}.
|
@ -1,159 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_shared_roster_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_shared_roster_riak).
|
||||
|
||||
-behaviour(mod_shared_roster).
|
||||
|
||||
%% API
|
||||
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
|
||||
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||
get_user_groups/2, get_group_explicit_users/2,
|
||||
get_user_displayed_groups/3, is_user_in_group/3,
|
||||
add_user_to_group/3, remove_user_from_group/3, import/3]).
|
||||
|
||||
-include("mod_roster.hrl").
|
||||
-include("mod_shared_roster.hrl").
|
||||
-include("xmpp.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
list_groups(Host) ->
|
||||
case ejabberd_riak:get_keys_by_index(sr_group, <<"host">>, Host) of
|
||||
{ok, Gs} ->
|
||||
[G || {G, _} <- Gs];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
groups_with_opts(Host) ->
|
||||
case ejabberd_riak:get_by_index(sr_group, sr_group_schema(),
|
||||
<<"host">>, Host) of
|
||||
{ok, Rs} ->
|
||||
[{G, O} || #sr_group{group_host = {G, _}, opts = O} <- Rs];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
create_group(Host, Group, Opts) ->
|
||||
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
||||
opts = Opts},
|
||||
sr_group_schema(),
|
||||
[{'2i', [{<<"host">>, Host}]}])}.
|
||||
|
||||
delete_group(Host, Group) ->
|
||||
try
|
||||
ok = ejabberd_riak:delete(sr_group, {Group, Host}),
|
||||
ok = ejabberd_riak:delete_by_index(sr_user, <<"group_host">>,
|
||||
{Group, Host}),
|
||||
{atomic, ok}
|
||||
catch _:{badmatch, Err} ->
|
||||
{atomic, Err}
|
||||
end.
|
||||
|
||||
get_group_opts(Host, Group) ->
|
||||
case ejabberd_riak:get(sr_group, sr_group_schema(), {Group, Host}) of
|
||||
{ok, #sr_group{opts = Opts}} -> Opts;
|
||||
_ -> error
|
||||
end.
|
||||
|
||||
set_group_opts(Host, Group, Opts) ->
|
||||
{atomic, ejabberd_riak:put(#sr_group{group_host = {Group, Host},
|
||||
opts = Opts},
|
||||
sr_group_schema(),
|
||||
[{'2i', [{<<"host">>, Host}]}])}.
|
||||
|
||||
get_user_groups(US, Host) ->
|
||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
||||
{ok, Rs} ->
|
||||
[Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_group_explicit_users(Host, Group) ->
|
||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
||||
<<"group_host">>, {Group, Host}) of
|
||||
{ok, Rs} ->
|
||||
[R#sr_user.us || R <- Rs];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
|
||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(),
|
||||
<<"us">>, {LUser, LServer}) of
|
||||
{ok, Rs} ->
|
||||
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|
||||
|| #sr_user{group_host = {Group, _}} <- Rs];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
is_user_in_group(US, Group, Host) ->
|
||||
case ejabberd_riak:get_by_index(sr_user, sr_user_schema(), <<"us">>, US) of
|
||||
{ok, Rs} ->
|
||||
lists:any(
|
||||
fun(#sr_user{group_host = {G, H}}) ->
|
||||
(Group == G) and (Host == H)
|
||||
end, Rs);
|
||||
_Err ->
|
||||
false
|
||||
end.
|
||||
|
||||
add_user_to_group(Host, US, Group) ->
|
||||
{atomic, ejabberd_riak:put(
|
||||
#sr_user{us = US, group_host = {Group, Host}},
|
||||
sr_user_schema(),
|
||||
[{i, {US, {Group, Host}}},
|
||||
{'2i', [{<<"us">>, US},
|
||||
{<<"group_host">>, {Group, Host}}]}])}.
|
||||
|
||||
remove_user_from_group(Host, US, Group) ->
|
||||
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}.
|
||||
|
||||
import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) ->
|
||||
G = #sr_group{group_host = {Group, LServer},
|
||||
opts = ejabberd_sql:decode_term(SOpts)},
|
||||
ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, LServer}]}]);
|
||||
import(LServer, <<"sr_user">>, [SJID, Group|_]) ->
|
||||
#jid{luser = U, lserver = S} = jid:decode(SJID),
|
||||
User = #sr_user{us = {U, S}, group_host = {Group, LServer}},
|
||||
ejabberd_riak:put(User, sr_user_schema(),
|
||||
[{i, {{U, S}, {Group, LServer}}},
|
||||
{'2i', [{<<"us">>, {U, S}},
|
||||
{<<"group_host">>, {Group, LServer}}]}]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
sr_group_schema() ->
|
||||
{record_info(fields, sr_group), #sr_group{}}.
|
||||
|
||||
sr_user_schema() ->
|
||||
{record_info(fields, sr_user), #sr_user{}}.
|
@ -1,182 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_vcard_riak.erl
|
||||
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2019 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_vcard_riak).
|
||||
|
||||
-behaviour(mod_vcard).
|
||||
|
||||
%% API
|
||||
-export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2,
|
||||
search_fields/1, search_reported/1, import/3, stop/1]).
|
||||
-export([is_search_supported/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_vcard.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ok.
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
is_search_supported(_LServer) ->
|
||||
false.
|
||||
|
||||
get_vcard(LUser, LServer) ->
|
||||
case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of
|
||||
{ok, R} ->
|
||||
{ok, [R#vcard.vcard]};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
_ ->
|
||||
error
|
||||
end.
|
||||
|
||||
set_vcard(LUser, LServer, VCARD,
|
||||
#vcard_search{user = {User, _},
|
||||
fn = FN,
|
||||
lfn = LFN,
|
||||
family = Family,
|
||||
lfamily = LFamily,
|
||||
given = Given,
|
||||
lgiven = LGiven,
|
||||
middle = Middle,
|
||||
lmiddle = LMiddle,
|
||||
nickname = Nickname,
|
||||
lnickname = LNickname,
|
||||
bday = BDay,
|
||||
lbday = LBDay,
|
||||
ctry = CTRY,
|
||||
lctry = LCTRY,
|
||||
locality = Locality,
|
||||
llocality = LLocality,
|
||||
email = EMail,
|
||||
lemail = LEMail,
|
||||
orgname = OrgName,
|
||||
lorgname = LOrgName,
|
||||
orgunit = OrgUnit,
|
||||
lorgunit = LOrgUnit}) ->
|
||||
US = {LUser, LServer},
|
||||
{atomic,
|
||||
ejabberd_riak:put(#vcard{us = US, vcard = VCARD},
|
||||
vcard_schema(),
|
||||
[{'2i', [{<<"user">>, User},
|
||||
{<<"luser">>, LUser},
|
||||
{<<"fn">>, FN},
|
||||
{<<"lfn">>, LFN},
|
||||
{<<"family">>, Family},
|
||||
{<<"lfamily">>, LFamily},
|
||||
{<<"given">>, Given},
|
||||
{<<"lgiven">>, LGiven},
|
||||
{<<"middle">>, Middle},
|
||||
{<<"lmiddle">>, LMiddle},
|
||||
{<<"nickname">>, Nickname},
|
||||
{<<"lnickname">>, LNickname},
|
||||
{<<"bday">>, BDay},
|
||||
{<<"lbday">>, LBDay},
|
||||
{<<"ctry">>, CTRY},
|
||||
{<<"lctry">>, LCTRY},
|
||||
{<<"locality">>, Locality},
|
||||
{<<"llocality">>, LLocality},
|
||||
{<<"email">>, EMail},
|
||||
{<<"lemail">>, LEMail},
|
||||
{<<"orgname">>, OrgName},
|
||||
{<<"lorgname">>, LOrgName},
|
||||
{<<"orgunit">>, OrgUnit},
|
||||
{<<"lorgunit">>, LOrgUnit}]}])}.
|
||||
|
||||
search(_LServer, _Data, _AllowReturnAll, _MaxMatch) ->
|
||||
[].
|
||||
|
||||
search_fields(_LServer) ->
|
||||
[].
|
||||
|
||||
search_reported(_LServer) ->
|
||||
[].
|
||||
|
||||
remove_user(LUser, LServer) ->
|
||||
{atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}.
|
||||
|
||||
import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) ->
|
||||
El = fxml_stream:parse_element(XML),
|
||||
VCard = #vcard{us = {LUser, LServer}, vcard = El},
|
||||
#vcard_search{fn = FN,
|
||||
lfn = LFN,
|
||||
family = Family,
|
||||
lfamily = LFamily,
|
||||
given = Given,
|
||||
lgiven = LGiven,
|
||||
middle = Middle,
|
||||
lmiddle = LMiddle,
|
||||
nickname = Nickname,
|
||||
lnickname = LNickname,
|
||||
bday = BDay,
|
||||
lbday = LBDay,
|
||||
ctry = CTRY,
|
||||
lctry = LCTRY,
|
||||
locality = Locality,
|
||||
llocality = LLocality,
|
||||
email = EMail,
|
||||
lemail = LEMail,
|
||||
orgname = OrgName,
|
||||
lorgname = LOrgName,
|
||||
orgunit = OrgUnit,
|
||||
lorgunit = LOrgUnit} =
|
||||
mod_vcard:make_vcard_search(LUser, LUser, LServer, El),
|
||||
ejabberd_riak:put(VCard, vcard_schema(),
|
||||
[{'2i', [{<<"user">>, LUser},
|
||||
{<<"luser">>, LUser},
|
||||
{<<"fn">>, FN},
|
||||
{<<"lfn">>, LFN},
|
||||
{<<"family">>, Family},
|
||||
{<<"lfamily">>, LFamily},
|
||||
{<<"given">>, Given},
|
||||
{<<"lgiven">>, LGiven},
|
||||
{<<"middle">>, Middle},
|
||||
{<<"lmiddle">>, LMiddle},
|
||||
{<<"nickname">>, Nickname},
|
||||
{<<"lnickname">>, LNickname},
|
||||
{<<"bday">>, BDay},
|
||||
{<<"lbday">>, LBDay},
|
||||
{<<"ctry">>, CTRY},
|
||||
{<<"lctry">>, LCTRY},
|
||||
{<<"locality">>, Locality},
|
||||
{<<"llocality">>, LLocality},
|
||||
{<<"email">>, EMail},
|
||||
{<<"lemail">>, LEMail},
|
||||
{<<"orgname">>, OrgName},
|
||||
{<<"lorgname">>, LOrgName},
|
||||
{<<"orgunit">>, OrgUnit},
|
||||
{<<"lorgunit">>, LOrgUnit}]}]);
|
||||
import(_LServer, <<"vcard_search">>, _) ->
|
||||
ok.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
vcard_schema() ->
|
||||
{record_info(fields, vcard), #vcard{}}.
|
29
test/README
29
test/README
@ -1,12 +1,9 @@
|
||||
You need MySQL, PostgreSQL, Redis and Riak up and running.
|
||||
You need MySQL, PostgreSQL and Redis up and running.
|
||||
MySQL should be accepting TCP connections on localhost:3306.
|
||||
PostgreSQL should be accepting TCP connections on localhost:5432.
|
||||
Redis should be accepting TCP connections on localhost:6379.
|
||||
Riak should be accepting TCP connections on localhost:8087.
|
||||
MySQL and PostgreSQL should grant full access to user 'ejabberd_test' with
|
||||
password 'ejabberd_test' on database 'ejabberd_test'.
|
||||
Riak should be configured with leveldb as a database backend and -pz
|
||||
should be pointed to the directory with ejabberd BEAM files.
|
||||
|
||||
Here is a quick setup example:
|
||||
|
||||
@ -25,27 +22,3 @@ $ mysql
|
||||
mysql> CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';
|
||||
mysql> CREATE DATABASE ejabberd_test;
|
||||
mysql> GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';
|
||||
|
||||
-------------------
|
||||
Riak
|
||||
-------------------
|
||||
$ cat /etc/riak/vm.args
|
||||
...
|
||||
## Map/Reduce path
|
||||
-pz /path/to/ejabberd/ebin
|
||||
...
|
||||
|
||||
For version < 2.x:
|
||||
|
||||
$ cat /etc/riak/app.config:
|
||||
...
|
||||
{riak_kv, [
|
||||
{storage_backend, riak_kv_eleveldb_backend},
|
||||
...
|
||||
|
||||
For version >= 2.x:
|
||||
|
||||
$ cat /etc/riak/riak.conf:
|
||||
...
|
||||
storage_backend = leveldb
|
||||
...
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
You can start the Docker environment with Docker Compose, from ejabberd repository root.
|
||||
|
||||
The following command will launch MySQL, PostgreSQL, Redis and Riak, and keep the console
|
||||
The following command will launch MySQL, PostgreSQL, Redis and keep the console
|
||||
attached to it.
|
||||
|
||||
```
|
||||
mkdir test/docker/db/mysql/data
|
||||
mkdir test/docker/db/postgres/data
|
||||
mkdir test/docker/db/riak/data
|
||||
(cd test/docker; docker-compose up)
|
||||
```
|
||||
|
||||
@ -31,14 +30,6 @@ You can run tests with (from ejabberd repository root):
|
||||
make test
|
||||
```
|
||||
|
||||
At the moment, starting from Erlang 21, some Riak tests are broken because Riak client is not compliant with OTP 21+.
|
||||
|
||||
To run everything except Riak tests, you can use the following command:
|
||||
|
||||
```
|
||||
CT_BACKENDS=mnesia,redis,mysql,pgsql,sqlite,ldap,extauth rebar ct suites=ejabberd
|
||||
```
|
||||
|
||||
## Cleaning up the test environment
|
||||
|
||||
You can fully clean up the environment with:
|
||||
@ -52,5 +43,4 @@ If you want to clean the data, you can remove the data directories after the `do
|
||||
```
|
||||
rm -rf test/docker/db/mysql/data
|
||||
rm -rf test/docker/db/postgres/data
|
||||
rm -rf test/docker/db/riak/data
|
||||
```
|
||||
|
@ -1,53 +0,0 @@
|
||||
# docker build -t ejabberd/riak .
|
||||
# docker run --rm -it -p 8087:8087 -p 8098:8098 -v "`pwd`/ebin:/usr/lib/ejabberd/ebin" --name ejabberd-riak ejabberd/riak
|
||||
# docker exec -it ejabberd-riak /bin/bash
|
||||
# docker push ejabberd/riak:latest
|
||||
FROM ubuntu:16.04
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
# ENV RIAK_VERSION 2.0.9-1
|
||||
# install riak=${RIAK_VERSION} to fallback to an older version
|
||||
|
||||
RUN \
|
||||
apt-get update -qq && \
|
||||
apt-get install -y curl apt-utils iputils-ping && \
|
||||
curl -s https://packagecloud.io/install/repositories/basho/riak/script.deb.sh | bash && \
|
||||
apt-get install -y riak && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Expose default ports
|
||||
EXPOSE 8087
|
||||
EXPOSE 8098
|
||||
|
||||
# Expose volumes for data and logs
|
||||
VOLUME /var/log/riak
|
||||
VOLUME /var/lib/riak
|
||||
|
||||
# Expose volumes for ejabberd code for map/reduce in Riak.
|
||||
# It can be overloaded to provide a new ejabberd_riak.beam file.
|
||||
# Note that ejabberd_riak.beam needs to be compiled with Erlang/OTP R16
|
||||
# as this is the version of Erlang Basho has packaged with Riak.
|
||||
COPY ejabberd_riak.beam /usr/lib/ejabberd/ebin/ejabberd_riak.beam
|
||||
VOLUME /usr/lib/ejabberd/ebin
|
||||
|
||||
# Install custom start script
|
||||
COPY riak-cluster.sh /sbin/riak-cluster.sh
|
||||
RUN chmod a+x /sbin/riak-cluster.sh
|
||||
|
||||
# Change configuration to make it work with ejabberd
|
||||
COPY advanced.config /etc/riak/advanced.config
|
||||
COPY riak.conf /etc/riak/riak.conf
|
||||
|
||||
# Install custom hooks
|
||||
COPY prestart.d /etc/riak/prestart.d
|
||||
# COPY poststart.d /etc/riak/poststart.d
|
||||
|
||||
# Prepare for bootstrapping schemas
|
||||
RUN mkdir -p /etc/riak/schemas
|
||||
|
||||
# Clean up APT cache
|
||||
RUN rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
WORKDIR /var/lib/riak
|
||||
|
||||
CMD ["/sbin/riak-cluster.sh"]
|
@ -1,27 +0,0 @@
|
||||
%% Config file used to set advanced configuration options
|
||||
|
||||
[{lager,
|
||||
[
|
||||
{extra_sinks,
|
||||
[
|
||||
{object_lager_event,
|
||||
[{handlers,
|
||||
[{lager_file_backend,
|
||||
[{file, "/var/log/riak/object.log"},
|
||||
{level, info},
|
||||
{formatter_config, [date, " ", time," [",severity,"] ",message, "\n"]}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{async_threshold, 500},
|
||||
{async_threshold_window, 50}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]},
|
||||
|
||||
{riak_kv, [
|
||||
%% Other configs
|
||||
{add_paths, ["/usr/lib/ejabberd/ebin"]}
|
||||
]}
|
||||
].
|
Binary file not shown.
@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Add standard config items
|
||||
cat <<END >>$RIAK_CONF
|
||||
nodename = riak@$HOST
|
||||
distributed_cookie = $CLUSTER_NAME
|
||||
listener.protobuf.internal = $HOST:$PB_PORT
|
||||
listener.http.internal = $HOST:$HTTP_PORT
|
||||
END
|
@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Cluster start script to bootstrap a Riak cluster.
|
||||
#
|
||||
set -ex
|
||||
|
||||
if [[ -x /usr/sbin/riak ]]; then
|
||||
export RIAK=/usr/sbin/riak
|
||||
else
|
||||
export RIAK=$RIAK_HOME/bin/riak
|
||||
fi
|
||||
export RIAK_CONF=/etc/riak/riak.conf
|
||||
export USER_CONF=/etc/riak/user.conf
|
||||
export RIAK_ADVANCED_CONF=/etc/riak/advanced.config
|
||||
if [[ -x /usr/sbin/riak-admin ]]; then
|
||||
export RIAK_ADMIN=/usr/sbin/riak-admin
|
||||
else
|
||||
export RIAK_ADMIN=$RIAK_HOME/bin/riak-admin
|
||||
fi
|
||||
export SCHEMAS_DIR=/etc/riak/schemas/
|
||||
|
||||
# Set ports for PB and HTTP
|
||||
export PB_PORT=${PB_PORT:-8087}
|
||||
export HTTP_PORT=${HTTP_PORT:-8098}
|
||||
|
||||
# Use ping to discover our HOSTNAME because it's easier and more reliable than other methods
|
||||
export HOST=$(ping -c1 $HOSTNAME | awk '/^PING/ {print $3}' | sed 's/[()]//g')||'127.0.0.1'
|
||||
|
||||
# CLUSTER_NAME is used to name the nodes and is the value used in the distributed cookie
|
||||
export CLUSTER_NAME=${CLUSTER_NAME:-riak}
|
||||
|
||||
# The COORDINATOR_NODE is the first node in a cluster to which other nodes will eventually join
|
||||
export COORDINATOR_NODE=${COORDINATOR_NODE:-$HOSTNAME}
|
||||
export COORDINATOR_NODE_HOST=$(ping -c1 $COORDINATOR_NODE | awk '/^PING/ {print $3}' | sed 's/[()]//g')||'127.0.0.1'
|
||||
|
||||
# Run all prestart scripts
|
||||
PRESTART=$(find /etc/riak/prestart.d -name *.sh -print | sort)
|
||||
for s in $PRESTART; do
|
||||
. $s
|
||||
done
|
||||
|
||||
# Start the node and wait until fully up
|
||||
$RIAK start
|
||||
$RIAK_ADMIN wait-for-service riak_kv
|
||||
|
||||
# Run all poststart scripts
|
||||
POSTSTART=$(find /etc/riak/poststart.d -name *.sh -print | sort)
|
||||
for s in $POSTSTART; do
|
||||
. $s
|
||||
done
|
||||
|
||||
# Trap SIGTERM and SIGINT and tail the log file indefinitely
|
||||
tail -n 1024 -f /var/log/riak/console.log &
|
||||
PID=$!
|
||||
trap "$RIAK stop; kill $PID" SIGTERM SIGINT
|
||||
wait $PID
|
@ -1,682 +0,0 @@
|
||||
## Where to emit the default log messages (typically at 'info'
|
||||
## severity):
|
||||
## off: disabled
|
||||
## file: the file specified by log.console.file
|
||||
## console: to standard output (seen when using `riak attach-direct`)
|
||||
## both: log.console.file and standard out.
|
||||
##
|
||||
## Default: file
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: off, file, console, both
|
||||
log.console = file
|
||||
|
||||
## The severity level of the console log, default is 'info'.
|
||||
##
|
||||
## Default: info
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: debug, info, notice, warning, error, critical, alert, emergency, none
|
||||
log.console.level = info
|
||||
|
||||
## When 'log.console' is set to 'file' or 'both', the file where
|
||||
## console messages will be logged.
|
||||
##
|
||||
## Default: $(platform_log_dir)/console.log
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
log.console.file = $(platform_log_dir)/console.log
|
||||
|
||||
## The file where error messages will be logged.
|
||||
##
|
||||
## Default: $(platform_log_dir)/error.log
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
log.error.file = $(platform_log_dir)/error.log
|
||||
|
||||
## When set to 'on', enables log output to syslog.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
log.syslog = off
|
||||
|
||||
## Whether to enable the crash log.
|
||||
##
|
||||
## Default: on
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
log.crash = on
|
||||
|
||||
## If the crash log is enabled, the file where its messages will
|
||||
## be written.
|
||||
##
|
||||
## Default: $(platform_log_dir)/crash.log
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
log.crash.file = $(platform_log_dir)/crash.log
|
||||
|
||||
## Maximum size in bytes of individual messages in the crash log
|
||||
##
|
||||
## Default: 64KB
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a byte size with units, e.g. 10GB
|
||||
log.crash.maximum_message_size = 64KB
|
||||
|
||||
## Maximum size of the crash log in bytes, before it is rotated
|
||||
##
|
||||
## Default: 10MB
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a byte size with units, e.g. 10GB
|
||||
log.crash.size = 10MB
|
||||
|
||||
## The schedule on which to rotate the crash log. For more
|
||||
## information see:
|
||||
## https://github.com/basho/lager/blob/master/README.md#internal-log-rotation
|
||||
##
|
||||
## Default: $D0
|
||||
##
|
||||
## Acceptable values:
|
||||
## - text
|
||||
log.crash.rotation = $D0
|
||||
|
||||
## The number of rotated crash logs to keep. When set to
|
||||
## 'current', only the current open log file is kept.
|
||||
##
|
||||
## Default: 5
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## - the text "current"
|
||||
log.crash.rotation.keep = 5
|
||||
|
||||
## Name of the Erlang node
|
||||
##
|
||||
## Default: riak@127.0.0.1
|
||||
##
|
||||
## Acceptable values:
|
||||
## - text
|
||||
## nodename = riak@127.0.0.1
|
||||
|
||||
## Cookie for distributed node communication. All nodes in the
|
||||
## same cluster should use the same cookie or they will not be able to
|
||||
## communicate.
|
||||
##
|
||||
## Default: riak
|
||||
##
|
||||
## Acceptable values:
|
||||
## - text
|
||||
distributed_cookie = riak
|
||||
|
||||
## Sets the number of threads in async thread pool, valid range
|
||||
## is 0-1024. If thread support is available, the default is 64.
|
||||
## More information at: http://erlang.org/doc/man/erl.html
|
||||
##
|
||||
## Default: 64
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
erlang.async_threads = 64
|
||||
|
||||
## The number of concurrent ports/sockets
|
||||
## Valid range is 1024-134217727
|
||||
##
|
||||
## Default: 262144
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
erlang.max_ports = 262144
|
||||
|
||||
## Set scheduler forced wakeup interval. All run queues will be
|
||||
## scanned each Interval milliseconds. While there are sleeping
|
||||
## schedulers in the system, one scheduler will be woken for each
|
||||
## non-empty run queue found. An Interval of zero disables this
|
||||
## feature, which also is the default.
|
||||
## This feature is a workaround for lengthy executing native code, and
|
||||
## native code that do not bump reductions properly.
|
||||
## More information: http://www.erlang.org/doc/man/erl.html#+sfwi
|
||||
##
|
||||
## Default: 500
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## erlang.schedulers.force_wakeup_interval = 500
|
||||
|
||||
## Enable or disable scheduler compaction of load. By default
|
||||
## scheduler compaction of load is enabled. When enabled, load
|
||||
## balancing will strive for a load distribution which causes as many
|
||||
## scheduler threads as possible to be fully loaded (i.e., not run out
|
||||
## of work). This is accomplished by migrating load (e.g. runnable
|
||||
## processes) into a smaller set of schedulers when schedulers
|
||||
## frequently run out of work. When disabled, the frequency with which
|
||||
## schedulers run out of work will not be taken into account by the
|
||||
## load balancing logic.
|
||||
## More information: http://www.erlang.org/doc/man/erl.html#+scl
|
||||
##
|
||||
## Default: false
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: true, false
|
||||
## erlang.schedulers.compaction_of_load = false
|
||||
|
||||
## Enable or disable scheduler utilization balancing of load. By
|
||||
## default scheduler utilization balancing is disabled and instead
|
||||
## scheduler compaction of load is enabled which will strive for a
|
||||
## load distribution which causes as many scheduler threads as
|
||||
## possible to be fully loaded (i.e., not run out of work). When
|
||||
## scheduler utilization balancing is enabled the system will instead
|
||||
## try to balance scheduler utilization between schedulers. That is,
|
||||
## strive for equal scheduler utilization on all schedulers.
|
||||
## More information: http://www.erlang.org/doc/man/erl.html#+sub
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: true, false
|
||||
## erlang.schedulers.utilization_balancing = true
|
||||
|
||||
## Number of partitions in the cluster (only valid when first
|
||||
## creating the cluster). Must be a power of 2, minimum 8 and maximum
|
||||
## 1024.
|
||||
##
|
||||
## Default: 64
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## ring_size = 64
|
||||
|
||||
## Number of concurrent node-to-node transfers allowed.
|
||||
##
|
||||
## Default: 2
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## transfer_limit = 2
|
||||
|
||||
## Default cert location for https can be overridden
|
||||
## with the ssl config variable, for example:
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
## ssl.certfile = $(platform_etc_dir)/cert.pem
|
||||
|
||||
## Default key location for https can be overridden with the ssl
|
||||
## config variable, for example:
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
## ssl.keyfile = $(platform_etc_dir)/key.pem
|
||||
|
||||
## Default signing authority location for https can be overridden
|
||||
## with the ssl config variable, for example:
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a file
|
||||
## ssl.cacertfile = $(platform_etc_dir)/cacertfile.pem
|
||||
|
||||
## DTrace support Do not enable 'dtrace' unless your Erlang/OTP
|
||||
## runtime is compiled to support DTrace. DTrace is available in
|
||||
## R15B01 (supported by the Erlang/OTP official source package) and in
|
||||
## R14B04 via a custom source repository & branch.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
dtrace = off
|
||||
|
||||
## Platform-specific installation paths (substituted by rebar)
|
||||
##
|
||||
## Default: /usr/sbin
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
platform_bin_dir = /usr/sbin
|
||||
|
||||
##
|
||||
## Default: /var/lib/riak
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
platform_data_dir = /var/lib/riak
|
||||
|
||||
##
|
||||
## Default: /etc/riak
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
platform_etc_dir = /etc/riak
|
||||
|
||||
##
|
||||
## Default: /usr/lib/riak/lib
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
platform_lib_dir = /usr/lib/riak/lib
|
||||
|
||||
##
|
||||
## Default: /var/log/riak
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
platform_log_dir = /var/log/riak
|
||||
|
||||
## Enable consensus subsystem. Set to 'on' to enable the
|
||||
## consensus subsystem used for strongly consistent Riak operations.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
## strong_consistency = on
|
||||
|
||||
## listener.http.<name> is an IP address and TCP port that the Riak
|
||||
## HTTP interface will bind.
|
||||
##
|
||||
## Default: 127.0.0.1:8098
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an IP/port pair, e.g. 127.0.0.1:10011
|
||||
## listener.http.internal = 127.0.0.1:8098
|
||||
|
||||
## listener.protobuf.<name> is an IP address and TCP port that the Riak
|
||||
## Protocol Buffers interface will bind.
|
||||
##
|
||||
## Default: 127.0.0.1:8087
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an IP/port pair, e.g. 127.0.0.1:10011
|
||||
## listener.protobuf.internal = 127.0.0.1:8087
|
||||
|
||||
## The maximum length to which the queue of pending connections
|
||||
## may grow. If set, it must be an integer > 0. If you anticipate a
|
||||
## huge number of connections being initialized *simultaneously*, set
|
||||
## this number higher.
|
||||
##
|
||||
## Default: 128
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## protobuf.backlog = 128
|
||||
|
||||
## listener.https.<name> is an IP address and TCP port that the Riak
|
||||
## HTTPS interface will bind.
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an IP/port pair, e.g. 127.0.0.1:10011
|
||||
## listener.https.internal = 127.0.0.1:8098
|
||||
|
||||
## How Riak will repair out-of-sync keys. Some features require
|
||||
## this to be set to 'active', including search.
|
||||
## * active: out-of-sync keys will be repaired in the background
|
||||
## * passive: out-of-sync keys are only repaired on read
|
||||
## * active-debug: like active, but outputs verbose debugging
|
||||
## information
|
||||
##
|
||||
## Default: active
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: active, passive, active-debug
|
||||
anti_entropy = active
|
||||
|
||||
## Specifies the storage engine used for Riak's key-value data
|
||||
## and secondary indexes (if supported).
|
||||
##
|
||||
## Default: bitcask
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: bitcask, leveldb, memory, multi, prefix_multi
|
||||
storage_backend = leveldb
|
||||
|
||||
## Simplify prefix_multi configuration for Riak CS. Keep this
|
||||
## commented out unless Riak is configured for Riak CS.
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## cs_version = 20000
|
||||
|
||||
## Controls which binary representation of a riak value is stored
|
||||
## on disk.
|
||||
## * 0: Original erlang:term_to_binary format. Higher space overhead.
|
||||
## * 1: New format for more compact storage of small values.
|
||||
##
|
||||
## Default: 1
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the integer 1
|
||||
## - the integer 0
|
||||
object.format = 1
|
||||
|
||||
## Reading or writing objects bigger than this size will write a
|
||||
## warning in the logs.
|
||||
##
|
||||
## Default: 5MB
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a byte size with units, e.g. 10GB
|
||||
object.size.warning_threshold = 5MB
|
||||
|
||||
## Writing an object bigger than this will send a failure to the
|
||||
## client.
|
||||
##
|
||||
## Default: 50MB
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a byte size with units, e.g. 10GB
|
||||
object.size.maximum = 50MB
|
||||
|
||||
## Writing an object with more than this number of siblings will
|
||||
## generate a warning in the logs.
|
||||
##
|
||||
## Default: 25
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
object.siblings.warning_threshold = 25
|
||||
|
||||
## Writing an object with more than this number of siblings will
|
||||
## send a failure to the client.
|
||||
##
|
||||
## Default: 100
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
object.siblings.maximum = 100
|
||||
|
||||
## Whether to allow list buckets.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.list_buckets = enabled
|
||||
|
||||
## Whether to allow streaming list buckets.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.stream_list_buckets = enabled
|
||||
|
||||
## Whether to allow list keys.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.list_keys = enabled
|
||||
|
||||
## Whether to allow streaming list keys.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.stream_list_keys = enabled
|
||||
|
||||
## Whether to allow secondary index queries.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.secondary_index = enabled
|
||||
|
||||
## Whether to allow streaming secondary index queries.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.stream_secondary_index = enabled
|
||||
|
||||
## Whether to allow term-based map-reduce.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.map_reduce = enabled
|
||||
|
||||
## Whether to allow JavaScript map-reduce.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_kv.map_reduce_js = enabled
|
||||
|
||||
## A path under which bitcask data files will be stored.
|
||||
##
|
||||
## Default: $(platform_data_dir)/bitcask
|
||||
##
|
||||
## Acceptable values:
|
||||
## - the path to a directory
|
||||
bitcask.data_root = $(platform_data_dir)/bitcask
|
||||
|
||||
## Configure how Bitcask writes data to disk.
|
||||
## erlang: Erlang's built-in file API
|
||||
## nif: Direct calls to the POSIX C API
|
||||
## The NIF mode provides higher throughput for certain
|
||||
## workloads, but has the potential to negatively impact
|
||||
## the Erlang VM, leading to higher worst-case latencies
|
||||
## and possible throughput collapse.
|
||||
##
|
||||
## Default: erlang
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: erlang, nif
|
||||
bitcask.io_mode = erlang
|
||||
|
||||
## Set to 'off' to disable the admin panel.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
riak_control = off
|
||||
|
||||
## Authentication mode used for access to the admin panel.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: off, userlist
|
||||
riak_control.auth.mode = off
|
||||
|
||||
## If riak control's authentication mode (riak_control.auth.mode)
|
||||
## is set to 'userlist' then this is the list of usernames and
|
||||
## passwords for access to the admin panel.
|
||||
## To create users with given names, add entries of the format:
|
||||
## riak_control.auth.user.USERNAME.password = PASSWORD
|
||||
## replacing USERNAME with the desired username and PASSWORD with the
|
||||
## desired password for that user.
|
||||
##
|
||||
## Acceptable values:
|
||||
## - text
|
||||
## riak_control.auth.user.admin.password = pass
|
||||
|
||||
## This parameter defines the percentage of total server memory
|
||||
## to assign to LevelDB. LevelDB will dynamically adjust its internal
|
||||
## cache sizes to stay within this size. The memory size can
|
||||
## alternately be assigned as a byte count via leveldb.maximum_memory
|
||||
## instead.
|
||||
##
|
||||
## Default: 70
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
leveldb.maximum_memory.percent = 70
|
||||
|
||||
## Enables or disables the compression of data on disk.
|
||||
## Enabling (default) saves disk space. Disabling may reduce read
|
||||
## latency but increase overall disk activity. Option can be
|
||||
## changed at any time, but will not impact data on disk until
|
||||
## next time a file requires compaction.
|
||||
##
|
||||
## Default: on
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
leveldb.compression = on
|
||||
|
||||
## Selection of compression algorithms. snappy is
|
||||
## original compression supplied for leveldb. lz4 is new
|
||||
## algorithm that compresses to similar volume but averages twice
|
||||
## as fast on writes and four times as fast on reads.
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: snappy, lz4
|
||||
leveldb.compression.algorithm = lz4
|
||||
|
||||
##
|
||||
## Default: on
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
## multi_backend.name.leveldb.compression = on
|
||||
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: snappy, lz4
|
||||
## multi_backend.name.leveldb.compression.algorithm = lz4
|
||||
|
||||
## Whether to allow search queries.
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.riak_search.query = enabled
|
||||
|
||||
## To enable Search set this 'on'.
|
||||
##
|
||||
## Default: off
|
||||
##
|
||||
## Acceptable values:
|
||||
## - on or off
|
||||
search = off
|
||||
|
||||
## How long Riak will wait for Solr to start. The start sequence
|
||||
## will be tried twice. If both attempts timeout, then the Riak node
|
||||
## will be shutdown. This may need to be increased as more data is
|
||||
## indexed and Solr takes longer to start. Values lower than 1s will
|
||||
## be rounded up to the minimum 1s.
|
||||
##
|
||||
## Default: 30s
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a time duration with units, e.g. '10s' for 10 seconds
|
||||
search.solr.start_timeout = 30s
|
||||
|
||||
## The port number which Solr binds to.
|
||||
## NOTE: Binds on every interface.
|
||||
##
|
||||
## Default: 8093
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
search.solr.port = 8093
|
||||
|
||||
## The port number which Solr JMX binds to.
|
||||
## NOTE: Binds on every interface.
|
||||
##
|
||||
## Default: 8985
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
search.solr.jmx_port = 8985
|
||||
|
||||
## The options to pass to the Solr JVM. Non-standard options,
|
||||
## i.e. -XX, may not be portable across JVM implementations.
|
||||
## E.g. -XX:+UseCompressedStrings
|
||||
##
|
||||
## Default: -d64 -Xms1g -Xmx1g -XX:+UseStringCache -XX:+UseCompressedOops
|
||||
##
|
||||
## Acceptable values:
|
||||
## - text
|
||||
search.solr.jvm_options = -d64 -Xms1g -Xmx1g -XX:+UseStringCache -XX:+UseCompressedOops
|
||||
|
||||
## The minimum batch size, in number of Riak objects. Any batches that
|
||||
## are smaller than this amount will not be immediately flushed to Solr,
|
||||
## but are guaranteed to be flushed within the
|
||||
## "search.queue.batch.flush_interval".
|
||||
##
|
||||
## Default: 10
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## search.queue.batch.minimum = 10
|
||||
|
||||
## The maximum batch size, in number of Riak objects. Any batches that are
|
||||
## larger than this amount will be split, where the first
|
||||
## search.queue.batch.maximum set of objects will be flushed to Solr, and
|
||||
## the remaining objects enqueued for that index will be retained until the
|
||||
## next batch is delivered. This parameter ensures that at most
|
||||
## "search.queue.batch.maximum object" will be delivered into Solr in any
|
||||
## given request.
|
||||
##
|
||||
## Default: 500
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## search.queue.batch.maximum = 500
|
||||
|
||||
## The maximum delay between notification to flush batches to Solr. This
|
||||
## setting is used to increase or decrease the frequency of batch delivery
|
||||
## into Solr, specifically for relatively low-volume input into Riak. This
|
||||
## setting ensures that data will be delivered into Solr in accordance with
|
||||
## the "search.queue.batch.minimum" and "search.queue.batch.maximum"
|
||||
## settings within the specified interval. Batches that are smaller than
|
||||
## "search.queue.batch.minimum" will be delivered to Solr within this
|
||||
## interval. This setting will generally hav no effect on heavily loaded
|
||||
## systems.
|
||||
##
|
||||
## Default: 500ms
|
||||
##
|
||||
## Acceptable values:
|
||||
## - a time duration with units, e.g. '10s' for 10 seconds
|
||||
## - the text "infinity"
|
||||
## search.queue.batch.flush_interval = 500ms
|
||||
|
||||
## The queue high watermark. If the total number of queued messages in a
|
||||
## Solr Queue Worker instance exceeds this limit, then the calling vnode
|
||||
## will be blocked until the total number falls below this limit. This
|
||||
## parameter exercises flow control between Riak and the Riak
|
||||
## Search batching subsystem if writes into Solr start to fall behind.
|
||||
##
|
||||
## Default: 1000
|
||||
##
|
||||
## Acceptable values:
|
||||
## - an integer
|
||||
## search.queue.high_watermark = 1000
|
||||
|
||||
## The strategy for how we handle purging when we hit the
|
||||
## search.queue.high_watermark.
|
||||
## - purge_one -> Removes the oldest item on the queue from an
|
||||
## erroring (references to fuses blown in the code) index in
|
||||
## order to get below the search.queue.high_watermark.
|
||||
## - purge_index -> Removes all items associated with one random
|
||||
## erroring (references to fuses blown in the code) index in
|
||||
## order to get below the search.queue.high_watermark.
|
||||
## - off -> purging is disabled
|
||||
##
|
||||
## Default: purge_one
|
||||
##
|
||||
## Acceptable values:
|
||||
## - one of: purge_one, purge_index, off
|
||||
## search.queue.high_watermark.purge_strategy = purge_one
|
||||
|
||||
## Whether to allow Yokozuna queries on this node
|
||||
##
|
||||
## Default: enabled
|
||||
##
|
||||
## Acceptable values:
|
||||
## - enabled or disabled
|
||||
## cluster.job.yokozuna.query = enabled
|
@ -35,14 +35,3 @@ services:
|
||||
container_name: ejabberd-redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
riak:
|
||||
image: ejabberd/riak:latest
|
||||
container_name: ejabberd-riak
|
||||
ports:
|
||||
- 8087:8087
|
||||
- 8098:8098
|
||||
volumes:
|
||||
- ./db/riak/data:/var/lib/riak
|
||||
environment:
|
||||
WAIT_FOR_ERLANG: 60
|
||||
|
@ -125,15 +125,6 @@ do_init_per_group(ldap, Config) ->
|
||||
set_opt(server, ?LDAP_VHOST, Config);
|
||||
do_init_per_group(extauth, Config) ->
|
||||
set_opt(server, ?EXTAUTH_VHOST, Config);
|
||||
do_init_per_group(riak, Config) ->
|
||||
case ejabberd_riak:is_connected() of
|
||||
true ->
|
||||
mod_muc:shutdown_rooms(?RIAK_VHOST),
|
||||
NewConfig = set_opt(server, ?RIAK_VHOST, Config),
|
||||
clear_riak_tables(NewConfig);
|
||||
Err ->
|
||||
{skip, {riak_not_available, Err}}
|
||||
end;
|
||||
do_init_per_group(s2s, Config) ->
|
||||
ejabberd_config:set_option({s2s_use_starttls, ?COMMON_VHOST}, required),
|
||||
ejabberd_config:set_option(ca_file, "ca.pem"),
|
||||
@ -177,13 +168,6 @@ end_per_group(ldap, _Config) ->
|
||||
ok;
|
||||
end_per_group(extauth, _Config) ->
|
||||
ok;
|
||||
end_per_group(riak, Config) ->
|
||||
case ejabberd_riak:is_connected() of
|
||||
true ->
|
||||
clear_riak_tables(Config);
|
||||
false ->
|
||||
Config
|
||||
end;
|
||||
end_per_group(component, _Config) ->
|
||||
ok;
|
||||
end_per_group(s2s, Config) ->
|
||||
@ -379,28 +363,6 @@ no_db_tests() ->
|
||||
carbons_tests:single_cases(),
|
||||
carbons_tests:master_slave_cases()].
|
||||
|
||||
db_tests(riak) ->
|
||||
%% No support for mod_pubsub
|
||||
[{single_user, [sequence],
|
||||
[test_register,
|
||||
legacy_auth_tests(),
|
||||
auth_plain,
|
||||
auth_md5,
|
||||
presence_broadcast,
|
||||
last,
|
||||
roster_tests:single_cases(),
|
||||
%%private_tests:single_cases(),
|
||||
privacy_tests:single_cases(),
|
||||
vcard_tests:single_cases(),
|
||||
muc_tests:single_cases(),
|
||||
offline_tests:single_cases(),
|
||||
test_unregister]},
|
||||
muc_tests:master_slave_cases(),
|
||||
privacy_tests:master_slave_cases(),
|
||||
roster_tests:master_slave_cases(),
|
||||
offline_tests:master_slave_cases(riak),
|
||||
vcard_tests:master_slave_cases(),
|
||||
announce_tests:master_slave_cases()];
|
||||
db_tests(DB) when DB == mnesia; DB == redis ->
|
||||
[{single_user, [sequence],
|
||||
[test_register,
|
||||
@ -519,8 +481,7 @@ groups() ->
|
||||
{redis, [sequence], db_tests(redis)},
|
||||
{mysql, [sequence], db_tests(mysql)},
|
||||
{pgsql, [sequence], db_tests(pgsql)},
|
||||
{sqlite, [sequence], db_tests(sqlite)},
|
||||
{riak, [sequence], db_tests(riak)}].
|
||||
{sqlite, [sequence], db_tests(sqlite)}].
|
||||
|
||||
all() ->
|
||||
[{group, ldap},
|
||||
@ -531,7 +492,6 @@ all() ->
|
||||
{group, pgsql},
|
||||
{group, sqlite},
|
||||
{group, extauth},
|
||||
{group, riak},
|
||||
{group, component},
|
||||
{group, s2s},
|
||||
stop_ejabberd].
|
||||
@ -1113,16 +1073,3 @@ split(Data) ->
|
||||
(_) ->
|
||||
true
|
||||
end, re:split(Data, <<"\s">>)).
|
||||
|
||||
clear_riak_tables(Config) ->
|
||||
User = ?config(user, Config),
|
||||
Server = ?config(server, Config),
|
||||
Master = <<"test_master!#$%^*()`~+-;_=[]{}|\\">>,
|
||||
Slave = <<"test_slave!#$%^*()`~+-;_=[]{}|\\">>,
|
||||
ejabberd_auth:remove_user(User, Server),
|
||||
ejabberd_auth:remove_user(Master, Server),
|
||||
ejabberd_auth:remove_user(Slave, Server),
|
||||
ejabberd_riak:delete(muc_room),
|
||||
ejabberd_riak:delete(muc_registered),
|
||||
timer:sleep(timer:seconds(5)),
|
||||
Config.
|
||||
|
@ -1,44 +0,0 @@
|
||||
define_macro:
|
||||
RIAK_CONFIG:
|
||||
queue_type: ram
|
||||
auth_method: riak
|
||||
sm_db_type: riak
|
||||
modules:
|
||||
mod_announce:
|
||||
db_type: riak
|
||||
access: local
|
||||
mod_blocking: []
|
||||
mod_caps:
|
||||
db_type: riak
|
||||
mod_last:
|
||||
db_type: riak
|
||||
mod_muc:
|
||||
db_type: riak
|
||||
mod_offline:
|
||||
db_type: riak
|
||||
mod_privacy:
|
||||
db_type: riak
|
||||
mod_private:
|
||||
db_type: riak
|
||||
mod_roster:
|
||||
versioning: true
|
||||
store_current_id: true
|
||||
db_type: riak
|
||||
mod_vcard:
|
||||
db_type: riak
|
||||
mod_vcard_xupdate: []
|
||||
mod_adhoc: []
|
||||
mod_configure: []
|
||||
mod_disco: []
|
||||
mod_ping: []
|
||||
mod_proxy65: []
|
||||
mod_s2s_dialback: []
|
||||
mod_legacy_auth: []
|
||||
mod_register:
|
||||
welcome_message:
|
||||
subject: "Welcome!"
|
||||
body: "Hi.
|
||||
Welcome to this XMPP server."
|
||||
mod_stats: []
|
||||
mod_time: []
|
||||
mod_version: []
|
@ -6,7 +6,6 @@ include_config_file:
|
||||
- ejabberd.mysql.yml
|
||||
- ejabberd.pgsql.yml
|
||||
- ejabberd.redis.yml
|
||||
- ejabberd.riak.yml
|
||||
- ejabberd.sqlite.yml
|
||||
|
||||
host_config:
|
||||
@ -15,7 +14,6 @@ host_config:
|
||||
mysql.localhost: MYSQL_CONFIG
|
||||
mnesia.localhost: MNESIA_CONFIG
|
||||
redis.localhost: REDIS_CONFIG
|
||||
riak.localhost: RIAK_CONFIG
|
||||
ldap.localhost: LDAP_CONFIG
|
||||
extauth.localhost: EXTAUTH_CONFIG
|
||||
localhost:
|
||||
@ -31,7 +29,6 @@ hosts:
|
||||
- pgsql.localhost
|
||||
- extauth.localhost
|
||||
- ldap.localhost
|
||||
- riak.localhost
|
||||
- sqlite.localhost
|
||||
|
||||
shaper_rules:
|
||||
|
@ -145,14 +145,9 @@ unsupported_iq(Config) ->
|
||||
master_slave_cases(DB) ->
|
||||
{offline_master_slave, [sequence],
|
||||
[master_slave_test(flex),
|
||||
master_slave_test(send_all)] ++
|
||||
case DB of
|
||||
riak -> [];
|
||||
_ -> [
|
||||
master_slave_test(from_mam),
|
||||
master_slave_test(mucsub_mam)]
|
||||
end
|
||||
}.
|
||||
master_slave_test(send_all),
|
||||
master_slave_test(from_mam),
|
||||
master_slave_test(mucsub_mam)]}.
|
||||
|
||||
flex_master(Config) ->
|
||||
send_messages(Config, 5),
|
||||
|
@ -172,9 +172,9 @@ setup_ejabberd_lib_path(Config) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% Read environment variable CT_DB=riak,mysql to limit the backends to test.
|
||||
%% Read environment variable CT_DB=mysql to limit the backends to test.
|
||||
%% You can thus limit the backend you want to test with:
|
||||
%% CT_BACKENDS=riak,mysql rebar ct suites=ejabberd
|
||||
%% CT_BACKENDS=mysql rebar ct suites=ejabberd
|
||||
get_config_backends() ->
|
||||
EnvBackends = case os:getenv("CT_BACKENDS") of
|
||||
false -> ?BACKENDS;
|
||||
|
@ -96,11 +96,10 @@
|
||||
-define(SQLITE_VHOST, <<"sqlite.localhost">>).
|
||||
-define(LDAP_VHOST, <<"ldap.localhost">>).
|
||||
-define(EXTAUTH_VHOST, <<"extauth.localhost">>).
|
||||
-define(RIAK_VHOST, <<"riak.localhost">>).
|
||||
-define(S2S_VHOST, <<"s2s.localhost">>).
|
||||
-define(UPLOAD_VHOST, <<"upload.localhost">>).
|
||||
|
||||
-define(BACKENDS, [mnesia, redis, mysql, pgsql, sqlite, ldap, extauth, riak]).
|
||||
-define(BACKENDS, [mnesia, redis, mysql, pgsql, sqlite, ldap, extauth]).
|
||||
|
||||
insert(Val, N, Tuple) ->
|
||||
L = tuple_to_list(Tuple),
|
||||
|
@ -36,7 +36,6 @@
|
||||
{sqlite, @sqlite@}.
|
||||
{pam, @pam@}.
|
||||
{zlib, @zlib@}.
|
||||
{riak, @riak@}.
|
||||
{redis, @redis@}.
|
||||
{elixir, @elixir@}.
|
||||
{stun, @stun@}.
|
||||
|
Loading…
Reference in New Issue
Block a user